Skip to content

Instantly share code, notes, and snippets.

@saper-2
Last active November 1, 2019 19:05
Show Gist options
  • Save saper-2/3595016aab7c2454c86e256374547a5f to your computer and use it in GitHub Desktop.
Save saper-2/3595016aab7c2454c86e256374547a5f to your computer and use it in GitHub Desktop.
Proof of concept plugin for domoticz to check if remote host is alive (needs some finshing)
# Remote IP Checker
#
# Author: saper_2, 2019
#
# version 0.0.1 : Initial release, based on 'Wan IP Checker v.1.2.5' by ycahome (https://www.domoticz.com/forum/viewtopic.php?t=16266)
#
#
#
"""
<plugin key="REMOTE-IP-CHECKER" name="Remote IP Checker" author="saper_2" version="0.1" externallink="">
<description>
<h2>Remote IP Checker v.0.1</h2><br/>
Based on 'Wan IP Checker v.1.2.5' by ycahome (https://www.domoticz.com/forum/viewtopic.php?t=16266)
</description>
<params>
<param field="Address" label="Check Remote hostname" width="200px" required="true" default="https://google.com/"/>
<param field="Mode1" label="Check Interval(seconds)" width="75px" required="true" default="60"/>
<param field="Mode3" label="Notifications" width="75px">
<options>
<option label="Notify" value="Notify"/>
<option label="Disable" value="Disable" default="true" />
</options>
</param>
<param field="Mode6" label="Debug" width="75px">
<options>
<option label="True" value="Debug"/>
<option label="False" value="Normal" default="true" />
</options>
</param>
</params>
</plugin>
"""
import Domoticz
import hmac
import hashlib
import time
import urllib
import urllib.request
import urllib.error
import urllib.parse
import socket
import os
#from urllib2 import urlopen
from datetime import datetime, timedelta
class BasePlugin:
enabled = False
pluginState = "Not Ready"
sessionCookie = ""
privateKey = b""
socketOn = "TRUE"
def __init__(self):
self.debug = False
self.error = False
self.nextpoll = datetime.now()
self.pollinterval = 60 #Time in seconds between two polls
return
def onStart(self):
Domoticz.Debug("onStart called")
self.pollinterval = int(Parameters["Mode1"]) #Time in seconds between two polls
if Parameters["Mode6"] == 'Debug':
self.debug = True
Domoticz.Debugging(1)
DumpConfigToLog()
else:
Domoticz.Debugging(0)
Domoticz.Log("Starting plugin... Checking URL: "+ Parameters["Address"])
#if 'remoIPaddress' not in Images: Domoticz.Image('remoIPaddress.zip').Create()
#Domoticz.Debug("Number of icons loaded = " + str(len(Images)))
#for image in Images:
# Domoticz.Debug("Icon " + str(Images[image].ID) + " " + Images[image].Name)
# create the mandatory child device if it does not yet exist
if 1 not in Devices:
Domoticz.Device(Name="Remote IP Alert", Unit=1, TypeName="Alert", Used=1).Create()
Domoticz.Device(Name="Remote IP 1", Unit=1, TypeName="Text", Used=1).Create()
Domoticz.Log("Device created.")
Domoticz.Heartbeat(int(Parameters["Mode1"]))
def onStop(self):
Domoticz.Log("Plugin is stopping.")
Domoticz.Debugging(0)
def get_host_ip(self, host):
try:
urlp = urllib.parse.urlparse(host)
hip = socket.gethostbyname(urlp.netloc)
return hip
except:
#print("Unable to get Hostname and IP")
Domoticz.Debug("Unable to get IP")
return "0.0.0.0"
def ping_host(self, host):
"""
Ping host using system ping command. Returns 0=host alive, 1=dead, 2=call system command failed.
"""
try:
urlp = urllib.parse.urlparse(host)
resp = os.system("ping -c 1 " + urlp.netloc)
if (resp == 0):
return 0
else:
return 1
except:
return 2
def onHeartbeat(self):
Domoticz.Debug("onHeartbeat called")
if Devices[1].nValue == 2:
Domoticz.Log("Reverting Remote IP Change status to normal.")
Devices[1].Update(nValue=1,sValue=Devices[1].sValue)
url = Parameters["Address"]
if mid(url,0,7)!= "http://" and mid(url,0,8)!= "https://" :
Domoticz.Error("Check my IP URL Prefix is wrong: 'http://' or 'https://' required.")
return
remoIP = self.get_host_ip(url)
pingres = self.ping_host(url)
if (pingres == 0):
if remoIP != "" and len(remoIP)<16:
#Domoticz.Debug("IP Discovery Site's response len is:"+ str(len(remoIP)))
Domoticz.Debug("Remote IP retrieved:" + remoIP)
OldRemoIP = Devices[1].sValue
OldRemoIP = OldRemoIP.strip(' \t\n\r')
Domoticz.Debug("Previous remote IP:" + OldRemoIP)
CurMin = str(datetime.now().minute)
if len(CurMin) == 1:
CurMin = "0" + CurMin
if Parameters["Mode6"] == 'Debug' and (mid(CurMin,1,1) == "3" or mid(CurMin,1,1) == "5" or mid(CurMin,1,1) == "0"):
Domoticz.Error("Debug is on. Trigering IP Change:")
OldRemoIP = "0.0.0.0"
if OldRemoIP != remoIP:
Domoticz.Log("Remote IP Updated to:" + remoIP)
Devices[1].Update(2,remoIP)
if Parameters["Mode3"] == 'Notify':
Domoticz.Log("Running Remote IP Notifications")
Domoticz.Debug("Remote IP retrieved:" + remoIP)
ServerURL = "http://127.0.0.1:8080/json.htm?param=sendnotification&type=command"
Domoticz.Debug("ConstructedURL ServerURL is:" + ServerURL)
MailDetailsURL = "&subject=Remote-IP-Changed&body=" + remoIP + "&subsystem=email"
notificationURL = ServerURL + MailDetailsURL
Domoticz.Debug("ConstructedURL is:" + notificationURL)
try:
response = urllib.request.urlopen(notificationURL, timeout = 30).read()
except urllib.error.HTTPError as err1:
Domoticz.Error("HTTP Request error: " + str(err1) + " URL: " + notificationURL)
return
Domoticz.Debug("Notification URL is :" + str(notificationURL))
else:
Domoticz.Log("Remote IP the same. Skipping")
#Devices[1].Update(1,remoIP, Images["remoIPaddress"].ID)
else:
Domoticz.Error("IP Discovery error.")
else:
# this should set icon "warning" (or yellow??)
Devices[1].Update(nValue=0,sValue="Ping fail ({}).".format(pingres))
# set displayed IP to 0.0.0.0 - how don't know: never written domoticz plugin
Domoticz.Error("Checking host alive error. ({0})".format(pingres))
global _plugin
_plugin = BasePlugin()
def onStart():
global _plugin
_plugin.onStart()
def onStop():
global _plugin
_plugin.onStop()
def onHeartbeat():
global _plugin
_plugin.onHeartbeat()
# Generic helper functions
def DumpConfigToLog():
for x in Parameters:
if Parameters[x] != "":
Domoticz.Debug( "'" + x + "':'" + str(Parameters[x]) + "'")
Domoticz.Debug("Device count: " + str(len(Devices)))
for x in Devices:
Domoticz.Debug("Device: " + str(x) + " - " + str(Devices[x]))
Domoticz.Debug("Device ID: '" + str(Devices[x].ID) + "'")
Domoticz.Debug("Device Name: '" + Devices[x].Name + "'")
Domoticz.Debug("Device nValue: " + str(Devices[x].nValue))
Domoticz.Debug("Device sValue: '" + Devices[x].sValue + "'")
return
#
# Parse an int and return None if no int is given
#
def parseIntValue(s):
try:
return int(s)
except:
return None
def mid(s, offset, amount):
return s[offset:offset+amount]
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment