Close
0%
0%

Desired State Configuration for Circuits

Blinking an LED using a Domain Specific Language applied through a Module Twin to a Docker container running Johnny 5 on a Raspberry Pi

Similar projects worth following
184 views
0 followers
Azure IoT Edge allows for intermittent connected devices to obtain desired properties through "Module Twins". These twins can be used as a desired state configuration to drive specific behavior within Edge Modules. Edge Modules run as container workloads to allow self-healing and rapid deployment without need for constant connectivity. When internet is available, devices can take advantage of cloud services to call methods within modules.

In this project, we develop and IoT Edge Module using the Azure IoT NodeJS SDK which obtains a desired state from the cloud that configures the GPIO pins on a Raspberry Pi to perform desired operations on an attached circuit using Johnny 5.

This can allow for interesting use cases like:
* Allow multiple modes of operation for a single circuit by applying different state configurations
* Redundant hardware failover with two devices attached to the same circuit when orchestrated and properly configured with kubernetes.

Background:

Desired state configuration is a popular concept that is often used when provisioning servers for the first time and to enforce compliance in running systems.  We extend this concept to circuitry using services that are designed for resilience and healthy operation in areas where network connectivity may be intermittent.  This approach allows us to change the behavior of a connected circuitry at run-time and allow for interesting scenarios involving hardware redundancy.  

The Azure IoT Edge runtime from Microsoft allows us to form a solid basis for the project.  This runtime runs as a service on local hardware and allows for orchestration of containerized "modules" which are configured per device in the Azure cloud.  Two system modules are always employed, the edge-agent which obtains and applies module deployment configurations and the edge-hub which allows for cached messaging to the cloud and inter-module communication.  

We started off by creating an Azure IoT Edge module using the Azure IoT NodeJS SDK.  This module receives a twin configuration which specifies desired and reported properties for a given device.  We employ a Domain Specific Language which is parsed into a Johny 5 configuration.  This allows us to define how a circuit should functionin the cloud, and apply it to our IoT Edge module.

An example configuration is provided below:

"config": "{\"peripherals\":[{\"type\":\"Led\",\"name\":\"alarm\",\"settings\":{\"pin\":\"GPIO18\"},\"initialState\": {\"method\":\"blink\",\"period\":500},\"outputAlias\":\"alias2\"},{\"type\":\"Button\",\"name\":\"button\",\"settings\":{\"pin\":\"GPIO20\"},\"outputAlias\":\"alias1\"}]}",

This example defines an LED device on GPIO18 with an initalState of blinking on/off every 500ms.   The state of the LED is able to propagate to other modules using the outputAlias.  A button is also employed on GPIO20 which publishes state changes to alias1.  In such a configuration, we can independently respond to state changes in additional modules by routing the outputAlias.

We currently support configuration of a thermometer, LED, and Button device using this mechanism.

Steps to reproduce:

To begin, you will need a Microsoft Azure subscription with a deployed IoT Hub.  You can deploy an IoT Hub to an existing subscription by following this guide.

Next, we you will want to begin configuration of your hardware by connecting an LED to GPIO18 of the Raspberry Pi.  Instructions for this process can be found here.

With circuitry and cloud services prepared, you will want to install the Azure IoT Edge runtime to your Raspberry Pi by following this guide.  Once the runtime is installed, you will need to manually provision the device by following these instructions.

Next we will create a special deployment within Azure that will allow us to blink our LED.

Create a deployment as shown below:

The image URI:

toolboc/johnny5onedge:0.0.981-arm32v7

The container create options:

{"ExposedPorts":{"9229/tcp":{}},"HostConfig":{"PortBindings":{"9229/tcp":[{"HostPort":"9229"}]},"Privileged":true,"Devices":[{"PathOnHost":"/dev/i2c-1","PathInContainer":"/dev/i2c-1","CgroupPermissions":"rwm"},{"PathOnHost":"/dev/gpiomem","PathInContainer":"/dev/gpiomem","CgroupPermissions":"rwm"}],"Mounts":[{"Type":"bind","Source":"/lib/modules/","Target":"/lib/modules/"}]}}

The Module twin's desired properties:

{
  "properties.desired": {
      "config": "{\"peripherals\":[{\"type\":\"Led\",\"name\":\"alarm\",\"settings\":{\"pin\":\"GPIO18\"},\"initialState\": {\"method\":\"blink\",\"period\":500},\"outputAlias\":\"alias2\"},{\"type\":\"Button\",\"name\":\"on\",\"settings\":{\"pin\":\"GPIO20\"},\"outputAlias\":\"alias1\"}]}"
  }
}

Save when you are finished.  Then skip through the "Specify Routes" and "Specify Metrics" sections until you get to...

Read more »

Portable Network Graphics (PNG) - 98.53 kB - 09/11/2018 at 07:39

Preview
Download

  • 1
    Tutorial

    Steps to reproduce:

    To begin, you will need a Microsoft Azure subscription with a deployed IoT Hub.  You can deploy an IoT Hub to an existing subscription by following this guide.

    Next, we you will want to begin configuration of your hardware by connecting an LED to GPIO18 of the Raspberry Pi.  Instructions for this process can be found here.

    With circuitry and cloud services prepared, you will want to install the Azure IoT Edge runtime to your Raspberry Pi by following this guide.  Once the runtime is installed, you will need to manually provision the device by following these instructions.

    Next we will create a special deployment within Azure that will allow us to blink our LED.

    Create a deployment as shown below:

    The image URI:

    toolboc/johnny5onedge:0.0.981-arm32v7

    The container create options:

    {"ExposedPorts":{"9229/tcp":{}},"HostConfig":{"PortBindings":{"9229/tcp":[{"HostPort":"9229"}]},"Privileged":true,"Devices":[{"PathOnHost":"/dev/i2c-1","PathInContainer":"/dev/i2c-1","CgroupPermissions":"rwm"},{"PathOnHost":"/dev/gpiomem","PathInContainer":"/dev/gpiomem","CgroupPermissions":"rwm"}],"Mounts":[{"Type":"bind","Source":"/lib/modules/","Target":"/lib/modules/"}]}}

    The Module twin's desired properties:

    {  "properties.desired": {      "config": "{\"peripherals\":[{\"type\":\"Led\",\"name\":\"alarm\",\"settings\":{\"pin\":\"GPIO18\"},\"initialState\": {\"method\":\"blink\",\"period\":500},\"outputAlias\":\"alias2\"},{\"type\":\"Button\",\"name\":\"on\",\"settings\":{\"pin\":\"GPIO20\"},\"outputAlias\":\"alias1\"}]}"  }
    }

    Save when you are finished.  Then skip through the "Specify Routes" and "Specify Metrics" sections until you get to "Target Devices".

    Set the Priority to 10 and add a target condition of tags.environment='blink'

    Submit the deployment and locate the device that was provisioned then select the "Device Twin":

    Add the following above properties as shown:

      "tags": {    "environment": "blink"  },

    Head back to the pi and execute the following commands in the terminal:

    sudo systemctl stop iotedge
    sudo iotedged -c /etc/iotedge/config.yaml

     After a few minutes, the deployment should be applied and the containers will get pulled down to the device and begin running.  If you did everything correctly, you should see the LED begin to blink!

View all instructions

Enjoy this project?

Share

Discussions

Similar Projects

Does this project spark your interest?

Become a member to follow this project and never miss any updates