-
Notifications
You must be signed in to change notification settings - Fork 0
[Tutorials] Development Documentation
This section describes how to start the tutorial applications step by step. The following tutorials are made:
- Python Application Tutorial
- C# Application Tutorial
- Go Application Tutorial
- Node-RED Application Tutorial
For ease of use of the following tutorial examples, .bat
and .sh
files have been created so that they automatically use predefined docker
commands to build and save an image. Their usage is also described in detail in the end section.
- Building and Pushing Registry Files with
.sh
and.bat
- Building and Saving
.tar
Files with.sh
and.bat
A prerequisite to be able to run the presented files is installing Docker.
In this section, application tutorials are discussed. Environment setup, application implementation and running of the application is described for a Python, C# and Go application. Links to application files are provided for each example given.
The LED DIO application is an application that can read and writes sensor status via TDC-E which runs on ARM 32 v7. To do so, it uses a REST API in one example, while it uses direct access in another example. The program randomly chooses whether to set the specified LED output on or off in an infinite loop.
Since the application works with a LED and the DIO interface, a requirement for the application to work is to set up the DIO interface. For help with the setup, refer to TDC‐E Interface Configuration's Digital Input Output section.
In this section, code written in the Python programming language for working with digital inputs/outputs is provided. Fetching and setting data via APIs and with Linux commands is discussed.
Three simple separate Python programs are created. The first program is used for continuously fetching the DIO value via an API, checking whether the sensor has detected something and setting the LED on as a response. The second program is used to set the DIO state to 1 or 0, or to set the LED on or off. Finally, a program for directly setting the DIO state is provided.
1.1.2.1. Fetching DIO State from API
To fetch the state of a DIO in Python, the following libraries are used:
-
requests
-
json
-
time
The requests
library is needed to access the API data as requests to the server are sent through it. The json
library is needed for working with JSON
data from the response object, while the time
module is used to make the program wait.
This example fetches the state of DIO_B. Before fetching the state of a pin, the user first needs to be authenticated with a Bearer token authentication. The token is generated as follows:
# gets authentication token for http requests
def getToken():
tokenUrl = "http://192.168.0.100:59801/user/Service/token"
password = "XXX"
myobj = {'password':password}
headers = CaseInsensitiveDict()
# setting header
headers["Content-Type"] ="application/x-www-form-urlencoded"
resp = requests.post(tokenUrl, data = myobj, headers=headers)
token = json.loads(resp.text)
return token["token"]
The token is fetched from the http://192.168.0.100:59801/user/Service/token
URL and a default password is provided and added to the request's header with the Content-Type
set to application/x-www-form-urlencoded
. The response uses the POST
method to send the request, then returns a response.
The program fetches the DIO state of pin B every five seconds indefinitely. It does so by calling the fetchCurrState
method, which calls getDio
in its body. This is how the code is implemented:
# fetches DIO state
def fetchCurrState(token):
resp = getDio(token, "http://192.168.0.100:59801/tdce/dio/GetState/DIO_B")
return resp['Value']
# gets dio_b object from url
def getDio(token, url):
api_response = requests.get(url, auth=BearerAuth(token))
data = api_response.text
resp = json.loads(data)
return resp
To get the DIO_B state, the URL http://192.168.0.100:59801/tdce/dio/GetState/DIO_B
is accessed by sending a GET
request to the address, providing an authentication token. The data is read from the API response, then the value is extracted from it, printing the value to the terminal.
1.1.2.2. Set DIO State with API
This application was made to demonstrate setting a DIO state to 0 or 1, depending on the user input. The main program looks like this:
if __name__ == "__main__":
payload = str(sys.argv[1])
if(payload=="1"):
js = '[{ "DioName": "DIO_A", "Value": 1, "Direction": "Output" }]'
elif(payload=="0"):
js = '[{ "DioName": "DIO_A", "Value": 0, "Direction": "Output" }]'
else:
print("Wrong value for DIO state.")
token = getToken()
setDios(token, js)
It is started by providing an argument to the Python script, which is then read into the payload
variable. If the user input is equal to 1
, it sets the value of the DIO to 1
, and if it is 0
, it sets the value to 0
. It fetches the authentication token in the same way as it was fetched in the example above, then sets the state to the user input using the following code:
def setDios(token, js):
#set LED state
url = "http://192.168.0.100:59801/tdce/dio/SetStates"
headers = CaseInsensitiveDict()
headers["Content-Type"] = "application/json"
requests.post(url, data=js, auth=BearerAuth(token), headers=headers)
It sends the created json
string to the specified url
, adds a application/json
header, then posts the data using requests.post
.
2.3. Direct Access to Values
The following application is created to read and set the value state of the GPIO and is used to execute a Linux TDC-E command directly on the device. It is a program that runs indefinitely and selects one of the commands specified in the commands
array.
commands = ["echo 1 > /sys/class/gpio/gpio496/value", "echo 0 > /sys/class/gpio/gpio496/value"]
while True:
# executes a random command from the list
execute(random.choice(commands))
time.sleep(5)
It turns the DIO ON
or OFF
each 5 seconds. Every time the command is executed, the Linux file is changed. The command is executed using the following logic:
def execute(cmd):
try:
output = subprocess.check_output(["sh", "-c", cmd], stderr=subprocess.STDOUT, universal_newlines=True)
print(output)
except subprocess.CalledProcessError as e:
print(e.output)
The execute()
function takes a command specified in the script and uses the subprocess
module to check the output of the command that is executed, then prints the output to the console. In case of an error, it prints the error.
NOTE: The file structure of the TDC-E specifies specific paths for individual gpios. Consult the manual linked above for working with your desired DIO.
Other commands can be given to the execute()
function. For example, reading the gpio value of pin A would require the following command:
cat /sys/class/gpio/gpio496/value
To see how a Python image is created, refer to this link.
Step 1. Building, Pushing, Saving
The files for this tutorial contain two ways to build, push or save the application developed for the TDC-E. These files have the extensions .bat
and .sh
respectively. Below is a list of the files available for building, pushing and saving the application:
-
build-registry.bat
- builds the image and pushes it to a registry, for Windows OS -
build-registry.sh
- builds the image and pushes it to a registry, for Linux OS -
build-tar.bat
- builds the image and saves it as.tar
file, for Windows OS -
build-tar.sh
- builds the image and saves it as.tar
file, for Linux OS
NOTE: The registry files need to be modified with text or code editing software, as the registry name should be modified to match the name of the available registry. See details below.
NOTE: On Linux, changing file permissions may be needed if by starting the file a permission denied
message is printed. To change file permission, use chmod [options] permissions file-name
. E.g. chmod 777 build-tar.sh
.
1.1.3.1. Creating Image with a Registry
If there is an available registry that will store the images, click on the build-registry.bat
if you're running Windows OS, or build-registry.sh
if you're running Linux OS. The image will be built automatically and sent to your registry with the annotated name. Now, the image is in your registry, and can be pulled from any other device with access to it. Now it needs to be downloaded to the device that is going to run it, namely your TDC-E device.
Then log onto your TDC-E device. See this short section for pulling the image to your device. Now proceed to Step 2.
1.1.3.2. Creating Image with a .tar
File
To create an image without a registry, click on the build-tar.bat
file if using the operating system Windows, or build-tar.sh
if using the operating system Linux. This should automatically build the image and save it to an archive called dioled.tar
. This archive can then be uploaded to the TDC-E by using Portainer. For help with the uploading process, refer to this section. Now proceed to Step 2.
Step 2. Creating a Container
Containers are needed to provide a runtime environment for the images you've created. The images are now safely stored on your TDC-E device and will need to be bound to a container next. Find the docker-compose.yml
file in the linked application files which is used to create a suitable environment for your application. Use this file and follow the steps described here. Choose one of the two described ways to create a container.
The container should now start running automatically if all is correct, and the application should be running on your device.
The AINValRead application is a simple C# application that reads AIN values from a websocket the program listens to. It prints the name of the AIN used, its previous value and new value.
The application requires AIN setup to run. For help with the setup of the analog values, refer to TDC‐E Interface Configuration's Analog Input section.
This simple application creates a task that listens to the TDC-E's websocket to fetch all necessary values, deserializing the received json
object to a struct of the following structure:
public class AnalogValueChange
{
public string AinName { get; set; }
public double PreviousValue { get; set; }
public double NewValue { get; set; }
}
The service uses a ClientWebSocket
client that it uses to connect to the needed websocket, creates a receiveBuffer
for bytes the websocket provides, and indefinitely asynchronously receives a result which reads the message from it, then deserializes the message to the AnalogValueChange
before printing the state.
while (true)
{
var result = client.ReceiveAsync(receiveBuffer, CancellationToken.None).Result;
var message = Encoding.UTF8.GetString(receiveBuffer.Array, 0, result.Count);
var avChange = JsonSerializer.Deserialize<AnalogValueChange>(message);
Console.WriteLine($"Received AnalogValueChange: AinName={avChange.AinName}, PreviousValue={avChange.PreviousValue}, NewValue={avChange.NewValue}");
}
To see how a C# image is created, refer to this link.
Step 1. Building, Pushing, Saving
The files for this tutorial contain two ways to build, push or save the application developed for the TDC-E. These files have the extensions .bat
and .sh
respectively. Below is a list of the files available for building, pushing and saving the application:
-
build-registry.bat
- builds the image and pushes it to a registry, for Windows OS -
build-registry.sh
- builds the image and pushes it to a registry, for Linux OS -
build-tar.bat
- builds the image and saves it as.tar
file, for Windows OS -
build-tar.sh
- builds the image and saves it as.tar
file, for Linux OS
NOTE: The registry files need to be modified with text or code editing software, as the registry name should be modified to match the name of the available registry. See details below.
NOTE: On Linux, changing file permissions may be needed if by starting the file a permission denied
message is printed. To change file permission, use chmod [options] permissions file-name
. E.g. chmod 777 build-tar.sh
.
1.2.3.1. Creating Image with a Registry
If there is an available registry that will store the images, click on the build-registry.bat
if you're running Windows OS, or build-registry.sh
if you're running Linux OS. The image will be built automatically and sent to your registry with the annotated name. Now, the image is in your registry, and can be pulled from any other device with access to it. Now it needs to be downloaded to the device that is going to run it, namely your TDC-E device.
Then log onto your TDC-E device. See this short section for pulling the image to your device. Now proceed to Step 2.
1.2.3.2. Creating Image with a .tar
File
To create an image without a registry, click on the build-tar.bat
file if using the operating system Windows, or build-tar.sh
if using the operating system Linux. This should automatically build the image and save it to an archive called cain.tar
. This archive can then be uploaded to the TDC-E by using Portainer. For help with the uploading process, refer to this section. Now proceed to Step 2.
Step 2. Creating a Container
Containers are needed to provide a runtime environment for the images you've created. The images are now safely stored on your TDC-E device and will need to be bound to a container next. Find the docker-compose.yml
file in the linked application files which is used to create a suitable environment for your application. Use this file and follow the steps described here. Choose one of the two described ways to create a container.
The container should now start running automatically if all is correct, and the application should be running on your device.
The LED DIO application is a simple application that can read and writes sensor status via TDC-E which runs on ARM 32 v7. To do so, it does not use web sockets nor https, but a direct interface. The program randomly chooses whether to set the specified LED output on or off in an infinite loop.
Since the application works with a LED and the DIO interface, a requirement for the application to work is to set up the DIO interface. For help with the setup, refer to TDC‐E Interface Configuration's Digital Input Output section.
This application is implemented relatively simply. It starts an infinite for loop which executes a function to change the LED value, then sleeps for 5 seconds before once again setting the LED to a different value.
The function is implemented so that it randomly chooses whether to start or stop the glow of the LED, then executes a shell command used to turn the LED on or off. If the value is 0, the LED is off. Otherwise, the LED is on.
It is also important to note the GPIO of the LED, since each digital input and digital output has a different values for their GPIO. The GPIO used for the program is 496, mapped to the A connector, and it is a digital output. If another configuration is needed, make sure to use the correct mapping.
The command is executed with the following Golang code:
out, err := exec.Command("sh", "-c", cmd).Output()
This code executes a shell command using the os/exec
Go package. The cmd
parameter is the parameter for changing the LED state. The LED is set to ON using the following command:
echo 1 > /sys/class/gpio/gpio496/value
This sets the value in the path /sys/class/gpio/gpio496/value
to 1
, turning the LED on. To turn it off, the following command is used:
echo 0 > /sys/class/gpio/gpio496/value
To see how a C# image is created, refer to this link.
Step 1. Building, Pushing, Saving
The files for this tutorial contain two ways to build, push or save the application developed for the TDC-E. These files have the extensions .bat
and .sh
respectively. Below is a list of the files available for building, pushing and saving the application:
-
build-registry.bat
- builds the image and pushes it to a registry, for Windows OS -
build-registry.sh
- builds the image and pushes it to a registry, for Linux OS -
build-tar.bat
- builds the image and saves it as.tar
file, for Windows OS -
build-tar.sh
- builds the image and saves it as.tar
file, for Linux OS
NOTE: The registry files need to be modified with text or code editing software, as the registry name should be modified to match the name of the available registry. See details below.
NOTE: On Linux, changing file permissions may be needed if by starting the file a permission denied
message is printed. To change file permission, use chmod [options] permissions file-name
. E.g. chmod 777 build-tar.sh
.
1.3.3.1. Creating Image with a Registry
If there is an available registry that will store the images, click on the build-registry.bat
if you're running Windows OS, or build-registry.sh
if you're running Linux OS. The image will be built automatically and sent to your registry with the annotated name. Now, the image is in your registry, and can be pulled from any other device with access to it. Now it needs to be downloaded to the device that is going to run it, namely your TDC-E device.
Then log onto your TDC-E device. See this short section for pulling the image to your device. Now proceed to Step 2.
1.3.3.2. Creating Image with a .tar
File
To create an image without a registry, click on the build-tar.bat
file if using the operating system Windows, or build-tar.sh
if using the operating system Linux. This should automatically build the image and save it to an archive called directdioled.tar
. This archive can then be uploaded to the TDC-E by using Portainer. For help with the uploading process, refer to this section. Now proceed to Step 2.
Step 2. Creating a Container
Containers are needed to provide a runtime environment for the images you've created. The images are now safely stored on your TDC-E device and will need to be bound to a container next. Find the docker-compose.yml
file in the linked application files which is used to create a suitable environment for your application. Use this file and follow the steps described here. Choose one of the two described ways to create a container.
The container should now start running automatically if all is correct, and the application should be running on your device.
The Node-RED tutorial example that is discussed here works with the TDC-E's internal modem and is a simple application that sends HTTP requests to fetch messages saved on the internal modem. The program can also send messages to a modem, providing a phone number and content to send. The TDC-E can thus store messages sent its way, and can also send SMS messages to different devices, for example to a mobile phone.
The application requires setting up your TDC-E, as it requires a username, password, a client ID and a client secret for oauth2
authentication. It also requires the TDC-E to have its modem set up, and a SIM card to be placed into its intended place. For help setting up the modem, refer to the Modem section in the Network Configuration documentation.
In this section, code for the application is provided and explained. For the code of the application, the following nodes are used:
- an
inject
node - an
oauth2
node (node-red-contrib-oauth2
) - a
function
node - a
http request
node - a
json
node - a
debug
node
Nodes are standalone code snippets that can be interconnected to form the programming logic of the application. Each node has a different functionality which corresponds to programming needs. Not all nodes are native and some, like oauth2
, need to be imported.
First, we will discuss fetching messages that were sent to the TDC-E's modem. To do so, the GET SMS
group inside the flow is used. to start the message fetch, use the inject
node labeled timestamp
. This message will send a request for an oauth2
token with the grant type Password, providing the Acess Token URL, username, password, Client Id and Client Secret parameters to do so. The access token is extracted in the get-msgs
function and an authorization
header is set.
An http request
with the GET
method is then sent to the specified URL
, and the server returns an array of json
objects that contain the messages sent to the modem. Those are then displayed in the debug
panel on the right side of the screen.
For sending an SMS to another device, the SEND SMS
group inside the flow is used. The inject
node and oauth2
node are identical to the nodes described above. The set-msg-parameters
function is important to note.
var token = msg.oauth2Response.access_token;
// insert phone number here
var phoneNumber = "+XXXXXXXXXXXX";
msg.headers = {
"authorization": "Bearer " + token,
"Content-Type": "application/json",
"accept": "*/*"
};
msg.payload = {
"phoneNumber":phoneNumber,
"content":"hello world"
};
return msg;
This is the implementation of this function. For it to work. The token is extracted from the oAuth2Response
, and a phone number of the device you want to send a message to needs to be provided here. Authorization, Content-type and Acceptance headers are set, and then a msg.payload
is created. This payload will be sent in the body of our POST
request made to the modem. It needs to contain a valid phone number and SMS content, which will be the message body. A POST
request will then be sent to the address http://192.168.0.100/devicemanager/api/v1/networking/modem/ppp0/sms/messages
. The device with the corresponding phone number should now receive a message with the same text as what was written in the program.
To run the application, several small steps are needed. Since the program runs on the TDC-E as it fetches data from it, Node-RED should be installed on your TDC-E device. For help with Node-RED installation, refer to this section. Now go to http://192.168.0.100:1880/.
Copy or download the .json
code from the application files. Select the upper right menu button, then go to Import. Now, either upload the downloaded file from the application files or paste the .json
code in the text box. The program is now imported, but some nodes may be missing. Since oauth2
is not a built-in node, it needs to be installed first. A screenshot of missing nodes is shown below.
To solve this issue, once again click on the menu in the top right corner and select Manage palette, then search for oauth2
for this specific node.
After importing the node, all nodes should be set up correctly, and the program is ready to start.
To start the application, select the Deploy button next to the menu button. Your application is now running and ready to take commands. To send a message or list received ones, click on the left side of any of the timestamp
nodes. All nodes are customizable.
In this section, code inside the provided .sh
and .bat
file is discussed.
In this section, building and pushing the image to a registry for the TDC-E device is discussed. In the files, there is a .sh
and .bat
file for that matter with their file structure and usage being very similar.
The structure of the .sh
file, used for the Linux operating system, is the following:
#!/bin/bash
docker build --no-cache -t registry-name:1.0.0 .
docker push registry-name:1.0.0
sleep 30
First, the file specifies that the file is a bash script. It does so with the #!/bin/bash
annotation. The docker image is built with the next statement. No cache is specified so that cached layers that were already built are ignored. This means that the build process will always be reset, which is useful for building when significant changed often occur in the Dockerfile (e.g. debugging or adding services). Keep in mind that the Dockerfile is run from top to bottom, issuing the commands in order, so top commands get executed first.
You can remove this --no-cache
flag, which will speed up the process of building the image on the next iteration of the run, as Docker cashes successful actions.
The build is tagged with the -t
flag. since a registry is used, replace the registry-name:1.0.0
with the name of your registry. This will be the tag for your image. Make sure to also replace the tag in the second line, as these names need to match. With the second command, the image is pushed to your specified registry under the same tag name.
In the end, sleep 30
is used so that results are displayed for 30 seconds before exiting the program.
The .bat
file works in the same way. The only difference is no specification of the file usage on top, and sleep 30
is replaced by timeout /t 30
, which serves the same function.
docker build --no-cache -t registry-name:1.0.0 .
docker push registry-name:1.0.0
timeout /t 30
The .tar
file building files are called build-tar.sh
for the Linux operating system and build-tar.bat
for the Windows operating system respectively. Both files have the serve the same function and are very similar. The structure of the build-tar.sh
file is the following:
#!/bin/bash
docker build --no-cache -t myapp:1.0.0 .
docker save -o myapp.tar myapp:1.0.0
sleep 30
The first line annotates that the written script is a bash shell script. The docker image is built with the next statement. No cache is specified so that cached layers that were already built are ignored. This means that the build process will always be reset, which is useful for building when significant changed often occur in the Dockerfile (e.g. debugging or adding services). Keep in mind that the Dockerfile is run from top to bottom, issuing the commands in order, so top commands get executed first.
You can remove this --no-cache
flag, which will speed up the process of building the image on the next iteration of the run, as Docker saves successful actions.
Then the command docker save
is used. This command specifies that the myapp:1.0.0
is being saved to the output myapp.tar
, which will contain all necessary items for running the image once transferred to Portainer. Then the program sleeps for 30 seconds, allowing any messages to show upon completing the script.
The Windows .bat
file functions in the same way. The only difference is no specification of the script at the start of the file, and instead of the sleep
command, timeout /t 30
is used, which also stops the application for 30 seconds before exiting.
docker build --no-cache -t myapp:1.0.0 .
docker save -o myapp.tar myapp:1.0.0
timeout /t 30