The 2020 Raspbian distribution for the AVNET SmartEdge IIOT Gateway uses systemd services to manage the hardware customisations.
In this series, I review what they do, how they interact.
Part 3 the IotConnect service, the core of the integration with AVNET's cloud services.
image source: avnet silica portal
IotConnect service
Under the name Silica, AVNET groups its IoT hardware and solutions. One of those solutions is the cloud IoTConnect service.
It's an online infrastructure that can collect your sensor data. Then you can analyse, present, share, and react upon that.
The custom Linux service that I'm reviewing here runs an example IoTConnect client on the gateway.
And it does some interactions with the WiFi, led and reboot custom parts.
In this post, I will only review the latter. I will not explain the sample application.
Here's the service registry content:
[Unit] Description=Smartedge-iiot-gateway IoTConnect SDK service StartLimitIntervalSec=0 [Service] ExecStart=/bin/bash /opt/avnet-iot/iotservices/iotconnect Restart=always RestartSec=10 [Install] WantedBy=default.target
The service calls a shell script at startup:
/opt/avnet-iot/iotservices/iotconnect
Content:
# ... echo "Starting Smartedge-iiot-gateway SDK " /bin/bash /opt/avnet-iot/iotservices/stopwd cd /opt/avnet-iot/IoTConnect/sample if ping -q -c 1 -W 1 8.8.8.8 > /dev/null; then python -u /opt/avnet-iot/IoTConnect/sample/example.py else echo "No network, restarting in 10 seconds" | tee -a /var/log/iot.log fi
This script deactivates the watchdog (later on a child script starts it again), then checks if the network is up.
When OK, it calls the demo application.
/opt/avnet-iot/IoTConnect/sample/example.py
Content:
I heavily cut here, to only show pieces of the demo that interact with customised hardware. IoTConnect code is removed.
# ... MessageCount = 0 IoTConnectConnecting = 1 # ... while not os.path.exists("/sys/class/leds/green/brightness"): time.sleep(2) myprint("Waiting for green led") os.system('chmod 666 /sys/class/leds/green/brightness') os.system('echo 0 >/sys/class/leds/green/brightness') while not os.path.exists("/sys/class/leds/red/brightness"): time.sleep(2) myprint("Waiting for green red") os.system('chmod 666 /sys/class/leds/red/brightness') os.system('echo 0 >/sys/class/leds/red/brightness') # ... def DoOTACommand(msg): myprint(str(msg['data']['command'])) mystring=str(msg['data']['command']) if [ mystring.split(" ")[0] == "ota" ]: wget.download(mystring.split(" ")[1]) filename=mystring.split(" ")[1] file = filename.split("/")[4] file = file[0:40] cmd = "mv " + file + " install.gz" os.system(cmd) cmd = "gunzip -c install.gz >install" os.system(cmd) cmd = "tar xf install" os.system(cmd) os.system("chmod 755 updates/install.sh") os.system("./updates/install.sh") # ... def SendDataToCloud(name): global sdk global SendDataArray global SendDataLock global PushDataNow global PushDataArray global my_config_parser_dict global MessageCount RefreshBasicToken = 0 myprint("Sending to cloud Task started") green = 1 count = int(my_config_parser_dict["CloudSystemControl"]["sendtocloudrate"]) try: while(True): ledprocess = cmdline("/opt/avnet-iot/iotservices/iotstat | grep led") if (ledprocess == ""): if (green == 1): os.system('echo 0 >/sys/class/leds/red/brightness') os.system('echo 1 >/sys/class/leds/green/brightness') green = 0 else: os.system('echo 0 >/sys/class/leds/red/brightness') os.system('echo 0 >/sys/class/leds/green/brightness') green = 1 time.sleep(1) # ... def Watchdogthread(): myprint(cmdline('/opt/avnet-iot/iotservices/startwd')) myprint("Using ATTINY Watchdog pet every 30 seconds") while 1: time.sleep(int(my_config_parser_dict["CloudSystemControl"]["useiotwatchdog"])) cmdline('echo t | tee /dev/watchdog1') myprint("Stopping ATTINY Watchdog.") myprint(cmdline('echo V | tee /dev/watchdog1')) # ... def main(argv): global my_config_parser_dict global d2cMsg global cpId global uniqueId global EndorsementKey global serial_number global my_sensor_dict global my_command_dict global sdk global template global template_name global ThreadCount global IoTConnectConnecting try: result = Popen( args="/opt/avnet-iot/iotservices/tpm_device_provision < crlf.txt", stdout=PIPE, shell=True ) id_ek = result.communicate()[0] if (result.returncode != 0): # Can't access TPM, try again time.sleep(1) result = Popen( args="/opt/avnet-iot/iotservices/tpm_device_provision < crlf.txt", stdout=PIPE, shell=True ) id_ek = result.communicate()[0] if (result.returncode != 0): myprint("Can't Access TPM, restarting") os.system("/bin/bash /opt/avnet-iot/iotservices/reboot") lines = id_ek.splitlines() uniqueId = lines[3] uniqueId = uniqueId.decode('utf-8') # ... if __name__ == "__main__": main(sys.argv)
A few highlights:
It controls the LEDs, but if ledservice is running, it doesn't.
Restarts watchdog and entertains it.
It can perform updates over the air for the IoT.
Accesses the Trusted Platform Module device to retrieve tokens.
Side effects:
It entertains the watchdog
Changes 2 front LED statuses
calls reboot if TPM not accessible.