IoT sensor metrics with Go - Part 1

In Nov 2015 I participated in Intel Roadshow where people hacked on Intel Edison powered projects.

After the hackathon, I couldn’t come up with a good idea what to do with the device, so I decided to go with the obvious one: reporting sensor readings.

Luckily the event also advertised EnableIoT platform which was exactly what I needed for my project.

This post is Part 1 of the 2-post series and covers high level info about parts involved.

Plan

  1. Why Go for IoT?
  2. Reading sensor data with Go
  3. EnableIoT platform and the API
  4. Pushing sensor data to the metrics platform
  5. Running sensor-reporter service on Intel Edison

(Part 2 is now available)

Why Go for IoT

For me it was an obvious choice for a few reasons:

Pros

Cons

Lack of official support didn’t seem like a show-stopper to me so I went forward with Go.

Reading Sensor Data with Go

Reading sensor data is pretty straightforward using Gobot library:

package main //analog_read.go

import (
	"fmt"

	"github.com/hybridgroup/gobot/platforms/intel-iot/edison"
)

func main() {
	device = edison.NewEdisonAdaptor("edison")

  // read from sensor pin "0"
	v, err := device.AnalogRead("0")
	if err != nil {
		fmt.Fatal(err)
	}

	fmt.Println("Read:", v)
}

EnableIoT platform and the API

Here’s high-level overview of parts involved for a quick reference. More detailed description is available on the official Wiki page.

+----------------+   +--------------------------------------------+
|    Account     |   |                    Device                  |
+- accessToken   |   +- deviceToken                               |
+- UUID          |   +- UUID                                      |
|                |   |   +-----------------+ +-----------------+  |
+----------------+   |   |    Component-A  | |    Component-B  |  |
                     |   +- UUID           | +- UUID           |  |
                     |   +- type           | +- type           |  |
                     |   |  [sensor1]      | |  [sensor2]      |  |
                     |   +-----------------+ +-----------------+  |
                     +--------------------------------------------+

where:

Pushing sensor data to the metrics platform

Since there was no Go API client I wrote one: go-iotkit. For example below snippet gives an idea of how pushing data works by sending single value “123”:

package main

import (
    "time"
    "github.com/gmarik/go-iotkit"
)

func main() {

  client := iotkit.NewClient(nil)

  // observations are submitted in batches
	batch := iotkit.ObservationBatch{
		AccountId: "AN-ACCOUNT-UUID",
		On:        iotkit.Time(time.Now()),
		Data:      []iotkit.Observation{
      {
        ComponentId: "A-COMPONENT-UUID",
        On:          iotkit.Time(time.Now()),
        Value:       "123",
      },
    },
	}

	_, err := client.ObservationAPI.Create(
		batch,
		iotkit.Device{
			"A-DEVICE-UUID",
			"A-DEVICE-JWT-TOKEN",
		},
	)

}

For API details look to the Wiki For Go examples look at go-iotkit observation tests.

Running sensor-reporter service on Intel Edison

Intel Edison is powered by Yocto Linux so it requires Linux executable deployed to the device. Deployment is done through ssh and the device has to have everything (network, sshd, etc) configured.

Is sensor-reporter is a Go program responsible for reading and submitting sensor data. It was quickly hacked together so if you see any improvements - don’t hesitate to send me a PR. It’s quite lengthy that’s why I’m not listing it here.

Yocto Linux uses systemd to run processes and it’s also used to keep sensor-reporter process always running, which requires a bit of configuration, for example like this.

[Unit]
Description=sensor-reporter light pin-3

[Service]
Environment='ACCOUNTID=************************************'
Environment='DEVICEID=************************************'
Environment='DEVICETOK=****************************************'
Environment='COMPONENTID=************************************'

Environment='SENSORPIN=3'
ExecStart=/opt/sensor-reporter -pin $SENSORPIN -delay 30s -flush-size 12 -component-uuid $COMPONENTID -device-token $DEVICETOK -device-uuid $DEVICEID -account-uuid $ACCOUNTID

Restart=always

Summary

This is the end of the Part 1 which is an overview what it takes to get sensor data reported from Intel Edison device using Go. In Part 2 we’re going to put everything together and have one sensor reporting its readings.

Comments