Currently, on 09/01/2017, the latest Raspbian Stretch release does not work with the Node.js packages. Stretch appears to have a later version of OpenSSL with breaks the gateway. I imagine that dependency will be corrected in the future. For that reason I am specifically using Raspbian Jessie
-
Flash the last version of Raspbian Jessie (http://downloads.raspberrypi.org/raspbian/images/raspbian-2017-07-05/2017-07-05-raspbian-jessie.zip) to your SD card using http://etcher.io
-
Boot the Pi using the flashed SD card and login as pi/raspberry
-
Connect the pi to your wifi network if it isn't hardwired
-
Optionally enable ssh/vnc so you can connect to your pi remote from a computer on the same network. From a terminal prompt on the pi run:
sudo raspi-config nonint do_ssh 0 sudo raspi-config nonint do_vnc 0
-
Now you can either vnc or ssh into the pi from your computer on the same network. You can download a VNC viewer from https://www.realvnc.com/en/connect/download/viewer/
-
Run the following commands on the pi in a terminal prompt, or via an ssh session.
-
Update apt-get package lists
sudo apt-get update
-
Update git:
sudo apt-get install git
-
Update to the latest Node.js version (v8.4 as of 09/01/2017):
curl -sL https://deb.nodesource.com/setup_8.x | sudo -E bash - sudo apt-get install nodejs
-
Ensure you are in your home folder, the clone the iot-edge-samples repo, and change into the /js/simple sample folder:
cd ~ git clone https://github.com/Azure-Samples/iot-edge-samples cd iot-edge-samples/js/simple
-
Install the packages from the package.json file
npm install
-
At the time this is being written (09/01/2017) there is a missing dependency that needs to be installed. There is a pull request in to get the dependency added to the package.json file, but for now you need to manually install the azure-iot-device-amqp library to support communication from the gateway to the iothub using AMQP
npm install azure-iot-device-amqp
-
Review the ~/iot-edge-samples/js/simple/gw.local.config.json file:
cat ~/iot-edge-samples/js/simple/gw.local.config.json
-
The file only loads two modules:
node_sensor
andnode_printer
. Thenode_sensor
module is implemented in the modules/sensor.js file. It is a simple node.js modules that simulates a three devices each with a temperature and humidity sensor value. It publishes a JSON payload with all three devices and their sensors in a single message to the gateway message broker. Thenode_printer
module is implemented in the modules/printer.js file. It simply dumps the message get gets from the gateway's message broker out to the console.The links section indicates that messages sent by the
node_sensor
and forwarded by the message broker to thenode_printer
modujle.{ "loaders": [ { "type": "node", "name": "node" } ], "modules": [ { "name": "node_printer", "loader": { "name": "node", "entrypoint": { "main.path": "modules/printer.js" } }, "args": null }, { "name": "node_sensor", "loader": { "name": "node", "entrypoint": { "main.path": "modules/sensor.js" } }, "args": null } ], "links": [ { "source": "node_sensor", "sink": "node_printer" } ] }
-
Go ahead and run the local only sample (note,
npm run local
uses the 'local' definition in package.json. You could alternatively just runnode app.js local
):npm run local
-
You should see output similar to the following (Press Enter to exit the gateway):
> [email protected] local /home/pi/iot-edge-samples/js/simple > node app.js local Gateway is running. Press return to quit. printer.receive - [{"name":"input","content":[{"sensorId":"device1","temp":120,"hmdt":66},{"sensorId":"device2","temp":129,"hmdt":54},{"sensorId":"device3","temp":123,"hmdt":99}]}] printer.receive - [{"name":"input","content":[{"sensorId":"device1","temp":34,"hmdt":89},{"sensorId":"device2","temp":76,"hmdt":21},{"sensorId":"device3","temp":143,"hmdt":38}]}] printer.receive - [{"name":"input","content":[{"sensorId":"device1","temp":109,"hmdt":57},{"sensorId":"device2","temp":13,"hmdt":76},{"sensorId":"device3","temp":132,"hmdt":73}]}] Gateway is quitting. printer.destroy sensor.destroy
-
To test publishing sensor data to the cloud, create an iot hub in Azure and provision a device id for the gateway to publish to. Copy the primary connection string for the device you provisioned.
-
Use
nano
on the pi to edit the ~/iot-edge-samples/js/simple/gw.cloud.config.json file so you can paste the device connection string you just copied into it.nano ~/iot-edge-samples/js/simple/gw.cloud.config.json
-
Locate the place holder for the device connection string:
… { "name": "iothub_writer", "loader": { "name": "node", "entrypoint": { "main.path": "modules/iothub_writer.js" } }, "args": { "connection_string": "<IoT Hub device connection string>" } } …
-
And replace it with the connection string you copied from above. For example:
… { "name": "iothub_writer", "loader": { "name": "node", "entrypoint": { "main.path": "modules/iothub_writer.js" } }, "args": { "connection_string": "HostName=edgeiot.azure-devices.net;DeviceId=simplesample;SharedAccessKey=eeJ1anRlgSrmUe98iH4sIEihM6Li+NrFqt7blqRVAQs=" } } …
-
Save your changes in nano. Press Ctrl-X to exit, Y to save your Changes and Enter to confirm writes to the original file
-
Now you can test the cloud version with:
Note: If you get an
FATAL ERROR: v8::ToLocalChecked Empty MaybeLocal.
error, just try running the command again. Sometimes I'll get that error two or three times before it works. I THINK this is related to an issue with Node.js 8.x, but not positive.npm run cloud
-
You should see output similar to the following:
> [email protected] cloud /home/pi/iot-edge-samples/js/simple > node app.js cloud Gateway is running. Press return to quit. printer.receive - [{"name":"input","content":[{"sensorId":"device1","temp":65,"hmdt":41},{"sensorId":"device2","temp":90,"hmdt":76},{"sensorId":"device3","temp":195,"hmdt":22}]}] printer.receive - [{"name":"input","content":[{"sensorId":"device1","temp":53,"hmdt":47},{"sensorId":"device2","temp":56,"hmdt":81},{"sensorId":"device3","temp":117,"hmdt":2}]}] printer.receive - [{"name":"input","content":[{"sensorId":"device1","temp":142,"hmdt":79},{"sensorId":"device2","temp":44,"hmdt":81},{"sensorId":"device3","temp":115,"hmdt":40}]}] Gateway is quitting. sensor.destroy printer.destroy iothub_writer.destroy
-
If you run a tool like Device Explorer or iothub-explorer on your computer, connect to your iot hub, and monitor the data from the device you are publishing as above
-
If you want to use MQTT instead of AMQP, you can install the
azure-iot-device-mqtt
module. From the ~/iot-edge-samples/js/simple directory run:Note: You can following a similar workflow to try using HTTP via the
azure-iot-device-http
module, although it seems to fail for me. Your mileage may vary.npm install azure-iot-device-mqtt
-
And modify the modules/iothub_writer.js file:
nano ~/iot-edge-samples/js/simple/modules/iothub_writer.js
-
Comment out the declaration of the
Protocol
variable that uses AMQP, and replace it with one that uses MQTT://let Protocol = require('azure-iot-device-amqp').Amqp; let Protocol = require('azure-iot-device-mqtt').Mqtt;
-
Save the changes and run it. The output should look the same as the AMQP output.