Showing posts with label jeenode. Show all posts
Showing posts with label jeenode. Show all posts

Wednesday, October 29, 2014

First steps with Node-RED

In my ongoing quest to find a good home automation software framework to run the hardware I built, I discovered Node-Red.  Node-Red is the self-professed "visual tool for wiring the Internet of Things".  Sounds promising.

Node-Red is a graphical programming environment based on node.js.  (Node.js is basically server-side javascript). Since it's built on node.js, Node-Red can run anywhere node.js runs.  It's all open source, and was started by IBM.



The interface to Node-Red runs completely in a web-browser, so there's no need to install anything on your development machine, and it is even usable from a mobile browser. It works by connecting wires between different functional nodes, kind of like the picture above.  There are lots of different nodes that do various things, from interfacing to a WeMo light switch to accessing emails from a Gmail account.

There is no built-in UI in Node-Red, but I think that might actually be an advantage.  It has numerous methods of connecting to a custom UI, and this way, you don't restrict users to a default UI that might not suit their application.

I got interested in Node-Red because I saw several different people using it to do home automation with JeeNodes.

Installation
I mostly followed the instructions here to install Node-Red to an old laptop running Xubuntu.

First I installed the Node.js package manager and Node.js itself:
sudo apt-get install npm
sudo apt-get install node

Then I downloaded the latest release zip file from nodered.org and unzipped to ~/dev
cded into that dir and ran 'npm install --production'.

Next up I launched Node-Red it by doing 'nodejs red.js'.  Running 'node red.js' doesn't work since the debian packages install it as nodejs to avoid a conflict. Eventually I ended up symlinking node to nodejs to make things easier:
ln -s /usr/bin/nodejs /usr/bin/node

And with that Node-Red seems to be up and running.

Node-Red ships with a pretty good set of basic nodes, but there is also a git repo that has even more nodes, so I thought I'd try that out.  I installed the extra nodes by doing 'cd nodes; git clone https://github.com/node-red/node-red-nodes.git'.

It should be noted that many of these additional nodes rely on node.js libraries and until those libraries are installed, the new node will not appear in the Node-Red palette.  As an example, if I want to use the suncalc node to generate an event at sunrise every day, I would need to install the suncalc library by doing 'npm install suncalc'.

Hello World
I ran through the initial tutorial and was successful.  Programs in Node-Red are called "flows". The basic design pattern in Node-Red is: drop and config nodes, wire them together, hit deploy.  Pretty simple, and even better, it actually works.

The debugging is a little simplistic in that you can print values to a debug log.  But again, it's simple, and it works, so I can't complain too much.

Flows can be exported as a json string, and imported by the same mechanism.  For the rest of this post I'll post the exported json for the flows I've used.

Controlling  execution
The Node-Red documentation has a good "hello world" tutorial, and has a tutorial on creating new plugin nodes, but it's a little sparse beyond that.  I did some experiments to figure out how the nodes in Node-Red actually execute.  Here's what I've figured out.

First off, Node-Red is completely event based.  Nothing executes unless an external event triggered it.  The "delay" and "trigger" nodes also allow timing based events to be generated.

The wires between the nodes are there to symbolize a data connection to the previous node.  More specifically the wires are really a graphical representation of how javascript Objects get passed to and from nodes.  These are usually referred to as msg objects and their contents can be somewhat arbitrary but most often contain a data member called payload.

So how can you control whether a node executes, like you can with an "if" statement in most text based languages?  If you return a "null" for any of the outputs then any of the subsequent nodes attached to that output don't execute.  A way to demonstrate that is by creating a function node that has multiple outputs which means you return an array of msg objects.  Any element in the array that has a value of null will prevent the connected node from executing.  By the way, this is exactly how a "switch" node works.  Check out the "demo switch" node in the example flow below.



Here's the example flow I'll be using for the rest of the post:
[{"id":"f64d219e.53a208","type":"inject","name":"","topic":"","payload":"","payloadType":"date","repeat":"","crontab":"","once":false,"x":439,"y":454,"z":"d5a6cdcf.6203b","wires":[["5863bf74.888a3"]]},{"id":"5863bf74.888a3","type":"function","name":"demo switch","func":"msg.payload = \"hello\";\n//return [null, msg];\nreturn [msg, msg];","outputs":"2","x":628,"y":452,"z":"d5a6cdcf.6203b","wires":[["6d0fe6ba.2d2e88"],["d6a0f7c1.e949e8"]]},{"id":"6d0fe6ba.2d2e88","type":"debug","name":"demo out 1","active":true,"console":"false","complete":"false","x":821,"y":407,"z":"d5a6cdcf.6203b","wires":[]},{"id":"d6a0f7c1.e949e8","type":"debug","name":"demo out 2","active":true,"console":"false","complete":"false","x":820,"y":486,"z":"d5a6cdcf.6203b","wires":[]},{"id":"1ec662d2.3b7c25","type":"http in","name":"","url":"/test","method":"get","x":450,"y":277,"z":"d5a6cdcf.6203b","wires":[["dd8cd3d3.17b08"]]},{"id":"9c30b932.4da1e","type":"debug","name":"test URL","active":true,"console":"false","complete":"false","x":850,"y":189,"z":"d5a6cdcf.6203b","wires":[]},{"id":"6b3281a7.0a29c8","type":"http response","name":"","x":841,"y":276,"z":"d5a6cdcf.6203b","wires":[]},{"id":"dd8cd3d3.17b08","type":"function","name":"Gen response","func":"var resp = \"Hello \" + msg.payload.name;\nmsg.payload = resp;\nreturn msg;","outputs":1,"x":665,"y":276,"z":"d5a6cdcf.6203b","wires":[["6b3281a7.0a29c8","9c30b932.4da1e"]]},{"id":"7a4aeee7.85b51","type":"inject","name":"","topic":"","payload":"","payloadType":"date","repeat":"","crontab":"","once":false,"x":424.5182189941406,"y":573.5229034423828,"z":"d5a6cdcf.6203b","wires":[["fbd25db9.042da"]]},{"id":"fbd25db9.042da","type":"function","name":"count","func":"if (context.hasOwnProperty(\"counter\"))\n\tcontext.counter += 1;\nelse\n\tcontext.counter = 0;\n\ncontext.global.counter = context.counter + 1;\n\nmsg.payload = \"local counter = \" + parseInt(context.counter, 10);\n\nreturn msg;","outputs":1,"x":602.5182647705078,"y":572.522876739502,"z":"d5a6cdcf.6203b","wires":[["caaa07a5.3555f8"]]},{"id":"caaa07a5.3555f8","type":"debug","name":"","active":true,"console":false,"complete":false,"x":782.5182189941406,"y":577.5229034423828,"z":"d5a6cdcf.6203b","wires":[]},{"id":"36a0278c.c95fd8","type":"inject","name":"","topic":"","payload":"","payloadType":"date","repeat":"","crontab":"","once":false,"x":424.5182189941406,"y":638.5228900909424,"z":"d5a6cdcf.6203b","wires":[["4b22fcbc.b4dd04"]]},{"id":"4b22fcbc.b4dd04","type":"function","name":"get global count","func":"msg.payload = \"global counter = \" + parseInt(context.global.counter, 10);\n\nreturn msg;","outputs":1,"x":603.5182189941406,"y":634.5229034423828,"z":"d5a6cdcf.6203b","wires":[["f51d7f6a.0ae28"]]},{"id":"f51d7f6a.0ae28","type":"debug","name":"","active":true,"console":false,"complete":false,"x":782.5182762145996,"y":633.5228900909424,"z":"d5a6cdcf.6203b","wires":[]}]

Local and Global variables
Within a function node there is a way to persist data between calls to that node that is both local to that node and global to all nodes.  It's documented pretty well here.  I created a quick demonstration of globals using a couple of function nodes.



First web service
Just to try out what I'd learned I used some techniques from here, and got a working test URL using http in and http response nodes!  Just pass a "name" parameter to the URL and it will print a Hello message.  Something like this: "http://site/test?name=Ken"




Conclusions
I really liked working with Node-Red, and I think I'll probably continue using it.

Pros
  • Open source and actively developed by IBM
  • Web-based development
  • Graphical programming/rule development
  • https and basic http authentication is supported.  See here for more info.
  • Mobile-friendly interface
Cons
  • No built-in UI
  • No built-in database for sensor readings, though there are nodes to interface with various DB formats

Friday, October 24, 2014

Trying out HouseAgent

For the last couple of years I've been looking for some Home Automation software to run the hardware that I'm slowly building to automate my house. There are so many choices that I'm not sure where to start.  I discovered HouseAgent mostly because it's written in Python, and I really like Python, so I thought I'd give it a test drive.

HouseAgent is a python-based home automation tool, with a promising architecture.  It appears that plugins are separate processes that communicate via AMQP, which means they can be written in (almost) any programming language.  It has a web interface, and a simple rules engine.

I installed the latest daily build of House Agent on a Windows 7 machine and ran into some problems.  The main problem was that it wouldn't launch.

After poking around for a while I figured out that you could run the House Agent daemon at the command line to get more info.  Just run 'houseagent.exe debug' to display debug messages.  I quickly discovered that there were files missing, namely houseagent.conf.  I grabbed these files from the git repo and put them in the places the error messages referred to.  The next error I had was that the port it was trying to use was already in use (8080) so I changed that in houseagent.conf.

At this point House Agent successfully launched, and I could get to the main web interface.  Then I went to the git repo for the JeeLabs plugin and grabbed all of the files there.  There wasn't any documentation so I made a directory called JeeLabs in the plugins folder in the House Agent install directory and copied all the files from the git repo there.  I then restarted the HouseAgent daemon and was able to successfully add a JeeLabs device.

I stopped at this point since I'll need to actually tie in some JeeNode hardware to continue my investigation.  There is a .conf file in the JeeLabs plugin directory that can be used to set the COM port to use and various other things.

There is also a fork of the JeeLabs which appears to be a little more up-to-date here. Even with those changes, when compared to another more up-to-date plugin, like ZWave, it looks like the JeeLabs plugin has been somewhat abandoned.

The web UI is also pretty plain and if I decide to use HouseAgent I'd like to modify it to look a little more snazzy. Right now it looks like an "admin" interface, rather than one that a user would really appreciate.  There does seem to be a branch where someone is working on mobile interface here.

At this point I kind of gave up since it seemed like getting HouseAgent to run was just fixing one bug after another.  HouseAgent seems like a great architecture but would probably take too much time and effort to make usable.

Pros:
  • Written in python (yeah!)
  • Good plugin architecture
  • Web-based UI
Cons: 
  • It doesn't look like HouseAgent has been under active developement in several years.  Has the project been abandoned?
  • In general, it appears to be a little rough around the edges
  • Web UI is a little ugly and not mobile friendly

Wednesday, January 09, 2013

Improved Security Node

I've spent some time recently polishing the Security Node demo I made a while back to the point where it is no longer a demo.  It's now installed and functioning in my house.

Here are some of the changes:

  • Integrated catisith2's keypad interface code
  • Added logic so alarm system is run completely by the JeeNode
  • Replicated original functionality of the DSC alarm control board
  • Added circuit to control the (very loud) siren
  • Send radio packets when events occur (alarm, arm, disarm, doors open/close)
  • Handle remote commands via radio (mainly arm/disarm commands)
  • Made a small "cheatsheet" with all the commands to attach inside the keypad panel

I've update the source code in my github repo.

I'm pretty satisfied with how the Security Node turned out but I have some things I'd like to change:

  1. The alarm system runs fine locally but my ultimate goal is to have an external interface so I can receive texts when events occur and remotely arm/disarm the system.  I'm still trying to figure out how I want to do that.  JC Wippler is doing some interesting research along these lines.
  2. There isn't much security with the arm/disarm radio messages, though I could encrypt the radio traffic pretty easily.
  3. The final board works well but it looks ugly.  I'd like to redraw everything in EagleCAD and have a proper PCB made.
  4. Adding a battery backup so the alarm will still work when there is a power outage.
Here are some pictures:

Security Node without JeeNode installed

Security Node installed

Keypad communicating with JeeNode


Thursday, July 12, 2012

Security Node demo

I created a demo recently to show off the security node I've been working on implementing using JeeNodes. This is not the final version (though the hardware is pretty close to final), eventually I want to use something like HouseAgent to control the entire system.

This was based on my work in reverse-engineering my security system.

Hardware
Very rough model of my house with simulated doors, panic button, and motion sensor.  The JeeNode is in the center.
The hardware consists of a JeeNode attached to 3 magnetic door sensors, a push button, a temperature sensor, and a motion sensor (with controllable power).  I built the circuit on protoboard since it is a one-off project and the circuit is pretty simple.  It attaches to the JeeNode via the standard port connectors, so it's a little like an arduino shield but with the JeeNode layout.

I decided to use this project as an excuse to try out Fritzing.  I primarily wanted to try this since I thought it might be a decent tool to use to lay out the components on the protoboard, since I usually use EagleCAD but it doesn't allow you to work with protoboard.  The breadboard view in Fritzing worked well for this but I still think I could have done it more quickly with pencil and paper.  But at least now I have a decent (if messy) electronic version.

The interface is simple.  The switches are wired directly to the digital inputs of the various JeeNode ports (also using some of the unused analog inputs as digital inputs).  I use the ATMega328's internal pull-up resistors to save some components in the schematic.  I used a 7805 voltage regulator to bring the 12 volt supply's voltage down to something more reasonable for the JeeNode.  The 5V is regulated further to 3.3V by the JeeNode's on-board regulator.


I added a couple of transistors to the circuit to control power to the motion sensor and siren which both use 12 volts.  I also inserted a switch in the siren circuit so there's a hardware way to turn the siren off just in case there is a software failure (the siren is REALLY loud).  While I'm testing things out I'll probably only have the siren circuit enabled while I'm home so I can monitor things.

Firmware
The firmware is pretty simple and has lots of room for improvement.  It should be noted that I haven't done any work to improve the power usage of the firmware since this node will be wall-powered (the motion sensor and siren require way too much power to be battery powered).  The sketch polls all of the inputs every 2 seconds and sends out a packet with the sensor readings.  It also checks for received packets that contain one of two commands: to power up/down the motion sensor or to turn on/off the siren.

In the near future I will probably make this sketch event-based; it will only send sensor packets when one of the inputs changes value (or once when the node first powers up.  I'll also probably make it handle a 3rd command to poll all of the inputs and return a packet with the data (force an event).  Since this node will always be wall-powered I probably won't bother with using the power management functions available in JeeLib.

Host Software
I wrote the host software in LabVIEW.  This is a prototype and will eventually be re-written to be a web-based interface (perhaps using HouseAgent).  The VI monitors the serial port for messages from a gateway JeeNode running the standard RF12demo sketch.  It then parses these messages and extracts the sensor value from them.  Based on pressing buttons on the front panel the VI will also send messages to the node to turn on power to the motion sensor; it then starts a timeout to allow the motion sensor time to initialize after power up.

I used Sketchup to create a quick, not-to-scale, 3D floor plan of the first floor of my house.  I think it spruces up the front panel nicely.


Screenshot of the host-side UI


The host including the host-side JeeNode connected via USB



Tuesday, June 19, 2012

JeeNode Review


I've been playing around with JeeNodes lately and I thought I'd post a review.

Executive Summary
I really, really like JeeNodes.  The software APIs are easy to use and intuitive.  Soldering them was easy.  The PCBs are well thought-out.  My main complaint is the documentation.  It's not that the documentation doesn't exist or that it is unclear.  The problem is the documentation is badly organized and hard to find.  I will attempt to organize the documentation I used in this posting.

Introduction
JeeNode v6 intro
I've been interested in doing some home automation projects and was looking for a good solution for smart wireless nodes.  I looked into the typcial XBee plus Arduino solution that lots of people used but I want to have many nodes and at $40-50 per node XBees were too expensive.  Then I found JeeNodes which can be summarized as inexpensive Arduinos with 2-way radios.  I purchased a set of 3 JeeNodes plus a USB-BUB from Modern Device.  The USB-BUB is a little USB adapter used to program a JeeNode.  It's only needed during programming so I bought one.

Assembly
JeeNode assembly
I largely followed the instructions from the site above.  The only major difference I found was that the large electrolytic cap provided with the kit was much taller than the one in the instructions so I would recommend leaving it for last. This component is the tallest thing on the board and it's easiest to solder the components from shortest to tallest.  For the right angle header on the end, it's a little different than the instructions which use a straight header; it's actually easier.  Just solder one pin then re-flow the solder as needed
to get it positioned properly, then solder the rest of the pins.


Initial Tests
JeeNode initial tests
As far as power settings: The Vout jumper on the USB-BUB should be set to 5V while the LGLV should be set to 3.3V (or VL).  The 5V will power the Jeenode and run through the onboard 3.3V regulator, while the 3.3V will be used for logic levels.

Software setup: Download arduino IDE from here.  Download and install JeeLib library from here using instructions in readme.

Next follow the instructions for the RF12demo sketch which should be located here: \libraries\JeeLib\examples\RF12\RF12demo\README

Luckily the RF12demo app is already flashed into the JeeNodes so you can skip that step.  I kept one JeeNode attached to the USB-BUB for communication and the other one I stuck into a breadboard and powered with 5 volts via the programming header pins marked VCC and GND. Worked like a charm.

Sending packets via the RF12demo sketch is described in stesp 9 and 10 of the README.

The RF12demo (the sketch that the JeeNodes come preprogrammed with) displays received messages like this:

"OK 2 122 3"

which is interpreted like this:
"OK" = checksum passed ("?" means checksum didn't pass)
"2" = node id
"122 3 ..." = data payload

Reference Material
JeeNode v6 schematics and user manual
JeeNode power tips

Impressions
I'm amazed at the quality of the end device.  The silkscreens are very good to the point where you really don't need assembly instructions.  Also the little things like the fact that the battery leads have built in strain relief through the PCB, and the port headers use the Sparkfun-style staggered holes to hold them in place
while soldering.  The software is easy to use especially once you've pinpointed some of the useful examples sketches from the JeeLib directory. The only thing that has been annoying is that the proper voltage settings for the USB-BUB are not spelled out; I had to look at the schematics for both the USB-BUB and JeeNode to figure out
the proper settings.  And as mentioned before generally the documentation is spread out willy-nilly across the jeelabs site.

Further Reading
The following examples are handy to use as building blocks for later reading.  I would also suggest perusing JC's blog and reading his various articles, he really goes in depth on various topics especially power management, which is very enlightening.

There are some very helpful and knowledgeable folks on the JeeLabs forums.

Here are some useful examples (from the the /libraries/JeeLib/examples/RF12 directory):
  • rfRangeTX - good example of a simple transmit
  • radioBlip - good example of putting processor and radio to sleep and waking up and sending message
  • roomNode - complex example of a full sensor node implementation


Monday, January 23, 2012

JeeNodes and a Motor Shield

Over the holidays I spent some time soldering up some stuff that I purchased lately.  The first is a Arduino Motor Shield from Adafruit.  I had just purchased this because it seemed generally useful, not because I had a specific project in mind.  I really hate wasting time breadboarding an h-bridge circuit when I just want to spin a motor.  It soldered up pretty easily in part due to the ridiculously detailed assembly instructions.  That wasn't meant as an insult to the instructions; I think it may have been the best documentation I've seen in quite a while.



The second soldering project was a set of three JeeNodes I bought to start working on doing some home automation projects. These assembly instructions were very good (though not *quite* as detailed as Lady Ada's typical instructions).  Everything went together smoothly, even the surface mount radio component that I was a little worried about.




I then ran the motor shield and all three JeeNodes through some tests to makes sure I had assembled them correctly.  I walked through the JeeNode tests here. It was really handy that all of the JeeNodes were pre-flashed with the RF12demo sketch which acts as a basic configuration and send and receive utility, which makes doing basic RF check out very simple.  Luckily everything worked on the first try.

Onward towards automating my house!