-
Schemas for everyone~!
04/26/2017 at 10:28 • 0 commentsThe next project log is still on the way. It's delayed as I'm trying to figure out a problem with data models.
This project is a mix of software and hardware development. The software part is rather tricky so I'm putting efforts into making the code base modular (or more accurately, making libraries).
The biggest hurdle I'm facing right now is dealing with JSON Schema. Since each device can have multiple resources, where each resource provides data that is described with one or more JSON schemas. OIC Spec v1.1.0 contains quite an extensive list of schemas for various resources. (doors, heart rate monitors, air conditioners, etc). So I'm deciding on how to deal with them, since vendors may specify their own schemas, it's just becoming a bit of a mess.
The plan for now will be generating code for the known schemas in OIC spec v1.1.0, whill be some work honestly. but hopefully soon i'll have a nice generic library that is not too complicated to use, which will be extended later on with dynmic things
-
Where it's at
04/15/2017 at 23:02 • 0 commentsHello World is great and all. But this is where my project sort of kinda explodes into a huge complex mess that's yet to be organsied.
My next project goal was to control a RGB LED from my phone or desktop.
- Add a RGB LED resoruce with information about how to send data to it
- Allow the App to identify the resource's schema and present a UI the easily control the resource.
Simple enough, right?
CoAP. What are they, we just don't know
I've mentioned CoAP as being the protocol of choice. but haven't explained what it is or what it provides. Simply put, Constrained Application Protocol (or CoAP [RFC7252]) is a constrained-resource friendly protocol that takes concepts from HTTP and applies it to an unreliable transport (like UDP).
- It provides the well known GET, PUT, POST and DELETE methods.
- Has response codes (2xx, 4xx, 5xx).
- Supports simple message reliability options
- Allows resources to be observed
- And (my favourite part) uses a
/.well-known/core
URI to allow anyone else on the network easily discover it's resources and additional meta data.
I like the discovery aspect to CoAP as it means you don't need to configure the ip address of the device (actually, anything at all about it). As clients will send out a multicast "GET /.well-known/core" request on the local network, then all CoAP server devices will eventually respond (with in a short random period) with a a list of their resources, and attached meta data.
To go into a bit more detail:
- A CoAP Client (App, or another device) sends a "Non-Confirmable GET /.well-known/core" request to 224.0.1.187 on port 5683
- Non-Confirmable means "You are not required to reply with a acknowledgement" otherwise, the network immediately becomes a mess of "Yup I got it"...
- 224.0.1.187 is a special IP address used for multicast messages specifically for CoAP
- A CoAP Server (a device with resources) is subscribed to the multicast address 224.0.1.187 and waits for messages that were sent to it.
- When the server receives a message that was sent to multicast. it waits a Leisure period before responding to the client directly (unicast) with another Non-Conformable message
- A Leisure period is by default 5 seconds. but can be any random period. however, Section 8.2 of RFC7252 has more specifics on what this period should be.
- Unicast means that the server sends the message to the client's ip address directly, and not through the multicast address.
- The client then receives a response and processes it like any other message.
What's so special about /.well-known/core?
/.well-known/core is a special resource that is easy to parse and human readable. An example looks like
;ct="0,50";rt="temperature";if="sensor",;anchor="/sensors/temp";rel="describedby"
A little confusing at first. but breaking it down shows
</sensors/temp>;ct="0,50";rt="temperature";if="sensor"
-> that there is one resource at /sensors/tempct="0,50"
-> that can be read in human readable "text/plain" or in "application/json"rt="temperature"
-> the resource uses a temperature Resource Typeif="sensor"
-> the resource interfaces like any other sensor (GET, PUT, POST, DELETE)
<http://exaample.com/schemas/temp>;;anchor="/sensors/temp";rel="describedby"
-> Not a resource, but a link to an external site that contains informationanchor="/sensors/temp"
this resource is metadata for/sensor/temp
rel="describedby"
This resource describes how to interface with/sensor/temp
I wont go into much more detail as it's all specified in RFC75252 and RFC6690
However, this allows an app to see what a device has to offer and any information needed to interact with the resources on a device.
Putting it all together
I created a LED resource on my device at /leds. The Lobaro-CoAP library is nice in that it automatically adds an entry to
/.well-known/core
for you. Then added a colour picker to my Xamain.Forms app (again this was no easy feat, I ended up building a custom control for Windows which took a lot of trial and error 😱). Finally, I added some busniness logic to show the color picker on a resource when it reconised the resource type reported by the devie.The result is very similar to my previous tweet (Sorry, I don't have video of my latest code in action... as it's not currently in action...)
https://twitter.com/NZSmartie/status/844921602995204096 <- Video in action on twitter
-
First Steps
04/14/2017 at 08:32 • 0 commentsThis project has been started already and well, haven't documented anything about it except for what's been posted here.
My first steps involved having a look at what's already available for IoT from a low level embedded developer point of view. Since I have no commercial background in IoT and wanted to build something for my home.
First round of researching found an already popular MQTT protocol which is primarily used over TCP. This protocol is a simple Subscribe/Publish messaging protocol with a few added features like passwords and (I think) forwarding messages onto nodes not directly accessible by the subscriber. It's clean, though, not feature rich.
For some reason I was interested in UDP IoT protocols (possibly for ease of jumping into Low Power mode and not worrying about TCP states). I Quickly found CoAP which was designed to follow in the footsteps of HTTP; As it's designed for low resource environments, includes URI schemes: `coap://` and `coaps://` (using DTLS), oobserve (subscribe) model and a pile of other features.
Okay Cool. Decided on CoAP, Now What?
I read through CoAP's RFC (yeah, all of it... Several times...) and learnt a few extra things:
- CoAP is transport agnostic (meaning it doesn't care if you're using BLE, nRF24, infrared, smoke signals, etc...) and wanted to keep that in mind while working on my implementation.
- It supports resrouce discovery using multicast (similar to how your phone knows there's chromecast on the network).
- Each resource on the device (leds, sensors, status, configuration) can provide a scheme and a data type. For example, LEDs can return data in human readable (text/plain) or in JSON (applicaiton/json).
The ESP32 has a nice framework for quickly getting started with it, called ESP-IDF. This framework includes a scrap bin full of useful components already configured to go. there is libCoAP included in there too. but when poking around with it. it's got a built in transport layer that's not easy to override. and ESP32's IP stack Light Weight IP (LWIP) doesn't support multicast properly (Will go into detail on request).
I found a neat little library called Lobaro-CoAP, no way near polished at libCoAP but it exposed the transport mechanism allowing me the choice of how and when I send the data from the device. So went with that!
Hello World~!
I set out to create a basic Hello World project. The requirements were:
- My phone must discover the device on the network
- The phone must list the resources on the device and allow me to GET the resource I selected.
- The ESP32 must connect to the WiFI and respond to CoAP discovery requests
- Have a simple /hello resource that can be found and provide a GET method.
Right. A phone app...
This is the part where I learn Xamarin.Forms and figure out how to build an app that works on both my phone and my computer. This took some time. but the results can be found at https://github.com/NZSmartie/CoapTest
The second challenge was getting the ESP32 to work as intended. I implemented lobaro-coap on my IoTNode project, hitting some limitations pretty quickly but after a few pull requests later. my ESP32 was responding to multicast messages and my app was finding the device with no problem!