Pi 2 Pocket Control

Update July 2015:  Hard to believe it is months since I wrote this – anyway a few of you have had trouble with this so I’m making some changes.

MeshThose of you who’ve been following my exploits for some time will know that initially I started using Arduino to control the home – typically I would use an Atmega 1284-based controller which in turn would talk via TCP/IP to my mobile phone and controls it’s own IO pins plus those of a number of simple Atmega 328-based boards (i.e. home-made customised Arduinos) via the hated NRF24L01 boards using a simple internal network.

I had this running in 3 buildings including heating and lighting. What I don’t like is having to go in and re-compile code every time I come up with a new idea for using the same inputs and outputs – and that’s where the new thinking with the Raspberry Pi2 and Node-Red is already starting to get me excited.

So that worked and all of that was fine except for the range of the NRF24L01 and the fact that they can’t listen and talk at the same time.

As for the network finding the best route – forget it as the NRF24L01 can’t even report signal strength. My next move was to be to start using 433Mhz based radios with spread spectrum etc. and that was coming along nicely when the ESP8266 devices turned up on the market. (All of this is documented in previous blogs if you’re interested in alternative routes to home control nirvana).

Don’t get me wrong, there’s nothing wrong with the home control setup I have using Arduinos – indeed this summer I will be spending the summer in Spain while the heating back home in the UK is controlled by an Arduino with just this kind of setup, I just want to move on to something more ambitious and with less compiling – especially when one of the rigs is on another continent!!

So the idea of using the Ethernet for everything appeals and that’s how I plan to proceed.

Shortly after the ESP8266s came about, the marvellous TuanPM MQTT library for these appeared and most of my earlier ideas went in the bin – this is just SO much a better way to do it. However there remains a problem….

If you want to roll your own as against using the rather restricted graphics (and somewhat steep learning curve) of the likes of OpenHab then there are not too many choices.

What I’d really like is for the designer of NETIO to get a move on and introduce MQTT – apparently that is in the works but don’t hold your breath and I’ve not found an equivalent for MQTT that is not attached to a particular system - so in the meantime I’m playing with TCP/IP and NETIO, which is what I use in the original system. NETIO lets you use any graphics you want and easily move it around the screen – it does have some issues however. If for example on your mobile phone,

serverYou have a couple of buttons to turn a light on and off and an indicator to show the status, they are completely separate – and that means you need to poll the light (say every half second) so you get realistic feedback from the light. I don’t like the old X-10 method of simply ASSUMING the state of anything.

So some time ago I thought it would be useful to recreate what I have already but using Node-Red which fascinates me more and more, on the Raspberry Pi 2. 

I should stress right now that there are no security measures with this – which is why I wanted MQTT in the first place. In over 2 years I have had ZERO problems with this (read later comment)  but you are warned if you replicate what I’m doing here. You could of course also arrange some setup that as soon as your APP powers up it triggers a VPN which would give you some security. Actually, that’s not a bad idea.

The image you see above right is typical of the control screens on my phone, I can control heating and lighting etc. and monitor the status of all outputs, the temperature, humidity and more – all using NETIO on my Android phone (it is also available for IOS). The control has several pages and only the current page generates Internet traffic so it is easy to end up with a really complex setup.

netioIn order to replicate this whole thing on the Pi using ESP8266 boards, I’ve put most of the pieces in place as you’ll see from previous blogs. But now to test TCP/IP control using a much simpler example. Over on the left we have a simple NETIO screen with  some buttons and labels – the latter will be the indicators – a pair of images  to show status off and on of GPIO pins on the Pi 2.  I’ll refer to this as the Pi from now on but I’m making no promises about the original Pi which I always assumed was too slow to bother with. I could be wrong.

So I press ON, the relevant LED comes on in the Pi, press OFF and that LED goes off – in addition, the indictor light on the APP reflects the true state of the LED.

Right now the NETIO app is using an external address using a port redirect on my router. I tend to insist on fixed port addresses from my service providers but you can easily get around that with services such as no-ip (DYNDNS) which are free if you don’t mind being harassed to update your details from time to time. remember – no security here so beware. As well as the host address and port – and protocol TCP/IP – I have EVENTBASED button ticked (add attribute if it is not there initially.

button onThe NETIO setup is easy enough, you tell it you want to use TCP, you set the address of your Pi and the PORT number and for each button you define what it is going to spit out. Generally speaking the package would expect the reply to terminate in a new line – you can add a TINY amount of security though not much by adding a string of characters in there. It would not stop anyone getting in but might protect you against any random rubbish coming in (again I’ve not seen that since I started 2 years or more ago). Anyway you have to send SOMETHING back or the buttons just lock up.

On the right you’ll see a typical button setup.. when you press the button it sends “gpio|1|1” out via TCP to the Pi2, which then needs to send nothing more than a new line for acknowledgement. The text and the format is entirely arbitrary. Since I discovered the SPLIT function in JavaScript  I figured this was the way to go, sending vertical line delimited arguments. I have also done RGB control but to keep things simple I’ll not discuss that here.

So what I’ve defined so far is simple enough… gpio,0,1 turns light 0 (pin 11 on the Pi connector) on… gpio,0,0 turns it off. I’ll leave you to ponder what gpio,1,1 and gpio,1,0 might do (hint, pin 12).

In addition I wanted to monitor the state of the outputs so the message simple becomes gpio?|0,  gpio?|1 for the two respective pins.

labelAnd here I came across my first issue with Node-Red… once you set a Pi pin to output – I could not for the life of me figure out how to read state the state of the pin and the program chucked out objections when I treated it as an input – thankfully there is always the dreaded global variable and that’ll do the job nicely.

So this is a simple visually designed process in Node-Red. The TCP comes in – it is processed by a server-side JavaScript function in node-red – which then shoves out commands to the two ports (in the case of output, not status) – and replies to the TCP by using the original incoming message (so it knows where to send the reply).

The TCP in and out setup are trivial (double-click) so I won’t go into them (Node-Red doesn’t need any init or anything for the GPIO pins  -they just work) – the fact that the FUNCTION has multiple outputs may worry you – I didn’t even realise you could do this until a while ago – it’s simple. The function button in node-red can return a single argument – or many using an array – in the case of an array, you can define more than one output – and send the relevant array subscript automatically to the relevant output without a single line of code. You want to return a message to a single output, then it’s simply return msg; if you want to send to more than one output it’s return [msg1,msg2] etc.  If you only want to send anything to one of the outputs, make the others null. The guys who designed this were brilliant imho.

And so without further ado, here is my simple function that handles the lot!!.  Note that a context variable can be used over and over for the same function block. Sticking .global. in the middle means it will work across all blocks – I figured I might want this information elsewhere.

var newMsg = { payload: msg.payload.trim() };
var myMsg=newMsg.payload.split("|");

if (myMsg[0]=="gpio")
    {
        newMsg.payload=myMsg[2];
        switch (myMsg[1]) {
            case "0":
                newMsg.topic="Update pins set gpio0=" + myMsg[2];
                context.global.gpio0=myMsg[2];
                msg.payload="status1="+context.global.gpio0+"\n";
                return [newMsg,null,null,null,msg,null];
            case "1":
                newMsg.topic="Update pins set gpio1=" + myMsg[2];
                context.global.gpio1=myMsg[2];
                msg.payload="status2="+context.global.gpio1+"\n";
                return [null,newMsg,null,null,msg,null];
            case "2":
                newMsg.topic="Update pins set gpio2=" + myMsg[2];
                context.global.gpio2=myMsg[2];
                msg.payload="status3="+context.global.gpio2+"\n";
                return [null,null,newMsg,null,msg,null];
            case "3":
                newMsg.topic="Update pins set gpio3=" + myMsg[2];
                context.global.gpio3=myMsg[2];
                msg.payload="status4="+context.global.gpio3+"\n";
                return [null,null,null,newMsg,msg,null];
        default: 
                return [null,null,null,null,msg,null];
        }
    }   
else if (myMsg[0]=="gpio?")
    {
        switch (myMsg[1]) {   
            case "0":
           
                msg.payload="status1="+context.global.gpio0+"\n";
                return [null,null,null,null,msg,null];
            case "1":
                msg.payload="status2="+context.global.gpio1+"\n";
                return [null,null,null,null,msg,null];
            case "2":
                msg.payload="status3="+context.global.gpio2+"\n";
                return [null,null,null,null,msg,null];
            case "3":
                msg.payload="status4="+context.global.gpio3+"\n";
                return [null,null,null,null,msg,null];
        default: 
                return [null,null,null,null,msg,null];
        }   
    }

else if (myMsg[0]=="mqtt") // message and topic passed on
    {
    msg.topic=myMsg[1];
    msg.payload=myMsg[2]+"\n";
     return [null,null,null,null,msg,msg];
    }

return [null,null,null,null,msg,null];

That function has 6  outputs. I’m controlling up to 4 ports and also I’m storing the state of the ports away when I change them into a MYSQL database, the result is that on power up I can now read that database and restore the outputs to their former glory.

more ports

and for initialising the ports on power up, a one-off trigger.. it doesn’t get any easier than this.

init

 

What is needed now – is a block to control and monitor an ESP-12 board and all it’s I/O over an MQTT link.  Later I mess around with TCP/IP sockets and my own graphics but it has to be said it is hard to beat NETIO for simplicity.

Have fun.

Facebooktwittergoogle_pluspinterestlinkedin

18 thoughts on “Pi 2 Pocket Control

  1. Hi. Thank you for your blog!
    Found a blog where he used node-red and openremote. Have you tried openremote instead of NETIO? Openremote is open source.

    1. BOY does that look complicated. What I would like in an ideal world is for the developer of NETIO to do what was hinted at around a year ago - add MQTT - it then becomes a piece of cake. As for it being open source, really, as I'm not planning in recompiling it, not that bothered as long as the solution works. NETIO has proven to be very reliable over time -but development seems to be painfully slow.

  2. Hi,
    I've just bought NetIo and tried to configure it to switch gpios on my RPi2 but I just can't get it to work.

    The TCP node setting in the Netio should have the ip address of the RPI and the port of the RPi, i.e. 1880 or should it have another because if I set the port in the TCP listner in node red to 1880 it generates and error because it's already in use, I know it should be simple but I can't sort it.
    If you could post the flow text that would be brilliant and maybe the netio TCP config info.

    Cheers

        1. Thanks for that I'll have a read at lunchtime, I had another go over breakfast this morning and it started to work, well nearly, I could change the status of the gpios.

          I think it's something to do with the NetIo and the updating of the app on the phone following a sync because it worked even though I didn't change anything from last night.

          It looks very promising though, thanks for you efforts.

          Phil

        2. Pete,
          Thanks for the update, struggled on through and have now got an app working that switches three GPIOs on and off and reports the status via the bulb icon but it one step forward and 2 backwards, just whe I think I get something it doesn't work, arrghh! anyway onwards and upwards this steep, steep learning curve, if I wasn't bald(ish) 🙂 already I soon will be.

          Phil

  3. Peter,
    Thingstudio supports MQTT out of the box and seems like it might be a better fit.

    1. Hi Guy

      I'm not sure why people bother with ThingStudio, it is just an installation of the normal Pi operating system with MQTT and Node-Red etc... we have made a script which we plan on releasing shortly via the blog which will automatically install MQTT (most likely RabbitMQ), Node-Red, various nodes, MYSQL and PHP etc onto a Pi so that folk can dive straight in and work with our boards and software. I've used the script which my colleague Aidan has written and it worked first time on an emulation - but we need to work on it for ease of use - but at the end of the day these installations are not at all complicated (and believe me I run a mile from anything complex in Linux). We plan to do some work on that this weekend but at the start of this coming week I start my travels to Spain so things might go quite until later in the week.

Comments are closed.