Coral part VII.

intro

 ... at work last week, I was planning to deal with something called Azure IoT Hub, but due to time constraints, I barely touched it. Luckily through some great efforts my colleagues made, I got a grasp of it, so when Friday came by, I was motivated to catch up. As you've seen from my previous articles, I'm interested in machine vision and Coral Boards. What those things have to do with Azure IoT Hub? My next project ...

explanation

 Our company project on IoT Hub at work is about monitoring different parameters of a freezer. Which assumes sensors that are measuring power consumption and temperature. It also assumes collecting these signals and forwarding them to an IoT hub, where we analyze them.

 I have no such sensors, so instead I came up with a LEGO use case: which character appears in front of my camera? When I place a LEGO figure in front of my camera, I would like it to be recognized and I would like to store that recognition in the cloud.

First steps:

Google Coral Board and Docker

 Microsoft suggests using Moby as a docker runtime, but they are okay with me using Docker in non-production environments. So, let's grab Docker:

# wget https://download.docker.com/linux/static/stable/aarch64/docker-20.10.3.tgz
# tar xzvf docker-20.10.3.tgz 
# sudo cp docker/* /usr/bin/

Complete post-installation steps:

# sudo groupadd docker
# sudo usermod -aG docker $USER
# newgrp docker 

And create a service for Docker:

# cd /etc/systemd/system
# sudo vi docker.service

```
[Service]
ExecStart=/usr/bin/dockerd
```

# sudo systemctl daemon-reload

We know that everything; always; works; for the first time (at least in articles), so we bravely test:

# docker pull hello-world
# docker images
REPOSITORY    TAG       IMAGE ID       CREATED         SIZE
hello-world   latest    a29f45ccde2a   13 months ago   9.14kB
# docker run hello-world

Hello from Docker!
This message shows that your installation appears to be working correctly.

Azure IoT Edge

Next step on our magic journey is to get the Azure IoT Edge installed:

# curl -L https://github.com/Azure/azure-iotedge/releases/download/1.1.0/libiothsm-std_1.1.0-1-1_debian9_arm64.deb -o libiothsm-std.deb && sudo dpkg -i ./libiothsm-std.deb
# curl -L https://github.com/Azure/azure-iotedge/releases/download/1.1.0/iotedge_1.1.0-1_debian9_arm64.deb -o iotedge.deb && sudo dpkg -i ./iotedge.deb

% Total    % Received % Xferd  Average Speed   Time    Time     Time  Current
                            Dload  Upload   Total   Spent    Left  Speed
100   641  100   641    0     0   2595      0 --:--:-- --:--:-- --:--:--  2595
100 4598k  100 4598k    0     0  6752k      0 --:--:-- --:--:-- --:--:-- 6752k
Selecting previously unselected package iotedge.
(Reading database ... 46240 files and directories currently installed.)
Preparing to unpack ./iotedge.deb ...
Adding system user `iotedge' (UID 109) ...
Adding new user `iotedge' (UID 109) with group `nogroup' ...
Creating home directory `/var/lib/iotedge' ...
Adding group `iotedge' (GID 118) ...
Done.
Adding user `iotedge' to group `docker' ...
Adding user iotedge to group docker
Done.
Unpacking iotedge (1.1.0-1) ...
Setting up iotedge (1.1.0-1) ...
===============================================================================

                                Azure IoT Edge

    IMPORTANT: Please update the configuration file located at:

    /etc/iotedge/config.yaml

    with your device's provisioning information. You will need to restart the
    'iotedge' service for these changes to take effect.

    To restart the 'iotedge' service, use:

    'systemctl restart iotedge'

    - OR -

    /etc/init.d/iotedge restart

    These commands may need to be run with sudo depending on your environment.

===============================================================================
Created symlink /etc/systemd/system/sockets.target.wants/iotedge.mgmt.socket → /lib/systemd/system/iotedge.mgmt.socket.
Created symlink /etc/systemd/system/multi-user.target.wants/iotedge.service → /lib/systemd/system/iotedge.service.
Created symlink /etc/systemd/system/sockets.target.wants/iotedge.socket → /lib/systemd/system/iotedge.socket.
Processing triggers for systemd (241-7~deb10u4) ...
Processing triggers for man-db (2.8.5-2) ...    

Provision the Device with an IoT Hub

... let the MS documentation talk for itself. As it's shown below (first steps), we need to edit the iotedge confiy.yaml file. You also can see that I'm ignoring reality and running things despite 'Warnings' and 'Errors'.

# sudo chmod u+w /etc/iotedge/config.yaml
# sudo vi /etc/iotedge/config.yaml
# sudo systemctl status iotedge
● iotedge.service - Azure IoT Edge daemon
    Loaded: loaded (/lib/systemd/system/iotedge.service; enabled; vendor preset: enabled)
    Active: active (running) since Sat 2021-02-20 09:30:07 UTC; 1s ago
        Docs: man:iotedged(8)
    Main PID: 5099 (iotedged)
    Tasks: 14 (limit: 4347)
    Memory: 7.8M
    CGroup: /system.slice/iotedge.service
            └─5099 /usr/bin/iotedged -c /etc/iotedge/config.yaml

Feb 20 09:30:07 rendel iotedged[5099]: 2021-02-20T09:30:07Z [INFO] - Finished removing modules.
Feb 20 09:30:07 rendel iotedged[5099]: 2021-02-20T09:30:07Z [INFO] - Edge issuer CA expiration date: 2021-05-21T09:20:45Z
Feb 20 09:30:08 rendel iotedged[5099]: 2021-02-20T09:30:08Z [INFO] - Starting management API...
Feb 20 09:30:08 rendel iotedged[5099]: 2021-02-20T09:30:08Z [INFO] - Starting workload API...
Feb 20 09:30:08 rendel iotedged[5099]: 2021-02-20T09:30:08Z [INFO] - Starting watchdog with 60 second frequency...
Feb 20 09:30:08 rendel iotedged[5099]: 2021-02-20T09:30:08Z [INFO] - Listening on fd://iotedge.mgmt.socket/ with 1 thread for management API.
Feb 20 09:30:08 rendel iotedged[5099]: 2021-02-20T09:30:08Z [INFO] - Listening on fd://iotedge.socket/ with 1 thread for workload API.
Feb 20 09:30:08 rendel iotedged[5099]: 2021-02-20T09:30:08Z [INFO] - Checking edge runtime status
Feb 20 09:30:08 rendel iotedged[5099]: 2021-02-20T09:30:08Z [INFO] - Creating and starting edge runtime module edgeAgent
Feb 20 09:30:09 rendel iotedged[5099]: 2021-02-20T09:30:09Z [INFO] - Updating identity for module $edgeAgent

```
sudo iotedge check
Configuration checks
--------------------
√ config.yaml is well-formed - OK
√ config.yaml has well-formed connection string - OK
√ container engine is installed and functional - OK
√ config.yaml has correct hostname - OK
√ config.yaml has correct URIs for daemon mgmt endpoint - OK
√ latest security daemon - OK
√ host time is close to real time - OK
√ container time is close to host time - OK
‼ DNS server - Warning
    Container engine is not configured with DNS server setting, which may impact connectivity to IoT Hub.
    Please see https://aka.ms/iotedge-prod-checklist-dns for best practices.
    You can ignore this warning if you are setting DNS server per module in the Edge deployment.
‼ production readiness: certificates - Warning
    The Edge device is using self-signed automatically-generated development certificates.
    They will expire in 89 days (at 2021-05-21 09:20:45 UTC) causing module-to-module and downstream device communication to fail on an active deployment.
    After the certs have expired, restarting the IoT Edge daemon will trigger it to generate new development certs.
    Please consider using production certificates instead. See https://aka.ms/iotedge-prod-checklist-certs for best practices.
‼ production readiness: container engine - Warning
    Device is not using a production-supported container engine (moby-engine).
    Please see https://aka.ms/iotedge-prod-checklist-moby for details.
‼ production readiness: logs policy - Warning
    Container engine is not configured to rotate module logs which may cause it run out of disk space.
    Please see https://aka.ms/iotedge-prod-checklist-logs for best practices.
    You can ignore this warning if you are setting log policy per module in the Edge deployment.
‼ production readiness: Edge Agent's storage directory is persisted on the host filesystem - Warning
    The edgeAgent module is not configured to persist its /tmp/edgeAgent directory on the host filesystem.
    Data might be lost if the module is deleted or updated.
    Please see https://aka.ms/iotedge-storage-host for best practices.
× production readiness: Edge Hub's storage directory is persisted on the host filesystem - Error
    Could not check current state of edgeHub container

Connectivity checks
-------------------
√ host can connect to and perform TLS handshake with IoT Hub AMQP port - OK
√ host can connect to and perform TLS handshake with IoT Hub HTTPS / WebSockets port - OK
√ host can connect to and perform TLS handshake with IoT Hub MQTT port - OK
√ container on the default network can connect to IoT Hub AMQP port - OK
√ container on the default network can connect to IoT Hub HTTPS / WebSockets port - OK
√ container on the default network can connect to IoT Hub MQTT port - OK
√ container on the IoT Edge module network can connect to IoT Hub AMQP port - OK
√ container on the IoT Edge module network can connect to IoT Hub HTTPS / WebSockets port - OK
√ container on the IoT Edge module network can connect to IoT Hub MQTT port - OK

17 check(s) succeeded.
5 check(s) raised warnings. Re-run with --verbose for more details.
1 check(s) raised errors. Re-run with --verbose for more details.    

Let's check that the device is visible in our IoT Hub (coralEdge-xxxxxx is the name):

# az iot hub device-identity list -n xxxxx
    [
    {
      "authenticationType": "sas",
      "capabilities": {
        "iotEdge": true
      },
      "cloudToDeviceMessageCount": 0,
      "connectionState": "Connected",
      "deviceEtag": xxxxx,
      "deviceId": "coralEdge",
      "deviceScope": "ms-azure-iot-edge://coralEdge-xxxxxx",
      "etag": xxxxx,
      "lastActivityTime": "2021-02-20T18:06:24.1691626Z",
      "modelId": "",
      "properties": {
        "desired": {
          "$metadata": {
            "$lastUpdated": "2021-02-20T09:23:53.6707052Z"
          },
          "$version": 1
        },
        "reported": {
          "$metadata": {
            "$lastUpdated": "2021-02-20T09:23:53.6707052Z"
          },
          "$version": 1
        }
      },
      "status": "enabled",
      "statusUpdateTime": "0001-01-01T00:00:00Z",
      "version": 2,
      "x509Thumbprint": {
        "primaryThumbprint": null,
        "secondaryThumbprint": null
      }
    }
  ]  

messaging

 Now it's possible to send messages from the board to the IoT Hub. Below is a super simple Python code to send a message:

from azure.iot.device.aio import IoTHubDeviceClient
from azure.iot.device import Message
import json 
import datetime
import asyncio

CONNECTION_STRING = "HostName=xxxxx;DeviceId=coralEdge;SharedAccessKey=xxxxx"

temp = []
temp.append({'timeCreated':datetime.datetime.now().isoformat(), "recognition": "Luke"})
temp = json.dumps(temp).encode()
message = Message(temp)

if __name__ == '__main__':
    client = IoTHubDeviceClient.create_from_connection_string(CONNECTION_STRING)
    asyncio.run(client.send_message(message))

On the other end at the IoT Hub one can monitor messages:

# az iot hub monitor-events -n xxxxx
Starting event monitor, use ctrl-c to stop...
{
    "event": {
        "origin": "coralEdge",
        "module": "",
        "interface": "",
        "component": "",
        "payload": [
            {
                "timeCreated": "2021-02-21T19:01:46.574708",
                "recognition": "Luke"
            }
        ]
    }
}

conclusion

 Today we've looked at how to transform the Coral Board into an Azure IoT Edge device. We also shown that image detection can be done on the edge, and it's enough to send only the result of that to the cloud.

... and I'm sorry to say, but to keep this article short, I left out some parts:

the message

Back to vaew.io