Last active
November 1, 2019 19:05
-
-
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)
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
# 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