Skip to content

Commit a6cd57b

Browse files
vikram-rana-synapticsSynaptics GitLab CI
andauthored
Release for version 0.2.1 (#3)
Co-authored-by: Synaptics GitLab CI <[email protected]>
1 parent 92cb7dd commit a6cd57b

24 files changed

+710
-145
lines changed
Lines changed: 31 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,31 @@
1+
name: Prepare release pull request
2+
3+
on:
4+
push:
5+
branches:
6+
- documentation/release/*
7+
8+
permissions:
9+
contents: write
10+
pull-requests: write
11+
12+
jobs:
13+
create-pull-request:
14+
runs-on: ubuntu-latest
15+
steps:
16+
- uses: actions/checkout@v4
17+
- uses: actions/setup-python@v5
18+
with:
19+
python-version: "3.12"
20+
- name: Install dependencies
21+
run: |
22+
pip install --upgrade pip setuptools wheel
23+
pip install --upgrade --requirement docs/requirements.txt
24+
- name: Sphinx build
25+
run: |
26+
sphinx-build docs _build
27+
- name: Create pull request
28+
run: gh pr create --base main --head ${{ github.ref_name }} --fill --label documentation || gh pr edit --add-label documentation
29+
env:
30+
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
31+

.gitlab-ci.yml

Lines changed: 53 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,53 @@
1+
image: python:3.12
2+
3+
build:
4+
stage: build
5+
before_script:
6+
- python --version ; pip --version # For debugging
7+
- pip install virtualenv
8+
- virtualenv venv
9+
- source venv/bin/activate
10+
script:
11+
- pip install sphinx sphinx-rtd-theme
12+
- sphinx-build docs build
13+
rules:
14+
- if: $CI_COMMIT_BRANCH !~ /documentation.*/ # Don't build on documentation branches.
15+
16+
prepare_release:
17+
stage: deploy
18+
before_script:
19+
- 'command -v ssh-agent >/dev/null || ( apt-get update -y && apt-get install openssh-client -y )' # Ensure ssh-agent is installed and running
20+
- eval $(ssh-agent -s)
21+
- ssh-add -L || true
22+
- chmod 400 "$GITLAB_DEPLOY_KEY" # Add ssh deploy keys
23+
- chmod 400 "$GITHUB_DEPLOY_KEY"
24+
- mkdir -p ~/.ssh
25+
- chmod 700 ~/.ssh
26+
- echo 'echo $GITLAB_DEPLOY_PASSPHRASE' > ~/.ssh/gitlab_passphrase && chmod 700 ~/.ssh/gitlab_passphrase
27+
- echo 'echo $GITHUB_DEPLOY_PASSPHRASE' > ~/.ssh/github_passphrase && chmod 700 ~/.ssh/github_passphrase
28+
- DISPLAY=None SSH_ASKPASS=~/.ssh/gitlab_passphrase ssh-add "$GITLAB_DEPLOY_KEY"
29+
- DISPLAY=None SSH_ASKPASS=~/.ssh/github_passphrase ssh-add "$GITHUB_DEPLOY_KEY"
30+
- ssh-add -L
31+
- rm ~/.ssh/*passphrase
32+
- touch ~/.ssh/known_hosts # Add known ssh hosts
33+
- echo "$GITLAB_KNOWN_HOSTS" >> ~/.ssh/known_hosts
34+
- echo "$GITHUB_KNOWN_HOSTS" >> ~/.ssh/known_hosts
35+
- git version # Set up git credentials
36+
- git config --global user.email "$GIT_EMAIL"
37+
- git config --global user.name "$GIT_USERNAME"
38+
script:
39+
- git status
40+
- 'git for-each-ref --count=2 --sort=-creatordate --format "%(refname)" refs/tags/[0-9]*\.[0-9]*\.[0-9]* | sed "s=refs/tags/=="'
41+
- '{ IFS= read -r new_version && IFS= read -r old_version; } < <(git for-each-ref --count=2 --sort=-creatordate --format "%(refname)" refs/tags/[0-9]*\.[0-9]*\.[0-9]* | sed "s=refs/tags/==")'
42+
- 'echo "New version: $new_version"'
43+
- 'echo "Old version: $old_version"'
44+
- git remote add gitlab "$GITLAB_URL"
45+
- git remote add github "$GITHUB_URL"
46+
- git fetch --all
47+
- git reset --soft github/main
48+
- git commit -m "Release for version $new_version"
49+
- git push --verbose --push-option ci.skip gitlab "HEAD:refs/heads/documentation/release/$new_version" # Skip ci to avoid potential infinite recursion loop on ci builds
50+
- git push --verbose github "HEAD:refs/heads/documentation/release/$new_version"
51+
rules:
52+
- if: '$CI_COMMIT_TAG =~ /^(0|[1-9]\d*)\.(0|[1-9]\d*)\.(0|[1-9]\d*)(?:-((?:0|[1-9]\d*|\d*[a-zA-Z-][0-9a-zA-Z-]*)(?:\.(?:0|[1-9]\d*|\d*[a-zA-Z-][0-9a-zA-Z-]*))*))?(?:\+([0-9a-zA-Z-]+(?:\.[0-9a-zA-Z-]+)*))?$/' # Bit OTT but semver.org/#is-there-a-suggested-regular-expression-regex-to-check-a-semver-string
53+

docs/conf.py

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -45,6 +45,7 @@
4545
extensions = [
4646
"sphinx.ext.autodoc",
4747
"sphinx.ext.doctest",
48+
"sphinx.ext.extlinks",
4849
"sphinx.ext.intersphinx",
4950
"sphinx.ext.todo",
5051
"sphinx.ext.coverage",
@@ -181,3 +182,8 @@
181182

182183
# Example configuration for intersphinx: refer to the Python standard library.
183184
intersphinx_mapping = {"python": ("https://docs.python.org/3.5", None)}
185+
186+
# External weblinks
187+
extlinks = {
188+
"githubSamples": ('https://github.com/DisplayLink/dl-7450/tree/main/%s', None)
189+
}

docs/dl_7450/quickstart.rst

Lines changed: 19 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -21,27 +21,29 @@ shown on the screen should match the sticker on the DL-7450 board.
2121

2222
.. image:: ../images/start_screen.png
2323

24-
25-
You should have received an archive file called *dl7450-samples.tgz*. Expand this archive:
26-
27-
.. image:: ../images/samples.png
28-
29-
The resulting files consist of some sample applications and README documents
30-
that show how to create some simple applications that will run on the DL-7450.
31-
32-
To send code to the dock we have provided a ``send_code.py`` python script, located
33-
in the *scripts* directory, to run this you will need some flavour of python 3
34-
installed, and the ``requests`` package installed. The script has been tested against versions 3.8 and 3.12.
35-
36-
For example, when running from the root folder of that archive::
24+
The DL-7450 SDK includes a set of sample code availabe to download
25+
:githubSamples:`here <samples>`. These, or your own bespoke applications can be
26+
sent to the dock via a REST API. We have provided a script, ``send_code.py``
27+
available :githubSamples:`here <scripts/send_code.py>`. To run this you will
28+
need some flavour of python 3 installed, and the ``requests`` package
29+
installed. You will also need the application key and secret and your
30+
enterprise ID and the DL-7450 ID, which you should have received with your
31+
reference board. For example, to run the :githubSamples:`carousel application
32+
<samples/http/carousel.py>`::
3733

3834
python ./scripts/send_code.py \
3935
--key 241FB8AF5E23E00406E985E6-My-Application \
4036
--secret 3334e363-efd2-a764-e789-d7daf71245f9 \
4137
--enterprise 4d0ec8a128f9a6814acf8a96 \
4238
--dock A7BBAFE26E7E94EE650DD9AC039EBC4569265A8EAD08A7F8BA1AAFFFF21523B \
43-
--file ./samples/http/carousel.py
39+
--file carousel.py
40+
41+
You can now start to develop your own DL-7450 applications.
4442

45-
.. warning::
46-
In Windows there is a length limit on the filesystem. If you hit any ``FileNotFoundError: [Errno 2] No such file or directory:``
47-
errors, be careful to check the path is not exceeding that limit - or turn the limit off.
43+
.. note::
44+
The DL-7450 reference boards are shipped with the read-only `datastore`
45+
populated with the :githubSamples:`default application
46+
<samples/introduction/default.py>`, and some `ImageStore` images and
47+
`KvStore` data to support the :githubSamples:`sample applications
48+
<samples>`. You are free to change the contents of the read-only store
49+
during development. Details can be found in the `datastore` documentation.

docs/library/datastore.rst

Lines changed: 97 additions & 41 deletions
Original file line numberDiff line numberDiff line change
@@ -6,52 +6,108 @@
66
.. module:: datastore
77
:synopsis: Data persistence services
88

9-
.. admonition:: Coming soon
10-
:class: tip
11-
12-
In this preview only data that has been saved in the factory data store is available for retrieval. For
13-
the workshop, we have populated the ImageStore with several splashscreen background images.
14-
15-
This module contains classes for managing storage and retrieval of application data. Persistent application
16-
data is of two possible types:
17-
18-
- *Factory settings:* Manufacturers can provision the DL-7450 with application data in the manufacturing
19-
process, such as branded splashscreen backgrounds or the URL of a content provider. It
20-
is also possible to provide unique-per-dock (UPD) data, such as enrolment tokens for IoT cloud service
21-
providers.
22-
- *Runtime settings:* Applications may store data that is not set in the factory, but which persists across
23-
DL-7450 restarts. Such data may include access tokens for cloud providers or local network settings
24-
that have been provisioned remotely after the dock has been deployed in an enterprise setting.
9+
This module contains classes for managing storage and retrieval of application
10+
data. Logically, the DL-7450 :py:mod:`datastore` is a single entity, with
11+
different partitions. There is an :py:class:`ImageStore` interface for
12+
retreiving images from the persistent data store. The image data is available
13+
as a python `bytearray` and the type is identified by one of the image type
14+
constants from the :py:mod:`image` module. Alternatively, a token may be used
15+
for later retreiving an image. This may reduce the number of copies of the
16+
image data created and used by your application. Simple key-value pairs can be
17+
stored and retrieved using the :py:class:`KvStore` interface. The python
18+
application itself also resides in the datastore, but is not explicitly
19+
accessible from the application. In later releases of the SDK, storage for
20+
futher types, such as fonts will be provided.
21+
22+
Data may also be stored in different ways. Persistent application data is of
23+
two possible types:
24+
25+
- *Factory settings* or *Read-only memory (ROM)* storage. Manufacturers can
26+
provision the DL-7450 with application data in the manufacturing process,
27+
such as branded splashscreen backgrounds or the URL of a content provider.
28+
It is also possible to provide unique-per-dock (UPD) data, such as
29+
enrolment tokens for IoT cloud service providers.
30+
- *Runtime settings:* Applications may store data that is not set in the
31+
factory, but which persists across DL-7450 restarts. Such data may include
32+
access tokens for cloud providers or local network settings that have been
33+
provisioned remotely after the dock has been deployed in an enterprise
34+
setting.
2535

2636
There is an additional non-persistent storage type:
2737

28-
- *Ephemeral settings:* Applications may store data that is useful at runtime, but is not essential to
29-
store across dock restarts. For example, image data can be large, and it is not possible to keep many
30-
on the Python runtime memory heap. In this case an application can store them in out-of-process memory
31-
and retrieve them on demand. An example use-case is using the ephemeral storage area to avoid having
32-
to make slow HTTP requests to obtain subsequent data.
33-
34-
There is an :py:class:`ImageStore` interface for retreiving images from the persistent data stores. The image
35-
data is available as a python `bytearray` and the type is identified by one of the image type constants from the
36-
:py:mod:`image` module. Alternatively, a token may be used for later retreiving an image. This may reduce the number
37-
of copies of the image data created and used by your application.
38-
39-
Simple key-value pairs can be stored and retrieved using the :py:class:`KvStore` interface.
40-
41-
42-
Constants
43-
---------
44-
45-
.. data:: datastore.FACTORY_DATA
46-
datastore.APPLICATION_DATA
47-
48-
Pick whether to use application data or factory data.
49-
50-
.. admonition:: Coming soon
38+
- *Ephemeral settings:* Applications may store data that is useful at
39+
runtime, but is not essential to store across dock restarts. For example,
40+
image data can be large, and it is not possible to keep many on the Python
41+
runtime memory storage. In this case an application can store them in
42+
out-of-process memory and retrieve them on demand. An example use-case is
43+
using the ephemeral storage area to avoid having to make slow HTTP
44+
requests to obtain subsequent data.
45+
46+
When an application requests an item from the datastore, unless explicitly
47+
stated otherwise, there is an order of preference. For example if the
48+
application requests a splashscreen background with image tag *default_img*,
49+
first the ephemeral store will be checked, followed by the runtime store and
50+
finally the ROM/factory store.
51+
52+
The amounts available for different types of data is currently as follows.
53+
There is no restriction on how data is distributed across the available
54+
storage, i.e. an applicaiton developer can use it as they see fit for code,
55+
images and key-value data.
56+
57+
+--------------+----------------------------+
58+
| Data Storage | Available |
59+
+==============+============================+
60+
| Factory/ROM | 13MB |
61+
+--------------+----------------------------+
62+
| Runtime | 13MB |
63+
+--------------+----------------------------+
64+
| Ephemeral | 128MB |
65+
+--------------+----------------------------+
66+
67+
68+
.. admonition:: Not-yet implemented
5169
:class: tip
5270

53-
These constants aren't available in this preview,
54-
and all data retrieval is from the factory data store.
71+
In the present version of the DL-7450 SDK only the application ROM store is
72+
implemented.
73+
74+
75+
76+
Application ROM Storage during development
77+
------------------------------------------
78+
79+
The Application ROM storage area, also referred to as *Factory storage*
80+
provides a mechanism to deploy a customer application and associated data in
81+
the manufacturing process. This enables the customer's DL-7450 dock to run the
82+
customer application on first boot after sale to the end user. The semantics of
83+
the application ROM store is as suggested by the name, a read-only data store.
84+
This supports a factory-reset operation on the dock. One usage pattern might be
85+
for a customer to ship a dock with a basic application in factory storage,
86+
which bootstraps another application that requires user-specific data in the
87+
field. Another usage pattern is that the application ROM store contains version
88+
N of the application, which can be updated to a later version which is stored
89+
in the runtime store. Yet another case is that the factory application might
90+
provide corporate imagery of the dock manufacturer, which can be overridden in
91+
the field by corporate imagery of the end-user. In all cases, a a factory reset
92+
will cause the application and its data to be restored to the state that it was
93+
manufactured in.
94+
95+
Therefore, the :py:mod:`datastore` APIs in the DL-7450 SDK do not allow the ROM store
96+
area to be written to. While this is the required behaviour in a production
97+
docking station, it is too restrictive for development. To support development,
98+
DisplayLink has provided a REST API in our development cloud to populate the
99+
factory store. The details are provided with the :githubSamples:`supporting
100+
scripts </scripts/README.md>`. Note that the operation is atomic and
101+
destructive - i.e. the application ROM store is replaced in a single operation.
102+
This mechanism will not be available to docks in production.
103+
104+
Ephemeral application code during development
105+
---------------------------------------------
106+
107+
To support development, DisplayLink provides a REST API to deploy new
108+
application code immediately to the dock. This makes use of ephemeral data
109+
storage. The details of how to use this API are given with the
110+
:githubSamples:`supporting scripts </scripts/README.md>`.
55111

56112

57113
Classes

docs/library/dock.DockInfo.rst

Lines changed: 0 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -51,11 +51,6 @@ Methods
5151

5252
Returns one of the constants described below.
5353

54-
.. admonition:: Coming soon
55-
:class: tip
56-
57-
The return value will always be `DockInfo.HOST_NOT_CONNECTED` in this preview.
58-
5954
Constants
6055
---------
6156

docs/library/mqtt.Client.rst

Lines changed: 42 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -81,15 +81,47 @@ application through relevant callbacks about MQTT events.
8181
asynchronously, when the connection is established, or when a connection
8282
cannot be established for some reason.
8383

84-
Example callback function::
84+
85+
It is important to note that the *on_connect* callback can be called
86+
multiple times. In particular if a connection is made successfully, but is
87+
later lost, the callback will be invoked twice, the second time as a
88+
failure. The MQTT will *automatically attempt to reconnect to the broker*.
89+
If this reconnection attempt is successful, yet another invocation of the
90+
*on_connect* callback will occur.
91+
92+
Example 1: the Client attempts to connect to the server, but does not
93+
provide the correct username and password. The *on_connect* callback will
94+
be invoked with status = 4. No further connection attempt will be made, and
95+
the failure is permanent.
96+
97+
Example 2: the client connects successfully. The *on_connect* callback is
98+
invoked with status = 0. Some time later, the local network is becomes
99+
unavailable. On the next failed ping attempt (see the *keepAlive* option),
100+
the *on_connect* callback is invoked with status = -1. However, the client
101+
will attempt to reconnect to the broker. The first attempt is after 1
102+
seconds, then 2, 4, 8, 16 and 32 seconds subsequently, and from then every
103+
1 minute. When the network is available again, and the client reconnects,
104+
the *on_connect* callback is invoked again with status = 0.
105+
106+
It is advisable for the application to keep track of the connection status.
107+
An example of an *on_connect* callback::
108+
109+
connected = False
85110

86111
def on_connect(rc, flags):
87112
if rc == 0:
88113
# connection accepted by the broker
114+
connected = True
89115
else:
90-
errMsg = mqtt.ErrorDescription(rc)
91-
# report or handle error.
92-
116+
if rc > 0:
117+
# permanent failure...
118+
if rc < 0:
119+
connected = False
120+
errMsg = mqtt.ErrorDescription(rc)
121+
if connected:
122+
# connection lost. Reconnect attempt follows
123+
else:
124+
# report or handle error. Reconnect attempt follows
93125

94126
*options* is a dictionary that contains a variety of optional parameters
95127
for this connection. The possible key-value pairs are described below. All
@@ -148,6 +180,12 @@ application through relevant callbacks about MQTT events.
148180
The *clean_session* option is currently set to 0 and cannot be changed in
149181
this version of the DL-7450 SDK.
150182

183+
The client automatically attempts to reconnect to the broker when a
184+
connection attempt fails. The minimum time for the retry is 1 second. If
185+
this fails, the next retry is 2 seconds, so on through 4, 8, 16 and 32
186+
seconds. After that, further attempts occur every minute. This procedure
187+
resets once a successful connection is made.
188+
151189
.. method:: publish(topic, message, qos)
152190

153191
This method initiates the publication of a message to the broker. The

docs/templates/layout.html

Lines changed: 4 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -14,12 +14,10 @@
1414
{% else %}
1515
<div class="wy-alert wy-alert-danger">
1616
<p>
17-
The information contained in this website is Synaptics confidential
18-
information, and is made available to you under the terms of our
19-
Non-Disclosure Agreement (NDA). This is a preview version of the
20-
DisplayLink DL-7450 Software Development Kit Documentation. The
21-
functionality that is described and made available in this version is
22-
subject to addition, removal or change without warning.
17+
This is a preview version of the DisplayLink DL-7450 Software
18+
Development Kit Documentation. The functionality that is described and
19+
made available in this version is subject to addition, removal or
20+
change without warning.
2321
</p>
2422
</div>
2523
{% endif %}

0 commit comments

Comments
 (0)