Viessmann probably won’t like me for this, but not everybody wants to spend 25€ p.a. for the Comfort & Savings feature offered by them. On the other hand, what I’m describing here, is a homegrown solution with all the usual caveats that come with it. The Viessmann Solution is definitely professional, waterproof and should be stable and working under most circumstances. So, it’s up to you to choose.
In Apple’s App Store I found the free app Locative from Bearologics, which does exactly what I want. It can create up to 20 virtual fences on an iPhone or iPad and send commands to any receiver (server). This can be a server hosted by a web hoster or, as in my case, a self-operated server on a Raspberry Pi. This server should be reachable from the internet, otherwise the whole thing is useless.
The special thing about Locative is that it works completely without a "company in the middle". According to the app store, Bearologic does not collect any user data.
What I’m describing here are the basics up to the point where you get a trigger (one user entering/leaving perimeter) to work with in Node-Red. Any other programming is up to you. E.g. presence detection i.e. nobody at home, reducing/raising the room temperature, etc.
Also, I won’t be going much into detail when describing Locative. In case you’re interested, please refer to my German language Blog https://www.rustimation.eu.
There is practically no documentation available but in general everything is quite straight forward. Locative’s user interface is available in German and English.
Locative has four screens:
Locations Screen: First you have to set up your fence and a perimeter around it. Don’t make it too small, 150 – 2500 m should do the trick. The bigger the circumference, the more time you are giving the heating system to warm up your home.
Then configure your webhooks for enter and exit. Webhook is just another word for a web address which Locative is accessing to trigger an event. We’ll cover that later. See screenshot below. I strongly recommend using the POST method.
The Settings Screen is helpful when you want to send test requests (enter only) to check your connectivity. The Test-Request uses the webhook settings on the same screen.
The Notification Screen which will lateron show the triggered activities.
Finally, the Info Screen has a button to enable logging which is also very helpful during setup.
Node-Red has its own webserver to display content like the edit screens or us/dashboard functionality. It can be reached at port 1880.
A word of caution: what I’m showing here, is threatening your security! If you open your Internet Router for Port 1880, everybody can access your Node Red System and create havoc.
In any case you should secure your Node-Red Editor with a password.
I recommend to experiment with local addresses in this chapter. A more secure way of exposing Node-Red to the Internet will be shown further down.
Let’s create a primitive test-stub in Node-Red:
The minimal Webserver consists of a http in node, a template node containing the response text which is played back by a http response node. The http in node listens to port 1880, hence Locative has to address that port.
Here’s the JSON for it:
[{"id":"c7b69f70141df5bd","type":"tab","label":"PHP-POST Remote","disabled":false,"info":"","env":[]},{"id":"747f98cb845836e5","type":"debug","z":"c7b69f70141df5bd","name":"debug 1","active":true,"tosidebar":true,"console":false,"tostatus":false,"complete":"false","statusVal":"","statusType":"auto","x":420,"y":240,"wires":[]},{"id":"9c4d9ad0982bbaae","type":"http in","z":"c7b69f70141df5bd","name":"","url":"webhook","method":"post","upload":false,"swaggerDoc":"","x":180,"y":240,"wires":[["747f98cb845836e5","77a737f18c60340f"]]},{"id":"77a737f18c60340f","type":"template","z":"c7b69f70141df5bd","name":"Response","field":"payload","fieldType":"msg","format":"html","syntax":"mustache","template":"Data has arrived","output":"str","x":420,"y":180,"wires":[["0c817e6bb44a55a3"]]},{"id":"0c817e6bb44a55a3","type":"http response","z":"c7b69f70141df5bd","name":"","statusCode":"","headers":{},"x":650,"y":180,"wires":[]}]
Go to Locative’s settings screen and enter the IP – using the internal network address - of the machine with Node-Red on it – followed by the path, you wish to access.
Please observe the leading http:// or https:// - without it, Locative won’t work.
If everything works as expected you should get a “Data has arrived” message in Locative after you pressed Send Test Request on the Settings Screen.
As stated before, do NOT expose port 1880 to the Internet. You will be hacked!
Let's take a look at the debug node’s data:
Voila! It already contains all the information we need to build our application. The enter/exit status is contained in msg.payload.trigger.
By using msg.payload.device, you can easily differentiate between users.
That’s it!
It is up to you to develop your desired features around this stub. All sorts of use cases can be imagined. I use it to turn on my external lights when coming home after sundown. Or you could open your garage door or, or ,or.
When controlling your heating system consider the required time to heat up your home. Maybe I’s a good idea to set up a geofence around your workplace. So, when you knock off and leave the premises, your heating is turned up. Likewise the “turn heating down fence” is drawn closely around your home. Etc.
While you can secure the Node-Red editor and admin interface, there is no easy way to secure Node-Red’s user interface (aka dashboard) with username and password.
One solution is to hide the above logic behind a forwarding (or proxy) page, which is accessible through the standard http:// or https:// ports 80 respectively 443. Only this or these ports are exposed to the Internet in your router. That way, Node-Red’s Port 1880 is not exposed. Node-Red stuff is handled internally inside the machine.
I have built a primitive php script that does exactly that. It uses basic authentication so you will have to set the according feature in Locative.
// forwarder.php
<?php
//debug setting
error_reporting (E_ALL | E_STRICT);
ini_set ('display_errors' , 1);
// Ende Debug
// Username and Password are hardcoded - not advised
if((isset($_SERVER['PHP_AUTH_USER'] ) && ( $_SERVER['PHP_AUTH_USER'] == "locative" )) AND
( isset($_SERVER['PHP_AUTH_PW'] ) && ( $_SERVER['PHP_AUTH_PW'] == "supersecret" )))
{
//receiving part
// collect value of input field
$request = file_get_contents('php://input');
$req_dump = print_r( $request, true );
$fp = file_put_contents( 'request.log', $req_dump );
//forwarding part
$ch = curl_init();
curl_setopt($ch, CURLOPT_URL,"http://localhost:1880/webhook");
curl_setopt($ch, CURLOPT_POST, 1);
curl_setopt($ch, CURLOPT_POSTFIELDS, $req_dump);
// receive server response
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
$server_output = curl_exec ($ch);
print_r($server_output);
curl_close ($ch);}
else
{echo "unauthorized";}
?>
So, how does this work?
Locative calls forwarder.php. The script checks whether basic authorization is provided and whether it matches the hard coded username and password. If this is correct, it then receives the data sent by Locative. This data is then forwarded internally via curl to Node-Red listening at port 1880. Node-Red accepts the data and returns the message set in the template node which is the passed on to Locative where it appears as a pop-up Message..
For the sake of simplicity, authentication handling it is straightforward with hardcoded username and password. I do not advise this in real applications! Passwords etc. should not be hardcoded in exposed applications.
In case you’re interested refer to my blog https://www.rustimation.eu or look up php basic authentication here PHP A primer on the basic authorization header and here How to encrypt and decrypt passwords using PHP.
For additional security the standard webserver on your machine - i.e. the one that handles php should work with SSL encryption (https://) – but that is a different topic.
I hope you find this useful. Comments and likes are greatly appreciated.
Christoph Krzikalla