Christopher Konopka
Published © GPL3+

"Smart Container App" with NB-IoT, Node and Pusher

Build a "smart container app" to monitor food shipments with NB-IoT, Node and Pusher.

IntermediateFull instructions provided2,043
"Smart Container App" with NB-IoT, Node and Pusher

Things used in this project

Hardware components

Programmable Wireless
Twilio Programmable Wireless
×1
Twilio Alfa Developer Kit
×1

Software apps and online services

Arduino IDE
Arduino IDE
Seeed Studio Wio LTE Library

Story

Read more

Schematics

Connected NB-IoT kit

Code

Code snippet #5

Arduino
  static unsigned long last_send = 0;

  if ((last_send == 0) || (millis() - last_send >= SEND_INTERVAL)) {
    last_send = millis();
  }
  delay(60000);

Code snippet #6

Arduino
    float temperature = dht.readTemperature();
    float humidity = dht.readHumidity();

    LOG(L_INFO, "Current temperature [%f] degrees celcius\r\n", temperature);
    LOG(L_INFO, "Current humidity [%f]\r\n", humidity);

Code snippet #10

Arduino
#include <Seeed_ws2812.h>
#include <BreakoutSDK.h>
#include <stdio.h>

#include <DHT.h>
#define SENSOR_PIN (D38)
#define DHTTYPE DHT11 
DHT dht(SENSOR_PIN, DHTTYPE);

#define SEND_INTERVAL (1 * 60 * 1000)
static const char *device_purpose = "Dev-Kit";
static const char *psk_key = "YOUR_PSK";
Breakout *breakout = &Breakout::getInstance();

WS2812 strip = WS2812(1, RGB_LED_PIN);

void enableLed() {
  pinMode(RGB_LED_PWR_PIN, OUTPUT);
  digitalWrite(RGB_LED_PWR_PIN, HIGH);
  strip.begin();
  strip.brightness = 5;
}

void setup() {
  dht.begin();
  owl_log_set_level(L_INFO);
  LOG(L_WARN, "Arduino setup() starting up\r\n");

  enableLed();
  strip.WS2812SetRGB(0, 0x20, 0x20, 0x00);
  strip.WS2812Send();

  breakout->setPurpose(device_purpose);
  breakout->setPSKKey(psk_key);
  breakout->setPollingInterval(1 * 60);  // SET TO 1 MINUTE POLLING

  LOG(L_WARN, "Powering on module and registering...");
  breakout->powerModuleOn();

  const char command[] = "Hello World from BreakoutSDK test app";

  if (breakout->sendTextCommand(command) == COMMAND_STATUS_OK) {
    LOG(L_INFO, "Tx-Command [%s]\r\n", command);
  } else {
    LOG(L_INFO, "Tx-Command ERROR\r\n");
  }

  strip.WS2812SetRGB(0, 0x00, 0x40, 0x00);
  strip.WS2812Send();
  LOG(L_WARN, "... done powering on and registering.\r\n");
  LOG(L_WARN, "Arduino loop() starting up\r\n");
}

void your_application_example() {
  char command[141];
  size_t commandLen = 0;
  bool isBinary     = false;
  static unsigned long last_send = 0;

  if ((last_send == 0) || (millis() - last_send >= SEND_INTERVAL)) {
    last_send = millis();

    float temperature = dht.readTemperature();
    float humidity = dht.readHumidity();

    LOG(L_INFO, "Current temperature [%f] degrees celcius\r\n", temperature);
    LOG(L_INFO, "Current humidity [%f]\r\n", humidity);
    char commandText[512];
    snprintf(commandText, 512, "Current humidity [%4.2f] and current temp [%4.2f]", humidity, temperature);
    breakout->sendTextCommand(commandText);
  }
  delay(60000);
}

void loop() {
  your_application_example();
  breakout->spin();
  delay(50);
}

Code snippet #12

JSON
{
    "name": "TwilioIoT -NBIoT-timeline",
    "version": "0.0.2",
    "description": "Real-time temp/humidity web app using TwilioIoT and T-Mobile's NBIoT network",
    "main": "server.js",
    "scripts": {
        "test": "echo \"Error: no test specified\" && exit 1"
    },
    "author": "cskonopka",
    "license": "MIT",
    "dependencies": {
        "body-parser": "^1.16.1",
        "db": "^1.1.1",
        "dotenv": "^6.2.0",
        "express": "^4.16.4",
        "path": "^0.12.7",
        "pusher": "^2.2.0",
        "twilio": "^3.27.0"
    }
}

Code snippet #16

JavaScript
var pusher = new Pusher({
    appId: PUSHER_APPID,
    key: PUSHER_KEY,
    secret: PUSHER_SECRET,
    cluster: PUSHER_CLUSTER,
    encrypted: true
});

Code snippet #17

JavaScript
var app = express();

app.use(bodyParser.json());
app.use(bodyParser.urlencoded({
    extended: false
}));

Code snippet #19

Arduino
app.post('/fromSIM', function(req, res) {
    console.log(req.body);
    var newCommand = {
        name: "Reading Received",
        command: req.body.Command
    }
    pusher.trigger('m2m-commands', 'new_command', newCommand);
    res.json({
        created: true
    });
});

Code snippet #25

JavaScript
Pusher.logToConsole = true;

    var serverUrl = "/",
        commands = [],
        pusher = new Pusher(PUSHER_KEY, {
            cluster: PUSHER_CLUSTER,
            encrypted: true
        }),
        channel = pusher.subscribe('m2m-commands'),
        commandList = document.getElementById('commands-list'),
        commandTemplate = document.getElementById('command-template');

    channel.bind('new_command', newCommandReceived);

Code snippet #30

JavaScript
        if (nodesSameClass.length == "6") {
            for (var i = nodesSameClass.length - 2; 0 <= i; i--)
                if (nodesSameClass[i] && nodesSameClass[i].parentElement)
                    nodesSameClass[i].parentElement.removeChild(nodesSameClass[i]);
        }

Code snippet #32

HTML
<!DOCTYPE>
<html>
    <head>
        <title>Twilio Narrowband</title>
        <link rel="stylesheet" href="https://unpkg.com/purecss@0.6.2/build/pure-min.css" integrity="sha384-UQiGfs9ICog+LwheBSRCt1o5cbyKIHbwjWscjemyBMT9YCUMZffs6UqUTd0hObXD" crossorigin="anonymous">
        <script src="https://code.jquery.com/jquery-3.3.1.slim.min.js" integrity="sha384-q8i/X+965DzO0rT7abK41JStQIAqVgRVzpbzo5smXKp4YfRvH+8abtTE1Pi6jizo" crossorigin="anonymous"></script>
        <script src="https://cdnjs.cloudflare.com/ajax/libs/popper.js/1.14.6/umd/popper.min.js" integrity="sha384-wHAiFfRlMFy6i5SRaxvfOCifBUQy1xHdJ/yoi7FRNXMRBu5WHdZYu1hA6ZOblgut" crossorigin="anonymous"></script>
        <script src="https://stackpath.bootstrapcdn.com/bootstrap/4.2.1/js/bootstrap.min.js" integrity="sha384-B0UglyR+jN6CkvvICOB2joaf5I4l3gm9GU6Hc1og6Ls7i6U/mkkaduKaBhlAXv9k" crossorigin="anonymous"></script>
        <link rel="stylesheet" href="https://stackpath.bootstrapcdn.com/bootstrap/4.2.1/css/bootstrap.min.css" integrity="sha384-GJzZqFGwb1QTTN6wy59ffF1BuGJpLSa9DkKMp0DgiMDm4iYMj70gZWKYbI706tWS" crossorigin="anonymous">
        <link rel="stylesheet" href="https://fonts.googleapis.com/css?family=Verdana">
        <link rel="stylesheet" href="./style.css">
        <meta name="viewport" content="width=device-width, initial-scale=1.0">
        <link rel="manifest" href="/manifest.json">
        <meta name="msapplication-TileColor" content="#ffffff">
        <!-- <meta name="msapplication-TileImage" content="/ms-icon-144x144.png"> -->
        <meta name="theme-color" content="#ffffff">
    </head>
    <body>
        <div class="container-fluid">
            <section>
                <div class="m2m-commands">
                    <div class="container">
                        <div class="icon">
                            <div class="row">
                                <img style="height:35%; margin: auto;" src="./assets/twilio.png">
                            </div>
                        </div>
                        <div class="centerdiv">
                            <div class="row">
                                <div class="commands-list" id="commands-list">
                                    <script id="command-template" type="text/x-template">
                                    <div class="user-icon">
                                        <img class="imgstyle" src="./assets/check.png" />
                                    </div>
                                    <div class="command-info">
                                        <div class="row">
                                            <div class="name">{{name}}</div>
                                        </div>
                                        <div class="row">
                                            <div class="text"><em>{{command}}</em></div>
                                        </div>
                                    </div>
                                    </script>
                                </div>
                            </div>
                        </div>
                    </div>
                </div>
            </section>
        </div>
        <script type="text/javascript" src="https://js.pusher.com/3.2/pusher.min.js"></script>
        <script type="text/javascript" src="./app.js"></script>
    </body>
</html>

Code snippet #33

HTML
<div class="commands-list" id="commands-list">
                                    <script id="command-template" type="text/x-template">
                                    <div class="user-icon">
                                        <img class="imgstyle" src="./assets/check.png" />
                                    </div>
                                    <div class="command-info">
                                        <div class="row">
                                            <div class="name">{{name}}</div>
                                        </div>
                                        <div class="row">
                                            <div class="text"><em>{{command}}</em></div>
                                        </div>
                                    </div>
                                    </script>
                                </div>

Github

https://github.com/Seeed-Studio/Grove_Temperature_And_Humidity_Sensor

Github

https://github.com/twilio/Breakout_Arduino_Library

Github

https://github.com/cskonopka/TwilioIoT

Credits

Christopher Konopka
10 projects • 20 followers
I love connecting things
Contact

Comments

Please log in or sign up to comment.