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.

 

Related Blog
Industrial I/O
Use the Industrial I/O
Control Industrial I/O directly from GPIO Pins
C Program for the Industrial I/O
Control Industrial I/O directly from Node-RED
Display Industrial I/O on Node-RED Dashboard
CAN Bus
Use the Isolated CAN
CAN programming in C on Linux: Filter and Mask
2020 Linux Image
The 2020 Linux Image and IoTConnect Scripts
Understand the Custom Scripts and Services (Pt. 1: intro and reset button service)
Understand the Custom Scripts and Services (Pt. 2: led service)
Understand the Custom Scripts and Services (Pt. 3: IoT Connect service)