Putting it all together in Imperihome

This blog entry is about using the Imperihome APP with Node-Red to control IOT. This is looking like the best APP out there.. Read on..

Please note: 14/03/2016 Update thanks to vastly improved understanding of Imperihome – part of this is  thanks to Peter Oakes and his homework (check him out on YouTube). See here for a new video on the setup… more up to date than this blog entry. https://www.youtube.com/watch?v=1p3OwICqQbc

I’m writing this for three reasons:

1. To clarify how Node-Red and Imperihome can work together to allow remote access to IOT

2. To form a base from which to expand

3. To get the conversation away from the original Imperihome article (previous blog) which is now WAY overcrowded.

So here is a basic setup for an RGB LED with colour, saturation and intensity control. Output is to debug but you could of course send that off to any RGB light or to MQTT (which is what I will do). Here is the API information for various devices..

Here is the APP itself in the Google Play Store.

The basic setup for using the Imperihome API (documented here – suggest printing this out it you are interested) is as follows:

You need to define:

  1. The system
  2. The rooms
  3. The devices

Rooms are merely a mechanism for separating stuff up into pages – use them as you will.

You set this up on Node-Red – then merely create a new SYSTEM using IMPERIHOME STANDARD SYSTEM in the App. If you don’t have password setting on your Node-Red pages then you don’t need a username and password. That simple. The local URL  in the APP will be http://192.168.0.x:1880/test1 – if you want to use this outside of the home at the very minimal you want username and pass and preferably setup https (the two security items being outside of the scope of this article).

Imperihome[6]

Let’s go through this step by step – the cream things are standard http input and output nodes. The latter need no setup at all, the input nodes need and address – I’ve called my base address “test1” – don’t worry you don’t have to create any test pages – you need do nothing more than set up this tab in Node-Red and setup the APP as I’ve described above.

The URLS for the first 3 http nodes are self explanatory – the last on (rest actions) is as follows:

/test1/devices/:deviceID/action/:actionName/:actionParameter

So the first 3 are incoming requests from the APP (by default every 5 seconds and at startup) – I change my default (in settings for the APP SYSTEM) to 2 seconds.

The system request and room requests are just setup – in this case I have one “room”  - I can have as many as I like and these are essentially tabs in the APP.

The orange units are functions you write yourself. The first function is merely setup.

msg.payload = { "id": "ISS:Test:01", "apiversion": 1};
return msg;

The third one – the rooms is also simple:

msg.payload = {"rooms": [{ "id": "roomID1", "name": "Test Room" }]};
return msg;

If you want more rooms you simply add them as such:

msg.payload = {"rooms": [{ "id": "roomID1", "name": "Test Room" },[{ "id": "roomID2", "name": "Other Room" }]};
return msg;

Ok, this takes us to the devices function. This simultaneously tells the APP what devices you have (you don’t need to set anything up on the APP at all other than your node-red page address the name of which (test1) is arbitrary.

var rgbState = global.get('rgbState') || 0;
var rgbLevel = global.get('rgbLevel') || 0;
var rgbColour = global.get('rgbColour') || "AAAAAAAA";

msg.payload = {"devices": [
{ "id": "dev01", "name": "RGB Light", "type": "DevRGBLight", "room": "roomID1", "params": [{"key": "dimmable", "value": "1"}, {"key": "whitechannel", "value": "0"}, {"key": "Status", "value": rgbState}, {"key": "Level", "value": rgbLevel}, {"key": "color", "value": rgbColour}]}
]};
return msg;

If you look at the Imperihome API instructions you’ll see all about parameters and types.

So – I pull in three global variables (which used to be of the form context.global.rgbstate but which are now accessed with .get and .put commands – looks odd if you’re not used to them but it’s simple enough.. the “!! 0” simply means return 0 or “AAAAAAAA”  if the variable has yet to be initialised.

Incidentally AAAAAAAA for a colour – yes that caught me out – it is HEX and the first 2 digits are irrelevant unless you are using WRGB LEDS.  I’m using RGB (the W is for WHITE).

So this sets up the RGB light device in the APP and prefills values – but also it is called regularly to update the APP display – such as the sliders and RGB control. rgbSTATE incidentally is for the APP RGB on-off button – and will be 1 or 0. Level will be 0-100 and the rgbColour will be any WRGB value (first 2 digits ignore).

What we are saying in that mess above is that this is an RGB light control in the main room, it is dimmable, we’re not using WHITE and here are the settings.

All that remains to do now is take action when the actual APP controls are changed… and that means storing updates to the global variables.

That is this bit extracted from above.

Imperihome[8]

So we have the http input and I described that URL above – and a simple switch – ie. which device are we talking about? I only have one device here…

Imperihome switch

See “dev01” – that is the name of the one and only device – really one should give the devices more meaningful names but that’ll do here.

There is one output from this switch node – there would be more if you added more (the +rule).

The output goes to a simple standard function (top)

msg.payload = { "success": true, "errormsg": "ok" };
return msg;

That then goes back to the APP via the http node. This is common to all devices…

So here it gets more interesting. You are taking in commands from the APP and doing something – firstly storing the results in global variables – but then taking RGB and brightness data and creating an output to go off to your RGB light – in this case just a debug output.

This is a bodge – does not take into account proper colour adjustment at various brightnesses – and right now people (just got your email Chris) are firing ideas at me so this version will go in the bin – but it will do for the purpose of experimenting.

 

function colorLuminance(hex, lum) {
    // Validate hex string
    hex = String(hex).replace(/[^0-9a-f]/gi, "");
    if (hex.length < 6) {
        hex = hex.replace(/(.)/g, '$1$1');
    }
    lum = lum || 0;
    // Convert to decimal and change luminosity
    var rgb = "#",
        c;
    for (var i = 0; i < 3; ++i) {
        c = parseInt(hex.substr(i * 2, 2), 16);
        c = Math.round(Math.min(Math.max(0, c + (c * lum)), 255)).toString(16);
        rgb += ("00" + c).substr(c.length);
    }
    return rgb;
}

switch (msg.req.params.actionName){
case "setStatus": global.set('rgbState', msg.req.params.actionParameter);  break; 
case "setColor":  global.set('rgbColour', msg.req.params.actionParameter);  break;
case "setLevel":  global.set('rgbLevel', msg.req.params.actionParameter);  break;
default: break;
}
if (global.get('rgbState') == '0' || global.get('rgbLevel') == '0') {
    msg.payload = 'RGB = 0,0,0';
} else {

    hexColor = colorLuminance(global.get('rgbColour').slice(2), -1+(parseInt(global.get('rgbLevel'))*0.01));

    msg.payload = 'RGB = ' + parseInt(hexColor.substr(1,2), 16) + ',' + parseInt(hexColor.substr(3,2), 16) + ',' + parseInt(hexColor.substr(5,2), 16);
    }
return msg;

 

The function above merely takes RGB and brightness and produces an RGB value adjusted by brightness.

The main code has a switch to check which command came in – to adjust status (1,0), level (brightness 0-100) and RGB value. These are merely stored in the global variables.

All that remains to do is output something suitable to the debug – it is crude but it works.

 rgb

 

So whenever you make a change to the on-off state of the control in the APP, or change colour, brilliance or saturation – you will see a new RGB value come out of the debug.

When first setup this works. I then go into the APP and adjust the refresh time to every 2 seconds and something strange happens… the level control “flickers”. It did this in my more complex set up and now does it in this simplified and “clean” version.

https://bitbucket.org/snippets/scargill/prn7L

Here are APP screenshots – ignore my username and pass.

Imperihome[10]

Imperihome[12]

 

Imperihome[14]

 

All very simple – and can be expanded on with multiple rooms, IP cameras and all SORTS of widgets – a BARGAIN at £4 for the APP.

Update 09/03/2016

It turns out that the brilliance slider thing was a bug – fixed. Meanwhile here’s a picture of my current setup with a few controls – note that the http responses are all tied together where the response is identical – makes for a much simpler layout.

imperihome

Facebooktwittergoogle_pluspinterestlinkedin

48 thoughts on “Putting it all together in Imperihome

  1. Hi Pete,

    I've copied your code into node red and done a test. As far as i can see the Level does flicker but not consistently. I have set the refresh to 2 seconds. But cant force the flicker to happen. I looks to happen when the phone comes out of sleep.

    Also what version of nodered are you running as the global.set and gobal.get don't work. Debug error so i just switch them back to context.

    Regards

    Paul

    1. Hi Pete,

      I notice that in the RGB you send out every 2 secs, the first two are always 'ff' maybe this is what causes the app to flick to 100%. I wonder if you can tweak it to test.

      Regards

      Paul

        1. I know - it is I think for WHITE... I wonder if the guys are Imperihome are aware of this - if anyone writes in their forums perhaps the question could be raised. Now that I've made this really simple example and taken all the crap out - my gut feelings are telling me this is a bug.

          1. Hi Pete,
            Like others, my node red doesn't like global.set /get 🙁 so I've tweaked the code to the one below - Please can you change your base code accordingly (or just use this 😉 I'm sure I'm not the only one who has problems with global.set/get
            I've defined the variables a bit differently - maybe that helps with the bug? Unfortunately, I can't test it though (But I will be buying an RGB lamp soon)
            https://bitbucket.org/snippets/Curlywurly/M8KGG

  2. Pete - thanks for the write up. I'm using the Lite version at the moment with my Philips Hue and Hue compatible lightstrips powered by dresden elektronik wireless FLS-PP http://www.amazon.co.uk/gp/product/B00NMSQ4QQ. These can control longer strips than the Philips Hue - I have 5m lengths.
    I love the Imperihome interface for these - the voice control is fantastic and was looking to link it with Node Red.

  3. Can confirm a "flicker" where the Brightness control goes to 100% randomly during the 2 second refresh.

    Not sure what's causing it.

    But now when testing again, the flicker has gone and I don't think I've actually changed anything. Perhaps a bug in the app?

    The issue does seem top go away when I set refresh rate to 5 sec or 1 sec. Odd.

    1. For me the issue does not go away at 1 second (but does not happen every second - more like every other second) and at 5 seconds it APPEARS to go away..

      I'm coming firmly down on the "BUG" suggestion. This surely cannot be caused by the simple code we're using here.

  4. And just to add a little bit, if you're trying to create a Scene.

    A Scene is actually a device (devScene) and will make a similar call when pressed. However, the http request node for normal devices won't work. Instead, you need the following:

    /test1/devices/:deviceID/action/:actionName

    It's basically the same as normal, but without the /:actionParameter

    1. So Steven - I tried:

      /test1/devices/:deviceID/action/:actionName

      and it did not work - so I ASSUME you need to also change the device definition/incoming... which is currently..

      What do I need to change (it's worth a try but it would be nice to know WHY we'd want this alternative version..

      { "id": "dev01", "name": "RGB Light", "type": "DevRGBLight", "room": "roomID1", "params": [{"key": "dimmable", "value": "1"}, {"key": "whitechannel", "value": "0"}, {"key": "Status", "value": rgbState}, {"key": "Level", "value": rgbLevel}, {"key": "color", "value": rgbColour}]}
      ]};

      Are you able to elaborate?

      1. Sorry, the above http address only works with a Scene "device". It won't work for normal devices like the RGB light.

        For example, add the following to the devices function

        {"id": "dev02", "name": "Scene1", "type": "DevScene", "room": "roomID1"}

        and you should see a sceneon the app after a refresh.

          1. Just to add, if you put the following snippet, you should see "Scene loaded" in the debug window.

            [{"id":"760ef358.89f10c","type":"http in","z":"85e92205.7a16e","name":"","url":"/test1/devices/:deviceID/action/:actionName","method":"get","swaggerDoc":"","x":268,"y":635,"wires":[["b1879507.4e7868"]]},{"id":"b1879507.4e7868","type":"switch","z":"85e92205.7a16e","name":"","property":"req.params.deviceID","propertyType":"msg","rules":[{"t":"eq","v":"dev02","vt":"str"}],"checkall":"true","outputs":1,"x":519,"y":672,"wires":[["a94732b4.56b8d","bb4a9412.44b568"]]},{"id":"bb4a9412.44b568","type":"function","z":"85e92205.7a16e","name":"","func":"msg.payload = \"Scene loaded\";\nreturn msg;","outputs":1,"noerr":0,"x":679,"y":712,"wires":[["3dd59244.c22a6e"]]},{"id":"3dd59244.c22a6e","type":"debug","z":"85e92205.7a16e","name":"","active":true,"console":"false","complete":"payload","x":836,"y":763,"wires":[]},{"id":"5a3f178f.a5c0e8","type":"http response","z":"85e92205.7a16e","name":"","x":799,"y":672,"wires":[]},{"id":"a94732b4.56b8d","type":"function","z":"85e92205.7a16e","name":"","func":"msg.payload = { \"success\": true, \"errormsg\": \"ok\" };\nreturn msg;","outputs":1,"noerr":0,"x":679,"y":672,"wires":[["5a3f178f.a5c0e8"]]}]

          2. As far as I can tell, a Scene is a way of making whatever-things happen at a touch of a button.

            For example, while I'm waiting for a useful time-picker (or a way around it), I currently have 4 Scenes which are something like:
            * Off to bed
            * Off to work
            * Morning
            * Evening

            Now, by pressing one of those scenes, I can automatically get the thermostat, lights, etc. at the touch of one button. For example, "Going to bed" would put the thermostat into "night mode", change the setpoint to say 10C, and turn off all the downstairs lights.

            I think you can also integrate Tasker, so I could have Tasker call a Scene when my phone recognises that I've come home (though I currently have no idea how to do that...).

  5. Hi Pete (Matthews) re your https://bitbucket.org/snippets/Curlywurly/M8KGG update - made no difference - you don't need a real device to test it... just the code as it is will show the bug. So again at 5 seconds update it happens every few, at 2 seconds update it is most times.... the brilliance will go to full (at least on the slider - it will NOT affect the output) and then go back to where you set it.

    1. Hi Peter,
      Sorry try again - wrong version
      N.B. I also changed the devices code from this
      { "id": "rgb01", "name": "RGB Light", "type": "DevRGBLight", "room": "roomID1ps", "params": [{"key": "dimmable", "value": "1"}, {"key": "whitechannel", "value": "0"}, {"key": "Status", "value": rgbState}, {"key": "Level", "value": rgbLevel}, {"key": "color", "value": rgbColour}]}

      to this
      { "id": "rgb01", "name": "RGB Light", "type": "DevRGBLight", "room": "roomID1ps", "params": [{"key": "dimmable"}, {"key": "whitechannel"}, {"key": "Status", "value": rgbState}, {"key": "Level", "value": rgbLevel}, {"key": "color", "value": rgbColour}]}

        1. Bigger problem for me 🙂 I went to your snippet and loaded it in - and it killed the App. I uninstalled it - reinstalled it - still killed... uninstalled, reinstalled, went back to original hello app - works (still flickers but at least it will start up)....

          This all started very bright and cheerful 🙂

  6. To those of you who mentioned they don't have global.get and global.set - can I PLEASE recommend that you upgrade your Node-Red installation - there is also flow.get and put and these will all work toward non-volatile information in the future - it really will pay dividends to keep up with the newer versions of Node-Red now.

    1. I wish I could Pete, but I can't easily upgrade the hosted node-red I use, so I have to use the old context method 🙁
      If the improvements were a significant change, then I'd be more inclined to agree with you but from what I've read, the new "flow" object is a similar thing to the "context" object anyway i.e. The "flow" object applies only to the nodes on that tab page .
      TBH, I'm dubious of using Node red for data storage anyway (Security/lack of query ability etc) and it doesn't look like future versions of node-red (>0.13) will improve on local storage query options. (as outlined near the bottom of this page - see the flow and context sections)
      http://nodered.org/docs/writing-functions.html

      Not sure how anyone else is getting on with this, but I've now set up a working version of Imperihome ISS in the cloud all for free - using hosted node-red, MQTT and Mongodb (no local R.pi needed etc).
      If I get time, I'll try to document it and post it up for others.

      1. Ah, sorry I thought you were using local node-red.

        Ok, your offering I'm sure lots of guys will make use of - that's great.. but personally, even with the best will in the world, my service provider can't guarantee 100% up time and the more external services I use, the most chance of failure. I've used Node-Red on a Pi2 with battery backup and in a year I've not had one fault (at all, in any aspect of Node-Red, MQTT and SQLITE) that wasn't down to me messing about - so I like to keep all services local.

    1. Hi Brian - no - I have not used IOS for some time - I'm a complete convert to Android - sorry can't advise. Someone else looking in may be able to comment....

  7. Hi Pete, I have just read that the REST API does not work on the ios so that puts an end to Node-red and the ios platform. Thanks for your help though great site.

  8. Hi Pete brought myself an android device followed the tutorial but just trying to switch a light on/off, I run the program and the light came up on the android unit with the on/off buttons, when I press the button nothing comes up in node-red, so I decided to add a pulse to the light which came up alright on the android when I press the pulse I get the error message (5/9/2016, 9:30:58 PMLight
    function : (error)
    ReferenceError: req is not defined (line 1, col 8)

    I thought it may be because I had setState but when i changed that to pulse as per documentation it made no difference still the same error message, do you have simple working example I could put into node-red to see where I am going wrong?

    1. Hi there

      I think in the blog or one near it I gave an example - Imperihome is not SIMPLE and takes some getting used to - but the example I gave should help. In some respects, Blynk is easier.

  9. found it in the write up there is a : missing in front of the action in the the ISS Rest Actions.

    /test1/devices/:deviceID/action/:actionName/:actionParameter

    should be

    /test1/devices/:deviceID/:action/:actionName/:actionParameter

  10. Hi Guys, I've been following this site for a while. I've been trying all sorts (OpenHAB, PiDome, Blynk, etc) and have come to the same conclusion as Pete that Node Red and Imperihome is what I'm after. I followed the RGB example and have managed to get that working over MQTT to a NodeMCU running an RGB strip. I also added a basic switch which will eventually run some outside lights. That too works well, but I'm also using a scheduler to turn the lights on and off at set times, also using MQTT. That works, but it's not updating the light status in Imperihome. So when it's on (switched on by the scheduler) it's still showing off in Imperihome.

    Could someone please explain how i would go about syncing the states. I tried using a function to change the global var 'swState' which is what i' using in the devSwitch function but that doesn't have any effect. Thanks.

    1. Never mind, my fault. I wasn't setting the variable correctly. I was setting it to 'off' instead of '0'.

  11. Hi Pete - I just about tore my hair out trying to get a connection set up from my (new) android phone. As it turns out, unless I deleted the 'demo' configuration in Imperihome, it would always refuse to connect! Once I deleted it, it worked like a charm!

    1. Yes that caught me out too first time, John.

      I had to reformat the phone the other day - something got to it and I could not be bothered with the whole investigation thing. Since then - despite putting my gmail account in so accurately that it is RECEIVING emails - it will NOT send them.... but it gets worse... incoming mails to pete@scargill.org come to my pete@scargill.net server and then onto gmail... it is complaining that my outgoing mails are being rejected by the scargill.net server.... erm, but outgoing mails don't go by that server - they go straight out of Gmail.. I think I may have entered a parallel universe.

  12. Another thing I noticed, Pete, was that I have been able to us the ISS on iOS - at least to switch on and off a lamp initially. I doubt I'll be able to return values to the app since it has no local server but it might be useful in certain circumstances.

    I got my Sonoffs last week and flashed them all with Easyesp which is a neat solution that is compact enough to allow OTA updating of whatever the final software load is. While you're connected to them, it's worth checking the settings and setting your local wifi credentials over serial.

    Lastly - your email - I didn't send this update that way since you have problems. I wonder if you are able to send and receive ok from a PC (to remove mail server problems from the scope). If all is well there. Also worth having a look to see if Gmail is forwarding anything to somewhere it shouldn't. I wonder if you still have some form of malware aboard? I wonder if it's worth downloading Bitdefender or the like to have a good scan? Lastly, I wonder if you use the auto backup which will restore your settings? Although it's possible that they have already been overwritten by the faulty stuff - might still be worth a try though.

  13. Hi Peter,

    (Sorry I added this comment in the old blog post, it can be deleted if you want)

    I have been following your progress for some time and now have 28 devices in my Imperihome device node. Are you aware if there is any limitation to the number of devices?

    I ask because I am seeing a problem after adding my 28th device and it is only happening to that device. The device is a dimmer, when I send a setting to the node from my Imperihome app, for example 30%, the light is set to 30% as expected. Then, as long as I have the app still running on my phone, it will sent 30% every 120 seconds. The problem does not end there, if I now send 80% the light goes to 80%, but the app will still send 30% every 120 seconds and now 80% every 120 seconds, and if I send 0% the app now started sending 30%, 80% and 0% every 120 seconds. If I force the app to stop then everything is fine, I don’t get any message every 120 seconds.

    Before I contact the people at Imperihome I just wanted to see if anyone has seen this issue and if so then how was it resolved.

    Mike

  14. Trying to follow along, thinking Imperihome might be the UI for MQTT-based home automation I've been looking for.

    Sorry to ask a basic question here, but I took this sample flow and pasted it into node-red, installed and configured Imperihome, and it all worked, with the single RGB light. Great! Now I just wanted to change the name of the light to 'fishtank' or whatever, but no matter what I do, it is ALWAYS called 'RGB Light'. I've restarted node-red, reinstalled Imperihome, removed/added systems, even added another device with a different name. I assume this would all be done by modifying the 'devices' function.

    Always the same result - one RGB light named 'RGB light'. What am I missing?

    1. Imperihome has it's benefits - but if you look at later blogs (this is now old) - Node-Red Dashboard is looking like a better bet in many ways... it's a while since I tried changing names in Imperihome, maybe someone else can comment in here?

      1. Thanks, Peter - it's easy to go down a wrong tributary on a blog this big! I'll stick with node-red; just a rookie in javascript so a bit of a learning curve (which I hate at my age).

    2. Hi - I note your later comment but just in case you decide to persist with Imperihome and assuming I have understood your issue correctly the resolution is simple. Once you have added a widget for the device to a screen, if you do a long press on the widget and then select configuration you can then either choose to hide the device name or set a custom name.

Comments are closed.