name: inverse class: center, middle, inverse layout: true
@unixbigot — IoT for Slackers
--- layout: true
@unixbigot — IoT for Slackers
--- class: center, middle template: inverse # IoT for Slackers How to bring IoT into your workplace simply and safely,
using .blue[NodeMCU], .red[Node-RED] and .blue[Slack]. .bottom.right[ Christopher Biggs
.blue[@unixbigot] ] ??? Well, G'day everyone! --- .left-column[ # Agenda ] .right-column[ ### **Introduction**: About .blue[Me] and my take on IoT ### **Hardware**: The .blue[ESP8266] Micro-controller ### **Software**: The .blue[NodeMCU] Lua environment ### **Internet**: The .blue[Slack] messaging platform ### **Things**: Some .blue[Ideas] to start you off ] ??? Tonight I want to show you that it's within your capability to construct Internet connected devices for your office and home even if you have no exposure to digital electronics. The tools have gotten so easy to work with that I reckon if you can assemble a coffee table from Ikea, then you can put your toaster on the internet. I'm going to touch on the device hardware and client software I recommend, but gloss over the history and justification given the time constraints. Then I'll talk about how I use the Node-RED platform as a bridge to allow simple low cost devices to communicate bidrectionally with social media and other internet platforms. --- template: inverse # About Me ??? First I want to talk briefly about the way I approach the Internet of Things. --- .left-column[ ## Intro ### About Me] .right-column[ * If I was a kid today, I'd be arrested. .img-600w[![Pyro](pyro.jpg)] .right[disclaimer:
not me
] ] ??? I've been a tinkerer since I was a kid. When I was a teenager I learned how to make a flameflower from laundry chemicals. I did blow myself up a time or two, but fortunately only a partway up. Getting into programming probably saved me from a messy death, but I've never lost my desire to mix things together and see what happens. Later on I found an even more dangerous and unwise hobby: managing programmers. --- .left-column[ ## Intro ### About Me] .right-column.small[ * Thinking about ways to inspire creativity in teams. * This presentation originated from my research for a team hackathon. .img-600w[![Creativity](creativity.jpg)] .right.flyspeck[Image:
Nicolas Raymond
] ] ??? Earlier this year, when I was leading a large dev team through an agile transformation, I planned a team building exercise in the form of an IoT hackathon where teams would brainstorm and build a device to enrich our office environment. I put a lot of thought into how to allow someone who knows a thing or two about software but next to nothing about electronics to get up to speed quickly and easily in the IoT realm. I've selected some tools and example projects that are within the skills and budget of an absolute beginner. --- .left-column[ ## Intro ### About Me ### IoT Philosophy] .right-column.small[ ## My IoT Philosophy * Low power, low complexity .img-400w[![IBM 360](ibm.jpg)] ] ??? So, let's talk about the way I approach the Internet of Things. First, I want to tell you what I think the IoT is NOT. The IoT is not just screwing a unix server to the wall. The first time I spoke on this topic I spent a fair bit of time justifying why we should limit the complexity of our IoT devices, but I think the massive denial of service attacks perpetrated in recent weeks by half a million zombified video cameras have made my point for me. If we're going to put computers in everything, they have to be simple, and secure, and easily managed. We can't all wait outside in the carpark every tuesday morning until the building finishes installing patches. --- .left-column[ ## Intro ### About Me ### IoT Philosophy] .right-column[ * .grey[Low power, low complexity] * Do one job efficiently and simply .img-400w[![Wall mounted Unix server](unix_wall.jpg)] ] ??? Now as it happens I DO have a unix server screwed to my wall. This is my home automation hub, which is a single-board Linux computer running Node-RED, a message broker, and some other services to tie all the peripheral devices into a thinking whole. I'm in the process of shifting that hub role to the cloud, and if you're starting out from scratch, that's the approach I recommend. What I'm suggesting here is that each device should honour the Unix Philosophy - focus on doing one job and be as simple as possible. This doesn't mean we don't have sophisticated behaviour, but the behaviour emerges from the communication of simple parts. I'm going to show you how you can use dirt cheap hardware and free cloud services to Inter-network all your Things into an cooperating whole. --- .left-column[ ## Hardware ### Arduino + Pi ] .right-column.small[ * 2005: Arduino, $50 - Revolutionised accessible electronics - Program in C++ * 2012: Raspberry Pi, $35. - Pros: Full Linux system. - Cons: Full Linux system. * WiFi was an extra cost add-on for Arduino and Pi. .img-250w[![Arduino NG](arduino_ng.jpg)] .img-250w[![Raspberry Pi](raspberry_pi.jpg)] ] ??? You might have heard about the devices that jumpstarted the revolution in physical computing, a board out of Italy called the Arduino, and a computer from the UK called the Raspberry Pi. Both of these are excellent products, and I use a number of them in my existing installations, but I want to skip over these to the next generation of IoT devices that are smaller, cheaper, and more importantly have versatile onboard wifi. --- .left-column[ ## Hardware ### Arduino + Pi ### ESP ] .right-column.small[ * 2014: Espressif ESP8266 - initially sold as a cheap WiFi Modem peripheral * Rapid diversification of hardware modules .img-500w[![ESP 8266](esp8266.jpg)] ] ??? About a two years ago we got a new player in the IoT market which dramatically shifted the cost-benefit tradeoffs. This company out of Shanghai called Espressif released a chip that they called the ESP. It was aimed at commodity devices like light-bulbs and thermostats, and also for use as a kind of "wifi modem" for other computers like the Arduino. To give you an idea of scale that's a double-A battery at right so the biggest of these modules is about the size of a matchbox. --- .left-column[ ## Hardware ### Arduino + Pi ### ESP ] .right-column.small[ ### The ESP8266 System-on-a-Chip .smaller[ * 80MHz 32-bit CPU * 64kB of on-board RAM * External flash ROM up to 16MB * On-board WiFi * 16 General-purpose Input/Output pins * SPI, I2C and Asynchronous serial communications * Proprietary real-time operating system * Packaged in a number of different hardware modules with between 2 and 22 IO pins ] ] ??? I wanna briefly describe the ESP itself. You have a 32-bit CPU that runs pretty fast for its size, and typically a few megabytes of flash RAM to store your programs. The manufacturer provides an operating system core that takes care of all the WiFi and TCP/IP protocols. It's got up to about 20 IO pins for talking to sensors and actuators, and its even powerful enough to run a small LCD screen. --- .left-column[ ## Hardware ### Arduino + Pi ### ESP ### Cheap as in Chips ] .right-column.small[ * All this for as little as two dollars * ...in unit quantity .img-400w[![NodeMCU Dev Kit](nodemcu_devkit.jpg)] ] ??? And it costs as little as two bucks. So in terms of computing power at the low end we've got the Arduino which is great at doing real-time stuff like running motors and sensors, and at the high end the Raspberry Pi that gives you a full Unix system with all its benefits and drawbacks, and in the middle there's the ESP, which has a bit of overlap with both the others and is really easy to work with. The combination of a pretty capable computing core with an insanely low cost means you can start putting these devices everywhere. --- template: inverse # Software ??? All right, so we've settled on a hardware platform for our Things. Now I want to talk about the software environment that it gives you. --- .left-column[ ## Software ### Options ] .right-column[ ### ESP as a platform * 2014: (Oct) NodeMCU project creates a Lua programming environment * 2014: (Nov) Arduino C++ runtime ported to ESP8266 * 2014: (Nov) MicroPython ported to ESP8266 * 2015: (Oct) Espruino micro-Javascript environment usable on ESP8266 ] ??? There's a number of programming enviroments that you can use with the ESP. The first one out of the gate was the NodeMCU project. These folks built a programming environment that's heavily inspired by Node-dot-JS, and this is the one that I'm going to tell you more about today. Around the same time we got a port of the Arduino runtime that allowed you to take your C++ code written for Arduino and run it directly on the ESP. So if you like C++ you can continue working with that. There's been a port of the MicroPython project to the ESP, and last year the Espruino Javascript environment was ported to ESP, although it's still not really stable. --- .left-column[ ## Software ### Options ### NodeMCU ] .right-column.small[ * 2014: (Nov) Open source NodeMCU Dev Kit design is published. * Boards cost under $5 .img-640w[![NodeMCU Pins](nodemcu_pins.png)] ] ??? In the hardware space the NodeMCU team also designed a development kit, which is open source hardware. You can buy it from folks who designed it, or elsewehre, for around five bucks. But you're not limited to the nodeMCU dev board, the software platforms I've discussed will run on any of the ESP modules. I'm even finding you can buy commercial products like remote control power points and whack nodemcu on them. The handy thing about the NodeMCU reference design is that it includes a USB interface so you can upload your code, and also power it from any USB power source. It's got one button on board, and one light emitting diode, so you can do simple projects with literally nothing else. It's got about a dozen extra IO pins that you can use to interface with other senors, actuators and displays. It's small enough to fit inside the lid of a mint tin, and hooking up peripheral modules is really quite easy even for someone with no previous electronics experience. --- .left-column[ ## Software ### Options ### NodeMCU ] .right-column.small[ ### The NodeMCU Lua Environment * Uses the lightweight "Lua" scripting language * Event-loop model inspired by NodeJS (but not actually Javascript) .img-800w[![NodeMCU rationale](nodemcu_why.png)] ] ??? Okay, so what is NodeMCU exactly. One or two of you might have heard of a little project called Node-dot-JS, which is a server side programming environment for Javascript. The key feature is that it's based around an event loop, non blocking IO, and callback functions. NodeMCU is unashamedly inspired by this, but using Lua in place of Javascript. If you don't know Lua, just imagine that Javascirpt and Python had a drunken one night stand, then abandoned baby Lua on the doorstep of a games studio. Anyway, when you're using NodeMCU you're running Espressif's OS core but you're interacting with a thin layer of Lua on top of that, including a language interpreter. Just like NodeJS you register callback functions for events. These events can be things like button presses, or timer interrupts, or network connections, or wifi events. --- .left-column[ ## Software ### Release ### Explosion ### NodeMCU ] .right-column.small[ * Cloud build service - Link RTOS core, Lua interpreter, Lua modules * IDE .blue[esp8266.ru/esplorer] * CLI .blue[github.com/kmpm/nodemcu-uploader] .img-500w[![ESPlorer](esplorer.png)] ] ??? So we've got a miniature computer on a board, and its got a button and a light built right in, and the possibility to plug in all sorts of stuff. We'll gloss over interacting with other hardware right now and talk briefly about getting the board set up. As I said, you can upload your OS into the NodeMCU board over USB. The boards come with the wifi modem firmware, which makes no sense at all, so the first thing you need to do is replace that with the NodeMCU firmware. You can check the whole project out from github and build it yourself if you want, but there's a cloud service where you just tick the options you want and it builds a custom firmware in a few minutes and emails you a link. Then you install it over USB, boot up and you can talk to the board with a command prompt, or use one of several IDEs. Much like working in Node you can noodle around in a command interpreter for testing and exploration, but generally you work at the level of code modules. --- .left-column[ ## Software ### Release ### Explosion ### NodeMCU ] .right-column.small[ * Comprehensive doco .blue[nodemcu.readthedocs.io] .img-800w[![NodeMCU documentation](nodemcu_doco.png)] ] ??? I'm skipping a lot of detail tonight to leave time for the fun parts, but the good news for you is there's a really nice documentation site for the NodeMCU project, it talks you through getting your firmware, installing it, and lists all the available tools for transferring files. There's really comprehensive doco for all the Lua modules and links to existing resources for the Lua language itself. --- template: inverse # Internet ??? All right so you've got a handle on the hardware we'll be using, and I've sketched out how the coding environment owes a lot to node.js, now lets see how to interface this with some workplace systems. Since I want you to be able to go back to your office and connect your toaster to the internet without having to do pesky things like asking for permission, I'm going to show you how to route around your network admin. Network admins can form a line to attack me in the break. --- .left-column[ ## Internet ### Slack ] .right-column[ * Slack is a cloud hosted team collaboration platform (chatserver) * Mobile, Desktop, Browser * Easy to use APIs .img-640w[![Slack homepage](slack_homepage.png)] ] ??? The way I'm going to interface Things to People is via the Slack messaging platform. If you're not using slack, work with whatever you do use, but from what I'm hearing, everyone's using slack these days even the ones whinging about how IRC was better. One of the really good things about Slack is that it has a whole pile of integrations with other platforms, along with a couple of general purpose webhook integrations that let you hook in pretty much anything you want. With slack integrations you can do things like have your software build system post slack messages about changes in build status of your projects, or have your performance monitoring system message you any time there is an outage or a traffic spike on your websites. When you bring IoT into the picture you can start having your physical devices interact with people and other systems via slack, they can send messages to slack, and they can receive and reply to messages from slack. --- .left-column[ ## Internet ### Slack ### Sending ] .right-column[ ### Device to Slack - .blue[Incoming Webhooks] .img-400h[![Slack admin](slack_admin.png)] .img-600w[![Slack webhooks](slack_webhooks.png)] ] ??? Okay so to be able to send things to slack we need to configure an integration that slack calls an Incoming Webhook. This will create a URL that you can POST to over HTTP, and your post triggers a message on a channel. Your post can be as simple as just a message, or it can contain other parameters to set the username, channel name, and other stuff. --- .left-column[ ## Internet ### Slack ### Sending ] .right-column.small[ * .grey[To send to slack, create an **Incoming Webhook**] * Testing your webhook ```bash curl -X POST --data-urlencode 'payload={"channel": "#demo", "username": "interruptingcow", "text": "MOOOO!.", "icon_emoji": ":cow:"}' https://hooks.slack.com/services/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 ``` .img-800w[![Webhook example](slack_inbound_test.png)] ] ??? Another thing I like about Slack is that it has really good documentation. When you go to the settings page for your webhook integration it has a whole expandable section that contains documentation for the webhook protocol and an example of how to test it from a shell prompt. Here we see an example of me calling the webhook from a terminal window, and a snippet of what channel members would see in their slack windows when the message arrives. --- .left-column[ ## Internet ### Slack ### Sending ] .right-column.small[ * .grey[To send to slack, create an **Incoming Webhook**] * .grey[Testing your webhook] * Doing HTTP from .blue[NodeMCU] ```Lua function slack_send(msg) local post_headers= 'Content-Type: application/json\r\n' -- build a message local post_body = '{ "channel": "#demo", "username": "interruptingcow", "icon_emoji": ":cow:", "text": "'..msg..'", "mrkdwn":true}' -- transmit our message http.post(slack_url, post_headers, post_body, function(code, data) if (code < 0) then print("HTTP request failed: code "..code) else print("Slack response: ", code, data) end end ) end ``` ] ??? Now here's some NodeMCU Lua code to send a message to slack. We just construct a JSON object to send to slack and then we use NodeMCU's http module to post it. Since everything in NodeMCU is asynchronous our sending function isn't going to wait for the post to complete, this means if we want to act on the outcome we need to provide a callback function that gets invoked later once the post operation has either succeeded or failed. But, you don't even have to do this, because I've done it for you. --- .left-column[ ## Internet ### Slack ### Sending ] .right-column.small[ * .grey[Doing HTTP from NodeMCU] * ...the easy way (.blue[github.com/unixbigot/manfred]) ```json // config.json { "application_name": "button", "button_message": "Everybody PANIC!!" } ``` ```json // credentials.json { "wifi_passwords" : { "ExampleCorp Wifi": "swordfish" }, "slack_webhook_url" :"https://hooks.slack.com/services/T1MV1421H/B2B01B5GV/thereisafroginmybidet" } ``` ```lua -- button.lua function button_start() register_button(config.pin_button, "down", button_event) end function button_event(level) slack(config.button_message); end ``` ] ??? Here we have a complete application that is built on top of the the framework that I wrote. What you see up on screen is literally all the code that you need to write to get interaction between a physical device and a slack channel. You upload the bundle of lua files for framework itself, then all you need to add is the configuration and some application callbacks, in the files you see on screen. So we set some configuration values and register some events with the framework, then when we get a button press on our hardware, we send a message to slack. Dead easy, but handy for all sorts of things. I'll talk about specific applications later. --- .left-column[ ## Internet ### Slack ### Sending ### Receiving ] .right-column.small[ ### Slack to Device - .blue[Outgoing webhooks] * Listen for keywords on a channel * .blue[POST] details to a URL .img-500w[![Outgoing setup](slack_outgoing_setup.png)] ] ??? Let's think about the other direction. To receieve messages from slack there is an integration called an outgoing webhook. Conceptually, outgoing is not much more complex than incoming, but there's two more things, we need to be aware of. First we need to choose which messages get sent to our devices. We could transmit everything said on slack to our IoT devices, but that would be inefficient, and creepy. So when you configure an outgoing webhook you can define a pattern that looks for particular text on a particular channel. When slack sees a message that matches your pattern it's going to bundle it up into a JSON data structure and POST it to the URL you defined. As well as the details of the message that triggered the hook, the post going to contain a token unique to that hook, so you can use this to authenticate, if the token is not correct you just ignore the post. --- .left-column[ ## Internet ### Slack ### Sending ### Receiving ] .right-column.small[ * Receiving .blue[POST]s in the cloud .img-500w[![IoT Broker](iot_broker.png)] ] ??? Second, we need some way for slack to reach our devices. We need to tell slack what the URL of our webhook is going to be. Your ESP device is probably inside a firewall or a NAT gateway, and it probably got a dynamic IP address assigned to it by your access point. So it's a bit of a hassle to have slack deliver an outgoing web hook direct to your device. Also you'd have to configure a separate hook for every device, and it turns out you only get 10 hooks on slack's free tier. Instead of going direct to our devices, we put a piece of middleware out in the cloud that is going to provide a hook endpoint to serve all our devices. The post handler parses the event, and publishes it to a lightweight message service, and the IoT device connects to the same message service and subscribes to the topics that it needs. So basically this resolves our one-way firewall problem by having our Things make outbound connections to a message service, in order to receive notifications forwarded from slack. --- .left-column[ ## Internet ### Slack ### Sending ### Receiving ] .right-column.small[ * Siting your .blue[middleware]: * Any old web server you already have * Red Hat OpenShift (prototyped, three free servers per account) * Amazon Lambda (prototyped, X free calls per month) * Amazon EC2 (this is what I'll demo) * localtunnel.me (a public endpoint for your internal servers) * Your favourite cloud service * Run your own MQTT broker, or try .blue[test.mosquitto.org] ] ??? In terms of what to use for your middleware, fundamentally you just need something that can receve a HTTP post and relay it to an MQTT message broker. If you're not familiar with MQTT, it's a really lightweight publish-subscribe message bus that's designed for telemetry and control, it gets used a lot for building automation. I started out using a spare PC in the office, then I set up an Amazon EC2 server. Openshift and Amazon Lambda are totally good choices too, I've done proofs of concept on both of those. At home I run the whole shebang on that Raspberry Pi that's ziptied to my wall. --- .left-column[ ## Internet ### Slack ### Sending ### Receiving ] .right-column.small[ * Using .red[Node-RED] (.blue[nodered.org]) as your middleware - Visual wiring system for the IoT - Make HTTP APIs, pubish and subscribe with MQTT - **hundreds** of plugins for all sorts of systems - eg. route your BI metrics to a custom phone app in an hour .img-800w[![Node Red Flows](nodered_hooks.png)] ] ??? Let's look at my middleware. Right now I'm using Node-RED as the glue layer between slack and my devices. Now if you were here last month you heard me talk about Node Red, but if not Node-RED is this amazing tool that originated at IBM and has just moved under the JS foundation. This flow-based visual programming system comes pretty darn close to that old dream of just dragging reusable blocks of code around on screen and joining them up. --- .fullpage[ ## A closer look at the .red[Node-RED] flows .img-900w[![Node Red Flows](nodered_hooks.png)] ] 1. Someone (or thing) slacks "Status for Project Icarus is green" 1. Node-red publishes `projects/icarus/status <= green` 1. A Thing subscribed to this topic receives the message ??? Here's a closer look at the flows that sit between slack and our things. We've got one flow which receives a HTTP post, confirms that it contains slack authentication token, then does a bit of pattern matching on the message. The message gets passed on to some logic that publishes to the message broker. So in this case if someone on slack says that the status for project Icarus is red, then that's going to match our status pattern, and get routed to a function which publishes an update to the message broker. The way that information gets around in node red is via messages (give details) Now, down the bottom there's another flow here which does the reverse. In a previous slide I showed how to post straight to slack from your NodeMCU device, but that does mean you're putting your slack authentication token in maybe dozens of devices. What you can do instead is publish a message to MQTT and have Node-RED subscribe to that topic, and forward message on to Slack. So here we have a flow that receives a message from MQTT, slaps a content-type header on top, then posts it out over HTTP. This has an advantage over direct communication with slack in that you can observe exactly what your things are up to, and you can lock down your firewall so that your things are only allowed to talk to your message broker and nothing else. --- .left-column[ ## Internet ### Slack ### Sending ### Receiving ### Networks ] .right-column.small[ ## Getting your Things on the Internet * Use your guest wifi * Use a personal hotspot * Use your office lan with caution ```json // credentials.json { "wifi_passwords" : { "Guest WiFi": "guest", "Alice's Phone": "margarita", "Bob's Phone": "daiquiri", "ExampleCorp Wifi": "swordfish" }, "mqtt_server": "nodered.unixbigot.id.au", "mqtt_user": "iot", "mqtt_pass": "userabetterpassword", "slack_topic" :"slack/inject" } ``` ] ??? I promised I'd tell you how to work around your network administrator. If you're going to do this stuff in the office, you don't necessarily have to use your office LAN. If you have a guest wifi network, that's ideal, or maybe you can set up a jailed network where any devices are only allowed to connect to your one MQTT server. In a pinch you can use a personal hotspot, the amount of data that these devices send is miniscule. In this configuration here I show how your devices can be configured to choose one of a number of wifi networks, and also how to post to slack by publishing to the message broker rather than direct to slack. Anyway if you run into objections in your workplace about security, I've got a couple of articles that talk about how to minimise the risks. --- template: inverse # Things ??? Okay let's talk about building some useful things. --- .left-column[ ## Things ### Electronics ] .right-column.small[ ### Electronics for Noobs * Don't panic, read [blog.unixbigot.id.au](http://blog.unixbigot.id.au/2016/09/iot-for-absolute-beginners.html) * Ones and zeros are volts and no volts * It's pretty much Lego bricks with wires .img-400w[![Electronics for dogs](electronics_for_dogs.gif)] .right.flyspeck[Image:
Out There Films
] ] ??? This is where you might start to feel like you're not in Kansas any more. Now, I've put together a shopping list and some worked examples of how to do some basic interactions, you'll find links to all these at the end of this deck. Digital electronics is just representing ones and zeroes with either high or low voltage, and here we're talking about the three to four volts that you get from one little lithium battery. From the point of view of a software engineer if you can make a function call to send an email, you can make a function call to turn on a light. The hardest thing you'll have to do is poke the right wire into the right little hole. I'm not going to talk too much more about wiring up your projects, but I have written a fair bit about it on my blog. --- .left-column[ ## Things ### Electronics ] .right-column.small[ ### Starter kit * Costs about $12 .img-400w[![IOT Starter Kit](iot_starter_kit.jpg)] ] ??? So here's your basic starter kit, we've got the NodeMCU devkit board itself, a solderless breadboard, a USB power bank and cable, some jumper wires, and some IO modules. You insert your devkit board onto the base board, and the little spring loaded sockets let you connect up jumper wires as easy as plugging in a headphone jack. Anyone remember headphone jacks? If you've never used a breadboard before, the principle is that each little row of five holes are wired together underneath, so if you want to join two wires you just plug them into any two sockets in the same row. --- .left-column[ ## Things ### Electronics ] .right-column.small[ ### Module extension kit * Sample bag of IO modules - $10 .img-400w[![IOT module Kit](iot_modules.jpg)] ] ??? Once you want to move beyond buttons and lights there's a huge variety of modules you can buy. Environmental sensors, motion detectors, knobs and joysticks, buzzers and vibrators and lasers, oh my. This sample bag here costs about ten bucks for the whole lot. You can get even get touchscreen displays that can show graphics and images again for under ten bucks. I'm sure you've noticed the info screens at the doors to this room, if you want to make your own, it's within your reach. --- .left-column[ ## Things ### Electronics ### Big Red Button ] .right-column.nopad.small[ ### The Big Red Button ```lua function button_start() register_button(config.pin_button, "down", button_event) end function button_event(level) slack("Everybody Panic!!"); end ``` .img-320h[![Panic Button](panic_button.png)] ] ??? Okay, going back to the simplest possible example before, here we have a thing that sends a message to slack when you push a button. Once again, we have one button and one light, but I've upsized the button quite a bit. This was designed to be the panic button for my operations team. I'm sure you can think of several applications for buttons like this, release announcements, doorbells, the donut truck is here, whatever you like. --- .left-column[ ## Things ### Electronics ### Big Red Button ] .right-column.nopad.small[ ### Team meeting alerts ```lua function meeting_start() register_button(config.pin_button, "down", meeting_button) mqtt_subscribe("teams/excalibur/meeting", 0, meeting_receive) end function meeting_button(level) if (meeting_state == 'idle') then slack("Standup meeting time!") mqtt_publish("teams/excalibur/meeting", "1") meeting_state='called'; flash_led(500) else slack("Meeting Ack!") if meeting_state == 'called' then mqtt_publish("teams/excalibur/meeting", "0") end meeting_state='idle'; stop_led() end end function meeting_receive(conn, topic, data) if (data == "1") then meeting_state = 'invited'; flash_led(500) else meeting_state='idle'; stop_led() end end ``` ] ??? Here's a more complicated example, that uses the exact same hardware. When you've got a team that isn't colocated, or has got remote members, you can deploy several big red buttons, or put one on every desk, and use them to initiate a team meeting. When someone hits the button, they all start flashing. Then each person can hit their button to acknowledge that they're on their way. Whenever someone whose light is on hits their button it sends an acknowledgement to slack and their light goes out. If the person who initiated the meeting hits their button, then it turns off all the lights for the whole team. Remember this code is crunched up a bit, but it's all the code I had to write for this application. --- .left-column[ ## Things ### Electronics ### Big Red Button ### Traffic Light ] .right-column.nopad.small[ ### Project status "Traffic Lights" ```lua function traffic_start() mqtt_subscribe("projects/icarus/status", 0, traffic_receive) end function traffic_receive(conn, topic, data) if data=="red" or data=="danger" then ws2812.write(string.char(0,0,0,0,0,0,0,255,0)) elseif data=="amber" or data == "yellow" or data=="warning" then ws2812.write(string.char(0,0,0,126,255,0,0,0,0)) elseif data=="green" or data=="good" then ws2812.write(string.char(255,0,0,0,0,0,0,0,0)) end end ``` .img-200h[![Traffic Lights](traffic_lights.jpg)] ] ??? This next example is a build status display, and demonstrates how to have devices react to messages in slack. This project uses an outgoing webhook to listen for messages about project status, then the status updates get published to the message broker. The hardware component uses some full colour LEDs that you can string together using just three wires. You could even build a jumbotron screen out of them with enough effort. The thing subscribes to the topic it cares about, then when it receives a message it updates the lights to reflect the status update. --- .left-column[ ## Things ### Electronics ### Big Red Button ### Traffic Light ] .right-column.nopad.center[ .img-320w[![Traffic Lights](traffic_light.gif)] ] ??? And here it is in operation. It's listening for status updates on a channel, and when a message comes in from jenkins or whatever saying that the status for project icarus is green, our webhook picks that up and posts it to node red, which puts it on the message bus. The device recieves the message and updates the lights. It also replies back to the channel about what it's done. --- .left-column[ ## Things ### Electronics ### Big Red Button ### Traffic Light ### Slacker Toast ] .right-column.nopad.small[ ## Slacker toast .img-640w[![Slacker toast](slacker_toast.jpg)] ] ??? Okay, here's one last example and its my favourite because it solves a serious problem of mine. I'm a chronic breakfast skipper so I'd typically start my day at the office with a coffee and toast from the break room. I'd put some bread in the toaster, then get into a conversation with someone, and more often than not I'd wander off back to my desk without my toast. So this project does several things. First it fetches the staff list from a webserver, in order to display a selection list on a little LCD. When you twiddle the dial you can select your name. This is the kind of dial that can be both turned and pressed as used in car radios. When you press the button it announces that you're making toast and begins timing. When the infrared sensor on the end of this arm detects an object, it announces that your toast is ready. If it doesn't see an object after five minutes it presumes someone stole your toast and announces that. There's only four discrete modules in this assembly, the NodeMCU, the LCD screen, the dial module, and the infrared sensor module. The whole lot cost under twenty bucks. --- template: inverse # Conclusion ??? So, that's what I can do with a bit of Slack, a bit of NodeJS, some Lua and less than twenty bucks worth of hardware. Now it's your turn, go forth and be silly. Get together, set a budget, order up some parts and put a day or a weekend into seeing who can come up with the most useful, most fun, most ridiculous Internet Thing. --- .left-column[ ## Intro ## Hardware ## Software ## Internet ## Things ## Conclusion ] .right-column[ ## Summary * Low-cost special purpose devices * Really easy software framework * Use the systems you already have * Glue misaligned parts with .red[Node-RED] ] ??? Just to recap, we've talked about the hardware that's available today and what it can do. I've talked about the NodeMCU software system and the framework I've built on top to simplify it further. I've showed you how to integrate with slack, as an example for you to try integrating whatever systems you already have. And I've showed you some ways to use Node-RED to bridge the gaps by building APIs out of boxes and string. --- .right-column[ ## Resources, Questions * Code: http://github.com/unixbigot/manfred * Tutorials: http://blog.unixbigot.id.au/ * Get in Touch: - Twitter: .blue[@unixbigot] - Email: .blue[christopher@biggs.id.au] * Consult Me: http://christopher.biggs.id.au/ ] ??? Okay, so that's all I have for you today. There's a lot more info, code examples, links and pictures on my blog, and on my github. I encourage you to get in touch if you've got any questions, either through twitter or github, or email. If you want to hold a hackathon, or do things in your workplace with IoT, hit me up. Over to you. --- .right-column.small[ ## Suppliers * China (cheap but slow) - [AliExpress.com](http://aliexpress.com) - See the shopping lists on [my blog](http://blog.unixbigot.id.au/2016/09/iot-for-absolute-beginners.html) * Australia - [Little Bird Electronics](http://littlebirdelectronics.com.au) - [Tronixlabs](http://tronixlabs.com.au) * USA - [Adafruit](http://adafruit.com) - [FriedCircuits](https://www.tindie.com/products/FriedCircuits/nodemcu/) ]