Skip to content

Commit

Permalink
Adding Notifier plugin support
Browse files Browse the repository at this point in the history
  • Loading branch information
enesbcs committed Jun 25, 2019
1 parent 8b3c49b commit 730fe67
Show file tree
Hide file tree
Showing 9 changed files with 380 additions and 8 deletions.
27 changes: 27 additions & 0 deletions RPIEasy.py
Original file line number Diff line number Diff line change
Expand Up @@ -162,6 +162,33 @@ def CPluginInit():
return 0

def NPluginInit():
tarr = []
filenames = glob.glob('_N*.py')
filenames.sort()
for fname in filenames:
tarr = [0,0,0]
tarr[0] = fname
with open(fname,"r") as fcont:
for line in fcont:
if "NPLUGIN_ID" in line:
tarr[1] = line[line.find("=")+1:].strip().replace('"',"")
if "NPLUGIN_NAME" in line:
tarr[2] = line[line.find("=")+1:].strip().replace('"',"")
break
tarr[0] = tarr[0].replace(".py","")
rpieGlobals.notifierselector.append(tarr) # create list for form select

#print("Load controllers from file")
Settings.loadnotifiers()

for x in range(0,len(Settings.Notifiers)):
if (Settings.Notifiers[x]) and type(Settings.Notifiers[x]) is not bool: # device exists
try:
if (Settings.Notifiers[x].enabled): # device enabled
Settings.Notifiers[x].plugin_init(None) # init plugin at startup
except:
pass

return 0

def RulesInit():
Expand Down
25 changes: 25 additions & 0 deletions Settings.py
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@
settingsfile = 'data/settings.json'
tasksfile = 'data/tasks.json'
controllersfile = 'data/controllers.json'
notifiersfile = 'data/notifiers.json'
pinoutfile = 'data/pinout.json'
netdevfile = 'data/netdev.json'
netmanfile = 'data/netman.json'
Expand Down Expand Up @@ -44,6 +45,7 @@

Tasks = [False]
Controllers = [False]
Notifiers = [False]

NetworkDevices = []
NetMan = None
Expand Down Expand Up @@ -232,3 +234,26 @@ def saveadvsettings():
except:
success = 0
return success

def savenotifiers():
global Notifiers, notifiersfile
success = 1
try:
f = open(notifiersfile,'w')
settingjson = jsonpickle.encode(Notifiers,max_depth=2) # Restrict Jsonpickle to encode vars at first object
f.write(settingjson)
except:
success = 0
return success

def loadnotifiers():
global Notifiers, notifiersfile
success = 1
try:
f = open(notifiersfile)
settingjson = f.read()
Notifiers = jsonpickle.decode(settingjson)
except Exception as e:
# print("Critical Jsonpickle error:",str(e))
success = 0
return success
3 changes: 1 addition & 2 deletions _C002_DomoMQTT.py
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,6 @@
#
# Copyright (C) 2018-2019 by Alexander Nagy - https://bitekmindenhol.blog.hu/
#
# missing! complete it based on c014!
import controller
import paho.mqtt.client as mqtt
import json
Expand Down Expand Up @@ -331,7 +330,7 @@ def senddata(self,idx,sensortype,value,userssi=-1,usebattery=-1,tasknum=-1,chang
misc.addLog(rpieGlobals.LOG_LEVEL_ERROR,"MQTT idx error, sending failed.")
else:
misc.addLog(rpieGlobals.LOG_LEVEL_ERROR,"MQTT not connected, sending failed.")
if (time.time()-self.lastreconnect)>30:
if ((time.time()-self.lastreconnect)>30) and (self.connectinprogress==0):
self.connect()

def on_connect(self):
Expand Down
10 changes: 8 additions & 2 deletions _C013_ESPEasyP2P.py
Original file line number Diff line number Diff line change
Expand Up @@ -277,10 +277,16 @@ def encode(self,ptype):
tbuf = [255,1]
ta = self.infopacket["mac"].split(":")
for m in ta:
tbuf.append(int(m,16))
try:
tbuf.append(int(m,16))
except:
tbuf.append(0)
ta = self.infopacket["ip"].split(".")
for m in ta:
tbuf.append(int(m))
try:
tbuf.append(int(m))
except:
tbuf.append(255)
tbuf.append(int(self.infopacket["unitno"]))
tbuf.append(int(self.infopacket["build"]%256))
tbuf.append(int(self.infopacket["build"]/256))
Expand Down
117 changes: 117 additions & 0 deletions _N001_Email.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,117 @@
#!/usr/bin/env python3
#############################################################################
################### Email notifier plugin for RPIEasy #######################
#############################################################################
#
# Copyright (C) 2019 by Alexander Nagy - https://bitekmindenhol.blog.hu/
#
import nplugin
import webserver
import rpieGlobals
import misc
import smtplib
import commands

class Plugin(nplugin.NPluginProto):
NPLUGIN_ID = 1
NPLUGIN_NAME = "Email (SMTP)"

def __init__(self,nindex): # general init
nplugin.NPluginProto.__init__(self,nindex)
self.server = "0.0.0.0"
self.port = 25 #25/465
self.security = 0 # 0:plain,1:ssl
self.sender = ""
self.receiver = ""
self.login = ""
self.passw = ""
self.subject ="" # template
self.body="" # template

def getuniquename(self):
return self.server

def plugin_init(self,enableplugin=None):
nplugin.NPluginProto.plugin_init(self,enableplugin)
if self.passw=="*****":
self.passw=""

def webform_load(self): # create html page for settings
webserver.addFormTextBox("Server","server",self.server,64)
options = ["Plain","SSL"]
optionvalues = [0,1]
webserver.addFormSelector("Protocol","security",len(options),options,optionvalues,None,self.security)
webserver.addFormNumericBox("Port","port",self.port,1,65535)
webserver.addFormTextBox("Sender","sender",self.sender,64)
webserver.addFormTextBox("Receiver","receiver",self.receiver,64)
webserver.addFormTextBox("SMTP login name","login",self.login,64)
webserver.addFormPasswordBox("STMP password","passw",self.passw,64)
webserver.addFormTextBox("Subject","subject",self.subject,64)
webserver.addHtml("<TR><TD>Body:<TD><textarea name='body' rows='5' cols='80' size=512 wrap='off'>")
webserver.addHtml(str(self.body))
webserver.addHtml("</textarea>")
return True

def webform_save(self,params): # process settings post reply
self.server = webserver.arg("server",params)
par1 = webserver.arg("security",params)
try:
par1=int(par1)
except:
par1=0
if par1<0 or par1>1:
par1=0
self.security=par1
par1 = webserver.arg("port",params)
try:
par1=int(par1)
except:
par1=25
if par1<1 or par1>65534:
par1=25
self.port=par1
self.sender = webserver.arg("sender",params)
self.receiver = webserver.arg("receiver",params)
self.login = webserver.arg("login",params)
passw = webserver.arg("passw",params)
if "**" not in passw:
self.passw = passw
self.subject = webserver.arg("subject",params)
self.body = webserver.arg("body",params)
return True

def notify(self,pmsg=""):
if self.initialized==False or self.enabled==False:
return False
if self.sender=="" or self.receiver=="":
return False
message = ("From: %s\r\nTo: %s\r\n" % (self.sender,self.receiver))
message += "Subject: "+self.mailparse(self.subject)+"\r\n\r\n"
if pmsg=="":
message += self.mailparse(self.body)
else:
message += self.mailparse(pmsg)
if self.server=="0.0.0.0" or self.server=="":
return False
try:
if self.security==0:
smtpObj = smtplib.SMTP(self.server, self.port)
elif self.security==1:
smtpObj = smtplib.SMTP_SSL(self.server, port=self.port, timeout=2)
if self.login!="" and self.passw!="":
smtpObj.login(self.login,self.passw)
smtpObj.sendmail(self.sender, self.receiver, message)
smtpObj.quit()
misc.addLog(rpieGlobals.LOG_LEVEL_INFO,"Mail sent!")
return True
except Exception as e:
misc.addLog(rpieGlobals.LOG_LEVEL_ERROR,str(e))
return False

def mailparse(self,ostr):
cl, st = commands.parseruleline(ostr)
if st=="CMD":
resstr=str(cl)
else:
resstr=str(ostr)
return resstr
29 changes: 28 additions & 1 deletion commands.py
Original file line number Diff line number Diff line change
Expand Up @@ -67,7 +67,9 @@ def doExecuteCommand(cmdline,Parse=True):
else:
retval = cmdline
cmdarr = retval.split(",")
if (" " in retval) and ("," in retval): # workaround for possible space instead comma problem
if (" " in retval) and not("," in retval):
cmdarr = retval.split(" ")
elif (" " in retval) and ("," in retval): # workaround for possible space instead comma problem
fsp = retval.find(" ")
fco = retval.find(",")
if fsp<fco:
Expand Down Expand Up @@ -350,6 +352,19 @@ def doExecuteCommand(cmdline,Parse=True):
os.kill(os.getpid(), signal.SIGINT)
commandfound = True
return commandfound

elif cmdarr[0] == "notify":
try:
plugin = int(cmdarr[1])
except:
plugin = 0
data = ""
if len(cmdarr)>1 and plugin>0:
sepp = ( len(cmdarr[0]) + len(cmdarr[1])+ 2 )
data = cmdline[sepp:].replace("==","=")
commandfound = doExecuteNotification(plugin-1,data)
return commandfound

if commandfound==False:
commandfound = doExecutePluginCommand(retval)
if commandfound==False:
Expand Down Expand Up @@ -379,6 +394,18 @@ def doExecutePluginCommand(cmdline):
return retvalue
return retvalue

def doExecuteNotification(num,cmdline):
retvalue = False
if len(Settings.Notifiers)<1:
return False
try:
num=int(num)
if num>=0 and num<len(Settings.Notifiers) and (Settings.Notifiers[num].enabled):
retvalue = Settings.Notifiers[num].notify(cmdline)
except Exception as e:
misc.addLog(rpieGlobals.LOG_LEVEL_ERROR,"Notification error: "+str(e))
return retvalue

def decodeeventname(eventname):
ten = eventname.strip().lower()
ec = -1
Expand Down
51 changes: 51 additions & 0 deletions nplugin.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,51 @@
#!/usr/bin/env python3
#############################################################################
################### Notification plugin skeleton ############################
#############################################################################
#
# Copyright (C) 2019 by Alexander Nagy - https://bitekmindenhol.blog.hu/
#

class NPluginProto: # Skeleton for every notification plugin! Override necessary functions and extend as neeeded!
NPLUGIN_ID = -1
NPLUGIN_NAME = "Notifier"

def __init__(self,nindex): # general init
self.number = self.NPLUGIN_ID
self.usesMessaging = True
self.usesGPIO=0
self.enabled = False
self.nindex = nindex
self.initialized = False

def getnpluginid(self):
return self.number

def getdevicename(self):
return self.NPLUGIN_NAME

def getuniquename(self):
return self.NPLUGIN_NAME

def webform_load(self): # create html page for settings
return ""

def webform_save(self,params): # process settings post reply
return True

def plugin_init(self,enableplugin=None): # init plugin when startup, load settings if available
if enableplugin != None:
self.enabled = enableplugin
if self.enabled:
if self.initialized == False:
self.initialized = True
return True

def plugin_exit(self): # deinit plugin, save settings?
if self.initialized:
self.initialized = False
return True

def notify(self,pmsg=""):
result = False
return result
2 changes: 1 addition & 1 deletion rpieGlobals.py
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@
# Copyright (C) 2018-2019 by Alexander Nagy - https://bitekmindenhol.blog.hu/
#
PROGNAME = "RPIEasy"
BUILD = 19174
BUILD = 19176
PROGVER = "0."+str(BUILD/1000)

gpMenu = []
Expand Down
Loading

0 comments on commit 730fe67

Please sign in to comment.