Node.js and the Internet of Things Using Intel Edison
-
What Is the Internet of Things (IoT)?
I think you'll agree that Internet of Things is pretty ambiguous. Any phrase with the word "things" in it is inevitably somewhat ambiguous, right? With a bit of moxie, I rejected the definitions I had found and I wrote my own. It is computation that is no longer limited to devices with screens. It's far more pervasive, it assumes an eventual connection to the cloud, and it integrates into and enriches the environment and our daily lives. In my opinion, the most important word in that definition is "enriches." If this modern age of computers doesn't result in a net improvement in people's lives, then we shouldn't even waste our time with it. Ultimately, the Things in the Internet of Things need to save us work, save us time, improve our communication with family members, bring us information we didn't have before, bring us valuable insight in the information that we weren't previously paying any attention to, and pretty much just improve the way that we, as humans, live and work. It has the power to change the impact that we have on our environment and our usage of natural resources. It has the power to enable means to measure our consumption of energy and thus, dramatically reduce it. In short, the Internet of Things is a really big deal, but lucky for us, it's also a blast. It's fun to watch gadgets light up and see data from the real world flood the screen and the network. It's fun to design things in 3-D and then watch them emerge from a pool of liquid resin in a 3-D printer. It's a lot of fun. Let's try to visualize and quantify the impact that IoT has already had and is going to continue to have on our world. Consider for a bit every device in the world that's connected, so don't count the calculator on your desk, but do count your thermostat if you're controlling it with your phone. Don't count your TV if it has a coax cable, but do count it if it has an Ethernet cable or Wi-Fi. Now, let's draw some circles. Orange for people and blue for these connected devices. In 2003, before the mobile revolution, we had far more people on the planet than we had devices. Many people in developed countries had connected PCs, but many others didn't. Many people had started carrying cell phones, but many others had not. Enter 2008. Now, Apple has created the iPhone and it's changing the way things work and the way people think. Suddenly, they're not just connecting and sharing or collecting information from their desk at home or work, but while they're walking the dog and while they're on a date. By the way, don't be that guy. In some time that year, the number of connected devices surpassed the number of human beings. Now, in 2015, there are far more devices than people. In 2020, it's projected that that trend will not only continue but compound, resulting in something like 50 billion connected devices. Surely, it's a massive coming revolution. Instead of a long, low wave of water approaching us slowly like many revolutions before, this one seems to be right on the horizon towering above and ready to crash down and disrupt so many facets of modern life. IoT really changes things. Before it, we, humans, are working on screens. Actually, at any given point, we're working on a screen to create our data. Therefore, the growth of data is linear. We see it grow as the number of humans and the number of screens grows. The cost of entry, that is the cost to purchase one of these screens, is relatively high. Unfortunately, much of the data that's generated is difficult enough to make sense of, but often times, no sense is made. After the Internet of Things however, Things create data. Our databases fill up overnight while sensors monitor and record the world around them. The data growth is then exponential as both devices and data collection points increase. Not only is the cost of the devices and components low, but the data storage is so low in a task so easy that we tend to end up with massive amounts of data that make it even more difficult to make any sense of. By the way, this eludes to the topic of big data. That's nearly an inevitable topic for those interested in the Internet of Things, but we're not going to cover that topic right now. Just do a search on Pluralsight, and you'll find all the information you need. In the internet as we've known it, we have a virtual wire connecting millions of laptops, desktops, phones, servers, et cetera. In the Internet of Things however, those devices are still there, but so are a lot of other things. We're going to be learning how to connect our own device to the internet with an Intel Edison inside, acting as the brain so it can communicate with a whole bunch of other fun things. Now, let's look at a few. The Things in the Internet of Things is ambiguous because we're talking about just about anything. I speculate that it will at some point become difficult to think of examples of things that should remain unconnected. We're talking about cars and diapers and fitness equipment and planter boxes, toasters, parking spots, bathroom scales, shoes, bird feeders, cattle, glasses, dog collars, kitchen appliances, and who knows? Maybe even a human heart. All able to participate in an orchestration that, once again, enriches our lives. Now, there are obviously security concerns here, but that has never not been the case with any revolution ever. They'll arise and they'll bite us, but we'll come up with clever ways to outwit the malicious types. All of these devices contain installations of small hardware components that take a little bit of hardware know-how to put together. They also usually involve a bit of specialized software know-how because of the code to target the hardware it specialized. There's a way around both of those constraints though. The specialist hardware is becoming standardized, and the specialized software is getting abstracted away with the ability to compose our applications using higher-level frameworks.
-
It's Better with Node
Here are two side-by-side examples of the code it takes to do the "Hello, World" of hardware projects, a blinking LED. On the left: the wiring code. On the right: the JavaScript. Wiring is an opensource programming framework adapted from basic C and intended to be used for projects exactly like this. There's nothing wrong with choosing wiring as your coding framework for your next IoT project, but if you have a device capable of running JavaScript, then sometimes, it's going to make your life a lot easier. By the way, it's difficult to draw up a perfectly fair comparison here between one and the other. The JavaScript you see on the right is employing a module that we'll look at later called Cylon. There's actually a short bit of setup to provide you with the Edison variable and the LED there so that you can toggle. Overall, you'll have means when you're in the JavaScript environment to make your code far more expressive and terse. When you're trying to do something more than controlling the hardware, such as employing a Wi-Fi card on an HTTP library to do requests to the web, not such an uncommon task as you can imagine. The advantages of a higher-level framework and language become even more clear. Here's some code a friend of mine wrote in an overall elegant and impressive use of C++ code to tell his Edison to fetch the latest value of a certain Bitcoin fund. The snippet you see shows the effort required to build a simple HTTP request up manually so that it can be submitted for a response. That's the kind of code that you'd probably rather a library do for you, right? Here's the same operation in JavaScript. The HTTP module comes free with Node.js, and calling APIs from the web is practically an everyday task for this framework. It's made for stuff like this, so it's really easy. It's really good at it. The biggest advantage is not actually the language itself, but JavaScript. In the last example, it was the HTTP module that was actually making our lives so much easier. That module's there for us because of the Node platform. The Node platform is a really rich ecosystem of code written by a lot of smart people that are very excited about this stuff. This vibrant community has written and published, last time I counted, over 135,000 modules that are free to include with a single line in your app whether it's for a website or an IoT device. You do something like this, and you're ready to tap into Twitter's streaming API. By the way, we're going to do exactly that in a later module, so keep watching. You use NPM on your local machine to access them. Need a simple web server? Use the built-in HTTP module. Need an VMC framework for websites and services? Require Express. Need a library for handling dates and times like a pro? Require moment. Need a massive and highly performant utility library? Just require lodash. Check out what it takes to write a simple web server in Node. You pull in the core HTTP module, and then you simply call the createServer method passing in a function that you want to handle requests as they arrive. If you need a web framework on top of that, here's what a basic Express website looks like. This is even shorter than the previous example. That's because the first line is requiring the Express module, and the Express module has its own dependencies and manages those so we don't have to. Express depends on the HTTP core module, for instance, but we don't have to specify that here. After requiring Express, we simply handle the default route. That means we're determining what happens when a person puts the device's host name or IP address in the browser's address bar with nothing after it. And we're serving an HTML file, nice and simple. Finally, if the request-response cycle that you get when you use an HTTP server is too expensive for what you're trying to do, you can use sockets. In Node, that's easy too. On the server side, you include the socket.io module, just like we did with the HTTP in Express in the previous examples. Then, you define what you want to happen when the server receives a socket message. Then on the client, you require the socket.io-client module, or if your client's a webpage that's going to run in someone's browser, you just add a script reference. Then you can emit a message, and it could hardly be any easier than that. It's cool too that each of these messages has only two bytes of envelope overhead, so you're sending hardly any extraneous data at all. I love playing with WebSocket. We'll see more of them in an example project later in this course.
-
In This Course
Here's the overview from the course so you can get an idea just what it is that you're about to learn. In this first module, you've been introduced to the Internet of Things. You've seen why it's such a hot topic, and you've been thoroughly convinced, I'm sure, that it's going to be a huge part of your very near future, whether you simply consume or decide to produce. In the next couple of modules, we're going to learn about some hardware. We're going to take a tour of the various devices available at the time of this recording, even though such a list is sure to be outdated within hours. We'll discuss which devices are suitable for which projects, and then we'll narrow the scope to the Intel Edison, which is a system on a chip that gives us the ability to write our high-level software, JavaScript, to talk to our low-level devices. Then in the next couple of modules, we'll write code, JavaScript code. We'll learn a couple of cool ways to write it and a couple of cool ways to deploy it to the device. We'll learn about a couple of libraries that will make life much easier. Finally, the last two modules will span all the topics and tie them together as we implement actual projects from end to end. We'll have examples throughout the other modules as well, but for these twin finale modules, I've handpicked my examples to teach you, first, the basics of creating a single and simple device and later, a more involved collaboration of multiple devices with some communication between them. I'm hoping that after hearing what you'll learn in this course, you won't even think about changing the channel. Just fetch an energy drink, and we'll jump right into our talk on the device landscape.
-
Understanding the Device Landscape
Introduction
Hi, welcome back, I'm Jeremy Foster. Thanks for watching this course on Nodejs and the internet of things using Intel Edison This module is on understanding the device landscape. You've been formally introduced to the Internet of things now we are moving into a two module section about the devices that can be used as the brains of a project. Most devices or systems are going to have a brain. It's not an absolute necessity. There are digital systems architected without a subsystem that qualifies as a central processing unit. But those aren't very common, usually there's a brain. And in this course we're definitely going to be working with systems that have brains. There are basically just two kinds of devices, microcontrollers and systems on a chip. Microcontrollers are a much simpler architecture and the code that you use to program them is pretty simple too. Systems on a chip are more complex architecture that allows the chip to run a standard operating system like Windows or Linux and that'll let you run node. That's not the only advantage though. Another advantage to running a standard operating system is that there are apps and libraries that you or someone else has already written that will often work just fine in this IoT environment, even if that's not what they were originally intended for. It's great to work with a popular platform because it means a lot of code's already been written. After we look at both types of processors, we'll take a quick look at some of the hardware that you can plug into your device to make it do things. And we will also have a glance at the various methods for the device to communicate outside itself. After we get a good general view, we'll spend the next module looking specifically at one device, the Intel Edison.
-
Microcontrollers
First then, let's look at microcontrollers. Microcontrollers like the processor in your phone or a computer are integrated circuits or ICs for short. They are made of silicone with junctions etched to form really small transistors. These transistors are engineered so they all work conditionally and form logic. A couple of transistors may work together to take a voltage low whenever it's high or high whenever it's low. That would be a logical not operation. The circuits in a microcontroller are simpler than your computer or even your phone though. There's less silicone and smaller instruction sets, that is there are fewer unique things that the processor is actually capable of doing. They often have less than 100K of integrated memory so, it's enough to run a series of instructions, but it's not enough to keep a bunch of code libraries, media assets and so forth in memory. Microcontrollers are designed to enable you the programmer to program some simple code that controls the I/O that's connected to whatever you're using for an IoT device. In devices with a microcontroller the devices I/O is attached to the processor but way of a bus and the various I/O pins are able to be addressed and manipulated by the processor. The most popular of these microcontroller based IoT devices is very easily the Arduino. but before we talk about the Arduino I want to take you back a step to a very popular and rather old microcontroller that's been the brain behind many a maker project even before this modern maker movement. I'm talking about the pick microcontroller and here it is in all of its simplicity, in three form factors actually. Now the fundamental difference between ICs, most ICs in a microcontroller is that most ICs have a specific intended purpose. They do one thing that might invert a logic value or generate a timing signal or they might amplify a signal but a microcontroller is not designed for a specific task. It's designed to take instructions that you the programmer give it, now that' awesome. That means that instead of one or two or even 10 things that it can do, it can do innumerable things. Microcontrollers like the pic then have been around for a while. But they are in the spotlight now thanks the popularity of devices like the Arduino. Actually, mostly thanks to the Arduino itself. Now the pick microcontroller's been around since 1976 and Arduino's hit the scene in something like 2005. The basic Arduino Uno is an IoT device. It combines some standard I/O pins, the power ports some timing chips, the USB port and a few other things with a microcontroller. Now it's not exactly pic but it's not far off. These sort of brains made by AtMel is a little bit of memory and enough processor power for most basic tasks. There are a lot of flavors of Arduino boards by the way, as you can see by this one alternate example of the Arduino micro small version of the Uno basically. Arduino is not the only microcontroller based IoT device though. Another popular choice is Spark. Spark is actually now called particle. Particle makes the very popular spark core device and as of this recording is about to release the photon and another model called the electron. Particle brings a couple of big wins to the world of microcontroller baseboards, namely compactness and connectivity. The sparks are a lot smaller than Arduino but still it still has sufficient specs. Additionally the core and the photon have Wi-Fi connectivity. You go through a little routine of telling these chips, what hotspot to connect to and they are suddenly internet-enabled. The up-and-coming electron even offers cellular connectivity for even more portability. With the electron you'll be able to create a device and assume that it's connected pretty much all the time. Spark also offers you the ability to write and deploy your code from their website and makes a number of things easier for the hobbyist that may not have a lot of experience.
-
Systems on a Chip
Next, we'll look at systems on a chip. A system-on-a-chip often referred to as simply SOC is dramatically more silicone than a microcontroller. The machine instruction set of an SOC, that is the list of very low level functions at the processors able to perform, is quite a bit bigger than that of a microcontroller. The processor and an SOC has a standard architecture with a standard set of machine instructions that major platform operating systems like Linux and windows have already targeted to run general computations. Systems on the chip generally have more memory and often they have an MMU or memory management unit. For mapping virtual memory locations to actual ones In `lighting up certain very powerful scenarios. Most system-on-a-chip devices also contain a microcontroller and a hardware bridges employed to allow the two to communicate, essentially allowing you to write high-level code to control out low-level functionality. That's what were after. We want to write something at a high level that has low-level effects. Now let me be clear that employing a system-on-a-chip device for your IoT project means accepting some more complexity microcontrollers are far easier and far simpler. If you need to communicate with hardware and that's pretty much it and your application is not a complicated one, you might just want use C or wiring code and use a microcontroller. The big advantage arising up to a system-on-a-chip device is that you get to run things like node. for microcontrollers Arduino has the Uno. By the way, you may have noticed that the I/O pins that is the black strips with the holes on the top this device, they are placed identically to the Arduino Uno, that's important and we'll talk about that soon. No conversation on IoT could be had without mentioning the extremely popular raspberry pie. This board selling like crazy and young and old alike are using it for all kinds of exciting projects. One of the big additions offered by the pie as folks like to call it for short, is the video port. It offers composite video as well as HDMI and that means that you get to hook it up to your monitor at a keyboard, mouse, and you've got yourself a full on computer. What's more, Microsoft announced that Windows 10 is going to work on the raspberry pie too. That means that we makers have a choice of two great operating systems for this device. Linux and windows. And we can choose the right tool for the job. Overall this is a really fun board. The Beaglebone Blacks is another one of these all-in-one systems like the pie. It also has a video port. It runs Debbie and Linux, it has a 1 GHz ARM processor HDMI and four gigs of built-in storage a little powerhouse here. The MinnowBoard MAX has a nice 1.33 GHz dual core Intel atom and two gigs of RAM in a more powerful available configuration. with boards like this one and Beaglebone and the pie you are not going to be hurting for process or power in almost any project you can think of. The not so much blown up microcontrollers as they are shrunk down desktop computers. The Tessel is a recent entry in the race relatively recent anyway, the Tessel is unique in that it runs Node.js, but it manages the running of node on the device so you don't have to mess around with the operating system, you can just deploy and run your program. Now the first generation device has four slots for add-on modules, but the new Tessel, the Tessel 2 builds a lot of functionality into the board itself, including Ethernet, Wi-Fi, and some USB ports. And if you're worried that the ease the tessel provides comes at the cost of power, stop worrying. Because it has a plenty beefy processor. and the makers promise root shell access to the actual OS on the device, should you need. Finally, the device I ended up choosing for this course is the Intel Edison. This is currently my chip of choice for a few reasons. It ranks right up there with the others in terms of specs and just look at the size of this thing. The device itself is the size of an SD card, the Edison's processor is a dual core 500 MHz adamant it's bridge to a single core 100 MHz microcontroller right there on the chip to give you what I was talking about that high-level software platform for low-level hardware control. Has a gig of memory and four gigs of storage. Furthermore, the Edison offers really excellent connectivity options with Wi-Fi and Bluetooth LE built right into the chip itself. Now working with a chip this small on its own would be quite a chore. So Intel created the Arduino Dev board for you. You dismount your Edison to the Dev board and the board's chipset provides hard buttons, a microSD card slot, USB headers, level shifting circuitry so you can work with an easier 3.3 V or 5 V instead of the Edison's native 1.8 V, and perhaps most importantly, it gives you pin headers that match the Arduino spec and are ready to take standard shields. And when you're finished with your development and you are you ready to install your Edison in some tiny IoT project without a single wire hanging off of it. You have modules created by Spark finest, sparkfun.com The guys at SparkFun were apparently excited enough about the Edison to design a good number of boards that stack up like an electronic sandwich. offering functionality with every layer, you can add all kinds of I/O access modules to it. There's a 9° of freedom chip that gives you three axis acceleration magnetometer and gyrometer, there is also a little board with a lipo battery for powering your gadget. So I hope you can see why I like this board and why I'm choosing it for this course for running Node.js apps and building fun IoT solutions. We are going to go in-depth on the Intel Edison and see how to get it all set up on your box, but first let's spend a bit more time exploring the differences between microcontrollers and systems on a chip and figure out exactly when to use which one. Choosing an SOC over micro controller gets you, among other things, Node.js. A node get you more than just JavaScript. JavaScript is a fun language to write in, but the real strength of standing up the Node platform is a massive number of modules in that awesome node community. When you run into a coding problem that you can't solve. You can but you can bet you are going to find someone on the Internet that can help, that's because a lot of people are writing Node.js. That's one of the nice things about writing with a popular language. Now in order to figure out which kind of brain microcontroller or SOC that you want to use. Let's have a look at three example IoT projects of increasing complexity and talk about what sort of device these projects might need. First let's take a basic sensor, a temperature sensor. This is going to be deployed on a job site and the date is going to be logged to an SD card where it's going to be checked every week by a field technician and analyzed for anomalies. This is certainly a simple device is just collecting the temperature, it needs to be connected to a temperature sensor then that's perhaps going to report its value as an analog voltage level. Low-level wiring code could be developed to wait a given interval, take a sample and record that sample to the card. You might imagine that whoever is using this device is likely interested in the temperature in a number of different locations. So this is so this entire devices is going to have to be deployed in an array. Now due to the simplicity of the requirements. and in the prohibitive cost of a higher order solution like an SOC device especially deployed in an array I'd recommend a simple and inexpensive microcontroller device for this. For this project, I'd probably start with an Arduino micro. Next, let's jump to the far right in this graphic and imagine that were tasked with implementing a robot, and what kind of brain might we need for this project. You can probably guess it's going to be rather complex. This robot may need to monitor an image from a camera and do certain digital image processing computations. It may need to respond to verbal cues, it certainly needs to read some sensor feedback and control an array of motors and actuators to move around. And these days it's not going to be a very interesting robot if you can't talk to a bunch of web services to get information. This projects is a prime candidate for system-on-a-chip solution in my opinion, With a platform like Node.js we'd be able to pull in modules to help with image processing, sensor reading, network stack messaging, using something like HTTP and web sockets and a whole bunch more. Any of the SOC boards that we talked about would probably do just fine for saw cutter but I'd likely choose either the raspberry pie If I wanted the advantage of a display that perhaps had a clean and modern windows 10 interface, or I'd go with the Intel Edison if I didn't need the display and I was instead looking for a compact solution. Now let's step back to the second of these three samples and pretend that we are going to create a terrarium. This is actually a project I've been wanting to do. This terrarium is going to allow a pet reptiles to live in the outmost style and comfort. It's furnished with a heating rock for temperature regulation. WebCam for remote viewing and actuated doors for releasing food at just the right time on schedule or on demand from a mobile website. How cool would it be to release crickets and watch them get gobbled up while you're flying on an airplane. So which way do we go with this one, microcontroller or system-on-a-chip. I can tell you that either one would certainly work. So this is where you have a choice to make now if you are like me, you'll still use a system-on-a-chip that allows you to write _____ code for controlling and coordinating system.
-
Sensors and Screens
In this course we are not going to spend a whole lot of time discussing the vast array of hardware components that you can connect to the brain to interact with people in the environment, but I'd like to spend just enough time to give you a taste of what's available and what you can do. First were going to talk about sensors and shields. Electronic components are discrete devices that somehow modify the behavior of an electronic system. Sensors are simply systems of electronic components that are designed to detect or measure information and interactions, convert them to an analog or digital electronic signal and make it available as an input to the IoT device. Now I can begin to show you even a good sampling of all the sensors available, so I've just chosen a few to talk about so you can get the general idea. Sensors are little nerve tips into the world that bring back information that you can use in the operation of whatever device your building. Sensors make it information or actions from people or their environment. Let's look at a few. This is a simple button. Fundamentally, a button is away for human to interact with the device right? Electronically, buttons causes the completion of a circuit. So if you design your circuit right, you can easily make it so that a press of the button delivers a five volt potential to a digital input pin. Whereas a release of the button drops the voltage to zero that value of 5 V or 0 V is then translated by your processor as a logical level a one or a zero, a true or false. Next we the temperature probe, now obviously a temperature sensor can be used to relay information to your device about its environment. The metal end can be placed in whatever location you want and the temperature will affect the resistance between the two wires at the other end. This is a passive sensor then where the resistance changes to interact with this sort of sensor you apply a voltage, Now remember the board that you're working with has power supplied to it and it can supply these passive sensors with power, so you apply a voltage to the sensor in a very simple circuit called the voltage divider and you plug it into an analog pin that allows you to pick up the analog range. Since the temperature is not a digital value might be 10°C or it might be 10.5°C, it's analog. The photocell detects the light level instead of the temperature level. That would provide a variable resistance just like the temperature sensor and like the temperature sensor you would use a voltage divider circuit to pick up that value and bring it to an analog pin to make it available to your program. Then suddenly, your program knows the level of light in the room. The line sensor introduces a little bit more complexity. This is actually a small circuit board as opposed to a simple component. It's a tiny printed circuit board with some resistors and an IC surface mounted, then it provides some holes with solder land so you can attach your pins to it. When you first grab a sensor like this you don't necessarily know how it works but it's very easy to take the model number Q-R-E-1-1-1-3. In this case, and do a web search for Q-R-E-1-1-1-3 datasheet. And you are bound to get an excellent PDF as one your first search results. This PDF is going to give you things like the physical package dimensions maximum ratings for voltage levels, electrical, and in this case, optical characteristics, performance curves and much more. You'll quickly learn to find the information that matters most to you and be able to parse data sheets all day long. Next we have a flex sensor. This is an interesting little sensor, it's also a passive sensor, so it's going to vary its resistance value but in this case it's going to vary its resistance value according to how much you bend it. You can imagine the uses for something like that. The ultrasonic Rangefinder is a fun little device cause it just looks like a pair of robot eyes. In fact, however, one of the two obvious cylinders is a sonic emitter and the other one's a collector this rather intelligent sensor sends out a sonic pulse little pulse of sound that you can't hear and then it picks it up and allows you to do some simple math to figure out how far away the nearest object is. This is great for some simple range findings scenarios. The CO2 sensor is pretty specific. Let's you know what sort of practical applications you could get into. The obvious application for this one is the detection of unwanted gas in a home so occupants can be safely alerted the MPL3115A2, altimeter and barometer is a very sensitive and rather complex device. It does a really excellent job of determining it's ambient air pressure and does all the necessary calculations to translate that into an actual altitude reading. It's so sensitive that it can determine differences in altitude as small as 1 foot. The components I've shown so far are what we would call sensors, they allow the board to detect things about its environment. But our device needs to be able to talk back to us, needs ways to relay information to us or to anybody else around it. It might do that visually, audibly hapticly or by some other means. Your basic LED your light-emitting diode is an extremely common site in IoT projects. LED's are very interesting little devices, they are actually diodes, what we call PN junction diodes. diodes are like a one-way valve for electricity, they let current flow one way but not the other. It's a cool little trick you can do with semiconductor junctions, in the case of an LED though, photons are emitted when electricity flows through it. Single light source LED's have two wires, notice that one's longer than the other so you know which way to push electricity through it. This is and LED with four leads, it's actually three LED's in one package a red, a green and blue. If you control the levels of the three component colors you can make just about any color in the rainbow. Lots of applications there, and if you want to create an array or a matrix of LED's. For some reason, you can imagine that you'd have a lot of wiring to do and it be difficult to control each light in the array individually, especially if they can all be an arbitrary color. Neil pixels by Adafruit make this type of thing very easy by allowing you to digitally address each of the lights in the array, you'll find them on small boards like this one, or in long strips or sheets and they are really handy and fun to play with. Your basic speakers is a good way to provide audible feedback for humans. You can play digital wave files or you can just beep and make sounds you can do whatever you want really. Haptic feedbacks often just the right thing and using a small vibration motor is a good way to get that done. Finally, there are quite a few different kinds of motors that you can use to make things move. What you see here is a servomotor gives you the ability to turn a small set increment. You could for instance mount a big red arm on a stepper motor and create a meter and then your device could then measure the temperature or some other analog value and Intel the arm to move exactly 5° to the right. Okay so were done with all the sensors and feedback components that were to look at but really soon I'll be pointing you to some electronics vendors and I encourage you to spend some good time browsing what's out there. Sometimes project ideas come from browsing components and seeing what's possible. For instance, I found a sensor that measures airborne particles to determine air quality. And I had the idea to couple that with an air purifier that only runs when the air quality is low enough. Next we going to talk about shields, now a shield might sound like a fancy term at first but it's really very simple. it's just a circuit board with some arrangement of components to create a circuit that does something, the important thing though is that the board has pins on the bottom that fit the design standardized by the Arduino Uno. Some of the pins are power pins. Some are digital pins and so on, and they're all in the same place every time. Furthermore, the shield should not only extend pins out the bottom to plug into the board, but it should also have headers on the top to receive pins from the next field. This means that a person should be able to stack a shield onto a board and then stack more shields on top of that. Any given shield may only use a couple of the pins but because all the pins are passed up the entire stack is accessible to the processor and your program. Here's an Arduino shield diagram, let's take a look at the various pins available in the shield standard. First pin zero and one are digital pins. We call these GP I/O pins or general purpose input output pins. When pins are digital, we're expecting to read values from them of either something close to 0 V or something close to 5 V or they give you the developer the chance to set them low 0 V or set them high 5 V. By using digital pins you can turn components on and off and you can implement logic. These first two digital pins are also a serial bus for sending and receiving serial data, but if you're using them as serial data then you're not able to use them as digital pins. That's okay though because pins 2-13 are also digital pins. That's a lot of pins and that's a good thing. Next you have digital ground, followed by an analog reference. There's a decent chance that you don't care about the a rough pin but in case you are working with analog input you may want to know that this pin can be used to customize the reference value for the high-end of the analog input voltage level. Next, you may see two pins labeled SDA and SCL These are not defined here in the standard, but you should know that a lot of modern boards will use this space for two pins that make up the I2C bus also called the I squared C bus. The I2C bus is very commonly used for some of the more complex components that we looked at For instance the altimeter on a chip that were talking about, Stretched to get hard to pull back complex data as analog voltage levels and so chip manufacturers use the I2C bus and they let you pull the data serially. It's not a super-fast bus like something like USB, but it's very simple and great for projects like this. on the other side of the board we've got six analog in pins pin zero through five. Now even though these pins are used for analog input. They can just as easily be configured like the other gpio pins as digital values. Next, you have your standard power pins in various voltage levels through the convenient to have multiple voltage levels since you'll find sensors and other components that ask you to provide them with 5 V and others that are looking for 3.3 Many boards vary just a little bit here regarding what power levels they provide so do double check so you don't smoke your components. An interesting note on the Intel Edison that were to be working with is that when you use the chip on its own or with a compact module from SparkFun, it actually uses 1.8 V projects so you have to be super careful not to melt your $50 board by overloading the I/O pins. By the way, if you're looking for the main reference for these pins. You can go to Arduino.cc/EN/reference/board. Here is a cool trick, if you look around a little bit. Not to worry because I'm the list out a few good vendors here in a little bit. You'll find something called a proto-shield. This is essentially an empty PCB printed circuit board that has the standard shield pin configuration and then just a bunch of through holes for soldering components. You can even find the same board with a tiny breadboard on top so you can just start poking component leads into the breadboard and wiring things up that way. It's extremely convenient. Hopefully I've whetted your appetite for components that you can use to build projects. If so, here are some folks that would be glad to sell you anything you need. I tend to use stuff from Sparkfun a lot, but Adafruit does some great stuff as well, especially around the concept of project ideas. Digi-Key, Mouser and Jameco have massive selections of the tiniest and most obscure components. RadioShack's great when they have a location near you and you just drop by instead of waiting for shipping, Amazon might be a good bet if you want to combine your order of transistors with say a load of baby diapers and some fresh tomatoes. And finally, you can give Ali Baba a try when you've proven your project and you're ready to order about 10,000 of them.
-
Communications
All right that does it for our tour of sensors and shields. Let's look next at how to get this fun little IoT device, talking to its neighbors by looking at communications hardware. These little devices aren't as much fun if they can't talk to other devices into the cloud. Networks have devices and cloud connected device scenarios that will make the projects really start to get interesting we've got a lot of options for communication, but they all have their pros and cons, so I want to equip you to decide which method is right for whatever it is that you're building. If you're working on a device that you already know is going to be sitting in your house or somewhere else where you might have a constant Ethernet connection. Then this is definitely a good way to go. You'll be all but assured of getting a high data rate and excellent reliability. Most devices in the IoT space that were moving around and they don't qualify for Ethernet connection so the rest of these communication methods that we are going to look at are wireless. All of these methods are going to use the RF spectrum for communicating RF stands for radiofrequency. Remember in high school physics when you learn that magnetic flux induces current in a wire and vice a versa that if you run current through a coil wire it becomes an electromagnet, that's what we're doing here. We want to transmit and receive RF signals so we build a device called a transceiver that's a transmitter and a receiver. It takes our data in the form of electricity and runs it through a coil of wire to create a magnetic signal that propagates through space, then a transceiver and another device picks that signal up and turns it back into a digital data signal. As possible to use sound and light as well, but I'm not going to cover these less common approaches. You've likely used Wi-Fi. The tried-and-true 802 to 11 method for communication. It's great for its high data rate and it's way popular so you'll find hotspots all over the world. And you can even use Wi-Fi directly between devices without relying on a hotspot. But it does use a lot of power on the device so you'll be better off if you have wall power or a big battery for your Wi-Fi solution. Bluetooth and Bluetooth LE are very good modern options Bluetooth classic not as much since it forces devices to go through a pairing ritual before they can chat. Bluetooth LE on the other hand is very exciting and has a very low data rate which is often perfectly acceptable IoT scenarios and especially considering the fact that this gives it very low power usage, I mean very low. A Bluetooth LE transceiver can run for years on a AA battery. One of the weaknesses of BLE as folks like to call it is its dependence on a star topology. This isn't always the best network topology for censoring device networks. BLE works great with phones and computers since most of them ship with BLE the only modules built right in. Xbee is a cool standard and RF communication like BLE it has a low data rate and low power consumption and it has the added advantage of implementing a full mesh network. This means that all XP transceivers propagate the message to every other transceiver covering as much area as possible. This is great for sensor networks and for applications such as home automation. nRF24 is an RF protocol that has a whole lot of positive attributes, but widespread awareness and adoption of it are not among them, at least not compared to the likes of Wi-Fi and BLE It has a lot of cool features like low-power modes, multiple channels, channel hopping, frequency calibration CRC for message fidelity and retransmit for reliability. cellular communication usually uses the common GSM format and has the huge advantage that there are already cell towers just about anywhere in the world, but there are enough people. You can find GSM shields for your device that instantly give it the ability to talk on the cellular network and we talked earlier about particles new electronic device that's planning to build that right into the tiny device as well as offers small inexpensive data plan. There are other ways too to get on the RF bands you can find a lot of proprietary RF communication out there your garage door openers, wireless keyboards and mice just about anything else that's wireless but neglects to implement one the standards that I've outlined. I've seen projects online where folks hacked into these wireless devices and started communicating over RF using these proprietary signals. and that does it for the device landscape and a little tour of some of the components sensors and shields that you might want to use in your project. Now let's narrow the scope down to a single device. The Intel Edison.
-
Setting Up the Intel Edison
Unboxing
Hi, welcome back, I'm Jeremy Foster. Thanks for watching this course on Node.js in the Internet of Things Using Intel Edison. This module is on setting up the Intel Edison. These are going to be specific instructions about setting up a specific device. But, the device we're working with, the Edison, is a Linux machine, so even though you'll certainly be working with a newer version of the Edison at some point, or working with another system all together, much of what you learn here should be of general value to you. If you want to see written instructions on this process of setting up the Intel Edison, you can also read my blog post at codefoster.com/edison-setup. We're going to start by unboxing the Edison and setting it up physically. This part's really easy. Then we'll flash the latest version from Intel, get it configured with a name, a password, and a Wi-Fi connection, and then we'll just look around and get oriented with the device and what we have to work with. Finally, we'll play a little bit with Node.js and see how to access the hardware with Java Script. That'll be exciting. Let's get started with the unboxing. The Edison is either sold alone, with an Arduino Dev board, or with a mini breakout board. The most popular, and my recommended way to get started is with the Arduino Dev board. With the Arduino Dev Kit, you get the Dev board, the Edison itself, some tiny nuts to hold the Edison on the board, and some standoffs to keep the sensitive underbelly of the device from touching stuff on your desk and shorting out a circuit. To assemble, you simply snap the Edison onto the board, applying pressure just above the 70 pin connector until you hear a dull snap. The holes on the Edison itself, line up with the posts and make it pretty obvious how it should be oriented. Then you screw the nuts onto the two posts to secure the chip. I've skipped this step and been sorry when I discovered my Edison had gotten loose inside its box and been bouncing around. Finally you drop the standoff screws down through the board from top to bottom and attach the plastic standoffs. To power your Edison, and to make the initial connection to your host system that you'll need in the next section, you'll use USB cables, two of them. The first one that's plugged into the inner of the two micro USB ports of the DEV board does two things, it provides power to your board and to the Edison itself, and it causes your Edison to show up on the computer as a disk drive so you can copy flash files to it. The second one, closer to the outside of the board has a single job, to provide a serial, or console connection to the device.
-
Flashing the Device
All right, now it's time to flash the device. Now, I'm going to show you the process for installing on Windows, because that's what I have and use, but the instructions for installing on Mac and Linux are pretty straightforward and readily available from Intel. It's just a few steps here that I'll show you, and then we'll walk through the whole thing in the upcoming demo. Hopefully by seeing the steps on slides, and then watching me do it later, it'll be clear for you. The first thing we need to do is install a couple of drivers. First we download and install the FTDI drivers. FTDI is the company that makes the chip on the Edison that allows you to connect to it by way of USB. So you need these drivers from the get go to get connected to your board. You find these drivers at ftdichip.com. Specifically at ftdichip.com/drivers/d2XX.htm now, as of this recording, the latest version of the driver that you should look for is called the 2.12.00 WHQL certified. Installation of this driver is pretty straightforward, and I don't expect that you'll run into any surprises. Next you need a driver pack from Intel. This pack includes drivers for RNDIS, CDC, and NDFU. Well, that's a mouthful. You might be wondering what all those things stand for. RNDIS is for Virtual Ethernet over USB. CDC is a standard for recognizing and communicating with devices. NDFU is functionality for updating firmware on devices. So, it's just a few utilities that we need to manage the device when it's connected to your computer. The latest version of these drivers can be found on Intel's software download page for the Edison, and you can find that by simply searching the internet for Intel Edison software downloads. When you get to that page, you'll see offers to download the integrated installer, the SDK, the Intel IOT Developer Kit, and the Intel Arduino IDE. But, the way that we're going to be developing on the Edison, you don't need any of that. So, just find, download, and install the Windows Standalone Driver, that version 1.2.1 as of this recording. You know what, while we're at it, let's just make sure you have one more thing installed on your computer. Bonjour is Apple's implementation of something called zero configuration, or MDNS. In our case here, it's going to allow us to reference our Edison by its name dot local. If you call your Edison George, then its host name will simply be George.local this means you don't have to hassle with discovering, remembering, and typing whatever IP address George gets assigned, and that's quite nice. The URL to get to the download page is complex, so just search for Bonjour print services for Windows, and you should land on a page that looks like this one. With the Edison plugged into your computer, and these drivers installed, you should see that a new lettered drive has appeared in Windows. This drive is not the Edison's primary file system. It's just a location that it's going to look in for flash files. So, let's copy the flash files over. To download the latest image, you need to go back to Intel software download page for the Edison. This is the exact URL, but to spare yourself, again, you can just find it by searching the internet for Intel Edison software downloads. Next, go to bit.ly/puttydownload and download and install either PuTTY or Plink, they're the same program, and they allow you to connect to something over a serial connection. PuTTY though has a UI, but Plink is the command line tool. I like to use Plink and stay on the command line, personally. Now the serial connection requires the USB cable that's towards the outside of the Arduino board that you likely already have plugged in. Once you've got a serial connection you commence to flash your device with a single command, reboot OTA. Don't worry about remembering that, we'll see it again in a little bit when we get into the demo. One of the advantages to having a serial connection to your device, is that you'll be able to see all the low level stuff the scrolls by the screen as the actual flash is occurring. What's actually being installed is the Yocto distribution of Linux. So, it's kind of a custom distribution of Linux that's made for tiny devices, embedded devices, things like that, and that's what Intel has chosen to be the default image for this device. Now, when the flash is done, you'll be taken to a login screen, and you can simply login as root with no password, and you'll be transported to the Linux prompt, there you are, full of possibilities. Now, you simply type configure underscore Edison space dash dash setup at the prompt and you'll be walked through a wizard to configure your device. We'll choose a name, a password, and a Wi-Fi hotspot.
-
Demo: Flashing the Device
Now, let's actually run through this entire driver install, flash, and configure process so you can see that even though it feels like a lot of steps, it's actually not too big of a deal. So, in this demo, we'll install all the drivers on our PC. We'll copy flash files over to the Edison. We'll run a single command that tells the Edison to reboot and flash with the files that we've copied. And then once the system is back up, we'll name it, give it a password, and hook it up to Wi-Fi. Let's go. So, like I mentioned, the first thing that we're going to need to do is install the FTDI drivers. And as I mentioned those drivers can be found at ftdichip.com/drivers/d2XX.htm here we are, and also as I mentioned, we're looking for the 2.12.00 WHQL certified drivers. We're just going to need to scroll down a little bit, and we'll find those drivers right here as a setup executable, click there. Run it. And the FTDI CDM drivers begin, we just extract those, choose next, accept, next, and that does it for the FTDI drivers. Next we need to find the Intel Edison software drivers. So, we're going to go to our favorite search engine and search for Intel Edison software downloads. You're going to find the downloads page as one of the first links here. This first one here does it for me. Now, like I mentioned, when you get here it's going to try to point you toward using the Windows 64 bit installer, and installing with the Intel XDK. I don't want to go that way. So, I'm just going to scroll down a little bit here and look for the Windows Standalone Driver. This is the only one I need, go ahead and run that driver. Choose next, I agree, next, install. (chiming) No problems there, click on finish. And the next thing we need to do is download the latest image for our Edison. You can see here that the latest image for the Yocto Image, that's the distribution of Linux that we're going to be running on the Edison, and actually, Yocto isn't the distribution itself. Yocto is more of a distribution generator. But, this is the Linux image that is made custom for the Intel Edison and release 2.1 is the latest version of that image, so we'll just go ahead and click on that. And for this one, this is not an installer. This is in fact a zip file. We'll just go ahead and save that. And once that's downloaded, we'll just go ahead and view this in the download folder. And we've got ourselves a zip file. Easy enough to unzip that. And the contents of this folder that I just unzipped are exactly what you need to copy to the Edison in order to flash the device. So, we have to get all of this to the Edison, let me just go ahead and scoot this window over to the left, and on the right I'll open another window. And in this window, what we really want is we want to get the drive letter for our Edison. Since we installed those drivers, this should be no problem. All we really need to do is make sure that we plug that serial USB. (chiming) You can hear that Windows is recognizing this. (chiming) And in a second, we're going to get another drive. (chiming) There it is. And this location, this is actually an old image, so we'll go ahead and delete this. This location is where we need to copy these files. So, we'll select everything. This is from what we've downloaded and unzipped. And we're going to copy it to, and in my case, the H drive. Your drive letter may very well be different. And this is that temporary place on the Edison itself that the Linux distribution knows to go and look for its flash files when we give it the flash command. I'll just speed that up with my video editing software. And there we go, all the files copied to the device. Now, you'll remember that there was one more download that we need to do, and this not on the Intel Edison software downloads page. We're going to jump back out to our search engine and search for Bonjour print services for Windows. Here you're going to find the latest version of Bonjour Print Services. And we won't run through the process now, but as you can see when you get there it's pretty easy to find that download button. Click and go through the next, next, finish process to get Bonjour Print Services installed on your machine. Now remember that the Bonjour Print Services is Apple's implementation of MDNS, or Zero Configuration and what this is going to be used for is to allow us to refer to our device by its name dot local. That's easier than having to discover and remember its IP address. Okay, so we've got this image, and we've got it copied over to our Edison. Now, the next thing we need to so is download over PuTTY or its sister project Plink. And we can do that by simply jumping to the browser and going to bit.ly/puttydownload. And you can see here that there is a download for PuTTY itself and there is also a download for Plink. And as I mentioned, PuTTY is a graphical user interface, Plink is something that you use from the command line. I think the graphical user interface will be pretty self-explanatory. I'm going to go ahead and show you the command line. That's what I know. I've already got this downloaded and installed. That process is extremely simple. So, I'll go ahead and close this. Jump out to my command prompt. And I'm going to type the command plink with an option for serial, saying that the serial port is com5, now if you don't know your serial port, an easy way to do that in Windows 8 and above is to hit Windows X, and the M for your device manager, which pops up, and then you can go down to your ports and look at the one that says USB serial port. You'd think that you'd look at one of these ones that say Intel Edison, those are the other USB header on the board. The one that simply says USB serial port, in this case is Com5 is the number that we're looking for. So, I say serial com5. I then need another option for the serial config, in this case it's expecting us to talk at 114200,8,1 N,N. That's the serial configuration that we're supposed to use. Now, something interesting about PuTTY or this board is that immediately when you connect you don't have any console output. And so I've seen people land here and say, I'm stuck, nothing's happening. You simply hit the enter key. You actually are there and you're ready to login to the Edison. You're going to have, kind of a default name here of Edison. That's the name of the board. Your user name is root. And the password in this case is empty. There's no password to start with, so you just hit enter there, or it'll just blaze right by and you should see root at Edison that's the main prompt you are now at the command prompt in Linux full of possibilities. It's kind of exciting to be here. Now we're here, we're at the image basically that shipped with the board, and we want to do something about that real quick. We've already downloaded this image, copied it to, in my case the H drive, and the Edison is ready to look at that and use it for flashing itself. And all it takes to kick that off is to type one command. And that command is reboot OTA. Now at this point, you're going to see a lot of stuff go by the screen. This is an entire procedure for (chiming) flashing the device. You can hear Windows recognition of the device fall out and come back in. The device is actually going to reboot a couple of times. It's going to flash itself. And you should end up right back at the prompt after just a few minutes. It is nice, by the way, that we still have this console connection, or serial connection to the board because no matter what the state of the processor, of the operating system, we'll be able to see it, even when it's going through its bootstrapping mechanism, the BIOS, We're going to be able to see all that stuff blaze by the screen here, so we'll get full disclosure. I'll go ahead and speed this up. And there we are, finished with the OTA and we're ready to login again. Now, you'll notice that the name of the device is still Edison. Where it says Edison login that's the name of the device. Our username is still root, and we don't have a password after that, and here we are back at the prompt again. Now, the first thing that you want to do is you want to set this up, or configure it for yourself. And the way to do that is to simply type configure Edison space dash dash setup. And what this does is it runs through the process of picking a new password. Having a password is important because if you don't have a password you're not going to be able to connect by way of Wi-Fi. I like to choose something simple, so I'll choose mine. You can choose whatever you want. All right, here we are, now it's asking us to give this Edison a unique device name. I'll just go ahead and call mine My Edison. It needs to be at least five characters. Now, remember, this is going to be the name of the device. It's also going to be the MDMS name with dot local that we use, so I'm going to go ahead and choose My Edison, is that correct? Yes, and you notice I'm getting these funny characters on my command line. You can ignore those. That's just something Plink is giving me in this console. Do you want to set up the Wi-Fi? I do. So, we're going to go ahead and answer yes to setting up the Wi-Fi. At this point it's looking for all the Wi-Fi hotspots around me, mine is actually my last name there. Is that correct, yes, and what's the password? All right, should have the information it needs to connect to my Wi-Fi. Now, my laptop that I'm using as my host PC is connected to the same exact Wi-Fi, and that's important, I now have an Edison device and a laptop that are both connected to the same device. At this point, this device is connected and there's a command called WPA underscore CLI space Status that you can run that will ask the Edison to tell you what's its current wireless network connection status. And you can see that I'm currently connected to the SSID of Foster, I do have an IP address it's 19268019, and so we're ready to connect. Right now we're still on serial, but it'll be really nice to shake this serial connection. So, I'm just going to go in and reach down to my Edison, and unplug the USB that's plugged into the outer of the two micro USBs on the board. Now, that's gone and I'm no longer able to use this terminal, because this was relying on that serial connection, so I'm back at my prompt. Now, I do remember that 192968.0.19 and I could ping that. I typed that wrong, let's go ahead and try again. There we go, and I do get a reply so it is responding to me, that's great. Let's go ahead and also ping myedison.local and that should resolve to the same IP address. In this case, it's resolving to the IP6 address. I would be able to do a dash four and that will give me the IPV4 address, and in this case it looks like it's timing out on that. I'm not sure exactly why, but we do know that we are able to access it, so that's fine. Now, at this point we are able to connect to that device and that's exactly where we want to be. We want to be able to ping it. We want to be able to SSH to it. We want to be able to copy files to it. And that's where we are.
-
Demo: Orientation
Okay, we're in good shape with our system up and running, named, and talking over Wi-Fi. Now let's ditch the serial connection and get a remote session to the board over Wi-Fi alone. Then we'll spend just a minute, looking around and getting comfortable with what's there. I'm calling this our orientation. In this demo we'll unplug the serial USB cable from the Edison, connect to the device using SSH using its MDNS network name that we set up. And then we'll take a brief look at the directory structure and just kind of get oriented to the machine. And practice copying files to the device using SCP. Should be a pretty quick one. Here we go. We'll jump back out to the console. And the first thing that we want to do is ping the MDNS name of our device and make sure that we're able to see that on the network. Remember we have to be connected to the same network as that device is. We are getting an IP four reply now, so that's good. We can SSH to the name of our device, of course using root as the user name. Here we are, we'll use my password. I like to choose one that's easy to type, and we are sitting at a Linux prompt. Now, at this prompt the root is obviously my user name, MyEdison is the name of the device, and the tilde is my home directory. I'm going to go ahead and go back up to the root directory, and you can see I'm at the root directory now. And now if I list my files and folders, you can see that there's a bunch of stuff on this device. Now, if you're not familiar with Linux and how Linux works, join the crowd. But there are actually some really good Linux orientation courses in the Pluralsight library. So, I'd strongly encourage you to go and look up some of those. I'm going to jump into the home directory, and list that out, and then jump into root, and you can see that we're back in home. So, home is actually an alias for home and root. And that's where we want to keep all of our files that we're going, all of our projects that we're going to be creating. So, let's go ahead and get a document to land right here. Just get any file to land right here. So, I'm going to jump back to my host by hitting control D. That'll get me out of SSH and back to my host on my local machine. Now, I just want to create a simple file that says, hello world, and we'll put that into a file called a.text, there we go. So now I've got a.text and if I type that out, I've got hello word. Let's go ahead and copy this to the device using root the user name, we'll say MyEdison.local. Now remember, that I can use this MDNS name anywhere and everywhere that I would otherwise have to specify the IP address. And this is where it's really nice because you can set up your device and you can use it with that name, and if your device gets reprovisioned and gets a different IP address, it really doesn't matter. As long as you give it that same name, all your scripts are going to work just fine. Now, with SSH, this is all we had to put. With SCP, we want to use a colon and then specify where were want this to go. And I've forgotten one thing. I'm going to run back here and specify a.text. That's the name of my file. I want this to just go right into my home directory, so let's go ahead and hit that. It should prompt me for my password. I'll type in my very easy to remember password, and it looks like that file has copied up. So, let's go ahead and SSH. I'll recall that from my history here, jump back on to the machine. There we go, list it out, and you can see that in my home directory I now a.txt file. So, that's kind of the Linux way of getting a file from here to there, and that's how we're going to copy all of our files to the machine.
-
Demo: Running Node.js on the Device
Well, consider yourself oriented. Let's do one more demo, and this time we're going to look at what it takes to write a little bit of code on our device. In this demo, we're going to jump into Node.js on the Edison and just see that it works from the device. We're going to write a little bit of Node.js code from the REPL and then a simple Hello World app. And finally just for kicks, we'll write a little web server and then go issue a request against that from our host machine. So, let's go. I'm going to open two command prompts here and show you a format that I like to work in with my local file system on the left and my remote file system on the right. That makes a lot of sense to me. So, I'm going to jump out to where I've already SSHed to my device, and I'm just going to show you that Node is working by typing node, and seeing that that takes us to the REPL, the read execute print loop system in Node. This is assurance alone that Node is working, but let's go ahead and write a quick line of code here. See that X actually has a value, and it's working as if it's real Java script, because in fact it is. I'll hit control C a couple times, to jump out of that REPL, now let's go ahead and write ourselves hello world Node application. I'll make a directory called, hello world to hold this, CD into that. No files in there right now. I'm going to go ahead and VI, app.js. It says, "Can't ready user input," and drops out of VI. Now, I wanted to take you this route just to show you the work around for this. I am not aware of the reason for this issue, but I've run into it, others on the web have as well, and I haven't seen a good resolution. So the way to do this is to actually jump out of your session, your SSH session and you can see that I was connected to 192168036 and remember I was SSHed to that by typing in root at and then the MDNS name of that device. When you use that MDNS name in some circumstances for some reason VI does not work. And the only thing you have to do is make sure you use the IP address in that case. Not too big of an inconvenience, a little bit annoying, but I guess that's just the way it is. So, we'll go ahead and go back into the hello world folder. We'll VI app js to create that. And in here we're going to do a simple hello world application. If I did a console log, and said, hello world, that would be enough. But let's get just a little bit fancy and let's actually put that into a function. So, we have a little bit more code here to prove that things are working. And I'm going to call my console log, and then I'm going to do a set time out. A typical Java script pattern. And this set time out I'm going to call myself, and I'm going to wait one second. Close my function and that should do it. So, let's go ahead and escape from VI and run Node app js. And then we have, hello world, being printed to the screen every second. No surprises or problems there. Now let's go ahead and move on to the third step which is to write a hello web server application. And we'll back up a folder here, and make a directory called hellowebserver, CD into that. And once again we'll VI app js. This time we're going to use the http module that's built into Node, so this does not have to be installed and be unpackaged because it's built into Node. And we can, with that http, create a server that is expecting a function, and the function is expecting a signature of a request and a response. Let's do a response right head. We want to write out at 200, and this is going to be a header value, which is a content type of text plain. That'll do it for that header. Close that down. We want to do a response write hello world. And finally a response end. That does it for our create server function. We'll close that function. Close our create server method call. And now we need to, with the server that's been created, we need to tell it that we want to listen on port 3000, that's a common one to listen at. That's really all the code that's required to create a web server and this is being created on the device, if in fact we execute this code from the device, so, let's go ahead and jump out of there. Now, with that running, we'll actually open our browser on our local machine here. This is on the host machine, obviously not running on the device itself, and so I can go to I can use its MDNS name there, and go to port 3000, and I should get a value of hello world. And in fact I have. Now, I'm hoping that this opens up your minds to all kinds of possibilities. The fact that it's so easy to just create a web server on our device and hit that web service from any other device, be it a phone or a PC or another IOT device, it's on the same network. You can use whatever client frameworks you want to make whatever interfaces you want. And this is really just the device telling you about who it is and what it's capable of doing, or whatever scenarios, whatever use cases that you want to light up in there. So, that's pretty exciting. Okay, now you understand where we're at with The Internet of Things. You have a solid understanding of the devices that are available to you for IOT projects, and you can completely set up an Intel Edison from scratch, and even write some basic software for it. Next, let's look more in depth at writing software. In the next module, we're going to start playing with Node.js and writing IOT apps.
-
Writing and Deploying JavaScript
JavaScript Editors
Hi, welcome back, I'm Jeremy Foster. Thanks for watching this course on Node.js and the Internet of Things using Intel Edison. This module is on writing and deploying JavaScript to your device. We're going to talk less now about hardware, and more about the software that you're going to write and deploy on your device to make it do what you want. Remember that although we chose a specific device, Intel Edison, for this course, most of what you learn about writing Node.js, and even about the modules, will apply to any system on a chip device that can run Node. This is pretty rich for a module, as you can see here, by the eight different sections. First, I'm going to mention the various JavaScript editors that you might choose to use to write your code. I'm going to cover the basics of the code writing itself, and the basics of sending the code to the device, so we can actually run it. Then I'll demo all of that, and then we're going to look at how Visual Studio makes writing code, and debugging, a whole lot better. Finally, I'll do my best to make your life even easier by giving you some guidance on automating the deployment of your code, as well. We'd better get started by looking at text editors for writing our JavaScript. I hardly need to discuss editors, I think, except to assure you that what we're dealing with here is plain old JavaScript files, so you can use your text editor of choice. I don't really stick to a single editor, but I have a little suite of preferences, depending on what I'm doing. If I'm remotely connected to a device, and I want to just tweak something, or even throw together a simple project, I'll use Nano or VI. If I'm developing on my host PC, I'll use Visual Studio, or Visual Studio Code, depending on the environment.
-
Basic Coding
Next, let's have a look at writing the most basic code possible for communicating with our device I/O. Remember, we're dealing with the Edison here. This is a system on a chip that allows us to write high level code, so our goal is to learn what's going on under the covers, but then work our way up the stack, until we can get out of the minutiae, and write in JavaScript. So let's start at the bottom. Now remember that SoC IoT devices are a main processor, bridged to a microcontroller. Now as far as the code you write, that should all be abstracted away from you. In fact, there's a library on pretty much every IoT device I've encountered that does exactly that. It's usually written in low level C, and it either gives you a C library that you can call as an API to the microcontroller, or it gives you mappings in a higher level language, like JavaScript or Python, or hopefully, it does both. That way, you have the choice to go low level, and write C, or go high level. Now in the Edison, that library is called libmraa. This library attempts to extract away not only the complexities of the microcontroller on a single board, but on multiple boards. It supports Intel Zone, Edison, and Galileo boards, as well as the popular Raspberry Pi, and some others. This means that you could write a program against the MRAA API, and move your code easily from one device to the other, with virtually zero code changes. Let's take a look at a quick example of the MRAA library in use. This will hopefully help you to understand what's always going on under the covers. Then we'll quickly put C behind us, and we'll use strictly JavaScript. Now this snippet of eight lines of C code uses the MRAA library to simply read a pin value, and print it to the screen every second. It'd be hard for me to get the whole C program on one screen for you, but this snippet would also require your basic include at the top, as well as a main loop, let's break it down. First, we initialize pin six, this is the actual pin that you see on the Edison's Arduino dev board, labeled with a 6. Next, we set that pin to be an input pin. Remember, these pins can each either be used for input or output, but we have to specify which, or at least, we do when we're at this level. Next, we use an infinite loop, and the fprintf statement to read the pin's value, and print it to the screen. The sleep(1) indicates that this will happen every second. Finally, we close our access to that pin when we're done reading from it. Now, I do realize that this line is not going to be executed, since we'll be stuck in the infinite loop the whole time. But I wanted to leave it there, from Intel's example, so you can see that it is necessary to manage your pin access by closing it out when you're done with it. Well, that was fun. Now the best way to get your hands on the libmraa library is by going to GitHub, to the intel-iot-devkit/mraa repository. Perhaps like me, though, you don't find much reason to dive down to the C level to get your work done. It's a bit geeky, and fun to do so, but I spend most of my days in more abstract code. So let's go ahead and climb back up the stack. Now conveniently, the MRAA library contains not only the C++ code, but bindings to JavaScript and Python, as well. It's actually all right there in the same GitHub repository. So now, let's take a look at the JavaScript API with a really simple example. Now at first glance, looking at this code, you may notice that this is not much shorter than the C example that we were just looking at. That won't normally be the case, except in painfully simple scenarios, like this one. Additionally, this is not just a snippet of JavaScript. This is the entire Node.js file, necessary to do exactly what we did a minute ago, using C. Read pin six, and print the output to the screen every second. First, we import the mraa module using require. Now, if you're brand new to Node.js, you'll actually get pretty far just knowing this one concept. When you need a third party module, you require it. Usually, when you require a module, you also have to install it using npm, but MRAA is already installed globally on the Edison, so you can get by with just this require statement. Next, we instantiate pin six using MRAA's Gpio function. Next, we set the direction for pin six. Note that at this level, using the MRAA library directly even through JavaScript, we're still having to set the pin direction. Now that might feel might like busywork to you, like it does to me, and thankfully, that chore's going to go away later when we start using a good library, you'll see. Finally, we read the pin, write the value to the console, and set that to have happen every second, using the common setTimeout JavaScript function. Note that we didn't have to close access to the pin now. Now keep in mind that, later in this course, we're going to introduce some libraries that will make even the hoops that we jump through here unnecessary. I hope you feel, though, like you understand what it is that happens, exactly, at the lowest level. But I hope that you also feel encouraged by the fact that you aren't going to have to go through all that ceremony every time. All right, so now that we've written some basic code, let's take a look at actually getting that code out to the device, so we can see it work.
-
Manual Deployment
It's time to take a look at deployment, getting your code from your host computer out to your device. Sure, you can remote to your device using an SSH session, you can edit your code there, and then set it spinning. But it's better, in a lot of ways, to develop locally, that is, develop on your host computer, so you can run a robust, full featured editor, and then just copy the files out to your device when you're ready to run them. The way to get code from your computer to the device is by using the Linux scp, or Secure Copy command. Now normally, you don't have scp on Windows, but there are a few ways to get it. The easiest that I've found is to just install Git on your machine, and then add the bin folder to your system path. The bin folder should be at C:\Program Files, in parentheses, (X86)\Git\bin. The code that you're looking at copies a single file, app.js, to a device called mydevice, using the root user, and it puts it in the helloworld folder in our home directory. We can also multiple files at once. To do that, we simply specify the complete space delimited list of files, as the first argument to the scp command. Here we're copying the app.js file, as well as the package.json file. This is a very common deployment for a Node.js app, by the way. The app.js file holds the program code, and the package.json files describes the dependencies. Notice that we're not copying all the dependencies, just the description of the dependencies. We can just restore the dependencies from the device itself, using its own internet connection.
-
Demo: Writing and Deploying Code
Now let's try to tie this all together by looking at a demo of text editors, writing code, and deploying our code. In this demo, we're going to use SSH to remote to the device, then we'll write a little bit of code to control a real life IoT device directly. Then we'll write the code locally, and deploy it to the device. In the process of doing all this, you'll see a couple of different text editors in action. Let's get started. First thing we wanted to do was SSH to our device, so we'll type ssh root at, my device happens to be called tweetmonkey, use the mDNS .local, and that jumps us into the device. You'll notice that I am using a key to avoid having to type in a password. I've landed at my home directory, and the first thing I want to do is jump right back into our Node REPL, and in that Node REPL, you saw that we were able to do typical JavaScripty things, like that. And in addition to that, I do want you to know that you have the ability to require, that's a Node concept, you have the ability to require the mraa library from right here. And if I do that from right here on the REPL, we'll actually see the returned object, the object that comes back from that module requirement. That's it, you don't really need to know what all of that means, but it is assuring to see that happen, and know that we have good access to the MRAA library. Let's go ahead and actually bring that MRAA library into a local variable, because we're going to use it. And the first thing we'll do is, we'll create a pin, a variable, a JavaScript variable for pin 13, something that we'll call pin13. Now in case you're not aware, most IoT devices, most boards, give you an LED on the device to represent pin 13, the pin itself actually still works as a digital output pin, going high and low, but it also gives you that visual representation, which is extremely handy for being able to tell whether or not things are even working. And it's always very satisfying, just to see a blinking LED, and knowing that you're doing everything right. So let's create ourselves a local variable, calling it pin13, because that's intuitive. And we will instantiate a new mraa.Gpio. This is just the way the API works. You do that by calling your mraa object, the Gpio method, passing in the pin number, and there you have pin13 is actually defined. It's not much of an object yet, but that's okay. Now we need to set the pin direction by calling the dir method, and passing in a mraa constant, which is DIR_OUT. This is telling it that this is, we're going to use pin 13 as an output pin, even though it can go, technically, it can go both directions. So the direction has been set, and now we have the ability to say pin13.write(1). And I just saw the LED come on on this board. Then, I can pin13.write(0), and I just saw that LED go off. So I am directly controlling that LED. Now this is not the way that you want to write code, jumping into the Node REPL manually. It takes a human being to do that, and writing directly to the mraa library. So we're going to start to make this easier. Let's jump out of the Node REPL. Here we are, back to our home directory. And let's do a little bit of dev on the device. I'll go ahead and make a directory called iot, switch into it, it's obviously empty for now. Let's go ahead and touch a file called app.js, so that exists now, and let's vi that file. Here, we're met once again with that issue that I showed you the workaround for, where vi says that it cannot read user input, and the only way around this is for us to jump out of our connection altogether, and instead of SSHing to the mDNS name, we have to SSH to the IP address. I don't happen to remember that, so we'll ping it. There we go. Comes back pretty quickly for us. And here we are, back in, into the iot folder, vi app.js, and it's working. Now what we want to write in here is, basically, the same code that we put into the Node REPL, just a second ago. We want to, we want to var mraa equals require mraa. And we want to var pin13 equals a new mraa.Gpio 13. pin23's direction should be set to mraa.DIR_OUT. And then, I can pin13.write high, and just for visual effect, let's say we want to do a setTimeout, writing a function, in which we say pin13.write zero, and we want that to occur after, oh, two seconds. There we go, that should work. So now we have an app.js that looks like this. And we want to run that, we simply node app.js. And I saw the light come on, and two seconds later, I saw the light go off, so in fact, that's working, doing development on the board. But now let's do a little bit of local development. So we'll jump off of the device, and now here we are, back at my console. On my console, I'll go ahead and create a directory called iot-local. That directory exists now, and I'm going to use Visual Studio Code, which at the command line, is just code, iot-local. Now the nice thing about Code is that if I code some file, it will launch that file in Code. But if I say Code, and I specify a directory, I can specify this directory by just doing a dot, or in this case, I'm going to say a local directory, this iot-local directory here. And what that's going to do for me is, it's going to open Visual Studio Code with that as the, basically as the project folder for this project. So there is recognition of a project folder within Code, even though, primarily, it's just working with files. Now if I come over here to the left, you see that it's got this concept of the folder there. And it gives me the opportunity to create a new file. So this is a very nice working environment. Back to app.js, so let's go ahead and write this. Now you've seen me write this a few times before, so I will not make you watch me type again. But all we're doing is bring in mraa library, creating a pin, pin13, setting its direction. Now I'm going to do things just a little bit different. I'm going to create a local variable called state, and set that to false, to start with. And then I'm going to create a function that will toggle this state, and the LED, as well. So this function is going to first take this state, and set it equal to not state. Then it's going to say, to pin13, that you should write the value of state. And finally, we should call, recursively, by setting timeout, and calling toggle. And we'll say, 500 milliseconds later, so this light's going to blink rather fast, rather quickly, it's going to blink every, every, it's going to come on in a half a second, and then off in half a second. So it'll blink at about once per second. Okay, so let's go ahead and save that. Now if we go look at that on the local directory structure, and what I've done is, I've set my directory structure up side by side here, so that on the right, let me just clear these, so they make good sense to you, on the right, we've got the remote machine, the device. And on the left, we've got my local machine. Now inside this iot-local folder, I have the app file, and it's off the screen, you can't see that. But let's go ahead and, and cat out app.js, and you can see that that's the project that we just wrote. Now on this machine, let's go ahead and, I've already created a file called iot-local, but actually, to make this authentic, I'm going to go ahead and wipe that out. So I'll make a directory called iot-local, this is where we want this to deploy. Sometimes this deployment process is quite manual, and you have to get to the device, and create a folder to even copy it in there. Unless, you devise a way to remotely create a folder, copy the files into it, and then even, maybe, do something more advanced, like execute node and start that process going. So now I've got this iot-local folder, and we can cd into that. There's nothing in it right now, as you can see, absolutely nothing in that folder. But from local, we can scp, copying app.js, as root, to our device, tweetmonkey.local, colon, we want it to go to the home directory, and inside of iot-local, let's make that so. It's not going to prompt me for a password, because I'm already set up, and now if I go to my remote device, you can see that app.js exists. And that file is everything we want it to be. Let's go ahead and node app.js, and it didn't work. Because there's one thing that I forgot, I created this wonderful function, and never called it. I need to kick it off, I need to kick it off with a function call. So I'll switch back to local, this will kind of demonstrate this production cycle that we have to go through, this development cycle, rather, where we need to modify things, and then, and then we need to deploy them. So I'll change that, save it, flip over to my local directory structure, I can usually recall these commands, so there's that one. It's going to copy right over top of it. And then I'll flip over to the remote window, and once again, try node app.js. And this time, I'm getting myself an error, and that error is a typical one. I have a variable, a JavaScript variable called state that is a Boolean value, because I initialized it with false, I kept flipping it to its inverse logical value. And yet, pin13.write has looked for a one or a zero. Well, that's an obvious fix. When I do my write, I can say, state, and if that's true, by this is using an immediate if function, if that's true, then one, and if it's false, then zero. Well, that fixes it. Once again, we'll go recall this. And this becomes kind of a typical cycle, where you change something, and then you flip over and you execute it, and finally have it working. And now I'm looking at my board, and the LED light is flashing, every 500 milliseconds, the state is toggling. So that does it for this demonstration on writing and deploying code the manual way.
-
Coding in Visual Studio
Now, we're going to look at using Visual Studio as your main editor for IoT projects using Node.js. There are some features in a rich IDE like Visual Studio that are particularly awesome in this scenario. Let's have a look. As I mentioned, sometimes I just want to edit a text file, and I might use a variety of tools for that, depending on the scenario. If I want to manage a project, I'll use Visual Studio for a number of reasons. I can keep multiple related projects in a single solution, which is a real convenience. I get really good Intellisense. The Intellisense in Visual Studio's not just parsing the code files, it's actually evaluating them, and discovering all the symbols, so it knows things, like which variables are in scope currently. If you're a GUI person, you get a nice graphical way of doing most of the stuff that you can do from the command line. I'm not so much a GUI person, but you may be. There's good GUI, too, for Visual Studio's Git support, which makes collaborating on projects something that you can do with a mouse. And finally, I like that, despite the fact that Visual Studio is far richer than the other editors, it's also still free. You can get the free Community Edition of Visual Studio at visualstudio.com. Now all those advantages I just mentioned are just Visual Studio itself. If you're working on Node.js projects, then the Node.js tools for Visual Studio are amazing and indispensable, I love them. With them, you get local and remote debugging, and by the way, it's pretty cool to be pressing F10 to step through your code while watching your IoT device on your desk take one step for each click. You also get good Node.js project support, and that support includes io.js, ES6, and TypeScript, awesome. You get a graphical user interface for npm in your project. That means that it's going to act a lot like NuGet in Visual Studio, if you're used to that. You get an interactive window, much like the Node REPL, at the command line, you get performance profiling, which is really huge, so you can see what part of your project is taking up all the time, and causing it to perform slowly. You get the ability to easily deploy back end projects to Azure, and you get a good test explorer for running tests. You can go to microsoft/nodejstools on GitHub to download the Node.js Tools for Visual Studio. You can even contribute to the project, if you'd like. While I was developing this course, Microsoft announced Visual Studio Code. Code is a brand new editor that works as well on Mac and Linux as it does on Windows. It's a significant departure from the Visual Studio editor that we know and use today. And so far, I think it's going to be complementary for me, I think I'm going to like it. What's exciting about Code is the fact that it's light, and lean, it starts for me in just over two seconds. I've already set it as my default editor for all types of code files, even Markdown files. It's in preview at this point, but it works really well. I've worked in a bit of Visual Studio Code into the demo coming up next, so hold on tight, to see what it looks like.
-
Demo: Coding in Visual Studio
In this next demo, I'm going to show you the power that Visual Studio, and the Visual Studio family of editors, brings to the Node.js world. First, I'll run through the installation of Visual Studio Community, and the plugin that enables strong Node.js support. It's called the Node.js Tools for Visual Studio. We'll do a little tour of the functionality that this tooling offers you, and how it makes working on Node.js projects more awesome. Then we're going to look at the installation and basic use of Visual Studio Code, so here we go. I'm going to go ahead and open Visual Studio Community Edition's website for you, and that is at visualstudio.com. And you see some basic selections here. Over on the right, there's a new option, Visual Studio Code, but on the left, you see that we've got Download Visual Studio Community. Visual Studio Community has some terms of service whereby, if you're not an enterprise using it for enterprise purposes, you're an enthusiast, a student, a small team, whatever, you can read the terms of service, you get to download it for free, so. You just go ahead and click on Download here, it's a really easy installation, should be basic. There are a lot of options in the install for the basic kind of development that you want to do, but do know that this is, this Community Edition is somewhat on par with the Professional Edition, if you're familiar with that from the past. And it offers you the ability to do lots of different languages, lots of different technologies, and stuff inside of Visual Studio, so it's very powerful. So go ahead and download that, and install it. You do have the option of installing the 2015 Edition, which is the latest, and is in RC as of this recording. Or, the last version, which is 2013. Now if you install the 2015, because it's in RC, you're actually getting the ultimate edition of that. That's what they release whenever they're still in RC, so. Go ahead and download and install Visual Studio. The next thing that you're going to need is from GitHub, and it's under Microsoft's, the repositories, and it's the repository called Node.js Tools. And if you go there, and scroll down just a little bit, you'll see the releases, and if you're using Visual Studio 2015 RC, then you want to go ahead and get the NTVS, that's the Node Tools for Visual Studio, 1.1 beta, so it is ready for 2015 RC. I'm using it, and it appears stable. If you're using 2013, I would maybe suggest still going ahead and getting the 1.1 beta, since it's quite stable, but the stable version is 1.0, does not work on 2015, so. This would be something where you click on that, and then go ahead and download that, and install it. And now let's have a little bit of a tour of what exactly that is going to give you. So I'll open Visual Studio for you. Now Visual Studio is an extremely robust development suite. I'm going to assume that you've got some familiarity with it, you may or may not. But we won't be able to cover too much of it. But I just want to show you the Node functionality in it. I'm going to go to File, New, Project. And because I installed the Node Tools for Visual Studio, I have this option in here, under JavaScript, under Node.js, to automatically create a number of different projects based on Node.js, you can see that I can do everything from an Azure cloud service, to a basic console application, to an Express application, using Express 3 or 4. And I can either just get an empty Express application, one that looks something like this, to an Express application that's a starter app, so you actually get a full website. And you can start from there, and make your website look the way you want. We're just going to start with a console application here. And I'll put it in my junk directory, and launch that. And there are a lot of other things that the Node Tools for Visual Studio gives you. One of those is the ability to get some Intellisense help in here. I'm going to go ahead and bring in the file system, this is a core module to Node, and it's just called fs. Now notice that when I start typing this, I get Intellisense even right here into fs. And it's describing this for me, saying, "File I/O is provided by simple wrappers," and so on, and so forth. So that's giving me a lot of help into the, into the bringing in of modules, so, super helpful there. And besides that, when I start to use the module fs, I hit dot, and it's going to enumerate all those methods inside, that's just absolutely tremendous. The camel casing is supported, so if I type af, I get the appendFile, and appendFileAsync, because of the camel casing. I also get valueOf, for some reason, I'm not sure. But I'm going to do appendFile, and then when I open the parentheses, I get parameter support into here, so. That's obviously very robust, and dynamic, such that if I write my own function, adding together three variables, let's just go ahead and complete this, a, and b, and c. There we go, I've got a nice little function there. And if I call sum, it's going to give me this ability into what those functions are. And if they have proper triple slash commenting built in, then it's going to give you the robust parameter options, and descriptions, as well, so. Very handy stuff here in the Node tools for Visual Studio. Besides the stuff that I just mentioned, you get all of the other stuff that Visual Studio gives you, things like the ability to search quite easily throughout the project, or throughout your entire solution. In fact, one of the other advantages is the fact that this project, can itself, live inside of a solution with other related projects. Often times you don't get that in a less robust IDE. You also get a test explorer, so all your tests, whether they're running on Jasmine, or Mocha, or whatever, can be run inside the test explorer, inside of Visual Studio. You have full deployment support for Azure, so it's very easy to just right-click, publish your project, and deploy that to Azure. And in one of my favorite features, you get remote debugging, so you get the ability to go into the debugger, attach to process, and in this attachment process, you can say, I'm interested in Node.js remote debugging. And then in here, you can just put the TCP address of that endpoint on your machine, on your Node process, whether that's local or remote, and attach directly to it. So it's pretty exciting to be able to debug an IoT device, and step through, and watch the device react with every step of your debugger tools. All right, now one of the great things that's built into Visual Studio 2015, it's an add-on to 2013, but it's built right into 2015, is the Task Runner Explorer. And I'm going to go to the other windows in here, and look for the Task Runner Explorer, and you'll see that this Task Runner Explorer is going to open up some events, four events in the build process in Visual Studio. Before the build, after the build, while I do a project clean, and when I do a project open. And then this is going to be able to look into a GULP file, or a GRUNT file, and pull out the tasks in those two very popular task runners, and enumerate those tasks on the left here, and allow me to tie them up. We're not going to drill into that right now, but that's a pretty huge feature of this tooling. Another one is the Node.js immediate window, or interactive window, that allows me to go, just type Node.js commands, including npm commands using a dot in front of it, from right here inside of Visual Studio. So if I wanted to do an npm install, or whatever, that works, and it's ready for me. Now that's Visual Studio Community. Let's go ahead and close that down now, and let's jump back out to our command line. And you saw me do this in the last one, but I didn't spend a whole lot of time on it. Let's just maximize this window. And you saw that I executed Code looking at a certain file. Here's the app.js, and actually, what you saw me do was execute Code pointing to a certain directory. But watch this, I'm going to type code, and then app.js, and launch that. And I'll get my instance of Visual Studio Code popping up with that file in well under two seconds. That's really valuable to me right there, just being able to bring that up so quickly. And besides being able to bring up the file, I can bring up the entire project by simply launching Code, pointing to the current directory. So now Code runs, and it comes up with that directory loaded, with a reference to the directory and all of the files within. Very, very handy. Now Visual Studio Code is a free version of Visual Studio that's cross platform, so it's ready to run on Windows, Mac and Linux, all three, that's excellent. And it has full Git support, as you can see here, it has a full debugger, and it has a lot of first class support for Node.js, it's one of the frameworks that it's targeting. It's targeting Node.js, and the new ASP.net 5. So extremely helpful coding environment, Visual Studio Code is. Hopefully you'll look at both of these versions of Visual Studio, and find the one that's right for you, and the kind of development that you do.
-
Automated Deployment
Next, we'll look at ways to make the deployment to your device easier. I showed you how to use SCP, the Secure Copy utility in Linux, to copy your files from your development computer to your device. Now if a person wanted to, they could stick to this workflow throughout the entire development cycle. You make a change to your code, you jump to the console, you type the command, then often in the second console window, you ssh to the device, so you can execute the new code using Node. It would be much better, however, to employ one of the following techniques for automating this deployment cycle. We're going to cover using Intel's IoT XDK, git, using npm, and finally, Gulp. Then, we'll look at a utility that I wrote for Gulp, called Candyman, and we'll see how the whole process can be automated in Visual Studio. Intel, who made the Edison, made an IDE called the Intel IoT XDK. It was Intel's intent to make the authoring and deployment of code simple and seamless. But unfortunately, I'm not a fan. The user experience in the program is initially unintuitive, and subsequently, awkward, I gave it a fair shot, but then I started looking for an easier option. One way to automate your deployment is to use Git. Git is a distributed source control system, that I'm sure you know has become incredibly popular. A distributed source control system's essentially just the ability to track changes to a repository of files, and then to keep the files and all the changes in sync with other repositories, including online repositories that may act as a central repository, and with repositories on other developers' machines. So it's not too much of a stretch to see that Git can be used to get your working directory project files over to a system that happens to be an IoT device. When you work with two standard Git repositories, and you want to push from one to the other, you need to make the target repository a quote-unquote bare repository, bare as in naked, not bear as in grrr. I'll let you search online to figure out how to do that, but it's really not hard, basically, just one line of Git code. But then, a bare repository doesn't contain the working files, like a regular repository does. So to make this work, you'll have to create a hook on the device that fires whenever some code is pushed to the repository on the device, and copies the files out to the deployment location. Now personally, I'm not a big fan of this method, for a variety of reasons. For one, it's using Git for something that it's not exactly made for. It works, but it just doesn't feel quite right to me. Second, the hook requires that you write some Linux shell scripts, and that doesn't sit well with me either. Shell scripts aren't that hard, but I don't know, it just doesn't feel right. And finally, it requires that I change some code, and then commit, and push it. Oftentimes, when I change a bit of code, and I want to see my IoT device light up with some new changes, it's not something I really want to commit. It's just something that I'm trying. I know that's a philosophical matter, but there you have it. So since I'm not so into this method, and I'm the author, let's move on. Another tool for moving bits from here to there is npm. You may know that npm is the Node package manager. It gets installed with Node.js, and it's the means by which you discover, install, upgrade, and uninstall Node.js packages. npm has a central repository, or registry, of modules. This is where members of the Node community publish modules for others to consume. So if you'd like, you can hijack this bit moving cycle, and use it to get your code to your device. This time, instead of going directly to the device, like we did with Git, we're going up to the internet, to the npm repository, and back down to the, from the internet, to our target device. Now I dislike this method somewhat less than the previous, but I still don't love it, the usage feels much more in line with what the tool is actually created for. Nevertheless, we're still committing small changes, and when each iterative change may really just be a trial. Additionally, it often times doesn't make sense to put projects in npm that are of no benefit to the Node community. The recent npm private modules offering could be used, but then, you're having to pay. Now unlike the previous method, and the next one, in fact, this method does require that we remotely log into the target device, in order to run the npm install command, to pull down the latest code. It also requires an internet connection. So let's keep this one in mind, but, let's keep looking. The third and final method I'm going to talk about is the one that I happen to prefer, and that's using Gulp. Gulp is a task runner, a workflow automation tool that's really quite wonderful. You may have heard of Grunt, or more likely, you heard of the two of them put together, like, "You could use Grunt or Gulp for that." I find it hilarious, by the way, that the two tools, which do almost the same thing, seem to be in nearly perfect suspension, with neither one yet winning the standards war. I consider Gulp to be the inevitable winner, though, having the clearly massive advantage that the tasks that it runs are really just JavaScript. It allows the utmost of freedom, in my opinion. The main reason that this method is my preferred is that this is exactly the type of scenario it was designed for. There are a few tasks that need to be done each time you build your project, and sending the code to its target device just happens to be one of those tasks. So let's look at how to use Gulp for this task. Remember that, fundamentally, we're just trying to get some files copied from the host computer to the target device, and we can use SCP for that. Now there are various Gulp task plugins that are intended to use SCP, as such. But I had a hard time finding one that worked well on all accounts. One didn't allow deep copies, that is, copying all of the nested directories, another didn't work well with a Windows machine as the host, and yet another one simply had a bug that I didn't feel like taking the time to fix. So I just wrote my own, we're going to talk about that next. Candyman is available in the npm registry, it's also available open source on GitHub. It's not restricted to use with Gulp, it's simply a tool for defining and executing console commands either locally on the host computer, or remotely on one or more target devices. The really nice part is that it allows you to configure one-to-many hosts, or actually, one-to-many target devices, and each of those in turn is going to be treated as the target device, and effectively allows you to distribute your code to many devices, without any extra effort. This works really well for when you have an army of peer IoT devices, that all run the same code. The real value of Candyman, in my opinion, is the two asynchronous functions that allow for the local and remote command executions. Beyond that, I've implemented a few commands, but you'll likely want to customize this for your own use. One of the tasks here that I'd like to note is the set startup, so far, we've been jumping to the device to execute the code. But when you finish your project, you'll likely want to install it, and make it so that restarting your device results in your code running. If anything goes awry, you want to simply hit reset, and know that it's going to start over, start over running your code. That's where the set startup task goes in. This is going to create a startup file using the latest and greatest systemd service in Linux. Even Debian and Ubuntu have decided to adopt systemd for services, so once again, we've got a standard, and we can all go to work. The cool thing about Visual Studio is that it actually enables two of the three methods that I've lined out. It has a really good interface and engine for Git integration, so after you set up a bare repository on your device, you'll have no trouble committing your code and pushing it out. It has good npm integration, too, but I don't think it has a means to publish an npm module through the interface. And of course, you wouldn't be running Visual Studio on your device in order to pull down npm modules. This doesn't exactly feel like a missing feature in Visual Studio, it's just something that doesn't necessarily belong. Now finally, the support for Gulp in Visual Studio is really good, and it facilitates a really good workflow. The Gulp tasks that are defined are recognized by a plugin in Visual Studio 2013. It's built into Visual Studio 2015, and beyond. And you're then given the option to map those tasks to the BeforeBuild, AfterBuild, Clean, and Solution Open events. So if you map the Gulp deploy command to your AfterBuild event, then suddenly, building your solution, or using the keyboard shortcut control-shift-B, results in the code actually going to the device. I'll show how this works in a subsequent clip. I do want to point out first, however, that you could even use the watch function in Gulp to trigger a code deployment every single time a file in the file system is changed. That's some really good and granular control.
-
Demo: Automated Deployment
Let's take a look at this automated deployment. I'm going to skip the git push method of deployment, and save you the pain of watching me write shell scripts, as well as the pain of me actually having to write shell scripts. I'll also skip the npm publish and install method, and we'll just look at my favorite method, and that is using Gulp and Candyman for deploying directly to the device. I'm going to go ahead and jump back to Visual Studio, we're looking at Visual Studio 2015 RC. And this is with the Node.js Tools for Visual Studio installed, so we already talked about those. Those are the tools that you can find on, let's just go ahead and jump out there, on github.com, on the Microsoft repo, and it's the nodejstools repository. Go here, and scroll down a little bit, go ahead and get those downloaded and installed. And you're going to be up and running with the same exact environment that I'm working in. Now once you have those tools installed, you can follow along and do File, New, Project, and under the JavaScript section, you get Node.js. And this is great, this is very robust, there are a lot of different project templates, and we're going to choose the blank Node.js console application, that's plenty for us. And we'll go ahead and hit OK. Now it doesn't really matter what our, what the logic for our app is, so in our app.js file, let's just go ahead and leave console.log, Hello world. That's just the simplest app in the whole world. Now what we want to look at here is getting this code, whatever it might be, to our device, in automated fashion. So we're going to use Gulp, now there are a couple things that you need to do to get started with Gulp. I'm going to go ahead and jump to the console, so I can just hit Windows-3, and that opens my PowerShell console, brings me right to my prompt. And I'm going to type in here that I want to do an npm install, with a dash g, that means global, gulp. Now I'm not going to run this on mine, because I've already got it installed, but you will go ahead and execute that command. It'll run through the installation of Gulp, and all of its dependencies. And then, in your project, you need to install Gulp locally. So it needs to be installed both locally and globally. So I'm going to go into this console application, into the specific project file, and this is where that app.js and that package.json file are. So this is where I want to install Gulp. So I'm going to do an npm install of gulp, but I'm going to say --save-dev. Now what this flag means is, I want to install Gulp, but this is really just a development dependency. I don't need this whenever my app goes into production. So it's important to add that dev flag on there, that --save-dev flag, and what this actually does is, it writes into the package.json file. So when this is finished, I'm going to type out the package.json file, and you're going to see that a line has been added to it. Not only has that line been added to the package.json file, but we've also actually got the installation of Gulp. So here's that, here's that installation file, let me try that again. gulp at version 3.8.11, or newer. So let's go ahead and jump back into Visual Studio. Now I've done the two things, that is, I've installed Gulp globally, and I've installed Gulp locally. So I want to get started with working with a Gulp file, and to do that, I'm going to right-click on my project, and add a New Item. There are a lot of different templates for things. This is really just a blank JavaScript file, and it's called gulpfile, so I'm going to make a new JavaScript file called gulpfile.js, then I'm going to go ahead and click Add. gulpfile.js appears, and there's not too much that needs to happen in here, just for a default. I'm going to go ahead and bring in the Gulp dependency, which is as simple as requiring gulp, so that's there. And then I'm going to write a, just a real basic gulpfile. I'm going to say gulp.task, and I'm going to call this one default, and then I get to write a function. And this is the simplest gulpfile, okay. Now this function is going to execute, so let's go ahead and give it a body. I want this body to be, let me first go ahead and end this properly, I want this body to be a simple console.log that we are running the default Gulp task. There we go. Okay, now I've saved that gulpfile.js file, and this should be ready to go. So I can jump back to my console. You'll find that you, with Node.js applications, you may, if you work with the same workflow as I do, you'll jump back and forth between your IDE and your console quite a bit. Now the dev tools, the Node.js Tools for Visual Studio, do make it quite nice to be able to manage some things right here in the GUI, in the graphical user interface. But I tend to jump out to the command line, and do it that way. So here at the command line, I should be able to just type gulp, and what that knows to do is to execute this default task. So we'll say gulp enter, and if we've done everything right, we should get running the default gulp task, right there. Okay, so that's working as expected. But let's write something that actually does what we want, and that is, copies our code out. So let's make another task, we'll call this deploy, and we want this to deploy our code. Well, how do we get started deploying code from here? What we actually need to do is execute some commands at the console, either locally or remotely. Now there are a number of packages that allow us to execute SSH commands, SCP commands. But I've wrapped that all up in a module that I call Candyman, it's by no means a finished product, but Candyman attempts to answer these kinds of questions. So let's go to github.com. Candyman is an open source project, and you can find it at codefoster/candyman. And if we go ahead and drill into the app.js of Candyman, you'll see the real, the sugar in this module is this execute remote async, and execute local async. Now these are methods that, using the Q promise library, actually run a either local or remote command, and return a promise. Now a promise is a way to get a placeholder that says, "I'll get back to you as soon as I'm done," and so we have an opportunity to execute some code whenever something is finished. So it becomes a way of handling workflow, or executing asynchrony, throwing things all onto the pipeline whenever a processor has time to get to those. Now behind the scenes, the RemoteAsync function here is actually just using SSH2 client. So this is a requirement here, in the Candyman library. There's a requirement for this SSH2 client, and that's how we do the remote commands. The local commands, on the other hand, are done using child processes. So this is going to do the equivalent of dropping down to the console, and executing a command. So if something doesn't work at your console, it's not going to work here in Candyman. So you're going to have to make sure that you have things working there. Okay, so let's go ahead and flip back to our code. Let's require candyman, and I'm going to use a capital C, because I know that with the Candyman module, I've followed a standard convention, whereby the module returns not an object, but it returns a function. And it's an instantiator function, it's a class function. And so I'm going to use the convention of a capital C here. Then I'm going to create my local, lower case candyman, and that's going to be a newly instantiated Candyman, passing in some configuration. Now I've pre-written that configuration, so that you don't have to watch me type once again. I'll go ahead and get that copied from another screen, and I'll paste this in, there we go. Now this is the configuration format that I chose for Candyman. I enumerate an array of target devices, and then I put some other, kind of default configuration data in here. This is the user that we're going to use to log into the devices, the password that we're going to be using, unless, of course, we already have keys set up. What the start file for our project is, in this case, ours is called app.js. And what the, basically, this is what the folder name is going to be. We're going to call this folder tweetmonkey. And then for the target devices, we have an opportunity here to add not just one, but a lot of different devices, and this is a way that we can deploy automatically to five, or 10, or 100 different devices, and let Candyman just distribute that code to all of those for us, so that could be really interesting. Especially if you want to create some sort of robotic swarms. In this case, we're just deploying to one device, that is, tweetmonkey, and hostname might be an IP address, but in this case, we can just use that mDNS name, and it's tweetmonkey.local, so just one device. So once I've instantiated all of this, I have the opportunity to call Candyman, and any of the methods that are in Candyman. Let's go look at what kind of methods are already in Candyman. Now this is where you might want to fork the project, and customize it yourself. I've just chosen what really works for me. There's one method called deploy that makes a directory in the remote, on the remote device, and then it copies the app.js and package.json file. You might not use this convention of calling your file app.js, you might choose to deploy all JavaScript files. This is the way I've chosen to do it. My projects are always very simple, and contain an app.js and a package.json, so that's what I want the deploy to contain. And so that's all that make up the deploy task, are those two remotely, this is a remotely executed command, and then locally, I'm going to call the SCP in order to copy those files out. So that's what actually happens whenever I call the candyman.deploy. So let's go ahead and call that in here, let's call candyman.deploy, it's that simple. Now candyman.deploy, like I mentioned, is an asynchronous function, it returns a promise. The way that Gulp works is, if you return a promise, then it will wait for that promise in order for this task to be complete. This is really important, because if you have a lot of Gulp tasks, you want first, the project to be deployed, and then something else to happen, and then something else to happen. And you can do that by simply returning this Candyman method, and then it will happen asynchronously. Okay, so this should be all wired up. I didn't show you the core, the default task running in Gulp, let me go ahead and show you that. I'm going to save this, and I'm going to jump back to the command line, we are at this, and oh, I actually did show you that working. I said gulp, and that called the default task. Now it's complaining about Candyman not existing. And that's fine, all we have to do is install Candyman, and that would be a dev only feature, so we're going to --save-dev. That's installed, and notice that you can see the dependencies if Candyman were installed, as well. Q, the promise library, and SSH2, that library for executing commands remotely. Now let's go ahead and do Gulp, without any parameters, and we get running the default Gulp task. And if I say gulp deploy, then I get the attempt, at least, to deploy this code out to the device. Now this has actually thrown an error, it was unable to reach that device. Let's go ahead and ping tweetmonkey.local, and make sure that we're able to access that. In fact, we are, so then let's jump out to our gulpfile.json. And we are configuring this with tweetmonkey.local, that looks good, so let's go ahead and try this again. Let's do a gulp deploy. And this time, it's worked just fine. Not sure why it failed the first time. May have just been a timing issue, but now we have successfully copied that out. So let's SSH, actually, let's go ahead and prove that this worked by, in the app.js file, let's put something in here that we'll recognize, "Hello world using candyman." And then we'll go back and do a gulp deploy again. That worked again, how let's ssh to tweetmonkey. Enter the tweetmonkey directory, that uses the project name variable that we set up in the configuration. We do have an app.js, and if I cat the app.js file, you should see "Hello world using candyman." And in fact, if we ran that, of course that's what it would console.log out. But no need to do that. Now that's great to be able to call, simply call gulp deploy, and have that entire project be deployed. But let's make it one step simple using Visual Studio. Visual Studio has a pane that is, that can be installed, in Visual Studio 2013 it's an add-on. And this pane is, you can find this under View, Other Windows, and it's called the Task Runner Explorer. With Visual Studio 2015 and beyond, this is built in. If I open this Task Runner Explorer, it's going to look for the presence of Gulp, the module deployed globally, it's going to look for Gulp deployed in this project, and it's going to look for this gulpfile. So it's going to look for all of those things to exist. Now once that's the case, I can come in here, and click Refresh, and it's going to enumerate the different tasks that I have in my gulpfile.js. default and deploy were both enumerated, so those are both here now. I can just double-click on those and run them directly. Now you get to see the results of that running. Here's running the default Gulp task, and here is an attempt to deploy this out to the device, pretty slick there. We can even automate this, so that we take this deploy, right-click on that, and go to Bindings, and say, "After I build, I want you to run this task." So when I do this, I get, in my gulpfile.js, I get this little comment, it's not going to bother anybody, but what it means to Visual Studio is, I want to bind the deploy task here to the AfterBuild function. So now, whenever I do a build in Visual Studio, that task is going to run, and it's going to deploy my code out to the device. This whole process is obviously a little bit easier if you map your deployment method, and then just have this automatically happen in Visual Studio whenever you build your project. That's what we're trying to do, is get everything streamlined and easy, so we can make quick iterations, change our code, try new things, and have it sent out to the board really quickly. All right, so we've looked at automating our deployment using Visual Studio, making, using Gulp and Candyman to make it quick and seamless, to get our code from our development environment, out to our production device. And watching our IoT project, whatever it might be, actually whir into motion, and do what it is that we asked it to do. All right, we've seen how to get started writing code for these system on a chip devices, but we only dabbled in the IoT specific code. I'm talking about code that turns on an LED, or reads from a temperature gauge. So far, we've just been working on the coding environment, and workflow options, and things like that. Now a little bit of IoT code that we have written has been pretty raw, the fact is that, once you get up to the level we're at now, where we've successfully run Node on the device, you have some really powerful options for writing the actual program logic. And that's what we're going to look at next. We're going to look at the Node modules that will make your life very, very easy when you're writing apps that not only talk to the device, but also do a lot of other modern things, like fetching data from the internet, creating APIs and web interfaces for the device, and a whole bunch more. I don't know about you, but I've had a good time with the content so far, but, buckle up, because from here to the end of the course, each module is even more exciting than the last.
-
Using a Module for Easier Device Control
Introduction to Cylon.js and Johnny Five
Hi, welcome back, I'm Jeremy Foster. Thanks for watching this course on Node.js and The Internet of Things using Intel Edison. This module's, I'm using a Node.js module for controlling hardware. This is a really good idea for a couple of reasons. First, it's easier, shorter, and more expressive code. By that, I mean it's easier for someone that hasn't seen your code before to tell what's going on and it's a really good thing. And the second reason it's a good idea to use a module is because it adds a layer of a distraction and it means that you'll be able to run the exact same program on any device that's supported by that module without having to change your code. So, you write software for turning your Edison into a robot and then, you want to swap the Edison out for a Raspberry Pi, done. First, I'll teach you about and demonstrate two of the most popular modules for talking to hardware devices. The first is called Cylon.js. The second is called Johnny Five. Both are pretty great actually. There are cases where I'll use one and cases where I'll use the other. Next, I'll drill into the Cylon library and show you how to use what it calls drivers to talk to the various hardware components that we're talking about. I'm going to get you pointed in the right direction if you need to write your own driver. Now, some of the components that you interact with will be a bit more complicated than a simple pin interface and will instead use the I2C Bus. We'll see how that works too. Finally, will look at some other Node.js modules that I think you'll find very helpful when you're working on an IoT project. Let's go ahead and start with the devices module. The first module is Cylon.js. Cylon implements a cool, modern, fluent API and does a really good job of abstracting where the hardware and it even gives your device a web interface and its own API. That means that after you target your device and implement all the components, you can expose them to other services on your network or even give folks a basic web page where they can click a button and make a motor turned. That's pretty cool. We'll see some examples soon. Here's the basic framework code for writing a Cylon.js app. You would write this code in the main app.js file of your project, and that's the file that you'd execute using node. Let's break this down. The first thing we do is we require the Cylon library, then we call Cylon's robot method that's responsible for defining our device. The nomenclature is a little off here. What I've been calling a device, our Intel Edison in this case, is referred to as a robot by Cylon. This robot definition is made up of a few simple components. First, a name. This is how we're going to refer to our robot later on in the work function. Next, there are connections. This is the driver that's going to be used. Since we're using an Edison, we're using the intel-iot driver. Do keep in mind that Cylon's going to see this and go looking for a package with a name, with that name intel-iot and prefixed with cylon-. So, we're going to need to npm install the cylon-intel-iot module in order for this to work. Next, a list of devices. In this case, Cylon's referring to all the things that you've hooked up to your robot. In this case we simply defined pin 2. Notice that we specified the direct-pin driver for this device. A string needs to match, one of the built-in drivers that Cylon recognizes. In this case, direct pin simply allows functions like digital read and digital write. Other more specific or involved drivers allow more abstract control of your devices. You can even write your own. Next, the work function defines what should happen once the robots all set up and all of its devices are ready to communicate. This is sort of like the main function in a C program. Finally, the start method kicks the whole thing off and it is sort of all there is to it to a Hello World app for Cylon. One of the other very cool offerings of the Cylon library is its ability to automatically generate an API in a user interface, let me explain. So you've built your Cylon robot, but now you have another program or service running somewhere else on your network that you want to be able to interface with this robot. Maybe your Cylon robot is a vacuum cleaner and you want your home automation system to be able to start it up. So, you turn on the API and then the other program is able to connect to it using standard interfaces like HTTP, MQTT, and Socket.io, and it connected architecture with multiple robots, this makes for some really exciting possibilities. To get more information about the API, go to cylonjs.com/documentation/api/http, or to mqtt or to socket-io. There's even a front-end application written in react that knows how to talk to the Cylon API and it automatically creates a standard user interface for humans to look at. This might act much like the UI that you use to configure your Wi-Fi router. All-in-all, it's pretty slick. Johnny Five's another really good option for talking to devices. The API is a bit less abstract and easier to understand, so maybe a better choice for beginners or the mildly intimidated. As far as I can tell, Johnny Five is not quite as robust. I don't see automatic API and user interface generation, for instance. But actually creating your own API and UI might not be too hard, might be something you might want to endeavor. The device and component driver supports very rich in Johnny Five though. Let's take a look at a basic Johnny Five program so you can compare the syntax to what you've seen of Cylon and make the best choice for you. The code is certainly terse and readable. We obviously need to require the Johnny Five module and then we need to bring in the specific device driver for our Edison. Then, we instantiate a board that represents the device for the rest of the program. And finally, we handle the ready method and we Implement whatever logic we want.
-
Demo: Blink
Let's have a look at both of these libraries in action. You may be able to tell from what you've seen already which of the libraries you like better, but we're going to use each to blink a simple LED to drive home the differences between the two and help you choose. By the way, for the rest of this course, I'm going to be working with the Cylon.js library. Let's start by programmatically blinking an LED. You've already seen me write the code for blinking an LED using the MRAA library directly and now we're going to use Cylon and then Johnny Five. I think, you'll see right away how much better the experience is using one of these modules versus the MRAA library directly. We'll go ahead and start at the console. I'm going to make a directory called blink-cylon and another one called blink-j5. So now, I have these two directories and we're going to create a node app in each of those. I'm going to go ahead and use Visual Studio Code this time. Let's go into blink-cylon first, and there's nothing in there, of course. We did after all just create it. Let's go ahead and create an app.js file using the touch command, it creates it, but it's empty, obviously, zero length. Now, we want a package.json file and the easiest way to do that is to NPM init. I like to just accept all the defaults, they're pretty good, and now I have my package.json file. Next, I need a gulp file so that I can use gulp and candyman to deploy this to my device. Now, instead of writing that all again, I'm going to simply copy and if you remember, we had this Node.jsConsoleApp1, inside of that was another folder of the same name and inside there, we had a pretty good gulp file already created. So, there we have gulpfile.js. Now, this is looking like a pretty good starting point for this app, so let's go ahead and say code and then dot to refer to the current directory and that's going to open Visual Studio Code with that directory as the working directory. So, you can see I have my app, my gulp file, and my package.json. Let's go ahead and edit that gulp file first. Now, the target devices is already correct. We have a device called tweetmonkey, that's the device that I have here on my desk. The project name, however, we want to change that to be called blink-cylon. It does use the user root, same password, starting file, app.js, that's all good. Notice that we are requiring gulp and candyman in here, and we have this default task that we no longer have any need for but we have a simple deploy task that's using the candyman deploy, which if you remember, copies app.js and package.json out to the device. We'll go ahead and save that. And now, from the command line again, there are a few packages that we're going to need to install. You know that we are using gulp and candyman and those are going to be saved as dev dependencies. So, I'm going to use the --save-dev flag which puts this in the package.json as a dev dependency. That means that while I'm working on this, I want those packages but I don't need them when I'm deploying this to the production device. You may or may not have known that you can specify multiple packages here when you do npm install. So, I'm installing both gulp and candyman at the same time. I'll go ahead and run that. That's done. Now, let's go and see what that did to our package.json file. You can see that it created dev dependencies section with candyman and gulp at their current versions or any version greater than that. So, that means that if I ever do an npm install, those are going to get installed and that's exactly what I want. Now, if you're using Cylon, there a few other dependencies that I need and these ones are not dev dependencies. These are actual production requirements for the app. Those are cylon, cylon-intel-iot which is a package that's used specifically for the Edison and the Galileo. I also need cylon-gpio and cylon-i2c. I'm going to install all of those with save, and now, it's let's look at our package.json file again and you can see that we have those marked as dependencies. That's very good. Now, let's go ahead and jump back into Visual Studio Code, look at our app file, and here's where we want to go ahead and write our application. What I'm going to do is open a browser and jump out to cylon.js.com, go to the Platforms. This is the easiest way to get started here. There are a lot of platforms that are supported by Cylon.js and on this list, it's the Intel Edison and one of the nice things is that the code, the sample code is given for us. In fact, it's already for a blinking LEDs. So really just going to be using this code here, let's copy that, paste that into our app.js file and now, you can see that we have this requirement on Cylon, we've already installed that, so that should be good. We connect to something called, that we're going to call Edison using the intel-iot adapter. Now, this right here, this adapter is the reason why we needed to install the cylon-intel-iot module. I like to clean this up a little bit and we've got devices clean this up a little bit, and we're connecting to pin 13 using the LED driver and we're calling that LED. This is something that we could call whenever we want but we're calling it LED there because it makes good sense. And now, in the work function, in the sample, it calls it and my, I like to call this something more sensible. In fact, I like to call it Edison because then it's referring to the Edison connection there, and it makes sense for me to refer to my Edison the LED on the Edison and then to call some method on that. Now, this every method is something that Cylon uses to automatically give you the functionality of doing something on a timer. So, there's no need to call set time out, like we did an MRAA function, we can simply say every one second Edison LED toggle. In one statement, on fluent statement, we achieve exactly what it is that we were trying to achieve. So, go ahead and save that. Now, you probably know by now that if you install gulp globally and locally, and you create yourself a, let me just go ahead and list this out a gulp file.js, so let's list out the gulp file.js, if you if you do those few steps, then you have the ability to simply call gulp and call the name of the task that you wish to run and that task will run. But I want to show you another way. In Visual Studio Code, you have the ability to hit Control + Shift + P which opens up your command box and allows you to type anything in here from the huge list of commands that are available in Visual Studio Code. Well, the search is good which is great because there's so many commands and if you just type the word task, you're going to see that there are a lot of different things involving tasks. And here's one called run task, that's helpful. Now, if I choose that it simply replaces my box with the word task, and notice that there's no caret in front of task like there was when I was doing a search, instead it just replaces it with task. So, from now on, you can simply hit Control + Shift + P and backspace that and you can go ahead and type task and Visual Studio Code is going to look if it's familiar with gulp and how gulpfile.js defines the tasks, it's going to enumerate that, it's going to give you a list of tasks that you can run and when you choose task deploy, it's going to go ahead and run that task deploy. Now, this task should be installing this on the device and it looks like it was successful. Let's go ahead and open ourselves another command prompt here and this one we're going to ssh to tweetmonkey and once it arrives at tweetmonkey, we'll be in our home directory, there we are. We'll list are directories out and you can see that we have a directory called blink-cylon. Let's go ahead and jump into that one. You can see the we have app.js and package.json. Now, what do you suppose will happen if we attempt to fire off app.js? Well, we are going to get an error message because it can't find the Cylon module. That makes good sense. Now, if I say npm install, it's going to npm install cylon, cylon-intel-iot, the gpio, the i2c, and it's also going to install gulp and candyman. Now, at this point, we don't need gulp and candyman. This is our production environment. So, we'll use the production flag to tell it that we do not want it to install the dev dependencies. Let's go ahead and kick that off and now, this is running on the Edison board. This is a Linux machine running this npm install and it has an internet connection, so it's going out to the internet to get these modules and pull those down. Now, if I do a node app.js, we're actually going to get a running app and I'm looking at the board with the flashing LED right now on my desk. So, that was the Cylon library, that was much better. Let's go ahead and type out app.js, so you can see that this is, must have that wrong name there. Oh, sorry, I'm on Linux. I need to cat app.js and you can see that this is a much more expressive, well-written code. Thanks to this Cylon module. Okay, let's go ahead and jump back over to our other console, go into blink Johnny Five and do pretty much the same thing. So, we're going to touch app.js, I'm going to a little bit faster this time for the sake of time, we'll do an npm init to create our directory. I mean, sorry, our package.json file. We'll go ahead and copy from blink-cylon the gulpfile.js and now, we have that and we'll go ahead and fire this off using code. That opens another instance of code, here it is, maximize that screen. Here's our gulp file. Now, the only change here is that we want to call this Johnny Five instead of Cylon. In our app.js file, this one's going to be completely different and our package.json file, I'm glad we started from scratch because we've got different dependencies here. Let's jump down your prompt and forward dependencies, actually before we do the dependencies, let's go look at the Johnny Five website. So, if I just do a search for Johnny Five js, you're going to get good links to Johnny Five on GitHub as well as Johnny Five's website. Now, a couple ways you can go here. If you go to Johnny Five's website, there's a really good information about the platforms that are supported once again. These icons are a little bit harder to see but this one down here is the Edison and I can look at this Edison and it's going to tell me what kind of a plugin it needs and it's going to give me some additional instructions, and those additional instructions, it's going to tell me exactly how to access the Edison. So, the Edison code itself, let's go ahead and jump down here. This is this is using galileo-io and this may be a bit old because there's actually edison-io that you can do. So, I'm going to show you this other code path, this other path we're getting to exactly here. let's go all the way back to where I did my search, got my search results, and go to GitHub page, and search for Edison on the GitHub page and see that there's a good example of an LED blink on the Intel Edison on the Arduino board, right. Now, this instead of using Galileo, it's using Edison. Those are going to be similar but it's nice to use this one. Let's go ahead and grab this, copy it, and then in Visual Studio Code, we want this to be our app.js file. Now, this is spelling out for us exactly what it is that we're going to need to require Johnny Five and edison-io. So now, we can drop down to our command line. We know that we need to npm install gulp and candyman, and we know that we want those to be saved as dev dependencies, but now we also know that we want to npm install these two dependencies, Johnny Five and edison-io. So, it's npm install johnny-five and edison-io using save. Let's go ahead and look at our package.json file. We've got our dependencies edison-io, the galileo-io was a dependency of one or the other of those and so that was brought in automatically for us and Johnny Five was brought in, gulp and candyman, our dev dependencies. Okay, let's go ahead and have a quick look at this code. Besides the dependencies, we've got the definition of our board, this is a new Edison and we're calling it IO right here and it's ending up being called board and so board is what we're going to use to set up an event for the ready function. This ready function is when the board is ready and all the devices are configured. We're going to create an LED which is just a driver that hangs off of the core Johnny Five library. LED is one of the core drivers. It knows what to do with an LED and in fact, with the LED you can simply say blink. If you don't specify, it's going to automatically pick a frequency, but you can even put a frequency in there if you want. So, this is really light expressive code, simply define LED on pin 13 and blink it. Okay, let's go ahead and save that and let's make sure that we've saved our gulp file as well and then let's drop down to the console and let's gulp deploy. We're doing it a different way this time, instead of doing it in Visual Studio, we'll do it right here at the command line, just so you can see both. And now, if I go ahead and jump over to my console where I'm remoted to the device and I back up one and I list these out, you can already see that blink-js has appeared. So, let's go into blink-js, I'm sorry, j5, and list that out and sure enough, we've got the app.js and the package.json just like we did before. And we do an npm install --production. This is actually installing a trusted version of that MRAA library local to the application. And in fact, this does take time but it does finish before too terribly long. So, I'll go ahead and speed through this for you. There we are. So, the Johnny Five blink demo should be all set up. We should be able to node app.js and there we are. I'm looking at the board on my desk with pin 13 LED flashing so that all work as expected. So hopefully, the advantages of Johnny Five and Cylon.js these libraries, for talking to devices, hopefully, the advantages are apparently clear for you and you're going to employ one of these and use it to communicate with your device. Next, we'll begin the Cylon.js and we'll actually look at some drivers in that system.
-
Cylon.js Drivers
In the blink demos, we used a driver for an LED. Defining an LED as a driver makes our code more sensible. You could use methods like turn on and turn off, which should make more sense in context, make your code more readable than if you were using things like a right one and right zero. Now, let's have a look at a few more drivers. We'll look at the drivers for a direct pin, a button, an analog sensor, an LED, an RGB LED, a motor, and a Servo motor. This isn't a complete list, by the way, of Cylon's built-in drivers. I'm showing all the non-device specific drivers that I think you'll be interested in. I have modified all of these examples to use an Intel Edison though assuming that's what you'll be working with as you follow this course. Keep in mind that some of these drivers such as direct pin and analog sensor are very generic and they would work for just about any device you can plug into your board. The more specific ones like LED and motor are really just a convenience to give you some sensible methods for working with your gadgets. Like I said, the direct pin is a very generic driver. With it, you get to read and write from pins using either digital or analog values. The read function may take some time depending on the system this library is working on, so those functions are implemented with call back so they can be run asynchronously. The button driver is really simple. It has a single isPressed command that lets you query whether or not the button is pressed and then it events that fire when the button is pushed and when it's released. Using drivers with events like this is a slick way to do things as compared to constantly pulling the pins to see if they've been pressed yet. The analog sensor like the direct pin driver allows for reading the analog value of a pin but it also allows you to set lower and upper value limits and then fire events when the sensor value drops down to the lower or reaches the upper. Once again, it's a convenience, nothing more. It's very common in IoT projects to work with LEDs. It's a quick and easy way to get visual feedback to the user, so the LED driver comes in handy. It gives you good commands like turn on and turn off to use instead of the left logical digital right one and digital right zero. The toggle command as handy as well and eliminates the need to even check the state of the light before altering it. The currentBrightness to check the brightness level and the brightness command for setting it allow you to determine a PWM value. PWM stands for pulse width modulation, it sounds more complicated than it is. Let me explain. If you set the voltage level on a pin that's wired up to an LED to zero volts so light be off. If you set the voltage to five volts, the light will be on. Now, if you very quickly modulate the voltage level by switching it back and forth from zero volts to five volts where half of the time, it's at five and half the time, it's at zero, then the LED will appear half lit. The effect on the LED is to cause it to glow proportional to the average voltage. If then you increase the amount of time the pin is held to five, this is called increasing the duty cycle. Then, you increase the brightness of the bulb. With PWM, we can use a digital pin to simulate an analog voltage level, so it's really helpful. RGB LEDs are simply three LEDs, red, green, and blue, all set into one component. They have three different voltage levels. They can take to control each of the colors. Calculating the levels can become a bit of a chore so the RGB LED driver lets you simply send a six-digit hex color code to the color command and it does the rest. If you're familiar with the six-digit hex color codes from the web, then you'll be perfectly comfortable picking these color codes and calling the color command. The motor is pretty straightforward like the LED. It's helpful to have more meaningful command names like turnOn, turnOff, toggle, and speed. Servos are motors with a construction such that they're good at moving incrementally. They're good for actuating robot limbs, opening doors, and controlling visual indicators like the speedometer on your car. The commands in the servo driver allow for easily setting the desired angle, checking the current angle, and even checking an angle to see if it's a safe one for the motor. And then, does it for a quick tour of the basic GPIO drivers.
-
Demo: Drivers in Action
The drivers we just looked at were all communicating with simple digital and analog components but some components aren't that simple. Some components are capable of reporting many different properties and the I2C Bus is our way of making that happen. We're going to look at some sample code for three I2C devices. Cylon supports more of these and you can create your own but these ones are quite popular and will help you to understand what it looks like to talk to this family of components. We'll look at an LCD screen for displaying text to a user, we'll look at a popular barometer component, and we'll look it a six degrees of freedom component. The LCD screen is an excellent device for getting data to a human. You can print information to the screen to provide a menu, show measurement values, or otherwise, just let a person know what's going on with the device. Cylon abstracts away all the complexities of the I2C Bus and it provides a simple print method, that's handy. This interface also includes a lot of other commands though for controlling the screen. You can control the cursor, blink characters on the screen, and turn the entire device back light on or off. When you're ready to start over with a new message, you can call clear and start from scratch. I find a lot of LCD screens available for devices. Some of them are simple like the ones this interface is intended for but others are rather rich with features and allow for multi-colors, touch input, and more. A barometer's another example of a device that's a good fit for I2C communications. The mpl115a2 device provides pressure and temperature readings and it be difficult to get the information that it provides as simple analog readings. Once again, Cylon is making this easy with get temperature and get pressure methods. By the way, there's a newer version of the mpl115a2 or at least a more capable version. It's called the mpl315a2. The newer device asks you for a bit of information about your location and altitude, and then instead of providing a pressure value that you have to turn into something meaningful, it does the math and gives you your exact altitude. It's more accurate too. In fact, it's so accurate it can detect a difference of altitude of about one foot, that's incredible. There's just one more I2C device example that I'll show you and that's the mpu6050, six degrees of freedom chip. Six degrees of freedom is often shortened to 6dof and it refers to the three axes of two different spatial meters, an accelerometer and a gyroscope. The accelerometer detects any translational movement of the device and the gyroscope detects any rotational movement of the device. And with both of these measurements working in coordination, we can determine a lot about the device's motion. One other spatial metric that this chip lacks is a magnetometer. A magnetometer detects the device's orientation relative to the Earth's magnetic field. Now, when a chip contains all three of these, we call it an 90dof, or 90-degrees of freedom chip. The mpu6050 happens to also have the temperature built-in which I find a little bit odd. If you're pressed for space and pins though and you need both of these functions, then it's a really good thing. So, that's all the I2C devices we're going to look at here. The overall concept is that I2C devices are ones that are too complicated to just return their readings as simple digital or analog values. And once again, the nice thing is that Cylon makes it very easy to communicate these components. Maybe you're looking to create your own module for Cylon so you can talk to a device other than the Edison or maybe you want to create support for an electronic component that isn't currently supported by Cylon. In that case, what you want to do is install Cylon CLI command line interface. You should install it globally using npm install cylon-cli -g. The command line interface gives you commands like cylon generate module mymodule to create an entirely new device type. It also gives you cylon generate driver mydriver to create a new driver. And if you want help with what the CLIs able to do, you can just type cylon help.
-
The I2C Bus and Custom Drivers
We looked at two very core IoT node modules, Cylon and Johnny Five. Now, let's look at a few other modules that will surely make your life easier while you're working on IoT projects. Here's a short list of some other modules that I think you might find useful because I have. The first four modules are core modules to Node.js. That means that you can require them in your code without having to npm install them. They attempt to cover the most fundamental tasks that might be common to node developers. The rest of these modules are third-party modules. To use them, you need to npm install them. Remember to add --save to have npm add the module of your package.json file effectively calling that module an official dependency of your application. The request module's not a core module but it's a very popular one. It's based on the HTTP core module and makes a lot of things that you can do with HTTP a whole lot easier. So, look in the request, look at some of the major methods for it, figure out what that's going to do to make your life easier. Express is a simple website framework. This is the backend to a lot of Node.js websites today. Express is really simple and they call it the unopinionated framework, and you can use it to create some simple route, see whether you're serving pages for humans to look at from your device or serving an API for other components or modules or devices to look at. Socket.io is for when you want to get away from the HTTP request response cycle and the HTTP protocol overall and you want to use the lighter, faster, smaller websocket protocol that's built into the w3c standard for the web stack. Socket.io is really exciting because it's really fast and you can get all of these different devices talking to each other with hardly any envelopes size at all. The Azure module is going to give you access to the entirety of Azure as a cloud backend. So, Azure's gigantic, there's a lot of stuff to it, lot of different features that you can take advantage of, and you can simply require Azure to get access to all of those. By the way, there's often times you don't need access to the entirety of Azure and so Azure, the module is broken down into various sub-modules and you can bring in just those focus modules. So, for instance, if all you need to do is access storage in the cloud, save some files up there, and then retrieve some files, then you can include the Azure Dash storage module as opposed to the entire Azure module. Bluesky module is one that I've seen lately that wraps the Azure storage API and gives you a really good streaming file access to Azure storage. It makes it work much more like nodes FS core file system module. Bleno is a module for accessing Bluetooth low energy on your device so you can use Bleno on the Intel Edison to access the BLE that's built right into that chip, and there's a module by Cylon called the cylon-api-http. This is what you're going to use if you want to create an HTTP API for your device. Keep in mind that HTTP is just one of the three protocols that Cylon supports for its APIs. You can also use MQTT and socket.io.
-
Other Helpful Modules
Now, let me demonstrate using a third-party module for your app by showing you how you might use the Express module to give your device a web interface. Actually, a little API. We looked briefly at how easy node makes it to create a web server and how easy the express library makes it to create a website framework or an API. Let's apply that here and see what it would take to create a web server on your device that exposed an API to other devices on a network. We'll start again at the shell and I'm going to create a directory called myapi. We'll move into that. Of course, it's empty. We'll go ahead and create our app.js file. We'll do an npm init and run through the defaults. Those are fine, and then we want that gulpfile.js. So once again, we'll copy this from one of our existing applications, there we go. That's a good place to start and let's open this up in code yourselves a good development environment. Now, let's go modify that gulp file, we've got our deploy task. The only thing we really need to set here is the name of our project. We'll call it myapi and just like that, we're done with gulp file. Now, let's jump back to the console and install, first of all, our dev dependencies which are gulp and candyman, --save-dev. There we go. Now, let's install our Cylon dependencies. So, we are going to be using the Edison, of course, so we need this intel-iot, we'll also need the gpio and the i2c. In this case, were going to be using Express as well. Let's save all of these as dependencies for our application and jump back into Visual Studio Code. Now, if we look at the package.json file, you can see that we do have gulp and candyman as dev dependencies. Let me go to app.js and here, what we want to do is write kind of a mash-up of our Express code and our Cylon code. Let's start with that Cylon example that we did a little bit ago just to blink the light. So, I'm going to go to File, Open, and then go into the blink-cylon, and I'm going to open the app.js file. So, let's start here, go ahead and close that one down and open our app.js file and paste that in, but we're also going to want to do an Express app, and the way I like to do this is to just go ahead and declare my app here, and then require Express and go ahead and instantiate that right away. So, this creates an app for me, and then I store that app here. Now, in my work function, instead of just calling edison.led.toggle, we're going to call edison.led.turnon or turnoff. These are the two methods that we want to call. The rest of this is the same. So, the connection is correct, the device that we're going to be connecting to is correct. We're just going to define an API route for turning this light on and define another for turning it off. We'll go ahead and do that in here. So, I can say, app.get, this is the way you doing it in Express, you do you define a get, which is going to be an HTTP get method, and this is going to be for when somebody does a get at API/lighton. Whenever they do that, we have the opportunity to run this function. This function does whatever we wanted to do and we do another one, that is an app.get api/lightoff, and that one should run this here and this is going to run whatever we want it to. So, for the light on, we want to turn the Edison on. That's going to be a method call. We'll copy that and paste it down here, turning that off, and now, whenever somebody does it, a get request to this route, this function should run which should turn on our Edison's LED, and likewise, if they call light off. All right, I'm going to go ahead and save that. Now, I'll jump back to my command line and gulp deploy that. We send this window over here, start a new window over here, and in this one, we're going to ssh to tweetmonkey. If I do a list now, I should see that my API app exists. So, let's go into myapi, I have app.js and package.json file, by now, you should have guessed that what we need to do is doing npm install, but we can use this production flag because we have no need right now for gulp and candyman. All we need is the Cylon packages and the Express package. In fact, you can always jump into your node modules folder. Let me try that again, and in fact, it did not install those and I'm not exactly sure why. Let's type, oh no, let's cat package.json, and we still don't have those dependencies. So, it's like this save didn't work. I may have been something wrong with the save on my device. So, let's do that again and still help you with the understanding anyway. Let's do a npm install, this was the cylon, cylon-intel-iot cylon-gpio, and cylon-i2c along with the Express and we want to save those and once those are done installing, we're going to jump into or at least type out the package.json file and there we go, must done something wrong the last time, now they exist. Let's go do another gulp deploy to get those out to our device. Notice how easy it is to get those out to the device. That's really important. Let's go ahead and type out this package.json file. It's not found yet because it's not quite done copying, not quite done copying. Oh, actually, it is done copying. I'm just using the Windows command instead of the Linux command for typing that out. There we have our dependencies. So now, this should work just fine. All right, now we're done installing that. Now, we got our node modules folder. Let's jump into that and see that we have Cylon gpio, i2c, the intel-iot and Express all brought right into there. Now, if we look at are app.js, we see, keep doing that. If we look at her app.js, we'll see that we have the correct Express and Cylon code for implementing this API. So, let's simply do node app.js, and this should run. Now, interestingly enough, there's one thing that I forgot that caused this to drop back out to the command line. Hopefully, you've got sharp eyes and you were able to tell what it is, but I'll just tell you that what I forgot to do is tell this API that we wanted to listen. We'll go ahead and let that listen on, say, port 3000, that's no problem. We'll save that, go back to our command line, and do a gulp deploy, let that go out. And once we cat the app.js file and see the listen command in there, than we know that it has, there it is. So now, we know that that's been copied out. So, we're ready to node app.js and now, this is going to break in the working function because now we have an Express web server that's running, so it's going to block the thread and it's going to keep it in the working state, and let me clear my left screen. In the screen on the left, I have my local machine. Now, this local machine and the remote device, the Intel Edison are both on the same network. So, I do have access to it. So, what I'm going to do is just do a curl at http://tweetmonkey is the name of the device local and we use port 3000, so I need 3000 there, /api/lightoff. Now, let me tell you that's what I'm looking at on my desk right now is an Edison with the pin 13 light on. So, this should turn it off and in fact, it just did. All right now, let's go and break that and let's do the same command but with on and in fact, the light just came on. So, what we've done here as we've given an API to our robot so that any other device on the same network is able to call into those API functions and cause it to do whatever functionality we want to extend. All right now, that wraps up this module using node modules to make your programming simple. Now, that we've covered the Internet of Things, the devices, and the software, we're ready to dive into some examples. We're going to start with a really simple example and I do mean simple. The code for the example in the next module will fit on a single page with room to spare. There's only a single component hooked up to the device and yet, I think, it does a really good job of showing just how a little bit of IoT can make for a whole lot of fun.
-
The Making of Tweet Monkey
Meet the Monkey and the Concept
Hi, welcome back. I'm Jeremy Foster. Thanks for watching this course on Node.js and the Internet of things using Intel Edison. This module's on the making of Tweet Monkey. I'm hoping that by seeing an entire project from concept to completion, you'll really get the concepts and you'll have some big ideas of your own. I'm certainly of the opinion that IoT projects are not truly exciting until they start communicating with each other and with the Cloud. But, we have to start somewhere, and we're going to start by making Tweet Monkey. First, I'll introduce to you my Tweet Monkey project. Tweet Monkey's a fun and easy example of an IoT project that just about anyone can implement. I'll walk through the simple hardware hack that's used to create Tweet Monkey, and then we'll look at the software hack. We'll take the principles we've already learned about writing code for devices and we'll add a little bit more, and we'll apply it to the real thing. We'll do full demos of this software hack in two parts. The code to use for simply controlling the monkey, and then the code to tap into Twitter. More on exactly why coming right up. And here he is now, Tweet Monkey. Now, this is his on behavior, which I suppose I didn't need to tell you. He's your typical cymbal-clanging circus monkey that squeaks and squawks and nods his head and makes general merriment. Anyone can go to the novelty shop or to the Internet and find such a fun product, insert the batteries and light it up. But, we're going to go a little bit further and we're going to get Tweet Monkey onto the Internet. The idea is this. Let's program Tweet Monkey to hold still until such time as someone, anyone in the whole world, composes a tweet with the hashtag of #tweetmonkey. At that point, Tweet Monkey should begin his animation hilarity, continue for say, two seconds, and then go silent again. Just that simple functionality is enough to amuse crowds, young and old. Just about everyone has a Twitter client in their pocket and is eager to greet Tweet Monkey and watch him go. Like I mentioned, I'm going to begin by showing how to modify Tweet Monkey and add some hardware. Then, we'll write the software to implement this rather fun scenario. Do keep in mind that with this exact same process you could modify most anything you want to turn it on and turn it off programmatically, according to whatever logic you want. The possibilities are really endless. Doesn't have to be a monkey and it doesn't have to be responding to Twitter. So, let's go ahead and get started.
-
The Hardware Hack
Now let's look at the hardware hack. I'll show you the surprisingly simple process of modifying the monkey so we can control him with an electronic circuit, as well as how to wire up the components and the board itself so that it all works together. The hardware hack for Tweet Monkey is really very simple. The first thing I did when I brought this gadget home is I inspected his battery bay and figured out how his existing switch works. It's a really simple mechanism. The switch on the outside of the battery bay slides back and forth, alternately connecting and disconnecting the conductive connection between the two batteries. So, you switch it one way, the batteries are not connected, it's an open circuit. You switch it the other way, and the batteries are connected, it closes the circuit, just like pretty much any electronics project we know. Now, all we need to do then is tap some wires into these metal contacts that you can see, and then connecting those two wires together will essentially bypass the switch and let the current flow. It will close the circuit by way of an alternate path, and that will animate Tweet Monkey. Now, as a bonus, the original switch still works just like normal, which is good for showing off Tweet Monkey's basic functionality when you don't have things wired up yet. I just used a small drill bit to drill two holes through the bay door and led two small gauge wires through the holes. Just a touch of solder permanently created conductive connections from each of those wires to each of those battery bay contacts. Now, if you're intimidated by or unequipped for soldering, you can instead go to your local Radio Shack and you can buy some conductive glue. A little dab of conductive glue and a little time to dry and you'll have a functional equivalent of a solder joint. Once these connections are made, all you have to do to make the monkey move is touch the two wires together. That bypasses the built-in switch and completes the circuit. Now, we're going to implement a little device though that does this according to logic. The component that we need for this job is called a relay. A relay is an electromechanical device. That means that it's both electrical and mechanical. When you give it a little bit of electricity, it mechanically closes another circuit inside, a circuit that usually is capable of carrying a lot more current than the first one. The advantage to a relay is it can act as a bridge between two isolated circuits. This monkey doesn't carry a ton of current, but even if it did, we'd be able to drive it with our little 3.3 or five volt logical voltage levels and release small amounts of current. In fact, the relay we're using here is made for 120 volt house wiring. You wouldn't need such a capable relay, but that's what I had laying around. I had what's called a Grove Starter Kit by Seeed Studio. That's seeed spelled with three e's. What you see here is a base shield by Seeed. It snaps onto any Arduino board using that standard pin-out that we talked about, and then it makes it easy to plug in all the components that come with this Grove Starter Kit. Here's the relay, and here's the jumper wires that make it easy to plug the relay into this base shield. Now, all of a sudden the relay is connected to the Edison and we didn't have to do any soldering or any wire twisting at all. Here's the whole mess hooked up together on my messy project desk. Now, if you're really into IoT by the way, it's required that you have a messy project desk. Now, this is a standard, everyday USB battery pack, nothing special. Remember, the Edison dev board can be powered by a micro USB, which makes it really convenient. Here's the Edison on its dev board with the Grove base shield installed, with one of those jumper wires connected to the relay and wired into Tweet Monkey.
-
The Software Hack
Now that we've got the hardware sorted out, it's time to start writing our software. All the code we're about to write, by the way, is available on my GitHub account at GitHub.com/codefoster/tweetmonkey. Feel free to clone it. Here once again is the basic framework code for writing a Cylon.js app, that we looked at in depth together in a previous module. Let's review it quickly so we're sure that we're ready for the Twitter code that's coming next. First, we require the Cylon library. Then, we call the robot method to define our robot. I'll call this Edison to be clear that this entity represents the board that we're working with. I'll use the Intel-IoT adapter to talk to the board. I'll define a single device using the basic, direct-pin driver. I'll mark that as pin two, and I'll call this monkey. This is actually our relay that we have plugged into pin two, but logically as far as our code is concerned, it's the monkey, so it makes sense to call it that. When the pin is high, the relay closes and the monkey animates. When it's low, the relay opens and the monkey goes silent. Here in the work function, we're going to put our Twitter code. But, for now, I've left this comment so that you can see how we would set the pin high be referring first to the Edison, then to the monkey, and finally to the method. Finally, we start this robot and that should kick things off. Next, we're going to want to connect to Twitter. Now, whenever you want to do something like this, you have to do a bit of research to find the right module. I found the Twitter module by browsing npmjs.org and looking for the Twitter modules that had a lot of use, and made sure that they utilized Twitter's streaming API. I didn't want my code to continuously be pulling Twitter, looking for tweets. Any tweets yet? How about now? How about now? But rather I wanted it to subscribe and let Twitter call me directly when the right tweet comes in. Next, we want to connect to Twitter by doing a simple require Twitter. Whenever you want to do something like this, you have to do a bit of research to find the right module. I found the Twitter module by browsing npmjs.org and looking for the Twitter modules that had a lot of use by other developers, and I made sure that they utilized Twitter's streaming API. I didn't want the code to continuously be pulling Twitter, looking for tweets. Any tweets yet? How about now? How about now? But rather, I wanted to subscribe and let Twitter call me directly when the right tweet comes in. Next, I need to authenticate on Twitter. Gone are the days when Twitter just let anybody use their API without authentication. Now, you have to register your app and get a consumer key and secret and an access token key and secret if you want to do so much as query public tweets. Don't worry, it's not that hard though. Here, I've put my actual keys in the config file. That way I can check in this app.js to GitHub as is and keep my actual Twitter account keys private by just not checking in the config.js file, or actually by checking it in with templated strings. If you're new to Node, that's what we're doing here, is we're requiring a file that actually lives in the same directory as the app.js. If you're new to Node, what we're doing here is requiring a file that actually lives in the same directory as the app.js file. You can get your own keys by going to apps.twitter.com, logging into your Twitter account, and following the simple directions to creating a new Twitter app. Then, we instantiate a Twitter object and configure it with our specific keys. From here forward, in this file we'll use the word twit to refer to this object. Now, to tie into the Twitter streaming API and tell it that we're interested in any tweets with the hashtag #tweetmonkey, first we call the stream method, then we tell it that we're interested in filtering tweets. We want to track the hashtag #tweetmonkey, and then in the resulting function body, we use the stream to tie up to the data event. That means that this code is going to fire every time a tweet is received, and the data object is going to hold the Tweet. So cool. So, we can console log out the screen name of the person that tweeted and the text of their tweet, then access Edison.monkey and animate Tweet Monkey by setting the pin high, then using a set timeout to wait two seconds and set the pin back low again. And that'll do it. Let's see the whole thing end to end.
-
Demo: Controlling the Monkey
Now, I ran through the software pretty quickly, so let's look at the whole thing again in demo form. First, we're going to write the code for simply controlling the monkey. We're going to leave Twitter out of this part and do that in the next demo. In this demo, we're going to start with a lot of code assets that we've already written, fundamentally this is just going to be our base Cylon project, like the one that we just used to turn a light on and off, only this time, we're toggling the relay that controls the monkey instead. We'll make sure that we have this ability, and then in the next demo we'll integrate with Twitter. Let's get started with Visual Studio. I'm using Visual Studio community edition this time instead of Visual Studio code. That's because we're going to be doing some remote debugging soon. Now, Visual Studio community gives us the ability to install the Node.js tools for Visual Studio, and those make Node.js in Visual Studio really awesome. With those tools, you get the ability to create a new project that is a Node.js project. Those are found under JavaScript, Node.js. And we just want a blank console application. Let's call ours Tweet Monkey and put it in our standard PS folder. Now, the project that Visual Studio builds for us is pretty sparse. Here's the app.js file. Let's go ahead and right click on Tweet Monkey and add some existing code. Now here we can back up to our earlier demo on blinking the LED using the Cylon library and install the app.js that we used for that, along with the gulp file. It says the app.js is already a part of this project, we can go ahead and overwrite that. Bring in those changes. Now you can see that our app.js is actually a base Cylon library. The only difference with ours is that our monkey's plugged into pin number two. We're going to use the direct pin driver since this is not an LED, and we'll give it a meaningful name, like monkey. And in the work function, let's not flash it, but let's add something a bit more meaningful, like Edison.monkey.digitalWrite(1). That'll turn the monkey to the animate state. Then we'll create a set timeout that is a function, and inside that function we'll do Edison.monkey.digitalWrite(0). That's going to take the monkey out of the animate state, and we'll delay for two seconds before running that. That's some pretty good base code. Now, we did bring in this gulp file and there's one discrepancy there. That project was called Blink Cylon and we want this one to be called Tweet Monkey. Save that. In order for this gulp file to work at all, we're going to have to open the command line here, so we'll go ahead and bring up our console. Change into tweet monkey and do an npm install. We need gulp and candyman, just like normal. We'll save those as dev dependencies. And since we're using Cylon, we'll install Cylon. Cylon intel IoT. Cylon GPIO and Cylon i2c. Those should be standard dependencies. Great. Time to gulp, deploy. Let's open up a new console window. And in that one we'll change out to the remote device and see if Tweet Monkey folder exists. And in fact it does, and the app.js and package json file have been copied out. We do need to install the dependencies, but we don't need the dev only dependencies, so we'll use the production flag. Go ahead and run our app, make sure we don't get any errors. That's correct, it says working, and then two seconds later we drop out. Let me show you why. In the code, in our work function, we're doing something, and then we're doing a little more after two seconds and then we have nothing left to do. So, this work function ends and we drop out. That's normal behavior. In our next module, however, we're going to be putting the Edison into a loop, into a state where it's going to continue to be working constantly, so we're not going to want to see that fall all the way out to the console. Now, for that first run, I didn't actually have the monkey plugged in. Let me go ahead and plug that in now... and run it again. (cymbals clanging) And there you can hear the monkey animating and within two seconds we're done. Wonderful. That does it for this demo. In the next demo, we're going to be adding our Twitter integration.
-
Demo: Responding to Tweets
And now we'll write just a little bit more code to get this monkey to respond to our tweets. In this demo, like we've already covered, we're going to call into Twitter's streaming API and give it a function that we want it to call whenever a certain tweet comes in. So, let's jump back to Visual Studio and start with the code that we've already got. The Twitter module that we want to include is called Twitter, and we'll bring that in using the conventional uppercase T as Twitter. Now, just requiring a module is not enough. You do have to actually make sure that it's installed. So, let's jump out to our console and npm install Twitter, and that's a dependency of this project, so we're going to use the dash dash save. Great. Now, we're going to include something called config. Now, the only reason that I'm doing config is so that I can hide my Twitter credentials from you, my audience. And in order to make that work, I'm going to go ahead and add an existing item called config. And it exists here, although we're not going to open that up. Now, I can paste in the instantiation of the Twitter object, and we have a local variable with a lowercase t called Twitter, remember that JavaScript is case sensitive, so this is a different object than this one, and it is using my config module and the keys that were defined in that config module to set that up. Now, this Twitter module is available to me all below, inside my work function there. So, all I really need to do is paste in a little bit of code to replace this manual animation of the monkey. And with this new code, what we're doing is hooking into the Twitter stream, filtering the statuses for something called Tweet Monkey, and whenever data is received, this handler for the data event is going to do the work for us, it's going to do the work of animating the monkey and then setting the timeout so that the monkey stops animating after two seconds. Great. Let's go ahead and deploy this and give it a try. So, we'll do our standard deploy, but I did copy that config file into my project, and I'm going to have to copy that up to the device as well. So, I'll do scp config.js to root@tweetmonkey.local... Slash tweet monkey. There we go, config.js should be up as well. Let's go ahead and jump out to our device and make sure that everything's working. Looks like we have not been able to find the Twitter module, and that's because although we installed it locally, and saved it into our package json file, and even copied the package json file back out to the device after that change, we haven't done a necessary npm install again to get the new modules. The production flag, whoops, that was spelled wrong. Which simply means that the dev dependencies are going to be installed, that won't hurt as at all. And just so you know, the two dev dependencies that we don't need that were just installed were gulp and candyman. And we can uninstall those with a simple npm uninstall. And they're gone. Let's run it again. And there we go, everything appears to be working. The only reason why we don't see any activity at this point is because there haven't been any tweets with the hashtag of #tweetmonkey. Let's go ahead and choose a filter that's going to be a little bit more popular. And we all know what everybody talks about on the Internet these days and that is cats, so let's just do a quick search for cat. Gulp deploy should get that code back out to our device. It's finished. Node app.js. And that's working, but we have no way of telling if we have any tweets right now, so let's try something else. We'll break that and let's go ahead and write a console log inside of our function here. We'll just say hi for now, make sure that that works. Gulp deploy it out to the device and run it, and we'll now get a hi every time somebody tweets anything that contains the text of cat. Run it. It's working, and there we go. In fact, people on the Internet are talking about cats. But, how do we figure out what it is that we're able to enter right here? We have this data object which represents our tweet, but it'd be really nice to just kind of figure out what that tweet is made of. Sure, we could go look at Twitter's online documentation, but there's a little bit better way. Let's go ahead and set a breakpoint here by pressing F9, and then we'll go to the tools menu. We'll go to the Node.js tools under remote debugging proxy and hit open containing folder. Now this remote debug.js file can be dragged into our project, it exists there now. We can jump out to our console and we can copy that just like we did with the config.js up to our device. Now it exists on the device. let's jump back to the device, and now instead of saying Node app.js, we'll simply say Node, that's not working very well for me, let me just clear. We'll say Node remote debug.js, and then app.js. So, we're actually launching a remote debug with Node, but we're passing an app.js as a parameter so that it can launch it using a proxy. And that appears to have worked, we are getting our hi messages. Now, let's jump over to Visual Studio. Remember, we're on a different device here, so this is kind of great. We'll go to the debug menu and attach to process. Inside of the transport we'll change this to Node.js remote debugging, and for the qualifier we'll enter tc:// and then the name of our device, in this case tweetmonkey.local, that might be an IP address if that's how you're connecting. And the port is 58 58. That port was designated in the console whenever we launched the debug proxy. But, it stays the same, so it should be the same for you. Now, let's go click refresh, don't click find up there, that'll take some time. But, we'll click refresh and it should find that process on that remote device. We'll click it, attach, and now our debugger should be attached, and in fact we have broken inside of our function and you should see that the hi's have paused on the device because we're broken. Then we hover over data and in fact I have a value there. Let me look inside of that. Oh, and I have all kinds of really good information here, I can scroll down. I have information about the user, what's the user's screen name, in fact there it is. And in fact, the text is the actual text of the tweet, so maybe that's exactly what we're looking for, so we want to say data.user.screen_name. There we go, so now we're going to get the user's screen name, a colon, and then the text. Maybe we'll specify some value here that will make this easy to determine. Save that. Let's go ahead and stop this using shift F5. And now we can use just a simple gulp deploy to update our app.js file. Now, instead of connecting with the remote debugger we'll just connect normal, the deploy is done so we'll launch this. And there it's working and we're getting those tweets, the text of those tweets are scrolling by, that's excellent. But, let's hook this up to Tweet Monkey instead of searching the Internet for cats. Alright, Tweet Monkey is plugged in. The designated hash #tweetmonkey has been used for the track value, we'll go ahead and leave our console.log in so that we can see what's being tweeted, and just after that occurs we should get a pin high, two seconds later we should get a pin low. We can go ahead and take this break point off with an F9, save that code, we'll deploy it. As soon as the deployment is finished, we execute Node app.js and we should be waiting at the working function. And I'll jump over to my Twitter client of choice in another window, compose a tweet, go ahead and tweet that, and it lands. Now let me jump back to Visual Studio and just bring your attention to the fact that this relatively modern, relatively capable example of hooking into an API like Twitter and controlling a modern IoT device is only this long. That's very few lines of code, so once again we're using very high level code to execute very low level logic. That does it for the making of Tweet Monkey. Next, we're going to look beyond a single IoT device at communications between them in the next and final module in this course. This includes, by the way, a sneak peek at Tweet Monkey's older brother, Command Monkey, so don't miss that.
-
Connected Devices
Overview
Hi, welcome back, I'm Jeremy Foster. Thanks for watching this course on NodeJS and the Internet of Things Using Intel Edison. This final module of the course continues on with IoT examples for showing the concepts that you've learned so far. We looked at the creation of a single device project, but now we need to talk about and create some examples that create multiple devices and explore the methods available for getting them to communicate with each other. It's my opinion that an IoT scenario is by definition connected and is not extremely interesting until it's involved in scenarios with the cloud and with other devices. One device, no matter how smart you make it is really just a gadget, anything in the internet of things has value based on its ability to communicate and relate with humans, with the world and with other things. The internet of things is all about collaboration. There's a term for device communication and of course there's an acronym as well. We call it D2D or device to device communication. When devices relay information back up to the server to cloud services for instance, we call that D2S or device to server communication. As far as devices talking to humans with LEDs and screens or with haptic feedback, well that's just classic UI, user interface. First we're going to overview some good methods and strategies for D2D and D2S communications and we'll review the communication methods that we talked about in the first hardware module. Next we'll look at a push method for D2S communications that will alleviate us having to waste precious clock cycles and battery life, constantly polling the server for state changes. I'll show an example of this push method by showing Tweet Monkey's older brother, Command Monkey. Next we'll have a look at cube based patterns, and see what Azure offers in that regard, and we'll do a demo using Service Bus for queues. And finally we'll talk briefly about a number of other services that Azure offers for IoT. Let's start right now with the overview. I'll start this overview by reviewing the communication hardware that we looked at before. The hardware layer is obviously necessary to make any communication at all possible. These are at least a few of the lowest level physical communication mediums that you can employ to get the chatting happening. Ethernet is a hard wire which only works if your device is in somewhat of a fixed location. The rest are wireless RS signals with their own protocols and their own set of advantages and disadvantages. Some work well at short range, others at long range. Some are star topology in the way that they connect, and they all come back to a central hub. Then others are full mesh, each connects to every other. We've already discussed each of these however, so, now we're going to talk about the various higher level software protocols that we have available, as well as some libraries and frameworks that make the entire task quite simple for you. You need to decide not only which hardware medium your project will use, but which software protocol as well. The protocols used for the web are mostly baked, we mostly use HTTP with a bit of web sockets. Some FTP and likely some trace others. The controversy and churn on the webs in the development frameworks and the client browsers, but in the IoT world there's still very little settle regarding communication protocols. When you're talking about little bitty devices, perhaps communicating intermittently over very thin network connections, everyone has an opinion about what the best protocol is, and unfortunately it seems like all the big players look for points of influence in the IoT space by writing their own. Thankfully though a few standards have emerged, at least to some degree. Let's start with HTTP and REST. Now if you're using Ethernet or Wi-Fi by the way, there's a good chance that you'll be using HTTP and REST. Hardly a dedicated IoT protocol, HTTP has been around for a long time and is the ubiquitous language of the internet. Perhaps that's why it's rather popular with devices as well. If your scenario isn't bothered by having a relatively small HTTP header tax or the stateless HTTP request response exchange cycle, then it's great to reuse what you already know and stick with HTTP. I won't go deep into REST architecture here, but if you're new to the concepts of either HTTP or REST, I encourage you to search the Pluralsight library as you'll find excellent courses on both of those. And I should know, I think I've watched all of them. One of the things to look for in a software protocol is message envelope size. The HTTP protocol, despite its popularity, doesn't allow me to send a very short message without the mandatory full HTTP header. That can add up to a lot of overhead when we're talking about a massive number of messages. One alternative is to use web sockets. Web sockets still actually uses HTTP but only for the initial handshake. After that, web sockets uses direct TCP messages with, get this, only 2 bytes of message envelope. So this is an excellent communication protocol and one that I'm very excited about. Do know that web sockets are better for what I'll call live communication, so when both ends are present. If you're dealing with more than asynchronous architecture where a client may come online for only a brief moment and doesn't have time to stick around and make sure that all of his messages are received, then what you're looking for is a message queuing system, which we'll touch on soon. CoAP which is not a message queuing system, attempts to solve some of the issues with http for using D2D and D2S communications while still maintaining easy mapping back to HTTP, so it can play well with the web as it works today. And if you understand how HTTP works, you'll understand a little about CoAP works. I don't know too much about this one but it's made specifically for IoT scenarios, so it's certainly worth a mention and maybe a little bit of research on your part. DDS is a networking middleware that may improve on HTTP and CoAP in that instead of a request response model it implements a pub sub model, that's publish and subscribe. That change there tends to alleviate the need for long polling of service and the performance load that that implies. AMQP is an extremely popular and useful protocol. This is the most prominent of the message queuing systems I was referring to, it's actually more of a protocol standard that's implemented by many different message queuing protocols. We'll talk more about message queuing and all the specific implementations of AMQP really soon. MQTT and XMPP are rather popular, but, I have to mention those separately because although they're message queuing protocols, they don't actually conform to the AMQP standard. Besides the hardware medium that you use to communicate and the software protocols that carry the messages, you'll likely want to know what your options are for communications platforms and frameworks to make communication easier. There are a lot of them, but I'll name a few and their pros and cons as I see them. MQTT is a really light and simple protocol and that makes it attractive. I know advocates for this protocol would claim that it's mission ready and I know that they'd be able to bring up a few examples. I'm not a fan of the fact that this protocol is proprietary and doesn't implement AMQP protocol, but I'm still hopeful about MQTT. I've never personally used RabbitMQ but I know it was made using Erlang and I know that's a very cool and very fast language, so the performance behind RabbitMQ is certainly going to be there. Azure Service Bus is my choice for message queuing system because it's battle tested on a lot of huge line of business applications and it comes with a full weight of Microsoft behind it, so I feel like it's going to not only be around for a while but it's going to be improving over time. In short, it's not only performant, but it's also arguably more future proof than the others. Nitrogen.js is a framework that sits on top of Azure Service Bus and takes care of a lot of the busy work that you'd otherwise have to do yourself like provisioning, authentication, authorization and admin interfaces. Node-discover is a node module that was designed to install on node server farms to allow for peer nodes, nodes running the same code, to intelligently select a master among them and facilitate real time communications. If a master node falls out of the farm for some reason, like the process just dies or it runs out of battery, a new master is automatically selected. Node-discover is more for real time networks as opposed to queue based networking that we're going to be talking about in a second. AllJoyn is not as much a platform or a framework as it is a standard by which devices of all kinds can discover, connect and communicate. All AllJoyn clients can easily advertise an enumeration of the capabilities and services that it provides. AllJoyn started at QualComm but the source code's since been signed over to the Linux foundation and it's open source. Microsoft and Windows 10 is going to support AllJoyn and I suspect a lot of others are too. It's always great when we settle on a standard, and I'm hoping this is the standard for device discovery.
-
Push
Let's take a look at what it means to push services instead of pulling them. We'll start with a counter example, this is the way you don't want to design a service if you don't have to. If you don't have push services enabled, then you're forced to do the opposite of push and that is poll. We call this continuous polling or long polling. Long pulling is simply a client calling to the server over and over to determine if some state exists or if anything has changed. The client issues a request and the server responds. In my example here, the red indicates that the answer was negative. That whatever the client was looking for was not true yet. The developer attempts to determine an appropriate polling interval and it continues to hammer the server, perhaps getting back only the occasional positive response here indicated by the green. You can probably tell that this is less than ideal. One of the biggest problems with this method is that network and processor utilization it incurs and that problem's amplified by the limited resources of your typical IoT device. One of the other more subtle problems with this approach is the fact that there's a delay associated with the determination of the desired state that may be as long as the value used for the polling interval. In other words, if you're trying to save your battery so you poll every 5 seconds, then you may check the server and get a negative response just before whatever you're looking to happen happens. You then have to wait 5 seconds before you can do another pull and find out. Let's remember for a second about the Tweet Monkey project you saw in the last module. Can you imagine forcing our device to call into Twitter every few seconds asking the same question every time? Do you have any new tweets with the hashtag tweet monkey? How about now? How about now? It'd be a major battery drain, and sending a request would not get a quick enough response because we would often times have to wait the entire length of our pull interval. On the contrary to the previous example, here's the general concept of creating push services. The first exchange is a negotiation of some kind. In this exchange the client negotiates protocols with the server and tells the server what it needs it to do whenever some new data comes available that the client cares about, then comes the beautiful part, client just sits there. It waits for the server to call it directly, when and only when there's a reason for it to do so. There might be a couple of seconds, or it might be a rather long time. In the tweet monkey example, we were using Twitter's streaming API which is a server designed for push. If you want to get a good overview of Twitter service and learn a bit about push in the process, I recommend you check out dev.twitter.com/streaming/overview. If you want to build your own push server, just hold on because I'm about to show you command monkey.
-
Command Monkey
It's time to meet command monkey, tweet monkey's older brother. The goal for the Command Monkey project is to allow me to say Monkey dance into my Microsoft band and cause the monkey to animate. The band relays the Cortana command to an app on the phone, written in JavaScript by the way, which calls a web service which pushes a web socket service down to the monkey telling him to animate. I created Command Monkey for a training course on Microsoft's voice assistant, Cortana, but as you can see the Cortana voice command and the phone app are doing extremely simple HTTP get command up to a service, so you could substitute most any device or service you want into there, in fact you could even use curl from the command line to issue that HTTP GET and cause to happen what you want to happen. The .service project you see here is actually a NodeJS project hosted in Azure. The push part of this then is between the .service project and the .device project which is Command Monkey. Now the code for this project is really short, I'm going to show you the code for the service as well as for the monkey himself. I want to point out that this entire project from the phone to the cloud to the device is written in JavaScript and I think that's really cool because I like writing JavaScript. By the way you can find out all about this project by visiting codefoster.com/commandmonkey. This is it, this is the entirety of the code on the server for Command Monkey. All this code has to do is let the monkey call in and register a listener. And let the commanding app, which like I said, could be anything even though it's Cortana on the phone in this case, call in to relay a command, let's break it down. First we require express and instantiate an express app in one statement. Then we require socket.io and we tell socket.io that it should listen to that express app. Then we create a simple variable to hold the socket that's going to be our listener. In this case, the monkey is going to be the listener. This variable is necessary because the server needs to know who to sends commands to, and this is where we remember that. Next, we define a route for an HTTP get request that's using the API/command route. And the handler for this, we check to see if we have a listener by doing the if(targetSocket). If there is one, we relay the command. Initiating a message with web sockets is as easy as calling the init method on a socket. Here we're issuing a command message, quote unquote command, that's the name that we decided to call it. And we're passing along a query string parameter. The command is not a keyword here, you can use whatever you decide on as socket message names. I'm just choosing to use command in this case because we're commanding the monkey to animate. Next we determine what happens when a socket client connects. In this case, there's only one socket client, the monkey. When the monkey connects, we want to define the set target socket message that the monkey will be able to call on the server. When he does, we'll simply store that socket for, like we say in the last step, when the API command route is triggered. And finally, we tell the express app to listen on the port that Node gave it. That's the server code, now let's take a look at the device. The client's job is to simply wait for commands to come in in the form of a socket message, and when they do, to turn the monkey on for two seconds, just like in the Tweet Monkey demo. The first thing to do here is to bring in cylon and the client module for socket IO called socket.io-client, that's different from socket.io, the server component, this is the client component. At the same time we require the client library we can connect to the server via its public URL. In this case I had the server deployed to Azure, so my URL was Command Monkey.azurewebsites.net. Notice that I don't need to specify a port, it will assume the default 80. The next chunk of code is your typical cylon code, but if we drill in to the work function, you'll see that we're doing simply two things here. First, we're emitting a message to the server, telling it that we're the listener, that is we're the socket connection that's interested in receiving commands. Remember that that triggers our server to store our socket, so that commands can be sent to it. Then we define handler for any socket messages that are received with the name command. In that handler we tell the monkey to animate for two seconds, and that does it. We have effectively used web sockets to create for ourselves a simple push model.
-
Queues
Next we're going to have a look at message queue systems and why they're important in IoT. If you did any college course work in computer science, you'll recall the queue data structure. If you're self teaching yourself all this computer science stuff though, don't worry. Queues a really simple concept. Everyone's waited in line for something, the first person to get in line gets service, and then the next person, and then the next. Until your turn though, you just wait. The size of the queue is obviously variable but the nice thing about a queue is you know that if you throw something else on to it it's going to get processed eventually. Now modern queue based messaging systems are based logically on the queue data structure. They provide a means for asynchronous communication. The difference between synchronous and asynchronous communication systems are analogous to chat clients versus email, if you try to send a chat message to someone when they're offline, then in many chat systems, the message fails or it falls into the ether. With email, however, you can send one any time you want and I can check it any time I want. This is important in IoT scenarios for two main reasons. The first reason is intermittent connectivity. It's one thing to have a constant Wi-Fi connection in the comfort of your development studio< but think about typical IoT installations that are often times in the middle of nowhere with limited power and really few options for communication. It's often a challenge for IoT devices to get a network connection, and when they do get a connection, it's very likely that it's not at the same time as the other devices or servers they want to communicate with. With a queue model, when a device finally gets a connection, it can simply send all the messages it's been holding on to and pick up and process any that are waiting for it. The second reason that asynchronous queue based communication is good for IT is because of scale. Often times, IoT solutions involve hundreds or thousands of censors collecting data at very high frequencies. If a queuing model is used for receiving and subsequently handling these messages, then it's possible to simply add worker processes to handle the messages. If the workers catch up and the queue gets short, these extra workers can just as quickly and easily be shut down. Azure implements queues as part of something called Azure Service Bus. Azure Service Bus is a common bus that allows devices to communicate regardless of how they connect to the network. Some of the devices might be inside a corporate firewall while others are right on the main pipe. But once they're all subscribed to a service bus, they're all using a common pub sub model for messaging. Queues are one aspect of this Azure service. The queue support is AMQP compliant, which means that it's going to be able to build cross platform and hybrid apps, as part of a unified architecture.
-
Demo: Service Bus
Let's take a look at some message queuing with a demo using Azure Service Bus. I want you to really get the concept of message queues, as well as get an introduction to implementing them. I'm going to start by creating an Azure Service Bus and then I'll create a queue within that. Then we'll create something to write messages into the queue and something to read them. When I was looking for a good scenario to demonstrate this, I looked over at a little quad copter drone that I've been playing with, so I created my example based on that. Let's create a commander that pushes messages into the queue and then a drone that pulls them out. The messages could be commands to fly to a certain location. The cool thing about this demo is that you can imagine a whole fleet of drones all looking at the same queue for their instructions. The commander may not care which drone fulfills its orders, but as soon as one has, the message should die and not be picked up by any other drones. Remember that the things that are standing in line in this example that are in the queue are the commands. So let's go. We'll start by jumping out to Azure. Currently I don't have any service bus namespaces created and that's the first thing we need to do, so I'm going to hit Create A New Namespace. And let's go ahead and call this namespace the Drone Commander namespace, now this needs to be globally unique, because it's going to be pre-pended to servicebus.windows.net and that needs to be available for you. I'm also going to go ahead and drop this into a region close to me, we're going to choose messaging as opposed to this being a notification hub, and the message tier can be either basic or standard, but I'll let you read the fine print on the differences as far as performance and price on basic and standard tiers. So let's just go ahead and hit Create. And that doesn't take very long for that to get created, and when it is, you'll notice that the status will change. There we are, now it's active. Let's go and drop into the drone commander service bus namespace and go over to the Queues, now notice that besides queues, a service bus namespace can also contain topics and relays, but we'll save those for another Pluralsight course. Under queues let's go ahead and create a new queue. Click Create. We'll call this Queue Commands, put it in the West, and it does belong to the drone commander namespace, so let's go head and create that. Let's click into that queue. And the next thing we need to do is we need to configure what are called some shared access policies. Shared access policies are shared permissions that are associated with a token that you can use in your application, and they allow you on the administration side here in the portal to configure which of these policies is allowed to do what in your application. So let's go to Configure, and you can see that currently we have no shared access policies, we'll go ahead and create one for the drone, and we'll say that the drone is only able to listen, it cannot send commands, at least not in this scenario. And then there's the commander. Now the commander is able to, maybe we can make it so that it was able to manage entirely, but let's just say for now that it's only able to send. Let's go ahead and give ourselves a management policy as well just in case we want to manage this from any applications. Let me go ahead and hit Save. Alright that's been created. Now just a note that I did kind of gloss over some of the more particular details of both a queue and of a service bus namespace, I just want you to get the general concept, you can dig into any of these individual parameters and figure out exactly what those do for you later on if you'd like. Okay I've got myself a service bus namespace, and I've got myself a queue. It's time to create a couple of Node applications to connect to that. One to connect as the drone and one to connect as the commander. Let's go ahead and open up a Console window. Put one over here on the left which is going to be the commander, and we'll put another Console window on the right which is going to be the drone. So I'll go ahead and make a directory called dronecommander, this will kind of contain everything, and then inside of dronecommander, this one's going to be the drone, so we'll make a directory called drone. And then in our other window we'll cd enter dronecommander and we'll make a directory called commander. Alright, now, let's start off in the commander, remember the commander is the one that sends, that issues the commands, we'll go ahead and create ourselves an app.js we'll create a package json by doing an npm init, run through the defaults which will be just fine, we now have an app.js and a package json file. Let's go ahead and open up Visual Studio code now with that. There we are. Now we need to go ahead and install the Azure node module because we're going to be connecting to the Azure Service Bus using this, using both the commander and the drone applications, so let's go ahead and drop that back down to the command line and do an npm install azure and this is going to be a permanent part of this so we'll save that. And now we're ready to jump into our code, let's open app.js and let's go ahead and create what we're going to call an svcs service and that is going to require the Azure module, and off of the Azure module we're going to create a ServiceBusService. Now that ServiceBusService needs a connection string in order to be okay, so we need to create that. That was a mistake. We need to create the connections string, and we get that connections string from back in the portal, now remember we're working on the commander here, and if after I've configured all my shared access policies I can go back to my Dashboard, click on Connection Information and I get a connection string for each of my shared access policies, so for the commander I can go ahead and copy this entire connection string, notice that contains the end point and the credentials and everything. So go ahead and paste that into there. Now that's what's going to be used for creating our service bus. Now what we need to do is issue a few commands, let's go ahead and do a for loop, let's say that we want to do something, oh I don't know, 50 times. And then in that loop we want to do an svc.sendQueueMessage and the queue that we're going to be using is the, let's go look at that, under Queues, it's the Commands queue. So that's what we type right here, the commands queue. And then what we want to actually send is going to be an object, now we could build that object in line right here or we can go ahead and create it for our loop or within our loop or whatever, I'm going to go ahead and just do it this way and say that the body, now this, it needs to conform to this pattern, we need to have a body and we optionally can have one or more custom properties. In this case I'm going to skip the custom properties and just put everything right into the body. That's one way that you can do it, you can just put the stringified version of a json object inside there and then it'll be easy to parse it on the other side, this is going to be a really simple object, in this case we're just going to be telling this drone exactly which latitude and longitude to go to, so let's say that the latitude is, now obviously this isn't realistic, but let's just use a sample value, and the longitude is also 1234. Now the send queue message function is expecting one more parameter and that is a function for handling errors. And we don't have to do anything with that right now, but we do at least have to specify the callback which we've done. So there we go, that should do it for the commander. Let's go ahead and jump over to our code where we're dealing with our drone. And in here we currently don't have anything, so let's touch app.js, npm init, run through the defaults, and then let's do an npm install azure --save. Now you'll notice that I'm using Node for both my commander and my drone and I'm not doing anything with devices at this point. One of the nice things about using Node is that it's easy to spin Node up locally on your host machine or in your device, and so you can get things working here on your host machine before you actually send it out to your device and add your cylon or your johnny-five code and make it actually interact with the pins and the censors and so on. I'm going to go ahead and start a session of Visual Studio Code from here. Now this is the drones, we'll move this over to the right, go ahead and edit our app.js, in this one we're also going to be using the connection string, so I'll just grab that and the service, paste those over there, but the connection string is definitely going to be different, that's the connection string for connecting as the commander. I actually want to jump back out, go to my connection information, now I want to connect as the drone. So I'll grab the connection string for the drone, we'll paste that in there, and notice that for the connection string the actual end point is identical, this is the drone commander service bus windows net, but then the shared access key name is drone, the shared access key is some difficult value, but that's unique for this specific connection, for this specific shared access policy. Nice thing about having various shared access policies is that later on, you can determine to expire the keys for certain shared access policies and regenerate them, and essentially deprecate certain devices that are connecting to your service bus, maybe they're troublesome devices and they need to be forced to come back in and get a new key. Alright next we're going to access the service, and just like we sent a message queue, we're going to say receive queue message. This is going to be accessing the same commands queue and we're going to specify a function, in this case, this one function handles the error and the messages, and we can say if there was not an error, then simply console log the message body. The message body is what we specify in there, we could print out the entire message, but we're choosing to just print out the body here. Now this receive queue is going to run one time and one time only. We don't want to just check in and pull one message off the queue, we want to continuously pull those off the queue, so let's go ahead and create this as a function and as a repeating function. So we'll write, we'll set timeout, calling ourselves, making this a recursive function, and specifying a value of 100 milliseconds as the call time. And I think that's it, so let's go ahead and make sure that all my files are saved in both, and then in my listening application, my drone, I'm going to go ahead and node app.js, make sure that that spins up, I should just get blocked if I don't have any errors in my code so far. Looks alright, and now in my commanding application, remember, this is going to send 50 commands, so let's go ahead and node app.js. Looks like the commands have been executed, those lat and longs are being processed by the drone. The drone is picking them up and we're assuming that it's flying through the air obeying it's commander, and going to the location that it's supposed to go to.
-
More Azure
And now we'll finish up with a quick tour of a few other features that Azure offers that can back up your IoT project. We just looked at Azure Service Bus, but Azure has a few more services to offer in the IoT category. Event Hubs allows for phenomenal ingestion of data. A single event hub can handle up to a gigabyte per second of data and it can handle either HTTP or AMQP. When you have a large number of censors with a large number of readings and a high sample rate, data can grow really fast. Event Hubs isn't usually where you use discretion about what data you're accepting, you simply ingest all the data you can as fast as you can. When you've got a massive stream of data coming in but only some subset of the stream do you care about for any given purpose, you can use Stream Analytics to tap into the stream, pull out what you want, discard the rest and perform some aggregations. One stream can feed another and multiple streams can tap the same flow of data from an event hub. This ingested data isn't a lot of good until you make some meaning of it, and that's what Azure Machine Learning is for. Azure ML makes it easy to create algorithms for breaking down data to figure out how to make future decisions based off of that data. And then Azure Notification Hub makes it simple to send messages to users on whatever push notification supports their platform of choice. And it's massively scalable as you would expect. Now I realize that this is all sounding a bit like an advertisement for Azure and I guess it sort of is, because it's a really tremendous platform for acting as the backplane behind your IoT project no matter how big or small. Alright, that does it for the subject of connected devices. And actually that does it for this entire course as well. We covered the exciting internet of things, we talked about devices that you can use to create intelligent hardware devices, we talked specifically about the Intel Edison, an excellent compact yet capable system on a chip for your IoT projects, we learned how you can write JavaScript for the Intel Edison using NodeJS, and we also looked at a few good modules to make your code writing a snap. Finally we looked at Tweet Monkey as an example of a very simple IoT project that you can totally emulate at home, and by the way, you're totally encouraged to do so. And we looked at Command Monkey and the whole subject of connecting devices to each other as well as to the cloud for really powerful scenarios. So thank you so much for joining me on this course. I hope you learned a lot and I look forward to having you on my next Pluralsight course.