More Webthings on IoT.js, MCUs, Tizen…

Connect webthings devices to gateway

So called “Webthings” (understand “servers”) are implementing WebThing API (this relates to W3C Web of Things (WoT) Thing Description).
Various languages can be used for implementation, today “Things Framework” page is listing NodeJS, Python, Java, Rust and ESP8266 (+ESP32).

Today’s challenge is to try IoT.js (the Internet of Things framework using JavaScript), as alternate runtime to NodeJS (on v8) and thus gain performance.

The consequence for application developers, is without adding complexity they can now also target more constrained devices using JavaScript high level language.

Make Webthings powered by IoTjs

My latest effort was to port webthing-node to IoT.js, this has been done by removing a couple of features (Actions, Events, Websockets, mDNS), then rewrite some JS parts that used latest ECMA features not supported by Jerryscript the underlying JavaScript interpreter, Also to preserve code structure I also reimplemented parts of express.js on IoT.js’ HTTP module.

This article will explain how to replicate this from scratch using Edison board running community Debian port., but it should be easy to adapt to other configurations. For GNU/Linux based OS this should flawlessly work too (as there is nothing specific here only GPIO pin for demo) while platforms supported by IoT.js should be possible too (Tizen:RT supported by ARTIK05x or NuttX as supported by STM32F4).

Setup Edison

Since IoT.js landed in Debian, I wanted to test it on Edison board running community maintained Debian port: jubilinux v9.

Note if you’re using (outdated) Poky/Yocto reference OS, it’s easy to rebuild on device too (just install libc6-staticdev).

Anyway here is the procedure to flash distro to Edison:

cd jubilinux-stretch
# Unplug edison
time sudo bash flashall.sh
# Plug USB cables to edison
Using U-Boot target: edison-blankcdc
Now waiting for dfu device 8087:0a99
Please plug and reboot the board

Flashing IFWI
(...)

(While I am on this, here is my bottle in the ocean, do you know How to unbrick a unflashable Intel Edison ?)

Then log in and configure system:

# Connect to terminal
picocom  -b 115200 /dev/ttyUSB0
U-Boot 2014.04 (Feb 09 2015 - 15:40:31)
(...)
Jubilinux Stretch (Debian 9) jubilinux ttyMFD2
rootlinux login: 
# Log in as root:edison and change password
root@jubilinux:~# passwd
root@jubilinux:~# cat /etc/os-release 
PRETTY_NAME="Jubilinux Stretch (Debian 9)"
NAME="Jubilinux Stretch"
VERSION_ID="9+0.4"
VERSION="9+0.4 (stretch jubilinux)"
root@jubilinux:~# cat /proc/version 
Linux version 3.10.98-jubilinux-edison (robin@robin-i7) (gcc version 4.8.4 (Ubuntu 4.8.4-2ubuntu1~14.04.3) ) #3 SMP PREEMPT Sun Aug 13 04:22:45 EDT 2017

Setup Wifi, the quick and dirty way:

ssid='Private' # TODO: Update with your network credentials
password='password' # TODO:
sed -e "s|.*wpa-ssid.*|wpa-ssid \"$ssid\"|g" -b -i /etc/network/interfaces
sed -e "s|.*wpa-psk.*|wpa-psk \"$password\"|g" -b -i /etc/network/interfaces

Optionally, we can change device’s hostname to custom one (iotjs or any name), it will be easier to find later:

sed -e 's|jubilinux|iotjs|g' -i /etc/hosts /etc/hostname

System should ready to use after rebooting:

reboot
apt-get update ; apt-get install screen ; screen

Then you should be ready to install precompiled IoT.js 1.0 package using apt-pining as explained before:

IoT.js landed in Raspbian

This will work, but for demo purpose, you can skip this and rebuild latest snapshot with GPIO module (not supported in default profile of version 1.0).

Rebuild IoT.js snapshot package

Based on Debian iotjs’s packaging file, you can rebuild a snapshot package from my development branch very easily:

apt-get update ; apt-get install git make time
branch=sandbox/rzr/devel/master
git clone https://github.com/tizenteam/iotjs -b "$branch" --recursive --depth 1
cd iotjs
time ./debian/rules && sudo debi

It took only 15 min to build on device, if short of resources you can eventually build deb packages out of device like explained for Raspberry Pi 0:

How to Run IoT.js on the Raspberry PI 0

WebThing for IoT.js

Now we have an environment ready to try my development branch of “webthing-node” ported to IoT.js (until ready for iotjs-modules):

cd /usr/local/src/
git clone https://github.com/tizenteam/webthing-node -b sandbox/rzr/devel/iotjs/master --recursive --depth 1 

Then just start “webthing” server:

cd webthing-node
iotjs example/simplest-thing.js

In other shell check if thing is alive:

curl -H "Content-Type: application/json"  http://localhost:8888/

{"name":"ActuatorExample","href":"/","type":"onOffSwitch","properties":{"on":{"type":"boolean","description":"Whether the output is changed","href":"/properties/on"}},"links":[{"rel":"properties","href":"/properties"}],"description":"An actuator example that just log"}

Then we can control our resource’s property (which actually just a LED on GPIO, but it could be a relay or any other actuator)

curl -X PUT -H "Content-Type: application/json" --data '{"on": true }' http://localhost:8888/properties/on
gpio: writing: true
curl http://localhost:8888/properties/on
{ "on": true }

Install webthing service

Systemd will help us to start the webthing server on boot listing on default http port:

unit="webthing-iotjs"
dir="/usr/local/src/$unit"
exedir="$dir/bin"
exe="$exedir/$unit.sh"
servicedir="$dir/lib/systemd/"
service="$servicedir/$unit.service"

mkdir -p "$exedir"
cat<"$exe" && chmod a+rx "$exe"
#!/bin/sh
set -x
set -e
PATH=$PATH:/usr/local/bin
cd /usr/local/src
cd webthing-node
# Update port and GPIO if needed
iotjs example/simplest-thing.js 80 45
EOF


mkdir -p "$servicedir" && cat<$service
[Unit]
Description=$unit
After=network.target

[Service]
ExecStart=$exe
Restart=always

[Install]
WantedBy=multi-user.target
EOF

Enable service:

killall iotjs
systemctl enable $service
systemctl start $unit
systemctl status $unit
reboot

Connect to gateway

Set up “Mozilla IoT gateway” as explained earlier, you can add some “virtual resources” to check it’s working too:

Connecting sensors to Mozilla’s IoT Gateway

Connecting our “ActuatorExample webthing” to gateway will require you to fill the explicit URL of Edison device.

Using your browser, open gateway location at mozilla-iot.org or http://gateway.local :

On “/things” page click on “+” button to add a thing, then “Add by URL…” wait for form:


Enter web thing URL:
iotjs.local

press “Submit” it will display:


ActuatorExample
On/Off Switch from iotjs.local:80

then press “Save” and “Done”, it should appear on Dashboard, you can click on “Actuator Example”‘s icon to turn it off or on.

Let’s verify is working by connecting a LED (Red) to Intel Edison’s minibreakout board (pinout) which is delivering 1.8V :

  • GPIO45: on J20 (bottom row), use the 4th pin (from right to left)
  • GND: on J19 (just above J20), use the 3th pin (from right to left)

Note, for later the reason why it was not scanned automagically is because I removed mDNS feature to ease the port, but a native or pure js module could be reintroduced later in, to behave like NodeJS webthing.

RGBLamp on Microcontrollers

Another platform to consider is ESP8266 (or ESP32), it’s a Wifi enabled microcontroller.
ESPxx are officially supported by Mozilla with a partial implementation of WebThings currently using native Ardiuno APIs. You can even try out my native implementation of RGBLamp.

If curious, you can also get (or make!) OpenSourceHardware light controller from Tizen community’s friend Leon.

Then it would worth comparing with a JavaScript version since JerryScript is supporting ESP8266.
Note that If IoT.js should be downsized for ESP8266, maybe ESP32 could be considered too (on FreeRTOS ?).

Other devices supported by IoT.js can be considered too, such as ARTIK05x (on TizenRT)

Standalone Tizen WebApp

Finally as a bonus chapter, while hacking on Tizen TM1, I made a standalone app that can login to Mozilla gateway and browse resources.

First time it should retrieve OAuth token, and then the browser is able to list existing resources.

If you don’t have a Tizen TM1 device, you can try using SDK or even your desktop browser (with CORS feature configured):

rm -rf tmp/chromium
mkdir -p tmp/chromium
chromium-browser --disable-web-security  --user-data-dir="tmp/chromium" https://rzr.github.io/webthings-webapp/

Feel free to contribute, for debugging purposes this URL can also be used
https://tizenteam.github.io/webthings-webapp/

More details on this experiment at https://github.com/rzr/webthings-webapp.

Further Reading