In Nov 2015 I participated in Intel Roadshow where people hacked on Intel Edison powered projects.
Got a temperature sensor running hooked to http server and LCD #edison #IntelMakerON #fun pic.twitter.com/IJCC0olW8c
— gmarik (@gmarik) November 21, 2015
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
- Why Go for IoT?
- Reading sensor data with Go
- EnableIoT platform and the API
- Pushing sensor data to the metrics platform
- 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
- static binary: no dependencies (unlike python or node)
- cross compilation: compile on my mac, copy to the device and run
- efficient: fast, statically typed, low memory footprint
- Gobot library: provides support for working with IoT devices
Cons
- no EnableIoT API client for Go; there are python one, node one and others but no Go one.
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:
- devices and components belong to an account
- devices host components
- component hosts sensor.
- UUIDs are used for identification
accessToken
anddeviceTokens
are JWT tokens and used for authentication
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.