i have something for you.
Many people use the phyton ping script from wiki.
https://www.domoticz.com/wiki/Presence_detection
But i missed some functions. So it was time to improve it.
New Functions:
- Sync Status
Old script does only set the device status. If the switch was directly changed in domoticz, the script doesn't get the informations back. If device is switched off in domoticz, then the script will it switch back to on.
You can control if the script should directly switch back to on or wait for x rounds or disable sync.
Control flags inside the script: syncstate and waitcount
- Support for dimmers
Old script set the dimmer level/status always back to on or off
- Ignore the on/off action in device
You have to start the script with a further parameter (NoOnOffEvent).
%Host %Switchid %Interval %Cooldownperiod %NoOnOffEvent
1 = NoOnOffEvent, 0 = Default
Important: Lua eventsystem does always get a device change
- New Action Variable
In somecases you want to switch a device without the eventsystem (lua/blocky/...).
If the script will change a device status then first a variable will be updated/created and set to 1.
You can use this variable in lua/blocky/... . If variable = 1 then "do nothing".
But you have to set the variable back to 0.
You can enable/disable the variable inside the script- ping_domo_variable = True
Variablename: Ping_IPADDRESS
- Installation
Open crontab with "crontab -e" in ssh and add your lines with your needed ips
# Device 1
*/10 * * * * sudo /home/pi/domoticz/scripts/custom/check_device_online.py 192.168.178.3 325 30 60 0
# Device 2
*/10 * * * * sudo /home/pi/domoticz/scripts/custom/check_device_online.py 192.168.178.2 327 30 30 0
Code: Select all
#!/usr/bin/python
# Title: check_device_online.py
# Author: Chopper_Rob, modified by borcon
#
# Date: 19-07-2017
# Version : 1.7.0
import sys
import datetime
import time
import os
import subprocess
import urllib2
import json
import base64
# Settings for the domoticz server
domoticzserver="127.0.0.1:8080"
domoticzusername = ""
domoticzpassword = ""
domoticzpasscode = ""
# Create in domoticz a variable with the name "Ping_YOURIPADDRESS"
# If the script will change a switch in domoticz, then
# first the variable will be set from 0 to 1.
# Then you can use the variable in lua
ping_domo_variable = True
# Sync device state with domoticz.
# Time to wait to set correct device status in domoticz, if domoticz state and last reported state are different
# This may happens, if someone changes the dummy device state in domoticz
# %Interval * waitcount = is the time to wait to set the device status
# Example 10 seconds interval * 5 = 50 seconds
syncstate = 1
waitcount = 2
# If enabled. The script will log to the file _.log
# Logging to file only happens after the check for other instances, before that it only prints to screen.
log_to_file = True
# The script supports two types to check if another instance of the script is running.
# One will use the ps command, but this does not work on all machine (Synology has problems)
# The other option is to create a pid file named _.pid. The script will update the timestamp
# every interval. If a new instance of the script spawns it will check the age of the pid file.
# If the file doesn't exist or it is older then 3 * Interval it will keep running, otherwise is stops.
# Please chose the option you want to use "ps" or "pid", if this option is kept empty it will not check and just run.
check_for_instances = "pid"
# DO NOT CHANGE BEYOND THIS LINE
if len(sys.argv) != 6 :
print ("Not enough parameters. Needs %Host %Switchid %Interval %Cooldownperiod %NoOnOffEvent.")
sys.exit(0)
device=sys.argv[1]
switchid=sys.argv[2]
interval=sys.argv[3]
cooldownperiod=sys.argv[4]
noonoffevent=int(sys.argv[5])
previousstate=-1
lastsuccess=datetime.datetime.now()
lastreported=-1
base64string = base64.encodestring('%s:%s' % (domoticzusername, domoticzpassword)).replace('\n', '')
domoticzurl = 'http://'+domoticzserver+'/json.htm?type=devices&filter=all&used=true&order=Name'
wait = 0
if check_for_instances.lower() == "pid":
#pidfile = sys.argv[0] + '_' + sys.argv[1] + '.pid'
pidfile = '/run/check_device_online.py_' + sys.argv[1] + '.pid'
if os.path.isfile( pidfile ):
print datetime.datetime.now().strftime("%Y/%m/%d %H:%M:%S") + "- pid file exists"
if (time.time() - os.path.getmtime(pidfile)) < (float(interval) * 3):
print datetime.datetime.now().strftime("%Y/%m/%d %H:%M:%S") + "- script seems to be still running, exiting"
print datetime.datetime.now().strftime("%Y/%m/%d %H:%M:%S") + "- If this is not correct, please delete file " + pidfile
sys.exit(0)
else:
print datetime.datetime.now().strftime("%Y/%m/%d %H:%M:%S") + "- Seems to be an old file, ignoring."
else:
open(pidfile, 'w').close()
if check_for_instances.lower() == "ps":
if int(subprocess.check_output('ps x | grep \'' + sys.argv[0] + ' ' + sys.argv[1] + '\' | grep -cv grep', shell=True)) > 2 :
print (datetime.datetime.now().strftime("%Y/%m/%d %H:%M:%S") + "- script already running. exiting.")
sys.exit(0)
def log(message):
print message
if log_to_file == True:
logfile = open(sys.argv[0] + '_' + sys.argv[1] + '.log', "a")
logfile.write(message + "\n")
logfile.close()
def domoticzstatus ():
json_object = json.loads(domoticzrequest(domoticzurl))
status = 0
switchfound = False
if json_object["status"] == "OK":
for i, v in enumerate(json_object["result"]):
if json_object["result"][i]["idx"] == switchid:
switchfound = True
if json_object["result"][i]["Status"] == "On":
status = 1
if "Set Level" in json_object["result"][i]["Status"]:
status = 1
if json_object["result"][i]["Status"] == "Off":
status = 0
if switchfound == False: print (datetime.datetime.now().strftime("%Y/%m/%d %H:%M:%S") + "- Error. Could not find switch idx in Domoticz response. Defaulting to switch off.")
return status
def domoticzrequest (url):
request = urllib2.Request(url)
request.add_header("Authorization", "Basic %s" % base64string)
response = urllib2.urlopen(request)
return response.read()
log (datetime.datetime.now().strftime("%Y/%m/%d %H:%M:%S") + "- script started.")
lastreported = domoticzstatus()
if lastreported == 1 :
log (datetime.datetime.now().strftime("%Y/%m/%d %H:%M:%S") + "- according to domoticz, " + device + " is online")
if lastreported == 0 :
log (datetime.datetime.now().strftime("%Y/%m/%d %H:%M:%S") + "- according to domoticz, " + device + " is offline")
if ping_domo_variable == True:
# Create variable in domoticz, if already exist, no problem
domoticzrequest("http://" + domoticzserver + "/json.htm?type=command¶m=saveuservariable&vname=Ping_" + device + "&vtype=0&vvalue=0" + "&passcode=" + domoticzpasscode)
# Set variable in domoticz to 0
domoticzrequest("http://" + domoticzserver + "/json.htm?type=command¶m=updateuservariable&vname=Ping_" + device + "&vtype=0&vvalue=0" + "&passcode=" + domoticzpasscode)
while 1==1:
#currentstate = subprocess.call('ping -q -c1 -W 1 '+ device + ' > /dev/null', shell=True)
currentstate = subprocess.call('sudo arping -q -c1 -W 1 '+ device + ' > /dev/null', shell=True)
# currentstate --> 1 = offline , 0 = online
# previousstate --> 1 = offline , 0 = online
# lastreported --> 0 = offline , 1 = online
# domoticzstatus() --> 0 = offline , 1 = online
#log ("currentstate:" + str(currentstate))
#log ("previousstate: " + str(previousstate))
#log ("lastreported: " + str(lastreported))
#log ("Domoticz State: " + str(domoticzstatus()))
#log (" ")
if currentstate == 0 : lastsuccess=datetime.datetime.now()
if currentstate == 0 and currentstate != previousstate and lastreported == 1 :
log (datetime.datetime.now().strftime("%Y/%m/%d %H:%M:%S") + "- " + device + " online, no need to tell domoticz")
if currentstate == 0 and currentstate != previousstate and lastreported != 1 :
if domoticzstatus() == 0 :
log (datetime.datetime.now().strftime("%Y/%m/%d %H:%M:%S") + "- " + device + " online, tell domoticz it's back")
if ping_domo_variable == True:
domoticzrequest("http://" + domoticzserver + "/json.htm?type=command¶m=updateuservariable&vname=Ping_" + device + "&vtype=0&vvalue=1" + "&passcode=" + domoticzpasscode)
if noonoffevent == 0 :
domoticzrequest("http://" + domoticzserver + "/json.htm?type=command¶m=switchlight&idx=" + switchid + "&switchcmd=On&level=0" + "&passcode=" + domoticzpasscode)
else:
domoticzrequest("http://" + domoticzserver + "/json.htm?type=command¶m=udevice&idx=" + switchid + "&nvalue=1&svalue=On" + "&passcode=" + domoticzpasscode)
else:
log (datetime.datetime.now().strftime("%Y/%m/%d %H:%M:%S") + "- " + device + " online, but domoticz already knew")
lastreported=1
wait = 0
if currentstate == 1 and currentstate != previousstate :
log (datetime.datetime.now().strftime("%Y/%m/%d %H:%M:%S") + "- " + device + " offline, waiting for it to come back")
if currentstate == 1 and (datetime.datetime.now()-lastsuccess).total_seconds() > float(cooldownperiod) and lastreported != 0 :
if domoticzstatus() == 1 :
log (datetime.datetime.now().strftime("%Y/%m/%d %H:%M:%S") + "- " + device + " offline, tell domoticz it's gone")
if ping_domo_variable == True:
domoticzrequest("http://" + domoticzserver + "/json.htm?type=command¶m=updateuservariable&vname=Ping_" + device + "&vtype=0&vvalue=1" + "&passcode=" + domoticzpasscode)
if noonoffevent == 0 :
domoticzrequest("http://" + domoticzserver + "/json.htm?type=command¶m=switchlight&idx=" + switchid + "&switchcmd=Off&level=0" + "&passcode=" + domoticzpasscode)
else:
domoticzrequest("http://" + domoticzserver + "/json.htm?type=command¶m=udevice&idx=" + switchid + "&nvalue=0&svalue=Off" + "&passcode=" + domoticzpasscode)
else:
log (datetime.datetime.now().strftime("%Y/%m/%d %H:%M:%S") + "- " + device + " offline, but domoticz already knew")
lastreported=0
wait = 0
if syncstate == 1 and currentstate == previousstate :
if lastreported != domoticzstatus() :
wait += 1
if waitcount <= wait :
if currentstate == 1 :
log (datetime.datetime.now().strftime("%Y/%m/%d %H:%M:%S") + "- " + device + " offline, domoticz state and last reported state are different, time to correct state to offline")
if ping_domo_variable == True:
domoticzrequest("http://" + domoticzserver + "/json.htm?type=command¶m=updateuservariable&vname=Ping_" + device + "&vtype=0&vvalue=1" + "&passcode=" + domoticzpasscode)
if noonoffevent == 0 :
domoticzrequest("http://" + domoticzserver + "/json.htm?type=command¶m=switchlight&idx=" + switchid + "&switchcmd=Off&level=0" + "&passcode=" + domoticzpasscode)
else:
domoticzrequest("http://" + domoticzserver + "/json.htm?type=command¶m=udevice&idx=" + switchid + "&nvalue=0&svalue=Off" + "&passcode=" + domoticzpasscode)
lastreported=0
wait = 0
else:
log (datetime.datetime.now().strftime("%Y/%m/%d %H:%M:%S") + "- " + device + " online, domoticz state and last reported state are different, time to correct state to online")
if ping_domo_variable == True:
domoticzrequest("http://" + domoticzserver + "/json.htm?type=command¶m=updateuservariable&vname=Ping_" + device + "&vtype=0&vvalue=1" + "&passcode=" + domoticzpasscode)
if noonoffevent == 0 :
domoticzrequest("http://" + domoticzserver + "/json.htm?type=command¶m=switchlight&idx=" + switchid + "&switchcmd=On&level=0" + "&passcode=" + domoticzpasscode)
else:
domoticzrequest("http://" + domoticzserver + "/json.htm?type=command¶m=udevice&idx=" + switchid + "&nvalue=1&svalue=On" + "&passcode=" + domoticzpasscode)
lastreported=1
wait = 0
time.sleep (float(interval))
previousstate=currentstate
if check_for_instances.lower() == "pid": open(pidfile, 'w').close()
borcon