Friday, May 31, 2019

Ping Ping Anybody Home ???

For a complete index of all my stories click this line

A nice feature of the Philips Hue lamps is called Geofencing. This just means that you can instruct the Hue bridge to automatically switch your lights on when you are approiaching your house. So for a time I wondered how they do that. And in fact it is very easy.

It is a technique that can be used for many different purposes. Not only to test if you are around but this also makes it possible to test wether your wireless apparatus are actually functioning.

It's called ping.

Ping

Ping is a network function that sends a command to an IP adress. If the device with that IP adress is connected to the router you will get a response. If the device is off (not connected) then you will get an error back.

It is even possible to ping web-adresses. That way you can see if a certain server on the web is on-line.
If you for example want to test wether this web-log is still on-line you could use something like the next command:
ping("http://lucstechblog.blogspot.nl/")

Ping Ping Anybody Home ?

So how is that going to tell me wether anybody is home or nearby. Well simple. Most people I know always carry their mobile phone around. So do I. And most of the time wifi is turned on. So if I give my phone, and for that my girlfriends phone etc, a fixed IP adress in my router I can Ping that IP adress et voila.

Give your home mates a fixed IP adress.

Start with opening the IP adress of your router in your browser. In my case my router has IP-adress 192.168.1.1 Your's may vary so look it up in the manual.



Enter the ip-adress in your browser and if you have a Zyxell router like I do you will be presented the above screen. Different routers give different results, but it should be easy to find the page that shows all connected devices.

As you can see I have given all my networked devices meaningfull names. So let's look at the details of my phone.



First you can see my phones IP-adress and as you can see I checked Static DHCP. This makes sure that everytime my phone connects to the router it will get the same IP adress.
Do this for all the phones and wireless apparatus in your home.

Ping ??

Ping is a wifi function. In some languages it is build in (yes in Basic) and in some languages it is not. What I wanted is to have my ESP Ping my devices and depending on the outcome switchs led's (relay's) on or off.

Standard C++ (Arduino) for the ESP has all kinds of Wifi functions build in but no Ping.

Fortunately Daniele Calanardi has build a library that we can use. You can download that library from the following link: https://github.com/dancol90/ESP8266Ping

Unpack the library and place it in your \Arduino\libraries folder and start the Arduino IDE.

Circuit



The hardware is simple just an ESP8266 (I used a NodeMCU) and 4 leds connected through 220 Ohm delimiting resistors. The led's are attached to D0, D1, D2 and D4.

The Arduino source



/*
 * Anybody Home ??? 
 * This program tests IP numbers with PING to see if they are
 * active. If so the Led will be on if the IP number is not
 * active the Led will be off
 * This way we can check activity and person presence
 * Written by Luc Volders
 */

#include 

<ESP8266WiFi.h>
#include 

<ESP8266Ping.h>

const char* ssid = "XXXXXXXXX";
const char* password = "YYYYYYYYY";

const IPAddress thermometer(192, 168, 1, 65);
const IPAddress domoticz(192, 168, 1, 66);
const IPAddress Lucsphone(192, 168, 1, 70);
const IPAddress elsphone(192, 168, 1, 72);

void setup() 
{
  pinMode(D0,OUTPUT);
  digitalWrite(D0,LOW);
  pinMode(D1,OUTPUT);
  digitalWrite(D1,LOW);
  pinMode(D2,OUTPUT);
  digitalWrite(D2,LOW);
  pinMode(D4,OUTPUT);
  digitalWrite(D4,LOW);
  delay(10);

  // Start by connecting to our WiFi network

  WiFi.begin(ssid, password);
  
  while (WiFi.status() != WL_CONNECTED)

 
  {
    delay(100);
  }
}

void loop() 
{  
  if(Ping.ping(thermometer)) 
    {
      digitalWrite(D0,HIGH);
    } 
  else 
    {
      digitalWrite(D0,LOW);
    } 
  if(Ping.ping(domoticz)) 
    {
      digitalWrite(D1,HIGH);
    } 
  else 
    {
      digitalWrite(D1,LOW);
    }  
    if(Ping.ping(Lucsphone)) 
    {
      digitalWrite(D2,HIGH);
    } 
  else 
    {
      digitalWrite(D2,LOW);
    }  
    if(Ping.ping(elsphone)) 
    {
      digitalWrite(D2,HIGH);
    } 
  else 
    {
      digitalWrite(D4,LOW);
    }  
  delay(1000);
}
    


Let's look closer to the program.

#include <ESP8266WiFi.h>
#include <ESP8266Ping.h>

to activate the wifi functions of the ESP we need to include the Wifi library and for Ping we need to include the ESP8266Ping.h library.

const char* ssid     = "XXXXXXXXX";
const char* password = "YYYYYYYYY";

Fill in your router's credentials so you will connect to your network automatically.

const IPAddress thermometer(192, 168, 1, 65);
const IPAddress domoticz(192, 168, 1, 66);
const IPAddress android(192, 168, 1, 70);
const IPAddress elsphone(192, 168, 1, 75);

Look in your router for the IP adresses of your Wifi Devices and replace the ones I have used.

The rest of the program is straighforward.

  if(Ping.ping(Lucsphone))    
    {                         
      digitalWrite(D2,HIGH) ; 
    }                         
  else                        
    {                         
      digitalWrite(D2,LOW);   
    }                         


In the loop all devices are pinged. In this part the IP number of my phone is pinged. If it is present Ping will respond with a 1. If I am not at home Ping will respond with a 0 and the led will be set on or off accordingly.

This can be optimized :

digitalWrite(D2,Ping.ping(Lucsphone));

However I wanted the code to be easy to follow for less experienced C++ programmers.

Basic program

Naturally (I know some loathe this) I wrote the same program in ESP-Basic which is my favorite rapid software devellopment platform. So I hereby give you the simple code that does the same as the C++ program:



io(po,D0,0)
io(po,D1,0)
io(po,D2,0)
io(po,D4,0)

timer 1000, 

[testping]

wait

[testping]

io(po,D0,ping("192.168.1.65")) 'thermometer

io(po,D1,ping("192.168.1.66")) 'domoticz

io(po,D2,ping("192.168.1.70")) 'luc's phone

io(po,D4,ping("192.168.1.72")) 'els phone

wait


Let us look at some details.

io(po,D0,0)
io(po,D1,0)
io(po,D2,0)
io(po,D4,0)

These lines set all the leds in the initial state which is off.

timer 1000, [testping]

This line initiates a timer that every second (1000 miliseconds) jumps to the routine testping.

io(po,D2,ping("192.168.1.70")) 'luc's phone

This line actually tests whether my phone is detected by the router so if I am in. Depending on the
feedback it sets the led on or off. Replace the IP numbers with your own.

That's all folks.

Just for usability I modified the program so it has a webpage on which the information is displayed as wellas leds giving the information. So if you are around the ESP the leds will show what's happening and if you are not in its neighbourhood you can check the webpage.


io(po,D0,0)
io(po,D1,0)
io(po,D2,0)
io(po,D4,0)

timer 1000, [testping]

wprint |<body style="background-color:powderblue;">|
wprint |<H1><span style="color: red;">|
wprint "Anybody Home ??"
wprint "</H1>"
wprint "<h3>Thermometer  "

textbox therm
cssid htmlid(), "background-color:powderblue;border-style: hidden;font-size: 16px;display:block;width:80px"

wprint "<br>"
wprint "Domoticz         "
textbox domo
cssid htmlid(), "background-color:powderblue;border-style: hidden;font-size: 16px;display:block;width:80px"

wprint "<br>"
wprint "Luc's phone      "
textbox lucphone
cssid htmlid(), "background-color:powderblue;border-style: hidden;font-size: 16px;display:block;width:80px"

wprint "<br>"
wprint "Els phone        "
textbox elsphone
cssid htmlid(), "background-color:powderblue;border-style: hidden;font-size: 16px;display:block;width:80px"

wprint "<br>"
button "QUIT", [progend]
wait

[testping]
therm = ping("192.168.1.65")
if therm = 1 then
io(po,D0,1)
therm = "available"
else
io(po,D0,0)
therm = "off line"
endif


domo = ping("192.168.1.66")
if domo = 1 then
io(po,D1,1)
domo = "available"
else
io(po,D1,0)
domo = "Domoticz off line"
endif

lucphone = ping("192.168.1.70")
if lucphone = 1 then
io(po,D2,1)
lucphone = "at home"
else
io(po,D2,0)
lucphone = "he's not in"
endif

elsphone = ping("192.168.1.72")
if elsphone = 1 then
io(po,D4,1)
elsphone = "available"
else
io(po,D4,0)
elsphone = "she's out"
endif

wait

[progend]
io(po,D0,0)
io(po,D1,0)
io(po,D2,0)
io(po,D4,0)
end

The result.





Modifications.

Use your imagination.

You can send the information to cloud-based IOT servers like thingspeak (look for a tutorial here:
https://lucstechblog.blogspot.nl/2017/11/thingspeak.html )

Replace the leds with relays so the lamps will go on if you approach your house.

Send the information to your home-automation system (like Domoticz which I am using) so
it can alter your thermostat settings or switch on your lights etc.

Till next time.
 

The next few weeks I am off on a long-earned holliday. There is however enough material on this web-log to get you going and start experimenting. So till July and remember:

Have fun !!

Luc Volders