Skip to content

Instantly share code, notes, and snippets.

@BretStateham
Last active September 1, 2017 20:00
Show Gist options
  • Save BretStateham/a78d0fbdd12ee028639e6a40dc6bf6a2 to your computer and use it in GitHub Desktop.
Save BretStateham/a78d0fbdd12ee028639e6a40dc6bf6a2 to your computer and use it in GitHub Desktop.
Running the IoT Edge (v1) npm Package Samples on Raspbian Jessie

Running the IoT Edge (v1) NPM Package Samples on Raspbian Jessie

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

  1. 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

  2. Boot the Pi using the flashed SD card and login as pi/raspberry

  3. Connect the pi to your wifi network if it isn't hardwired

  4. 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
  5. 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/

  6. Run the following commands on the pi in a terminal prompt, or via an ssh session.

  7. Update apt-get package lists

    sudo apt-get update
  8. Update git:

    sudo apt-get install git
  9. 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
  10. 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
  11. Install the packages from the package.json file

    npm install
  12. 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
  13. Review the ~/iot-edge-samples/js/simple/gw.local.config.json file:

    cat ~/iot-edge-samples/js/simple/gw.local.config.json
  14. The file only loads two modules: node_sensor and node_printer. The node_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. The node_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 the node_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"
        }
        ]
    }
  15. Go ahead and run the local only sample (note, npm run local uses the 'local' definition in package.json. You could alternatively just run node app.js local):

    npm run local
  16. 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
    
  17. 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.

  18. 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
  19. 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>"
    }
    }
    
  20. 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="
    }
    }
    
  21. Save your changes in nano. Press Ctrl-X to exit, Y to save your Changes and Enter to confirm writes to the original file

  22. 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
  23. 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
    
  24. 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

  25. 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
  26. And modify the modules/iothub_writer.js file:

    nano ~/iot-edge-samples/js/simple/modules/iothub_writer.js
  27. 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;
  28. Save the changes and run it. The output should look the same as the AMQP output.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment