The AME Stack

From IoT with AME
Revision as of 09:00, 19 June 2018 by Ctreber (talk | contribs)
Jump to navigation Jump to search

The AME Stack

Functional design goals:

  • Support deployment of multiple devices of the same kind, without having to change the configuration in multiple files
  • Simply add standard-capabilities like measuring temperature or switching a relay to a device
  • Provide status information for debugging and operations, without consuming too much memory and processing time

Architectural design goals:

  • Have MQTT interface with TCP, not with the ESP8266
  • Use streaming instead of a chain of buffers, as buffers are limited and awkward to handle (make them too big and memory is gone; make them too small and you'll get overruns)
  • I want my code to be readable by humans. And, yes, this can be done. Even in the limited Arduino environment. Without compromising speed and memory consumption.

Hardware design goals:

  • As little wiring as possible, as wiring is tiring after when assembling multiple devices

And thus generation 3 of my MQTT stack was born (and it is still growing up).

AC_ESP8266

AC_ESP8266 provides access to the ESP8266 on C++ level, no more, no less. It uses two (blowing my own horn) clever functions to compose commands and to parse responses based on pattern expansion/ matching.

The buffer used for command assembly and response parsing is the only one in the whole class. Writing and reading IP data is performed streaming. Callbacks announce the arrival of data and loss of connection.

Regarding command assembly and response parsing I think even that could be migrated to streaming mode, though pattern matching would be not that easy, I guess.

AC_TCP_ESP8266

AC_TCP_ESP8266 provides streaming TCP functionality based on - you guessed it - the ESP8266. It deals with loss of TCP and WLAN connectivity.

It does what is required to get the ESP working again, which, frankly sometimes is not easy and a pain in the back. This includes resetting the chip via software and - optionally - hardware (it uses the reset pin of the ESP).

If you want to, it even can turn the ESP off and on again. I think that does exhaust all options available.

AC_MTTQ

AC_MTTQ provides standard MQTT functions with QoS 0 or 1. More honestly QoS "0.5" as it properly produces ACK messages to the broker, but arriving ACKs are discarded and missing ACKs don't prompt retries).

Unlike other libaries AC_MQTT does not get unhappy if a ping response gets lost while performing publish and subscribe operations.

AC_IoT/ Devices

Devices are derived from AC_IoT. AC_IoT provides convenience on device level with concepts such as centrally configured device name and MQTT-ID that get used wherever appropriate.

In example, a device with MQTT-ID "garden01" uses "garden01" as a prefix for topics in publications and subscriptions of its capabilities.

When the MQTT connection is established AC_IoT reports the version of the IoT framework, the device version, the IP and MAC addresses, and the number of connect attempts.

In example, the messages

  • "garden01/versionIoT 1.038"
  • "garden01/version 1.010"
  • "garden01/connectAttempts 12"
  • "garden01/ip 192.168.2.76"
  • "garden01/mac 5d:de:ad:be:ef"

would be sent.

Capabilities

Capabilities can easily be added to a device. For a gardening system you maybe add capabilities "temperature", "spoil moisture", "rain", and "relay" (ie, to turn an irrigation system on and off).

A capability encapsulates hardware intricacies, possess a built-in name, and provides configuration options such as a capability ID (a number), update intervals, I/O pins and so on.

In example, a capability encapsulating a BMP280 air pressure and temperature sensor with the built-in name "pressure" has been assigned capability ID "1". The capability will produce publications at a configurable interval using the name of the device, the name of the capability, the capability ID, and the attribute name.

Building on the example above, publications would use the topics

  • "garden01/pressure01/pressure" and
  • "garden01/pressure01/temperature"

Additionally, Capabilities report their version and input and output parameters when the MQTT connection is established. In example, the messages

  • "garden01/pressure01/version 1.001"
  • "garden01/pressure01/capa01 <pressure:<d>" and
  • "garden01/pressure01/capa02 <temperature:<d>"

would be sent, indicating the production of two output attributes with the names "pressure" and "temperature" with numeric output format.

Status Information and Logging

Since a whole bunch of components are working together things can get tough when there is a problem.

The AME stack provides logging via I2C and status information via a RGB-LED.

Logging can be switched off in production

  • at build time by simply not compiling it in at all (thus saving space as well) or
  • at runtime via switching an I/O pin on or off on Arduino reset

The status LED is programmable and consumes only one Arduino pin. It is able to provide quite a bit of useful information!

  • Regarding the WLAN connection:
    • Description to be done (no connection/ trying/ connected)
  • Regarding the TCP connection:
    • Description to be done (no connection/ trying/ connected)
  • When the MQTT connection is in place
    • The LED twitches every second, indicating the Arduino is running and not stuck in an endless loop
    • Every time a message is sent, it flashes in blue, indicating the attempt is being made
    • Every time a message is received, it flashes in ???, indicating a message has been received (the broker did sent it our way)
    • Every time a ping response is received, it changes color (either green or magenta), indicating pings are being sent and received (the broker replied)