Adapting a WoT Thing Description for LPWAN usage

After playing around with MQTT, the Thing Description specification and a Micropython WebThing API library from Mozilla, i was wondering about a possible combination with LPWAN technologies. LPWAN is short for Low Power Wide Area Networks, radio networks that can cover larger areas, typically some kilometers around a base station. Examples for LPWANs are the famous LoRaWAN, SIGFOX, Weightless and Narrowband IoT (ok, the latter is more in the telco/carrier space, but with similar properties regarding uplink).

The Web of Things bindings currently available focus on higher-level protocols such as HTTP, Websockets or MQTT. All of them need TCP/IP as the basic protocol stack to work. No IP, no HTTP. Even if we would use CoAP as a protocol better suited for constrained devices, we'd be down to UDP, which still is IP-based. LPWAN technologies typically do not work with a TCP/IP stack, because looking at some of the radio aspects such as bandwidth, packet size and latency, the overhead of an IP-stack is too much to be a valid option.

SIGFOX, as an example, allows for a packet size of 12 bytes in an uplink message, and 8 bytes in a download message. LoRaWAN works with different spreading factors, and The Things Network forum has a great post on data rate and packet size, regarding their fair access policy. In the end, payload sizes here are quite limited, too. Plus the number of messages per timeframe are very limited, which means when sending something you'd typically have to wait some minutes before you may send again (duty cycle within the 868/915MHz band).

So, regarding LPWANs we have

  • no TCP/IP, which means no higher level protocols too
  • very limited packet sizes, forcing us to carefully select what to transmit (on a byte-, and sometimes, bit-level), potentially compressing it too
  • no direct request/response paradigm, which means some interactions such as "Read property xyz" have to be carried out in a different way.

On the other side, after some time having worked with SIGFOX, LoRA and NB-IoT devices, i think some mapping should be possible. Of course not a full Web Of Things binding, but a mere test adaption of the Thing Description and its interactions to some LPWAN-based devices.

Thing interactions for LPWANs

How can one map the interactions regarding Properties, Actions and Events to the limiting factors of LPWANs? Let's look at data first.

Pretty much everything around Web of Things is based on JSON and JSON-LD, which is great for processing by both humans and machines. At the same time, it's too large for LPWANs small packet sizes. Luckily, there are some JSON-compatible options. One is MessagePack, a binary representation of JSON. And there is CBOR, essentially the same but defined in an RFC. Within the LoRaWAN universe, CayenneLPP is often cited. It's Cayennes "Low Power Payload", a compression schema with additional semantics such as Data types like Temperature (2 bytes at a 0.1 deg data resolution).

So there are some methods (and libraries) to choose from. How could interactions look like?

Properties

Properties are things like "Temperature", "LED state" or "HumidityThreshold", so data points a device either collects from the environment, or controls within its enviromment, or simply stores for processing them. Properties can be read and/or written.

Getting a property is typically understand like a "get" request addressed to the device. Now if downlink messages can reach the device only few times per day, this latency is probably not acceptable. Instead, the device could actively report the state of its properties in (regular) uplink messages. For the interactions this means we could not query the device for individual properties, but have to wait for it to report them somewhere. The limiting factor is that the amount of properties have to fit into a single uplink message or that properties are split up across several uplink message, and the receiver(s) are able to contruct the original data from it.

Setting a property has to be a downlink message from the network to the device. Here we'd have to accept this probably being a store-and-forward mechanism: A PropertySet request has to be placed at the LPWAN provider portal, fitting into a single packet and then be forwarded to the device when it's about time. Another mechanism is that downlink messages need to be requested by devices, so every time a device reports its properties, it can request a downlink message and process it.

Actions

Actions are triggered on the device, such as "Flash LED", "Open greenhouse window" etc. In a way, triggering actions is comparable to setting a property: It's a downlink message, and we probably cannot guarantee a timely delivery. Depending on the LPWAN's characteristics, this might be acceptable for some type of actions (e.g. "Trigger watering for 10 minutes"), for others maybe not ("OpenGarageDoorRightNow").

Events

Events such as "Watering Ended after 10 minutes" are easier to handle. They could be temporarily stored on the device, and transmitted as an uplink message instead of a property report update. In Web of Things terminology, Actions and events can carry payloads (e.g. details of an event). Regarding the limited packet size, it's a challenge to place both the event and its payload into a packet, and not cannibalizing the space needed for property updates. So its probably a tradeoff about what is more important to transmit.

Implementation

Now how to get this to life? I could imaging a SIGFOX demo case. I'd limit events to be without payload, which would make up to 8 events fit into a single byte, as a bit field. Events are transmitted in an uplink message together with a report of all properties. Every uplink message sets the request for a downlink message. A downlink message can be of two types: Either it's a request for setting a property, or triggering an action. In the first case, the downlink message contains property ID and value. In the latter case, it's the action ID and some form of small payload.

I'd opt for MessagePack in the first place, because i've been working with a C library that's good for embedded devices, and it worked out well. Data structures could be like so (pseudo-code):


struct UplinkMessage {
  EventBitmap   uint8;    // signal up to 8 events in a bitfield

  // here come all properties, just need to make sure
  // it all fits in 11 bytes. (12 minus the event bitmap byte above)
  PropertyA     typeA;
  PropertyB     typeB;
  // ...
}

struct DownlinkMessage {
  MessageType   bool;     // true: setProperty request, false: actionRequest

  union {
    SetPropertyRequest {
      PropertyID  uint8;  // as char or int, 1=A, 2=B..
      union {
        PropertyA     typeA;
        PropertyB     typeB;
        // ...
      }
    }
    ActionRequest {
      ActionID        uint8;
      ActionPayload   PayloadType;    
    } 
  }
}

That looks quite raw. Nothing much left of models, self-description and the good things, all down to bits and bytes. But i think i'll give this a try :) At the network-side of SIGFOX, a gateway can easily transform the messages into JSON, and connect to other Web of Things services.