class XBMCNotificationListener(XplPlugin): """ Create listener for xPL messages about xbmc notifications """ def __init__(self): """ Create lister for XBMC notifications """ XplPlugin.__init__(self, name='xbmc_not') # Create logger self.log.debug("Listener for XBMC notifications created") # Get configuration self._config = Query(self.myxpl, self.log) address = self._config.query('xbmc_not', 'address') delay = self._config.query('xbmc_not', 'delay') maxdelay = self._config.query('xbmc_not', 'maxdelay') self.log.debug("Config : address = " + address) self.log.debug("Config : delay = " + delay) self.log.debug("Config : maxdelay = " + maxdelay) # Create XBMCNotification object self.xbmc_notification_manager = XBMCNotification(self.log, address, delay, \ maxdelay) # Create listeners Listener(self.xbmc_notification_cb, self.myxpl, { 'schema': 'osd.basic', 'xpltype': 'xpl-cmnd' }) self.enable_hbeat() self.enable_hbeat() def xbmc_notification_cb(self, message): """ Call XBMC notification lib @param message : message to send """ self.log.debug("Call xbmc_notification_cb") if 'command' in message.data: command = message.data['command'] if 'text' in message.data: text = message.data['text'] if 'row' in message.data: row = message.data['row'] if 'delay' in message.data: delay = message.data['delay'] self.log.debug("Call _notify") self.xbmc_notification_manager.notify(command, text, row, delay)
class Mochad(XplPlugin): def __init__(self): # Connect to the socket XplPlugin.__init__(self, name = 'mochad') self.mochad_socket = None self._config = Query(self.myxpl, self.log) self.__host = self._config.query('mochad','mochad-host') self.__port = self._config.query('mochad','mochad-port') if self._config.query('mochad','cm15') == "True": self.__cm15 = True else: self.__cm15 = False if self._config.query('mochad','cm19') == "True": self.__cm19 = True else: self.__cm19 = False if self.__cm15: self.__itf = "pl" elif self.__cm19: self.__itf = "rf" self.connect() child_pid = os.fork() if child_pid == 0: self.listener() else: return None def connect(self): for res in socket.getaddrinfo(self.__host, self.__port, socket.AF_UNSPEC, socket.SOCK_STREAM): af, socktype, proto, canonname, sa = res try: self.mochad_socket = socket.socket(af, socktype, proto) except socket.error, msg: self.mochad_socket = None continue try: self.mochad_socket.connect(sa) except socket.error, msg: self.mochad_socket.close() self.mochad_socket = None continue break
class CIDManager(XplPlugin): """ Manage the modem to get CID """ def __init__(self): """ Init plugin """ XplPlugin.__init__(self, name='cidmodem') # Configuration self._config = Query(self.myxpl, self.log) device = self._config.query('cidmodem', 'device') cid_command = self._config.query('cidmodem', 'cid-command') # Init Modem cid = CallerIdModem(self.log, self.send_xpl) # Open Modem try: cid.open(device, cid_command) except CallerIdModemException as e: self.log.error(e.value) print(e.value) self.force_leave() return # Start reading Modem cid_process = threading.Thread(None, cid.listen, "listen_cid", (), {}) cid_process.start() self.enable_hbeat() def send_xpl(self, num): """ Send xPL message on network @param num : call number """ print("Input call : %s " % num) msg = XplMessage() msg.set_type("xpl-trig") msg.set_schema("cid.basic") msg.add_data({"calltype" : "INBOUND"}) msg.add_data({"phone" : num}) self.myxpl.send(msg)
class Zwave(XplPlugin): def __init__(self): XplPlugin.__init__(self, name='zwave') Listener(self.zwave_cmd_cb, self.myxpl, { 'schema': 'zwave.basic', 'xpltype': 'xpl-cmnd' }) self._config = Query(self.myxpl, self.log) device = self._config.query('zwave', 'device') speed = self._config.query('zwave', 'speed') print(device, ' ', speed) # device='/dev/ttyUSB0' self.myzwave = ZWave(device, speed, self.zwave_cb, self.log) self.myzwave.start() self.enable_hbeat() self.myzwave.send('Network Discovery') sleep(3) def zwave_cmd_cb(self, message): if 'command' in message.data: cmd = message.data['command'] node = message.data['node'] if cmd == 'level': lvl = message.data['level'] self.myzwave.send(cmd, node, lvl) else: self.myzwave.send(cmd, node) def zwave_cb(self, read): mess = XplMessage() if 'info' in read: self.log.error("Error : Node %s unreponsive" % read['node']) elif 'Find' in read: print("node enregistré : %s" % read['Find']) elif 'event' in read: mess.set_type('xpl-trig') mess.set_schema('zwave.basic') mess.add_data({ 'event': read['event'], 'node': read['node'], 'level': read['level'] }) self.myxpl.send(mess) elif 'command' in read and read['command'] == 'Info': print("Home ID is %s" % read['Home ID'])
class CIDManager(XplPlugin): """ Manage the modem to get CID """ def __init__(self): """ Init plugin """ XplPlugin.__init__(self, name='cidmodem') # Configuration self._config = Query(self.myxpl, self.log) device = self._config.query('cidmodem', 'device') cid_command = self._config.query('cidmodem', 'cid-command') # Init Modem cid = CallerIdModem(self.log, self.send_xpl) # Open Modem try: cid.open(device, cid_command) except CallerIdModemException as e: self.log.error(e.value) print(e.value) self.force_leave() return # Start reading Modem cid_process = threading.Thread(None, cid.listen, "listen_cid", (), {}) cid_process.start() self.enable_hbeat() def send_xpl(self, num): """ Send xPL message on network @param num : call number """ print("Input call : %s " % num) msg = XplMessage() msg.set_type("xpl-trig") msg.set_schema("cid.basic") msg.add_data({"calltype": "INBOUND"}) msg.add_data({"phone": num}) self.myxpl.send(msg)
class Zwave(XplPlugin): def __init__(self): XplPlugin.__init__(self, name = 'zwave') Listener(self.zwave_cmd_cb, self.myxpl,{'schema': 'zwave.basic', 'xpltype': 'xpl-cmnd'}) self._config = Query(self.myxpl, self.log) device = self._config.query('zwave', 'device') speed = self._config.query('zwave', 'speed') print(device, ' ', speed) # device='/dev/ttyUSB0' self.myzwave = ZWave(device, speed, self.zwave_cb, self.log) self.myzwave.start() self.enable_hbeat() self.myzwave.send('Network Discovery') sleep(3) def zwave_cmd_cb(self, message): if 'command' in message.data: cmd = message.data['command'] node = message.data['node'] if cmd == 'level': lvl = message.data['level'] self.myzwave.send(cmd, node, lvl) else: self.myzwave.send(cmd, node) def zwave_cb(self, read): mess = XplMessage() if 'info' in read: self.log.error ("Error : Node %s unreponsive" % read['node']) elif 'Find' in read: print("node enregistré : %s" % read['Find']) elif 'event' in read: mess.set_type('xpl-trig') mess.set_schema('zwave.basic') mess.add_data({'event' : read['event'], 'node' : read['node'], 'level' : read['level']}) self.myxpl.send(mess) elif 'command' in read and read['command'] == 'Info': print("Home ID is %s" % read['Home ID'])
class MirrorManager(XplPlugin): """ Manage the Mir:ror device and connect it to xPL """ def __init__(self): """ Init plugin """ XplPlugin.__init__(self, name='mirror') # Get config # - device self._config = Query(self.myxpl, self.log) device = self._config.query('mirror', 'device') # Init Mir:ror mirror = Mirror(self.log, self.send_xpl) # Open Mir:ror try: mirror.open(device) except MirrorException as e: self.log.error(e.value) print(e.value) self.force_leave() return # Start reading Mir:ror mirror_process = threading.Thread(None, mirror.listen, "mirror-process-reader", (self.get_stop(),), {}) self.register_thread(mirror_process) mirror_process.start() self.enable_hbeat() def send_xpl(self, device, type, current): """ Send xPL message on network """ print("device:%s, type:%s, current:%s" % (device, type, current)) msg = XplMessage() msg.set_type("xpl-trig") msg.set_schema("sensor.basic") msg.add_data({"device" : device}) msg.add_data({"type" : type}) msg.add_data({"current" : current}) self.myxpl.send(msg)
class TtsManager(XplPlugin): """ Manage Tts """ def __init__(self): """ Init manager """ XplPlugin.__init__(self, name = 'tts') # Configuration self._config = Query(self.myxpl, self.log) software = self._config.query('tts', 'software') self.log.debug("Init info for tts created") ### Create tts objects self.my_tts = Tts(self.log, software) self.log.debug("Create object for tts created") # Create listener Listener(self.tts_cb, self.myxpl, {'schema': 'tts.basic','xpltype': 'xpl-cmnd'}) self.log.debug("Listener for tts created") self.enable_hbeat() def tts_cb(self, message): """ Call tts lib @param message : xPL message detected by listener """ # body contains the message self.log.debug("Function call back : entry") if 'speech' in message.data: speech = message.data['speech'] else: self._log.warning("Xpl message : missing 'speech' attribute") return try: self.log.debug("function call back : before send") self.my_tts.send(speech) self.log.debug("function call back : after send") except: self.log.error("Error while sending tts : %s" % traceback.format_exc()) return
class MirrorManager(XplPlugin): """ Manage the Mir:ror device and connect it to xPL """ def __init__(self): """ Init plugin """ XplPlugin.__init__(self, name='mirror') # Get config # - device self._config = Query(self.myxpl, self.log) device = self._config.query('mirror', 'device') # Init Mir:ror mirror = Mirror(self.log, self.send_xpl) # Open Mir:ror try: mirror.open(device) except MirrorException as e: self.log.error(e.value) print(e.value) self.force_leave() return # Start reading Mir:ror mirror_process = threading.Thread(None, mirror.listen, "mirror-process-reader", (self.get_stop(), ), {}) self.register_thread(mirror_process) mirror_process.start() self.enable_hbeat() def send_xpl(self, device, type, current): """ Send xPL message on network """ print("device:%s, type:%s, current:%s" % (device, type, current)) msg = XplMessage() msg.set_type("xpl-trig") msg.set_schema("sensor.basic") msg.add_data({"device": device}) msg.add_data({"type": type}) msg.add_data({"current": current}) self.myxpl.send(msg)
class RfxcomUsbManager(XplPlugin): """ Manage the Rfxcom Usb device and connect it to xPL """ def __init__(self): """ Init plugin """ XplPlugin.__init__(self, name='rfxcom') # Get config # - device self._config = Query(self.myxpl, self.log) device = self._config.query('rfxcom', 'device') if device == None: self.log.error('Device is not configured, exiting') print('Device is not configured, exiting') self.force_leave() return # Init RFXCOM self.rfxcom = RfxcomUsb(self.log, self.send_xpl, self.send_trig, self.get_stop()) # Create a listener for all messages used by RFXCOM # TODO !!!!! # Create listeners Listener(self.process_x10_basic, self.myxpl, { 'schema': 'x10.basic', 'xpltype': 'xpl-cmnd' }) Listener(self.process_x10_security, self.myxpl, { 'schema': 'x10.securiy', 'xpltype': 'xpl-cmnd' }) Listener(self.process_ac_basic, self.myxpl, { 'schema': 'ac.basic', 'xpltype': 'xpl-cmnd' }) Listener(self.process_remote_basic, self.myxpl, { 'schema': 'remote.basic', 'xpltype': 'xpl-cmnd' }) Listener(self.process_control_basic, self.myxpl, { 'schema': 'control.basic', 'xpltype': 'xpl-cmnd' }) # Open RFXCOM try: self.rfxcom.open(device) except RfxcomException as e: self.log.error(e.value) print(e.value) self.force_leave() return # Start reading RFXCOM rfxcom_process = threading.Thread(None, self.rfxcom.listen, "rfxcom-process-reader", (self.get_stop(), ), {}) self.register_thread(rfxcom_process) rfxcom_process.start() self.enable_hbeat() # lighting1 def process_x10_basic(self, message): """ Process command xpl message and call the librairy for processing command @param message : xpl message """ address = message.data["device"].lower() command = message.data["command"].lower() if message.data.has_key("level"): level = message.data["level"].lower() else: level = 0 if message.data.has_key("protocol"): protocol = message.data["protocol"].lower() else: protocol = "x10" # Prepare xpl-trig to send if success trig_msg = message trig_msg.set_type("xpl-trig") # call appropriate function if protocol in ("x10", "arc", "elro", "waveman", "chacon", "impuls"): self.rfxcom.command_10(address, command, protocol, trig_msg) elif protocol in ("koppla"): self.rfxcom.command_12(address, command, level, protocol, trig_msg) elif protocol in ("harrison"): self.rfxcom.command_18(address, command, protocol, trig_msg) def process_x10_security(self, message): """ Process command xpl message and call the librairy for processing command @param message : xpl message """ address = message.data["device"].lower() command = message.data["command"].lower() if message.data.has_key("delay"): delay = message.data["delay"].lower() else: delay = None # Prepare xpl-trig to send if success trig_msg = message trig_msg.set_type("xpl-trig") self.rfxcom.command_20(address, command, delay, trig_msg) def process_ac_basic(self, message): """ Process command xpl message and call the librairy for processing command @param message : xpl message """ # TODO : finish address = message.data["address"].lower() unit = message.data["unit"] if unit.lower() == "group": unit = 0 group = True else: unit = int(unit) group = False command = message.data["command"].lower() if command == "preset": level = int(message.data["level"]) else: level = 0 if message.data.has_key("eu"): eu = message.data["eu"] else: eu = False # Prepare xpl-trig to send if success trig_msg = message trig_msg.set_type("xpl-trig") self.rfxcom.command_11(address, unit, command, level, eu, group, trig_msg) def process_remote_basic(self, message): """ Process command xpl message and call the librairy for processing command @param message : xpl message """ # TODO pass def process_control_basic(self, message): """ Process command xpl message and call the librairy for processing command @param message : xpl message """ msg_type = message.data["type"] msg_current = message.data["current"] msg_device = message.data["current"] self.log.debug( "CONTROL.BASIC received : device = %s, type = %s, current = %s" % (msg_device, msg_type, msg_current)) self.rfxcom.xplcmd_control_basic(device=msg_device, type=msg_type, current=msg_current) def send_xpl(self, schema, data={}): """ Send xPL message on network """ print("schema:%s, data:%s" % (schema, data)) self.log.debug("schema:%s, data:%s" % (schema, data)) msg = XplMessage() msg.set_type("xpl-trig") msg.set_schema(schema) for key in data: msg.add_data({key: data[key]}) self.myxpl.send(msg) def send_trig(self, message): """ Send xpl-trig given message @param message : xpl-trig message """ self.myxpl.send(message)
class X10Main(XplPlugin): '''Manage x10 technology using heyu ''' def __init__(self): """ Create the X10Main class This class is used to connect x10 (through heyu) to the xPL Network """ XplPlugin.__init__(self, name='x10_heyu') self._heyu_cfg_path_res = "" self._config = Query(self.myxpl, self.log) self._heyu_cfg_path_res = self._config.query('x10_heyu', 'heyu-cfg-path') try: self.__myx10 = X10API(self._heyu_cfg_path_res, self.log) except Exception: self.log.error("Something went wrong during heyu init, check logs") self.log.error("Exception : %s" % traceback.format_exc()) exit(1) #Create listeners Listener(self.x10_cmnd_cb, self.myxpl, { 'schema': 'x10.basic', 'xpltype': 'xpl-cmnd' }) #One listener for system schema, allowing to reload config #Listener(self.heyu_reload_config, self.myxpl, {'schema': 'domogik.system', 'xpltype': 'xpl-cmnd', # 'command': 'reload', 'plugin': 'x10'}) #One listener for system schema, allowing to dump config #Listener(self.heyu_dump_config, self.myxpl, {'schema': 'domogik.system', 'xpltype': 'xpl-cmnd', # 'command': 'push_config', 'plugin': 'x10'}) self.log.debug("before start X10monitor") self._monitor = X10Monitor(self._heyu_cfg_path_res) self._monitor.get_monitor().add_cb(self.x10_monitor_cb) self._monitor.get_monitor().start() self.enable_hbeat() self.log.debug("Heyu correctly started") #def heyu_reload_config(self, message): # """ # Regenerate the heyu config file # First, it needs to get all config items, then rewrite the config file # and finally restart heyu # @param message : an XplMessage object # """ # #Heyu config items # result = self._config.query('x10', '') # if result is not None: # heyu_config_items = filter(lambda k : k.startswith("heyu-file-"), result.keys()) # heyu_config_values = [] # for key in heyu_config_items: # heyu_config_values.append(result[key]) # #Heyu path # myheyu = HeyuManager(self._heyu_cfg_path_res) # try: # myheyu.write(heyu_config_values) # except IOError: # self.log.warning("Heyu config file can't be opened") # res = myheyu.restart() # if res: # self.log.warning("Error during heyu restart : %s" % res) # else: # print("empty res") # #def heyu_dump_config(self, message): # """ # Send the heyu config file on the network # @param message : an XplMessage object # """ # #Heyu path # myheyu = HeyuManager(self._heyu_cfg_path_res) # lines = myheyu.load() # mess = XplMessage() # mess.set_type('xpl-trig') # mess.set_schema('domogik.config') # count = 0 # for line in lines: # key = "heyu_file_%s" % count # count = count + 1 # mess.add_data({key : line}) # self.myxpl.send(mess) def x10_cmnd_cb(self, message): """ General callback for all command messages @param message : an XplMessage object """ commands = { 'on': lambda d, h, l: self.__myx10.on(d), 'off': lambda d, h, l: self.__myx10.off(d), 'all_units_on': lambda d, h, l: self.__myx10.house_on(h), 'all_units_off': lambda d, h, l: self.__myx10.house_off(h), 'all_lights_on': lambda d, h, l: self.__myx10.lights_on(h), 'all_lights_off': lambda d, h, l: self.__myx10.lights_off(h), 'bright': lambda d, h, l: self.__myx10.bright(d, l), 'dim': lambda d, h, l: self.__myx10.dim(d, l), 'brightb': lambda d, h, l: self.__myx10.brightb(d, l), 'dimb': lambda d, h, l: self.__myx10.dimb(d, l), } cmd = None dev = None house = None level = None if 'command' in message.data: cmd = message.data['command'] if 'device' in message.data: dev = message.data['device'] if 'house' in message.data: house = message.data['house'] if 'level' in message.data: level = message.data['level'] self.log.debug("%s received : device = %s, house = %s, level = %s" % (cmd, dev, house, level)) commands[cmd](dev, house, level) self.x10_monitor_cb(dev, cmd) def x10_monitor_cb(self, unit, order, args=None): """ Callback for x10 monitoring @param unit : the unit of the element controled @param order : the order sent to the unit """ self.log.debug("X10 Callback for %s" % unit) mess = XplMessage() mess.set_type("xpl-trig") mess.set_schema("x10.basic") mess.add_data({"device": unit}) mess.add_data({"command": order}) if args: mess.add_data({"level": args}) self.myxpl.send(mess)
class KNXManager(XplPlugin): """ Implements a listener for KNX command messages and launch background listening for KNX events """ def __init__(self): """ Create listener and launch bg listening """ XplPlugin.__init__(self, name = 'knx') # Configuration : KNX device self._config = Query(self.myxpl, self.log) try{ device = self._config.query('knx', 'device') }except{ self.log.error("Can get device parameter use ipt:192.168.0.148") device = "ipt:192.168.0.148" } ### Create KNX object try: self.knx = KNX(self.log, self.send_xpl) self.log.info("Open KNX") self.knx.open(device) except KNXException as err: self.log.error(err.value) print(err.value) self.force_leave() return ### Start listening try: self.log.info("Start listening to KNX") knx_listen = threading.Thread(None, self.knx.listen, "listen_knx", (), {}) knx_listen.start() except KNXException as err: self.log.error(err.value) print(err.value) self.force_leave() return ### Create listeners for commands self.log.info("Creating listener for KNX") Listener(self.knx_cmd, self.myxpl,{'schema':'knx.basic'}) self.add_stop_cb(self.knx.close) self.enable_hbeat() ### test if config file exist path = self.get_data_files_directory() if os.path.exists(path)== False: try: os.mkdir(path) self.log.info("create KNX data folder") except: self.log.error("can't create KNX data folder as %s" %path) path = path+"/knx.txt" if os.path.exists(path)== False: try: fichier= open(path,'w') fichier.write('') fichier.close() print "Création du fichier de stockage %s" %path self.log.info("Create KNX data file") except: self.log.error("Can't create KNX data file") ### Load the configuration file in the plugin self.log.info("Start read knx data file") filetoopen= self.get_data_files_directory() filetoopen= filetoopen+"/knx.txt" fichier=open(filetoopen,"r") for ligne in fichier: if ligne[:1]!="#": listknx.append(ligne) print ligne fichier.close self.log.info("Finish to read KNX data file") for i in range(len(listknx)): stat=listknx[i] if stat.find("check:true")>=0: stat=stat[stat.find("adr_stat:")+9:] stat=stat[:stat.find(" ")] print stat command="groupread ip:127.0.0.1 %s" %stat subp2=subprocess.Popen(command, shell=True) self.log.info("Plugin ready :)") def send_xpl(self, data): """ Send xpl-trig to give status change """ self.log.info("receive an xpl message") ### Identify the sender of the message lignetest="" command = "" dmgadr ="" msg_type="" test = "" val="" sender = 'None' sender = data[data.find('from')+4:data.find('to')-1] sender = sender.strip() groups = 'None' val = 'None' msg_type = 'None' command = 'None' if sender!="pageinatio": print "emetteur |%s|" %sender command = data[0:4] lignetest="" groups = data[data.find('to')+2:data.find(':')] groups =":"+groups.strip()+" " print "groups |%s|" %groups ### Search the sender in the config list i=0 lignetest="" for i in range(len(listknx)): if listknx[i].find(groups)>=0: lignetest = listknx[i] typeadr=lignetest[lignetest.find(groups)-4:lignetest.find(groups)] typeadr=typeadr.replace("_","") test=lignetest[lignetest.find('datatype:')+9:] datatype=test[:test.find(' ')] if typeadr=="stat": if lignetest.find('dpt_stat')!=-1: test=lignetest[lignetest.find('dpt_stat:')+9:] datatype=test[:test.find(' ')] test=lignetest[lignetest.find('adr_dmg:')+8:] dmgadr=test[:test.find(' ')] datatype=lignetest[lignetest.find('datatype:')+9:lignetest.find(' adr_dmg')] msg=XplMessage() msg.set_schema('knx.basic') if command != 'Read': val=data[data.find(':')+1:-1] val = val.strip() print "valeur=|%s|" %val print "datapoint type=|%s|" %datatype msg_type = datatype val=decodeKNX(datatype,val) print "Valeur decode=|%s|" %val if command == 'Writ': print("knx Write xpl-trig") command = 'Write' msg.set_type("xpl-trig") if command == 'Resp': print("knx Response xpl-stat") command = 'Response' if sender!="0.0.0": msg.set_type("xpl-stat") else: msg.set_type("xpl-trig") if command == 'Read': print("knx Read xpl-cmnd") if sender!="0.0.0": msg.set_type("xpl-cmnd") else: msg.set_type("xpl-trig") if sender!="0.0.0": msg.add_data({'command' : command+' bus'}) else: msg.add_data({'command': command+' ack'}) msg.add_data({'group' : dmgadr}) msg.add_data({'type' : msg_type}) msg.add_data({'data': val}) print "sender: %s typeadr:%s" %(sender, typeadr) self.myxpl.send(msg) def knx_cmd(self, message): type_cmd = message.data['command'] groups = message.data['group'] groups = "adr_dmg:"+groups+" " lignetest="" valeur=message.data['data'] print "Message XPL %s" %message for i in range(len(listknx)): if listknx[i].find(groups)>=0: lignetest=listknx[i] break print "ligne test=|%s|" %lignetest #si wirte groups_cmd/si read, groups stat if lignetest!="": datatype=lignetest[lignetest.find('datatype:')+9:lignetest.find(' adr_dmg')] cmdadr=lignetest[lignetest.find('adr_cmd:')+8:lignetest.find(' adr_stat')] command="" print "Command: |%s|" %type_cmd print "Groups: |%s|" %cmdadr print "datatype: |%s|" %datatype print "valeur avant codage: |%s|" %valeur if type_cmd=="Write": print("dmg Write %s") %type_cmd valeur = message.data['data'] data_type = message.data['type'] print "valeur avant modif:%s" %valeur val=valeur value=encodeKNX(datatype, val) data_type=value[0] valeur=value[1] print "Valeur modifier |%s|" %valeur if data_type=="s": command="groupswrite ip:127.0.0.1 %s %s" %(cmdadr, valeur) if data_type=="l": command="groupwrite ip:127.0.0.1 %s %s" %(cmdadr, valeur) if type_cmd == "Read": print("dmg Read") command="groupread ip:127.0.0.1 %s" %cmdadr if type_cmd == "Response": print("dmg Response") data_type=message.data['type'] valeur = message.data['data'] if data_type=="s": command="groupsresponse ip:127.0.0.1 %s %s" %(cmdadr,valeur) if data_type=="l": command="groupresponse ip:127.0.0.1 %s %s" %(cmdadr,valeur) if command!="": print "envoie de la command %s" %command subp=subprocess.Popen(command, shell=True) if command=="": print("erreur command non définir, type cmd= %s" %type_cmd) ### ajout d'un device dans le fichier de configuration du KNX if type_cmd=="Add": groups = message.data['group'] test="" print "Commande Add Valeur=|%s|" %valeur print groups if groups=="UI": print "Add device" Adr_dmg=valeur[:valeur.find(":")] valeur=valeur[valeur.find(":")+1:] Adr_cmd=valeur[:valeur.find(":")] valeur=valeur[valeur.find(":")+1:] dptype=valeur[:valeur.find(":")] valeur=valeur[valeur.find(":")+1:] Adr_stat=valeur[:valeur.find(":")] valeur=valeur[valeur.find(":")+1:] dpt_stat=valeur[:valeur.find(":")] valeur=valeur[valeur.find(":")+1:] check=valeur[:valeur.find(":")] valeur=valeur[valeur.find(":")+1:] comentaire=valeur test="" for i in range(len(listknx)): print listknx[i] if listknx[i].find(Adr_dmg)>=0: test=listknx[i] print test break if groups=="Delete": test="" filetoopen= self.get_data_files_directory() filetoopen= filetoopen+"/knx.txt" e=open(filetoopen,"r") o=e.read().split("\n") e.close() f=open(filetoopen,"w") ligne=int(valeur,10)-1 print ligne for i in range(len(o)): if i!=ligne: if o[i]!="": f.write(o[i]+"\n") else: print "ligne a supprimer:|%s|" %o[ligne] testy=str(o[ligne])+"\n" if listknx.count(testy)>=1: listknx.remove(testy) else: print listknx print o[i] f.close() msg=XplMessage() msg.set_schema('knx.basic') msg.set_type("xpl-trig") msg.add_data({'command': 'Add-ack'}) msg.add_data({'group' : 'Delete'}) msg.add_data({'type' : 's'}) msg.add_data({'data': 'OK'}) self.myxpl.send(msg) if groups=="UI": msg=XplMessage() msg.set_schema('knx.basic') msg.set_type("xpl-trig") msg.add_data({'command': 'Add-ack'}) msg.add_data({'group' : 'UI'}) msg.add_data({'type' : 's'}) if test == "": filetoopen= self.get_data_files_directory() filetoopen= filetoopen+"/knx.txt" fichier=open(filetoopen,"a") ligne1="# %s \n" %comentaire ligne2="datatype:%s adr_dmg:%s adr_cmd:%s adr_stat:%s dpt_stat:%s check:%s end \n" %(dptype,Adr_dmg,Adr_cmd,Adr_stat,dpt_stat,check) fichier.write(ligne1) fichier.write(ligne2) fichier.close listknx.append(ligne2) print "Retour du xPL" msg.add_data({'data': 'OK'}) else: print "Error" msg.add_data({'data': 'Error domogik address:'+Adr_dmg+' already existe'}) self.myxpl.send(msg) if groups=="Request": print "Requette de fichier" msg=XplMessage() msg.set_schema('knx.basic') msg.set_type("xpl-trig") msg.add_data({'command': 'Add-ack'}) msg.add_data({'group' : 'Request'}) msg.add_data({'type' : 's'}) print "Resquest files" filetoopen= self.get_data_files_directory() filetoopen= filetoopen+"/knx.txt" fichier=open(filetoopen,"r") data=[] for ligne in fichier: data.append(ligne[:ligne.find("end")]) message="" msg.add_data({'dim': len(data)}) for i in range(len(data)): message=message+data[i]+"," msg.add_data({'data[%s]' %i : data[i]}) if message=="": message="None" msg.add_data({'data': message}) fichier.close self.myxpl.send(msg)
class Earth(XplPlugin): ''' The plugin itself. ''' def __init__(self): """ Create the cron class """ XplPlugin.__init__(self, name = 'earth') self.log.debug("__init__ : Start ...") self.config = Query(self.myxpl, self.log) try: delay_cron = int(self.config.query('earth', 'delay-cron')) except: delay_cron = 30 error = "Can't get configuration from XPL : %s" % (traceback.format_exc()) self.log.warning("__init__ : " + error) self.log.warning("Continue with default values.") cron = CronQuery(self.myxpl, self.log) cont = 3 cron_started = False while not self.get_stop().isSet() and cont>=0: try : res = cron.is_running_server() except : pass if res : cron_started = True cont = -1 else: self.log.debug("Can't talk to cron plugin. Retries=%s" % cont) self.get_stop().wait(delay_cron) cont -= 1 if not cron_started : self.force_leave() error = "Can't talk to cron plugin. Exiting ..." self.log.error("__init__ : "+error) return else : self.log.info("Communication with the cron plugin established.") self.log.debug("__init__ : Try to start the earth API") try: self._earth = EarthAPI(self.log, self.config, self.myxpl, \ self.get_data_files_directory(), \ self.get_stop(), self.get_sanitized_hostname()) except: self.force_leave() error = "Something went wrong during EarthAPI init : %s" % \ (traceback.format_exc()) self.log.error("__init__ : "+error) return self.log.debug("__init__ : Try to create listeners") Listener(self.request_cb, self.myxpl, {'schema': 'earth.request', 'xpltype': 'xpl-cmnd'}) Listener(self.fired_cb, self.myxpl, {'schema': 'earth.basic', 'xpltype': 'xpl-trig', 'current': 'fired'}) Listener(self.basic_cb, self.myxpl, {'schema': 'earth.basic', 'xpltype': 'xpl-cmnd'}) self.add_stop_cb(self._earth.stop_all) self.log.debug("__init__ : Enable the heartbeat") self.enable_hbeat() self._earth.plugin_enabled(True) self.log.info("Plugin earth correctly started.") def request_cb(self, message): """ General callback for timer.request messages @param message : an XplMessage object """ self.log.debug("request_cb() : Start ...") self._earth.command_listener(self.myxpl, message) self.log.debug("request_cb() : Done :)") def basic_cb(self, message): """ General callback for timer.basic messages @param message : an XplMessage object """ self.log.debug("basic_cb() : Start ...") self._earth.action_listener(self.myxpl, message) self.log.debug("basic_cb() : Done :)") def fired_cb(self, message): """ General callback for timer.basic messages @param message : an XplMessage object """ self.log.debug("fired_cb() : Start ...") self._earth.fired_listener(self.myxpl, message) self.log.debug("fired_cb() : Done :)")
class IPXManager(XplPlugin): """ Implements a listener for IPX command messages and launch background listening for relay board status """ def __init__(self): """ Create lister and launch bg listening """ XplPlugin.__init__(self, name="ipx800") # Configuration : list of IPX800 self.ipx_list = {} num = 1 loop = True self._config = Query(self.myxpl, self.log) while loop == True: model = self._config.query("ipx800", "model-%s" % str(num)) login = self._config.query("ipx800", "login-%s" % str(num)) password = self._config.query("ipx800", "password-%s" % str(num)) name = self._config.query("ipx800", "name-%s" % str(num)) address = self._config.query("ipx800", "ip-%s" % str(num)) inter = self._config.query("ipx800", "int-%s" % str(num)) if name != None: self.log.info( "Configuration : login=%s, password=***, name=%s, ip=%s, interval=%s" % (login, name, address, inter) ) self.ipx_list[name] = { "login": login, "password": password, "model": model, "ip": address, "interval": float(inter), } num += 1 else: loop = False # no ipx configured if num == 1: msg = "No ipx800 board configured. Exiting plugin" self.log.info(msg) print (msg) self.force_leave() return ### Create IPX objects num_ok = 0 for ipx in self.ipx_list: self.ipx_list[ipx]["obj"] = IPX(self.log, self.send_xpl, self.get_stop()) try: self.log.info("Opening IPX800 named '%s' (ip : %s)" % (ipx, self.ipx_list[ipx]["ip"])) self.ipx_list[ipx]["obj"].open( ipx, self.ipx_list[ipx]["ip"], self.ipx_list[ipx]["model"], self.ipx_list[ipx]["login"], self.ipx_list[ipx]["password"], ) except: self.log.error("Error opening board '%s' : %s " % (ipx, traceback.format_exc())) print ("Error opening board '%s' : check logs" % ipx) else: num_ok += 1 # no valid ipx800 board detected if num_ok == 0: msg = "No valid IPX800 board configured. Exiting plugin..." self.log.info(msg) print (msg) self.force_leave() return ### Start listening each IPX800 for ipx in self.ipx_list: try: self.log.info("Start listening to IPX800 named '%s'" % ipx) ipx_listen = threading.Thread( None, self.ipx_list[ipx]["obj"].listen, "listen_ipx", (self.ipx_list[ipx]["interval"],), {} ) ipx_listen.start() except IPXException as err: self.log.error(err.value) print (err.value) # we don't quit plugin if an error occured # we can loose a board for a little time # self.force_leave() # return ### Create listeners for commands self.log.info("Creating listener for IPX 800") # Listener(self.ipx_command, self.myxpl, {'schema': 'control.basic', # 'xpltype': 'xpl-cmnd', 'type': ['output', 'count']}) Listener(self.ipx_command, self.myxpl, {"schema": "control.basic", "xpltype": "xpl-cmnd", "type": "output"}) self.enable_hbeat() self.log.info("Plugin ready :)") def send_xpl(self, msg_device, msg_current, msg_type): """ Send xpl-trig to give status change @param msg_device : device @param msg_current : device's value @param msg_type : device's type """ msg = XplMessage() msg.set_type("xpl-trig") msg.set_schema("sensor.basic") msg.add_data({"device": msg_device}) if msg_type != None: msg.add_data({"type": msg_type}) msg.add_data({"current": msg_current}) self.myxpl.send(msg) def ipx_command(self, message): """ Call ipx800 lib function in function of given xpl message @param message : xpl message """ if "device" in message.data: msg_device = message.data["device"] if "type" in message.data: msg_type = message.data["type"].lower() if "current" in message.data: msg_current = message.data["current"].lower() data = "device=%s, type=%s, current=%s" % (msg_device, msg_type, msg_current) print data data_name = msg_device.split("-") ipx_name = data_name[0] elt = data_name[1][0:-1] num = int(data_name[1][-1]) if not ipx_name in self.ipx_list: self.log.warning("No IPX800 board called '%s' defined" % ipx_name) return # check data if elt == "led" and msg_current not in ["high", "low", "pulse"] and msg_type != "output": self.log.warning("Bad data : %s" % data) return # TODO in a next release : other checks : counter # action in function of type if elt == "led" and msg_type == "output" and msg_current in ["high", "low"]: self.ipx_list[ipx_name]["obj"].set_relay(num, msg_current) elif elt == "led" and msg_type == "output" and msg_current == "pulse": self.ipx_list[ipx_name]["obj"].pulse_relay(num)
class KarotzMain(XplPlugin): '''Manage ZiBase ''' def __init__(self): """ Create lister and launch bg listening """ try: XplPlugin.__init__(self, name = 'karotz') except: self.log.error("Error to create Karotz Xplplugin=%s" % (traceback.format_exc())) return self._config = Query(self.myxpl, self.log) self.instid = self._config.query('karotz', 'installid') self.lang = self._config.query('karotz', 'language') try: self.log.info("Starting library") self.karotz=Karotz(self.log,self.instid) self.log.info("Started") except: self.log.error("Error to create Karotz object=%s" % (traceback.format_exc())) return self.log.info("Creating listener for Karotz") Listener(self.xpl_command, self.myxpl, {'schema': 'karotz.basic', 'xpltype': 'xpl-cmnd'}) #self.add_stop_cb(self.stop) self.enable_hbeat() self.log.info("Plugin ready :)") def xpl_command(self, message): """ Call karotz lib function in function of given xpl message @param message : xpl message """ cmd = None dev = None value = None if 'command' in message.data: cmd = message.data['command'] if 'device' in message.data: device = message.data['device'] if 'value' in message.data: value=message.data['value'] if 'time' in message.data: tps=message.data['time'] if 'right' in message.data: right=message.data['right'] value=right if 'left' in message.data: left=message.data['left'] self.log.debug(message.data) if value == None : self.log.warning("value not specified") return else: #self.log.debug("xpl %s received : device = %s value=%s " % (cmd, device, value)) self.log.debug("xpl %s received " % (cmd) ) try: if cmd=='tts': self.log.debug("xpl command=%s language=%s" % (cmd, self.lang)) self.karotz.tts(value,self.lang.upper()) if cmd=='led': self.log.debug("xpl command=%s color=%s time=%s" % (cmd, value,tps)) self.karotz.led(value,tps) if cmd=='ears': self.log.debug("xpl command=%s right=%s left=%s" % (cmd, right, left)) self.karotz.ears(right,left) except: self.log.error("Error to send command=%s" % (traceback.format_exc()))
class GAgendaListener(XplPlugin): """ Listen for xPL messages to get infos from agenda """ def __init__(self): """ Create lister for google agenda requets """ XplPlugin.__init__(self, name = 'gagenda') # Create logger self.log.debug("Listener for Google agenda created") # Get config self._config = Query(self.myxpl, self.log) self._email = self._config.query('gagenda', 'email') self._password = self._config.query('gagenda', 'password') self._calendar_name = self._config.query('gagenda', 'calendarname') # Create object self._gagenda_manager = GAgenda(self.log, \ self._email, \ self._password, \ self._calendar_name, \ self._broadcast_events) # Create listener for today Listener(self.gagenda_cb, self.myxpl, {'schema': 'calendar.request', 'xpltype': 'xpl-cmnd', 'command': 'REQUEST'}) self.enable_hbeat() def gagenda_cb(self, message): """ Call google agenda lib @param message : xlp message received """ self.log.debug("Call gagenda_cb") if 'command' in message.data: command = message.data['command'] if 'date' in message.data: date = message.data['date'] # if it is a request command if command == "REQUEST": self.log.debug("Google agende request command received for " + \ str(date)) if date == "TODAY": self._gagenda_manager.get_today_events() elif date == "TOMORROW": self._gagenda_manager.get_tomorrow_events() else: self._gagenda_manager.get_events_at_date(date) def _broadcast_events(self, events): """ Send xPL message on network @param events : list of events """ for entry in events: my_temp_message = XplMessage() my_temp_message.set_type("xpl-trig") my_temp_message.set_schema("calendar.basic") print("entry = ") print(entry) my_temp_message.add_data({"object" : entry["object"]}) my_temp_message.add_data({"startdate" : entry["startdate"]}) self.myxpl.send(my_temp_message)
class SmsManager(XplPlugin): """ Manage Sms """ def __init__(self): """ Init manager """ XplPlugin.__init__(self, name = 'sms') # Configuration self._config = Query(self.myxpl, self.log) login = self._config.query('sms', 'login') password = self._config.query('sms', 'password') phone = self._config.query('sms', 'phone') operator = self._config.query('sms', 'operator') operator = operator.lower() if (operator == "orange"): from domogik_packages.xpl.lib.sms_orange import Sms if (operator == "sfr"): from domogik_packages.xpl.lib.sms_sfr import Sms if (operator == "bouygues"): from domogik_packages.xpl.lib.sms_bouygues import Sms self.log.debug("Init info for sms created") ### Create Sms objects self.my_sms = Sms(self.log,login,password,phone) self.log.debug("Create object for sms created") # Create listener Listener(self.sms_cb, self.myxpl, {'schema': 'sendmsg.basic','xpltype': 'xpl-cmnd'}) self.log.debug("Listener for sms created") self.enable_hbeat() def sms_cb(self, message): """ Call sms lib @param message : xPL message detected by listener """ # body contains the message self.log.debug("Function call back : entry") if 'body' in message.data: body = message.data['body'] else: self._log.warning("Xpl message : missing 'body' attribute") return if 'to' in message.data: to = message.data['to'] else: self._log.warning("Xpl message : missing 'to' attribute") return try: self.log.debug("function call back : before send") self.my_sms.send(to,body) self.log.debug("function call back : after send") except: self.log.error("Error while sending sms : %s" % traceback.format_exc()) mess = XplMessage() mess.set_type('xpl-trig') mess.set_schema('sendmsg.confirm') mess.add_data({'status' : 'Sms not send'}) mess.add_data({'error' : 'function send'}) self.myxpl.send(mess) return # Send xpl-trig to say plugin receive command mess = XplMessage() mess.set_type('xpl-trig') mess.set_schema('sendmsg.confirm') if self.my_sms.status_send == 0: mess.add_data({'status' : 'Sms not send'}) mess.add_data({'error' : self.my_sms.status_error}) else: mess.add_data({'status' : 'Sms send'}) self.myxpl.send(mess)
class RelayBoardUSBmanager(XplPlugin): """ Manage USB Relay Board """ def __init__(self): """ Init manager """ XplPlugin.__init__(self, name = 'gceusbrb') # Configuration : list of relayboard self.relayboards = {} num = 1 loop = True self._config = Query(self.myxpl, self.log) while loop == True: name = self._config.query('gceusbrb', 'rb-%s-name' % str(num)) device = self._config.query('gceusbrb', 'rb-%s-device' % str(num)) if name != None: self.log.info("Configuration : name=%s, device=%s" % (name, device)) self.relayboards[name] = {"device" : device} else: loop = False num += 1 ### Create Relayboardusb objects ex.SamsungTV for relayboard in self.relayboards: self.relayboards[relayboard]['obj'] = Relayboardusb(self.log,self.send_xpl) try: self.log.info("Opening RelayBoard named '%s' (device : %s)" % (relayboard, self.relayboards[relayboard]['device'])) self.relayboards[relayboard]['obj'].open(self.relayboards[relayboard]['device'],relayboard) except RelayboardusbException as err: self.log.error(err.value) print err.value self.force_leave() return # Create listener Listener(self.relayboard_cb, self.myxpl, {'schema': 'control.basic','xpltype': 'xpl-cmnd', 'type': 'output'}) self.log.debug("Listener for gceusbrb created") self.enable_hbeat() self.log.info("RB Plugin ready :)") def send_xpl(self, msg_device, msg_current, msg_type): """ Send xpl-trig to give status change @param msg_device : device @param msg_current : device's value @param msg_type : device's type """ msg = XplMessage() msg.set_type("xpl-trig") msg.set_schema('sensor.basic') msg.add_data({'device' : msg_device}) msg.add_data({'type' : msg_type}) msg.add_data({'current' : msg_current}) self.myxpl.send(msg) def relayboard_cb(self, message): """ Call gceusbrb lib @param message : xPL message detected by listener """ # device contains name of relayboard which will be used to get device if 'device' in message.data: msg_device = message.data['device'] if 'type' in message.data: msg_type = message.data['type'].lower() if 'current' in message.data: msg_current = message.data['current'].upper() data = "device=%s, type=%s, current=%s" % (msg_device, msg_type, msg_current) data_name = msg_device.split("-") rb_name = data_name[0] elt = data_name[1][0:-1] num = int(data_name[1][-1]) self.log.info("RelayBoard command received for '%s' on '%s'" % (rb_name, msg_device)) if not rb_name in self.relayboards: self.log.warning("No Relay board called '%s' defined" % rb_name) return # check data if elt == 'led' and msg_current not in ['HIGH', 'LOW'] and msg_type != 'output': self.log.warning("Bad data : %s" % data) return # action in function of type self.relayboards[rb_name]['obj'].set_relay(num, msg_current)
class Dawndusk(XplPlugin): ''' Send Dawn and Dusk messages over XPL ''' def __init__(self): """ Create the dawndusk class """ XplPlugin.__init__(self, name='dawndusk') self.log.info("dawndusk.__init__ : Start ...") self._config = Query(self.myxpl, self.log) self.log.debug("dawndusk.__init__ : Try to get configuration from XPL") try: longitude = str(self._config.query('dawndusk', 'longitude')) latitude = str(self._config.query('dawndusk', 'latitude')) if latitude == None: latitude = "47.352" if longitude == None: longitude = "5.043" boo = self._config.query('dawndusk', 'cron') if boo == None: boo = "False" use_cron = eval(boo) boo = self._config.query('dawndusk', 'test') if boo == None: boo = "False" test = eval(boo) self.devices = {} num = 1 loop = True while loop == True: xpltype = self._config.query('dawndusk', \ 'xpltype-%s' % str(num)) schema = self._config.query('dawndusk', \ 'schema-%s' % str(num)) addname = self._config.query('dawndusk', \ 'addname-%s' % str(num)) add = self._config.query('dawndusk', 'add-%s' % str(num)) command = self._config.query('dawndusk', \ 'command-%s' % str(num)) dawn = self._config.query('dawndusk', 'dawn-%s' % str(num)) dusk = self._config.query('dawndusk', 'dusk-%s' % str(num)) if schema != None: self.log.debug("dawndusk.__init__ : Device from \ xpl : device=%s," % (add)) self.devices[add] = { "schema": schema, "command": command, "dawn": dawn, "dusk": dusk, "addname": addname, "xpltype": xpltype } else: loop = False num += 1 except: error = "Can't get configuration from XPL : %s" % \ (traceback.format_exc()) self.log.error("dawndusk.__init__ : " + error) longitude = "5.043" latitude = "47.352" use_cron = False test = False raise DawnduskException(error) self.log.debug( "dawndusk.__init__ : Try to start the dawndusk librairy") try: self._mydawndusk = DawnduskAPI(longitude, latitude, use_cron, \ self.myxpl, self.log) except: error = "Something went wrong during dawnduskAPI init : %s" % \ (traceback.format_exc()) self.log.error("dawndusk.__init__ : " + error) raise DawnduskException(error) self.log.debug("dawndusk.__init__ : Try to add the next event \ to the scheduler") try: self.add_next_event() #for test only if test == True: self._mydawndusk.sched_add(datetime.datetime.today() + \ datetime.timedelta(minutes=1), \ self.send_dawndusk,"dawn-test") self._mydawndusk.sched_add(datetime.datetime.today() + \ datetime.timedelta(minutes=6), \ self.send_dawndusk,"dusk-test") except: error = "Something went wrong during dawnduskScheduler \ init : %s" % (traceback.format_exc()) self.log.error("dawndusk.__init__ : " + error) raise DawnduskException(error) self.log.debug("dawndusk.__init__ : Try to create listeners") Listener(self.dawndusk_cmnd_cb, self.myxpl, { 'schema': 'dawndusk.request', 'xpltype': 'xpl-cmnd' }) if use_cron == True: #We need to catch the dawndusk trig message to schedule the next one Listener(self.dawndusk_trig_cb, self.myxpl, { 'schema': 'dawndusk.basic', 'xpltype': 'xpl-trig' }) self.enable_hbeat() self.log.info("dawndusk plugin correctly started") def __del__(self): """ Kill the dawndusk plugin """ del (self._mydawndusk) def dawndusk_trig_cb(self, message): """ General callback for all command messages @param message : an XplMessage object """ self.log.debug("dawndusk.dawndusk_trig_cb() : Start ...") mtype = None if 'type' in message.data: mtype = message.data['type'] status = None if 'status' in message.data: status = message.data['status'] self.log.debug("dawndusk.dawndusk_trig_cb : type %s received \ with status %s" % (mtype, status)) if mtype == "dawndusk" and status != None: #We receive a trig indicating that the dawn or dus has occured. #We need to schedule the next one self.add_next_event() for dev in self.devices: self.log.debug("sendMessages() : Send message to device %s" % dev) mess = XplMessage() mess.set_type(self.devices[dev]["xpltype"]) mess.set_schema(self.devices[dev]["schema"]) mess.add_data({self.devices[dev]["command"] : \ self.devices[dev][status]}) mess.add_data({self.devices[dev]["addname"]: dev}) self.myxpl.send(mess) self.log.debug("dawndusk.dawndusk_trig_cb() : Done :)") def dawndusk_cmnd_cb(self, message): """ General callback for all command messages @param message : an XplMessage object """ self.log.debug("dawndusk.dawndusk_cmnd_cb() : Start ...") cmd = None if 'command' in message.data: cmd = message.data['command'] query = None if 'query' in message.data: query = message.data['query'] self.log.debug("dawndusk.dawndusk_cmnd_cb : command %s received \ with query %s" % (cmd, query)) mess = XplMessage() mess.set_type("xpl-stat") sendit = False if cmd == 'status': if query == "dawn": mess.set_schema("datetime.basic") dawn = self._mydawndusk.get_next_dawn() mess.add_data({"status": dawn.strftime("%Y%m%d%H%M%S"), \ "type": "dawn" }) sendit = True self.log.debug("dawndusk.dawndusk_cmnd_cb : query= %s, \ status= %s" % (query, dawn)) elif query == "dusk": mess.set_schema("datetime.basic") dusk = self._mydawndusk.get_next_dusk() mess.add_data({"status" : dusk.strftime("%Y%m%d%H%M%S"), \ "type": "dusk" }) sendit = True self.log.debug("dawndusk.dawndusk_cmnd_cb : query= %s, \ satus= %s" % (query, dusk)) elif query == "fullmoon": mess.set_schema("datetime.basic") dusk = self._mydawndusk.get_next_fullmoon() mess.add_data({"status" : dusk.strftime("%Y%m%d%H%M%S"), \ "type": "fullmoon" }) sendit = True self.log.debug("dawndusk.dawndusk_cmnd_cb : query= %s, \ satus= %s" % (query, dusk)) if query == "fullmoondawn": mess.set_schema("datetime.basic") fullmoondawn = self._mydawndusk.get_next_fullmoon_dawn() mess.add_data({"status": \ fullmoondawn.strftime("%Y%m%d%H%M%S"), \ "type": "fullmoondawn" }) sendit = True self.log.debug("dawndusk.dawndusk_cmnd_cb : query= %s, \ status= %s" % (query, fullmoondawn)) elif query == "fullmoondusk": mess.set_schema("datetime.basic") fullmoondusk = self._mydawndusk.get_next_fullmoon_dusk() mess.add_data({"status" : \ fullmoondusk.strftime("%Y%m%d%H%M%S"), \ "type": "fullmoondusk" }) sendit = True self.log.debug("dawndusk.dawndusk_cmnd_cb : query= %s, \ satus= %s" % (query, fullmoondusk)) elif query == "daynight": dawn = self._mydawndusk.get_next_dawn() dusk = self._mydawndusk.get_next_dusk() mess.set_schema("dawndusk.basic") mess.add_data({"type": "daynight"}) if dusk < dawn: mess.add_data({"status": "day"}) self.log.debug("dawndusk.dawndusk_cmnd_cb() : \ status= day") else: mess.add_data({"status": "night"}) self.log.debug("dawndusk.dawndusk_cmnd_cb() : \ status= night") sendit = True if sendit: self.myxpl.send(mess) self.log.debug("dawndusk.dawndusk_cmnd_cb() : Done :)") def add_next_event(self): """ Get the next event date : dawn or dusk """ ddate, dstate = self.get_next_event() self._mydawndusk.sched_add(ddate, self.send_dawndusk, dstate) def get_next_event(self): """ Get the next event date : dawn or dusk @return rdate : the next event date @return rstate : the event type : DAWN or DUSK """ dawn = self._mydawndusk.get_next_dawn() dusk = self._mydawndusk.get_next_dusk() if dusk < dawn: rdate = dusk rstate = "dusk" else: rdate = dawn rstate = "dawn" return rdate, rstate def send_dawndusk(self, state): """ Send a xPL message of the type DAWNDUSK.BASIC when the sun goes down or up. This function is called by the internal cron @param state : DAWN or DUSK """ self.log.debug("dawndusk.sendDawnDusk() : Start ...") mess = XplMessage() mess.set_type("xpl-trig") mess.set_schema("dawndusk.basic") mess.add_data({"type": "dawndusk"}) mess.add_data({"status": state}) self.myxpl.send(mess) self.add_next_event() for dev in self.devices: self.log.debug("sendMessages() : Send message to device %s" % dev) mess = XplMessage() mess.set_type(self.devices[dev]["xpltype"]) mess.set_schema(self.devices[dev]["schema"]) mess.add_data({self.devices[dev]["command"] : \ self.devices[dev][state]}) mess.add_data({self.devices[dev]["addname"]: dev}) self.myxpl.send(mess) self.log.info("dawndusk : send signal for %s" % state) self.log.debug("dawndusk.sendDawnDusk() : Done :-)")
class roowifi(XplPlugin): ## Implements a listener for RooWifi messages on xPL network def __init__(self): ##### ## Create listeners ## Listener(self._plcbus_cmnd_cb, self.myxpl, {'schema': 'plcbus.basic','xpltype': 'xpl-cmnd',}) ## ## device = self._config.query('plcbus', 'device') ##### ##Create listener for roowifi ## print("On rentre dans __init__") XplPlugin.__init__(self, name='roowifi') self._config = Query(self.myxpl, self.log) # creation d'un tableau pour recuperer les eventuels roombas self.roombas = {} num = 1 loop = True while loop == True: #Get each roomba settings print("On rentre dans while") name = self._config.query('roowifi', 'name-%s' % str(num)) ip = self._config.query('roowifi', 'ip-%s' % str(num)) port = self._config.query('roowifi', 'port-%s' % str(num)) user = self._config.query('roowifi', 'user-%s' % str(num)) password = self._config.query('roowifi', 'password-%s' % str(num)) delay = self._config.query('roowifi', 'delay-%s' % str(num)) ## retirer les valeurs default, une fois le pb de reuperation de config du plugin regler if name == None: name = "roomba" if ip == None: ip = "192.168.1.64" if port == None: port = 9001 if user == None: user = "******" if password == None: password = "******" if delay == None: delay = 60 print( "Configuration : name=%s, ip=%s, port=%s, user=%s, password=No_Log, delay=%s" % (name, ip, port, user, delay)) loop = False ## if name != None: self.log.info( "Configuration : name=%s, ip=%s, port=%s, user=%s, password=No_Log, delay=%s" % (name, ip, port, user, delay)) print( "Configuration : name=%s, ip=%s, port=%s, user=%s, password=No_Log, delay=%s" % (name, ip, port, user, delay)) self.roombas[name] = { "ip": ip, "port": port, "user": user, "password": password, "delay": delay } else: loop = False num += 1 ### Create Roomba object self._roombamanager = command(self.log) # Create listeners ##Listener(self.roowifi_command, self.myxpl, {'schema': 'control.basic', 'xpltype': 'xpl-cmnd', 'type': 'command'}) Listener(self.roowifi_command, self.myxpl, { 'schema': 'control.basic', 'xpltype': 'xpl-cmnd' }) self.log.info("Listener for roowifi created") #print ("Listener for roowifi created") self.enable_hbeat() print(" FIN __init__") def roowifi_command(self, message): ##Call roowifi lib ##@param message : xPL message detected by listener print(" On rentre dans roowifi_comand") #except KeyError: # self.log.warning("Roomba named '%s' is not defined" % device) # return false if 'device' in message.data: device = message.data['device'] ip = self.roombas[device]["ip"] port = int(self.roombas[device]["port"]) #user = self.roombas[device]["user"] #password = self.roombas[device]["password"] delay = int(self.roombas[device]["delay"]) ##if 'current' in message.data: ## msg_current = message.data['current'].upper() ##if 'type' in message.data: ## msg_type = message.data['type'].lower() ##if msg_type == 'command' and msg_current.lower() in ['clean']: #if msg_type == 'command' and msg_current.lower() in ['clean']: if 'command' in message.data: print(" Une commande est recue !") lacommand = message.data['command'] print("La comande est : clean !") self.log.debug("Clean command receive for '%s'" % device) # Our listener catch a Message with low output command status = self._roombamanager.command(ip, port, device, lacommand) # Send xpl-trig to say plugin whell receive high command if status == True: #print ("high ACKed") self.log.debug("high command Ack on relay '%s'" % device) mess = XplMessage() mess.set_type('xpl-trig') mess.set_schema('sensor.basic') mess.add_data({'device': device}) mess.add_data({'type': 'command'}) mess.add_data({'current': 'clean'}) self.myxpl.send(mess) if 'dock' in message.data['command']: print("La comande est : dock !")
class Lighting(XplPlugin): ''' Manage lighting schema over XPL ''' def __init__(self): """ Create the lighting class """ XplPlugin.__init__(self, name='lighting') self.log.debug("lighting.__init__ : Start ...") self._config = Query(self.myxpl, self.log) self.log.debug("lighting.__init__ : Try to get configuration from XPL") try: #self.use_cron = bool(self._config.query('lighting', 'usecron')) self.broadcast = bool(self._config.query('lighting', 'broadcast')) #self.presence = bool(self._config.query('lighting', 'presence')) except: error = "Can't get configuration from XPL : %s" % \ (traceback.format_exc()) self.log.exception("lighting.__init__ : " + error) #self.use_cron = True self.broadcast = True #self.presence = True raise LightingException(error) self.log.debug( "lighting.__init__ : Try to start the lighting librairy") try: self._mylighting = LightingAPI(self.broadcast, \ self.myxpl, self.log, self.get_data_files_directory()) except: error = "Something went wrong during lightingAPI init : %s" % \ (traceback.format_exc()) self.log.error("lighting.__init__ : " + error) self.force_leave() raise LightingException(error) self.log.debug("lighting.__init__ : Try to create listeners") Listener(self.lighting_config_cmnd, self.myxpl, { 'schema': 'lighting.config', 'xpltype': 'xpl-cmnd' }) Listener(self.lighting_basic_cmnd, self.myxpl, { 'schema': 'lighting.basic', 'xpltype': 'xpl-cmnd' }) # Listener(self.lighting_basic_trig, self.myxpl, # {'schema': 'lighting.basic', 'xpltype': 'xpl-trig'}) self.enable_hbeat() self._mylighting.reload_config() self.log.info("Plugin lighting correctly started.") def lighting_basic_trig(self, message): """ General callback for all command messages @param message : an XplMessage object """ self.log.debug("lighting_basic_trig() : Start ...") self._mylighting.basic_trig_listener(message) self.log.debug("lighting_basic_trig() : Done :)") def lighting_config_cmnd(self, message): """ General callback for all command messages @param message : an XplMessage object """ self.log.debug("lighting_config_cmnd() : Start ...") self._mylighting.config_cmnd_listener(message) self.log.debug("lighting_config_cmnd() : Done :)") def lighting_basic_cmnd(self, message): """ General callback for all command messages @param message : an XplMessage object """ self.log.debug("lighting_basic_cmnd() : Start ...") self._mylighting.basic_cmnd_listener(message) self.log.debug("lighting_basic_cmnd() : Done :)")
class ZiBaseMain(XplPlugin): '''Manage ZiBase ''' def __init__(self): """ Create lister and launch bg listening """ XplPlugin.__init__(self, name = 'zibase') self._config = Query(self.myxpl, self.log) self.address = self._config.query('zibase', 'ip') self.inter = self._config.query('zibase', 'interface') self.port = int(self._config.query('zibase', 'port')) self.valvar=self._config.query('zibase', 'envar') self.interv=int(self._config.query('zibase', 'interv')) self.log.info("Creating listener for ZiBase") Listener(self.zibase_command, self.myxpl, {'schema': 'zibase.basic', 'xpltype': 'xpl-cmnd'}) try: self.ip_host=get_ip_address(self.inter) self.log.debug("Adress IP Host=%s" % (self.ip_host)) except: self.log.error("IP Host not found=%s" % (traceback.format_exc())) return try: self.api = APIZiBase(self.log,self.address) except: self.log.error("API ZiBase error=%s" % (traceback.format_exc())) return try: self.th=ServerZiBase(self.log,self.ip_host,self.port,self.myxpl) self.th.start() except: self.log.error("Server ZiBase error=%s" % (traceback.format_exc())) self.stop() try: self.api.Connect(self.ip_host,self.port) except: self.log.error("Connection ZiBase error=%s" % (traceback.format_exc())) self.stop() if self.valvar=="True" : try: self.log.info("Start reading internal variables") var_read=XplTimer(self.interv,self.zibase_read_var,self.myxpl) var_read.start() except: self.log.error("reading internal variables error") return self.add_stop_cb(self.stop) self.enable_hbeat() self.log.info("Plugin ready :)") def zibase_command(self, message): """ Call zibase lib function in function of given xpl message @param message : xpl message """ commands = { 'off': 0, 'on': 1, 'preset-dim' : 2, } protocols = { 'PRESET': 0, 'VISONIC433' : 1, 'VISONIC868' : 2, 'CHACON' : 3, 'DOMIA' : 4, 'X10' : 5, 'ZWAVE' : 6, 'RFS10' : 7, 'XDD433AL' : 8, 'XDD868AL' : 9, 'XDD868INSH' : 10, 'XDD868PILOT' : 11, 'XDD868BOAC' : 12, } cmd = None dev = None protocol = None preset_dim = 0 if 'command' in message.data: cmd = message.data['command'] if 'device' in message.data: chaine=message.data['device'].split(':') try: dev = chaine[0].upper() protocol=chaine[1].upper() except: self.log.error("Syntax device not valid") if 'preset-dim' in message.data: preset_dim=message.data['preset-dim'] self.log.debug(message.data) if protocol == None : self.log.warning("Protocol not specified") return else: self.log.debug("%s received : device = %s protocol = %s number protocol=%s preset=%s" % (cmd, dev, protocol, protocols[protocol],str(preset_dim))) try: self.api.sendCommand(dev, commands[cmd], protocols[protocol],int(preset_dim)) except: self.log.error("Sendcommand error") return self.th.send_xpl_cmd(message.data['device'], cmd, preset_dim) def stop(self): self.log.debug("Stop plugin in progress...") self.var_read.stop() self.api.Disconnect(self.ip_host,self.port) self.th.stop() return def zibase_read_var(self): try: datas=self.api.getVariables() for data in datas: elmt=data.split(':') stats=['sta:' + elmt[1]] self.th.send_xpl_sensor(stats,elmt[0],'xpl-stat') except: self.log.error("Read var error=%s" % (traceback.format_exc()))
class X10Main(XplPlugin): '''Manage x10 technology using heyu ''' def __init__(self): """ Create the X10Main class This class is used to connect x10 (through heyu) to the xPL Network """ XplPlugin.__init__(self, name = 'x10_heyu') self._heyu_cfg_path_res = "" self._config = Query(self.myxpl, self.log) self._heyu_cfg_path_res = self._config.query('x10_heyu', 'heyu-cfg-path') try: self.__myx10 = X10API(self._heyu_cfg_path_res, self.log) except Exception: self.log.error("Something went wrong during heyu init, check logs") self.log.error("Exception : %s" % traceback.format_exc()) exit(1) #Create listeners Listener(self.x10_cmnd_cb, self.myxpl, {'schema': 'x10.basic', 'xpltype': 'xpl-cmnd'}) #One listener for system schema, allowing to reload config #Listener(self.heyu_reload_config, self.myxpl, {'schema': 'domogik.system', 'xpltype': 'xpl-cmnd', # 'command': 'reload', 'plugin': 'x10'}) #One listener for system schema, allowing to dump config #Listener(self.heyu_dump_config, self.myxpl, {'schema': 'domogik.system', 'xpltype': 'xpl-cmnd', # 'command': 'push_config', 'plugin': 'x10'}) self.log.debug("before start X10monitor") self._monitor = X10Monitor(self._heyu_cfg_path_res) self._monitor.get_monitor().add_cb(self.x10_monitor_cb) self._monitor.get_monitor().start() self.enable_hbeat() self.log.debug("Heyu correctly started") #def heyu_reload_config(self, message): # """ # Regenerate the heyu config file # First, it needs to get all config items, then rewrite the config file # and finally restart heyu # @param message : an XplMessage object # """ # #Heyu config items # result = self._config.query('x10', '') # if result is not None: # heyu_config_items = filter(lambda k : k.startswith("heyu-file-"), result.keys()) # heyu_config_values = [] # for key in heyu_config_items: # heyu_config_values.append(result[key]) # #Heyu path # myheyu = HeyuManager(self._heyu_cfg_path_res) # try: # myheyu.write(heyu_config_values) # except IOError: # self.log.warning("Heyu config file can't be opened") # res = myheyu.restart() # if res: # self.log.warning("Error during heyu restart : %s" % res) # else: # print("empty res") # #def heyu_dump_config(self, message): # """ # Send the heyu config file on the network # @param message : an XplMessage object # """ # #Heyu path # myheyu = HeyuManager(self._heyu_cfg_path_res) # lines = myheyu.load() # mess = XplMessage() # mess.set_type('xpl-trig') # mess.set_schema('domogik.config') # count = 0 # for line in lines: # key = "heyu_file_%s" % count # count = count + 1 # mess.add_data({key : line}) # self.myxpl.send(mess) def x10_cmnd_cb(self, message): """ General callback for all command messages @param message : an XplMessage object """ commands = { 'on': lambda d, h, l: self.__myx10.on(d), 'off': lambda d, h, l: self.__myx10.off(d), 'all_units_on': lambda d, h, l: self.__myx10.house_on(h), 'all_units_off': lambda d, h, l: self.__myx10.house_off(h), 'all_lights_on': lambda d, h, l: self.__myx10.lights_on(h), 'all_lights_off': lambda d, h, l: self.__myx10.lights_off(h), 'bright': lambda d, h, l: self.__myx10.bright(d, l), 'dim': lambda d, h, l: self.__myx10.dim(d, l), 'brightb': lambda d, h, l: self.__myx10.brightb(d, l), 'dimb': lambda d, h, l: self.__myx10.dimb(d, l), } cmd = None dev = None house = None level = None if 'command' in message.data: cmd = message.data['command'] if 'device' in message.data: dev = message.data['device'] if 'house' in message.data: house = message.data['house'] if 'level' in message.data: level = message.data['level'] self.log.debug("%s received : device = %s, house = %s, level = %s" % (cmd, dev, house, level)) commands[cmd](dev, house, level) self.x10_monitor_cb(dev, cmd) def x10_monitor_cb(self, unit, order, args = None): """ Callback for x10 monitoring @param unit : the unit of the element controled @param order : the order sent to the unit """ self.log.debug("X10 Callback for %s" % unit) mess = XplMessage() mess.set_type("xpl-trig") mess.set_schema("x10.basic") mess.add_data({"device" : unit}) mess.add_data({"command" : order}) if args: mess.add_data({"level" : args}) self.myxpl.send(mess)
class SamsungTVManager(XplPlugin): """ Manage Samsung televisions """ def __init__(self): """ Init manager """ XplPlugin.__init__(self, name = 'tv_samsg') # Configuration : list of televisions self.televisions = {} num = 1 loop = True self._config = Query(self.myxpl, self.log) while loop == True: name = self._config.query('tv_samsg', 'tv-%s-name' % str(num)) device = self._config.query('tv_samsg', 'tv-%s-device' % str(num)) if name != None: self.log.info("Configuration : name=%s, device=%s" % (name, device)) self.televisions[name] = {"device" : device} else: loop = False num += 1 ### Create SamsungTV objects for television in self.televisions: self.televisions[television]['obj'] = SamsungTV(self.log) try: self.log.info("Opening Samsung Television named '%s' (device : %s)" % (television, self.televisions[television]['device'])) self.televisions[television]['obj'].open(self.televisions[television]['device']) except SamsungTVException as err: self.log.error(err.value) print(err.value) self.force_leave() return # Create listener Listener(self.television_cb, self.myxpl, {'schema': 'control.basic', 'xpltype': 'xpl-cmnd', 'type': 'television'}) self.log.debug("Listener for tv_samsg created") self.enable_hbeat() def television_cb(self, message): """ Call tv_samsg lib @param message : xPL message detected by listener """ # device contains name of television which will be used to get device if 'device' in message.data: name = message.data['device'] if 'current' in message.data: command = message.data['current'] else: self._log.warning("Xpl message : missing 'current' attribute") return if 'data1' in message.data: data1 = int(message.data['data1']) else: data1 = None try: device = self.televisions[name]["device"] except KeyError: self.log.warning("Television named '%s' is not defined" % name) return self.log.info("Television command received for '%s' on '%s'" % (name, device)) status = self.televisions[name]['obj'].send(command, data1) # Send xpl-trig to say plugin receive command print("S=%s" % status) if status == True: mess = XplMessage() mess.set_type('xpl-trig') mess.set_schema('sensor.basic') mess.add_data({'device' : device}) mess.add_data({'type' : 'television'}) mess.add_data({'current' : command}) if data1 != None: mess.add_data({'data1' : data1}) print(mess) self.myxpl.send(mess)
class XplBridgeManager(XplPlugin): """ Send xpl message from hub to serial device and vice versa """ def __init__(self): """ Init plugin """ XplPlugin.__init__(self, name='xpl2ser') # Configuration self._config = Query(self.myxpl, self.log) # Configuration : list of devices to check self.dev_list = {} num = 1 loop = True while loop == True: dev = self._config.query('xpl2ser', 'device-%s' % str(num)) if dev != None: self.log.info("Configuration : device=%s" % dev) # init object baudrate = self._config.query('xpl2ser', 'baudrate-%s' % str(num)) self.dev_list[dev] = {"baudrate": baudrate} num += 1 else: loop = False # no device configured if num == 1: msg = "No device configured. Exiting plugin" self.log.info(msg) print(msg) self.force_leave() return ### Start listening each device for dev in self.dev_list: try: self.dev_list[dev]["obj"] = XplBridge(self.log, self.send_xpl, self.get_stop()) # Open serial device self.log.info("Open '%s'" % dev) try: self.dev_list[dev]["obj"].open( dev, self.dev_list[dev]["baudrate"]) except XplBridgeException as e: self.log.error(e.value) print(e.value) self.force_leave() return self.log.info("Start listening for '%s'" % dev) dev_listen = threading.Thread(None, self.dev_list[dev]["obj"].listen, "listen_serial", (), {}) dev_listen.start() except: self.log.error(traceback.format_exc()) print(traceback.format_exc()) # We don't quit plugin if an error occured # a device may have disappeared # Notice that it won't be read if device come back #self.force_leave() #return # Create listeners # Notice : this listener and callback function make this plugin send # on serial port each xpl message it reads on serial port # TODO : update this ! #Listener(self.xplbridge_cb, self.myxpl) self.enable_hbeat() self.log.info("Plugin ready :)") def send_xpl(self, resp): """ Send xPL message on network @param resp : xpl message """ print("Input xpl message : %s " % resp) try: msg = XplMessage(resp) self.myxpl.send(msg) except XplMessageError: error = "Bad data : %s" % traceback.format_exc() print(error) self.log.error(error) def xplbridge_cb(self, message): """ Call xplbridge lib for sending xpl message to serial @param message : xpl message to send """ self.log.debug("Call xplbridge_cb") mesg = message.to_packet() # Write on serial device self.log.debug("Call write() ") self.br.write(mesg)
class foscam(XplPlugin): """ Implements a listener for Foscam relay messages on xPL network """ def __init__(self): """ Create listener for Foscam Relay """ XplPlugin.__init__(self, name='foscam') self._config = Query(self.myxpl, self.log) # Configuration : list of cameras self.cameras = {} num = 1 loop = True while loop == True: #Get each camera settings name = self._config.query('foscam', 'name-%s' % str(num)) ip = self._config.query('foscam', 'ip-%s' % str(num)) port = self._config.query('foscam', 'port-%s' % str(num)) user = self._config.query('foscam', 'user-%s' % str(num)) password = self._config.query('foscam', 'password-%s' % str(num)) delay = self._config.query('foscam', 'delay-%s' % str(num)) if port == None: port = 80 if user == None: user = "" if password == None: password = "" if delay == None: delay = 0 if name != None: self.log.info( "Configuration : name=%s, ip=%s, port=%s, user=%s, password=No_Log, delay=%s" % (name, ip, port, user, delay)) self.cameras[name] = { "ip": ip, "port": port, "user": user, "password": password, "delay": delay } else: loop = False num += 1 ### Create FOSCAM object self._foscammanager = RELAY(self.log) # Create listeners Listener(self.foscam_command, self.myxpl, { 'schema': 'control.basic', 'xpltype': 'xpl-cmnd', 'type': 'output' }) self.log.info("Listener for Foscam relay created") #print ("Listener for Foscam relay created") self.enable_hbeat() def foscam_command(self, message): """ Call Foscamn lib @param message : xPL message detected by listener """ if 'device' in message.data: device = message.data['device'] if 'current' in message.data: msg_current = message.data['current'].upper() if 'type' in message.data: msg_type = message.data['type'].lower() try: ip = self.cameras[device]["ip"] port = int(self.cameras[device]["port"]) user = self.cameras[device]["user"] password = self.cameras[device]["password"] delay = int(self.cameras[device]["delay"]) except KeyError: self.log.warning("Camera named '%s' is not defined" % device) return if msg_type == 'output' and msg_current.lower() in ['high']: print("high recu") self.log.debug("high command receive on relay '%s'" % device) # Our listener catch a Message with low output command status = self._foscammanager.close_relay(ip, port, user, password, device) # Send xpl-trig to say plugin whell receive high command if status == True: #print ("high ACKed") self.log.debug("high command Ack on relay '%s'" % device) mess = XplMessage() mess.set_type('xpl-trig') mess.set_schema('sensor.basic') mess.add_data({'device': device}) mess.add_data({'type': 'output'}) mess.add_data({'current': 'high'}) self.myxpl.send(mess) if msg_type == 'output' and msg_current.lower() in ['low']: print("low recu") self.log.debug("low command receive on relay '%s'" % device) # Our listener catch a Message with low output command status = self._foscammanager.open_relay(ip, port, user, password, device) # Send xpl-trig to say plugin whell receive low command if status == True: #print ("low ACKed") self.log.debug("low command Ack on relay '%s'" % device) mess = XplMessage() mess.set_type('xpl-trig') mess.set_schema('sensor.basic') mess.add_data({'device': device}) mess.add_data({'type': 'output'}) mess.add_data({'current': 'low'}) self.myxpl.send(mess) if msg_type == 'output' and msg_current.lower() in ['pulse']: print("pulse recu") self.log.debug("pulse command receive on relay '%s'" % device) # Our listener catch a Message with output pulse output command status = self._foscammanager.pulse_relay(ip, port, user, password, delay, device) # Send xpl-trig to say plugin whell receive pulse command if status == True: print("pulse ACKed") self.log.debug("pulse command Ack on relay '%s'" % device) mess = XplMessage() mess.set_type('xpl-trig') mess.set_schema('sensor.basic') mess.add_data({'device': device}) mess.add_data({'type': 'output'}) mess.add_data({'current': 'pulse'}) self.myxpl.send(mess)
class VelbusManager(XplPlugin): """ Managages the velbus domogik plugin """ def __init__(self): """ Init plugin """ XplPlugin.__init__(self, name='velbus') self._config = Query(self.myxpl, self.log) # get the config values device_type = self._config.query('velbus', 'connection-type') if device_type == None: self.log.error('Devicetype is not configured, exitting') print('Devicetype is not configured, exitting') self.force_leave() return device = self._config.query('velbus', 'device') #device = '192.168.1.101:3788' if device == None: self.log.error('Device is not configured, exitting') print('Device is not configured, exitting') self.force_leave() return # validate the config vars if (device_type != 'serial') and (device_type != 'socket'): self.log.error('Devicetype must be socket or serial, exitting') print('Devicetype must be socket or serial, exitting') self.force_leave() return if device_type == 'socket' and not re.match('[0-9]{1,3}.[0-9]{1,3}.[0-9]{1,3}.[0-9]{1,3}:[0-9]+', device): self.log.error('A socket device is in the form of <ip>:<port>, exitting') print('A socket device is in the form of <ip>:<port>, exitting') self.force_leave() return # Init RFXCOM self.manager = VelbusDev(self.log, self.send_xpl, self.send_trig, self.get_stop()) self.add_stop_cb(self.manager.close) # Create a listener for all messages used by RFXCOM Listener(self.process_lighting_basic, self.myxpl, {'xpltype': 'xpl-cmnd', 'schema': 'lighting.basic'}) Listener(self.process_shutter_basic, self.myxpl, {'xpltype': 'xpl-cmnd', 'schema': 'shutter.basic'}) # Create listeners try: self.manager.open(device, device_type) except VelbusException as ex: self.log.error(ex.value) self.force_leave() return self.manager.scan() # Start reading RFXCOM listenthread = threading.Thread(None, self.manager.listen, "velbus-process-reader", (self.get_stop(),), {}) self.register_thread(listenthread) listenthread.start() self.enable_hbeat() def send_xpl(self, schema, data): """ Send xPL message on network """ self.log.info("schema:%s, data:%s" % (schema, data)) msg = XplMessage() msg.set_type("xpl-trig") msg.set_schema(schema) for key in data: msg.add_data({key : data[key]}) self.myxpl.send(msg) def send_trig(self, message): """ Send xpl-trig given message @param message : xpl-trig message """ self.myxpl.send(message) def process_lighting_basic(self, message): """ Process xpl chema lightning.basic """ print message #self.send_xpl("lighting.device", message.data) device = message.data['device'] chan = message.data['channel'] if message.data["level"] == 'None': message.data["level"] = 0 self.manager.send_level( device, chan, message.data["level"]) def process_shutter_basic(self, message): """ Process xpl chema shutter.basic """ self.send_xpl("shutter.device", message.data) add = message.data['device'].split('-') chan = int(add[1]) address = add[0] if message.data["command"] == "up": self.log.debug("set shutter up") self.manager.send_shutterup( address, chan ) elif message.data["command"] == "down": self.log.debug("set shutter down") self.manager.send_shutterdown( address, chan ) else: self.log.debug("Unknown command in shutter.basic message")
class XplBridgeManager(XplPlugin): """ Send xpl message from hub to serial device and vice versa """ def __init__(self): """ Init plugin """ XplPlugin.__init__(self, name='xpl2ser') # Configuration self._config = Query(self.myxpl, self.log) # Configuration : list of devices to check self.dev_list = {} num = 1 loop = True while loop == True: dev = self._config.query('xpl2ser', 'device-%s' % str(num)) if dev != None: self.log.info("Configuration : device=%s" % dev) # init object baudrate = self._config.query('xpl2ser', 'baudrate-%s' % str(num)) self.dev_list[dev] = { "baudrate" : baudrate } num += 1 else: loop = False # no device configured if num == 1: msg = "No device configured. Exiting plugin" self.log.info(msg) print(msg) self.force_leave() return ### Start listening each device for dev in self.dev_list: try: self.dev_list[dev]["obj"] = XplBridge(self.log, self.send_xpl, self.get_stop()) # Open serial device self.log.info("Open '%s'" % dev) try: self.dev_list[dev]["obj"].open(dev, self.dev_list[dev]["baudrate"]) except XplBridgeException as e: self.log.error(e.value) print(e.value) self.force_leave() return self.log.info("Start listening for '%s'" % dev) dev_listen = threading.Thread(None, self.dev_list[dev]["obj"].listen, "listen_serial", (), {}) dev_listen.start() except: self.log.error(traceback.format_exc()) print(traceback.format_exc()) # We don't quit plugin if an error occured # a device may have disappeared # Notice that it won't be read if device come back #self.force_leave() #return # Create listeners # Notice : this listener and callback function make this plugin send # on serial port each xpl message it reads on serial port # TODO : update this ! #Listener(self.xplbridge_cb, self.myxpl) self.enable_hbeat() self.log.info("Plugin ready :)") def send_xpl(self, resp): """ Send xPL message on network @param resp : xpl message """ print("Input xpl message : %s " % resp) try: msg = XplMessage(resp) self.myxpl.send(msg) except XplMessageError: error = "Bad data : %s" % traceback.format_exc() print(error) self.log.error(error) def xplbridge_cb(self, message): """ Call xplbridge lib for sending xpl message to serial @param message : xpl message to send """ self.log.debug("Call xplbridge_cb") mesg = message.to_packet() # Write on serial device self.log.debug("Call write() ") self.br.write(mesg)
class OneWireManager(XplPlugin): def __init__(self): """ Init onewire """ XplPlugin.__init__(self, name='onewire') try: ### get all config keys self._config = Query(self.myxpl, self.log) device = self._config.query('onewire', 'device') cache = self._config.query('onewire', 'cache') if cache == "True": cache = True else: cache = False ### Add Event listener Listener(self.read_xpl, self.myxpl,{'schema':'sensor.basic'}) ### DS18B20 config ds18b20_enabled = self._config.query('onewire', 'ds18b20-en') ds18b20_interval = self._config.query('onewire', 'ds18b20-int') ds18b20_resolution = self._config.query('onewire', 'ds18b20-res') ### DS18S20 config ds18s20_enabled = self._config.query('onewire', 'ds18s20-en') ds18s20_interval = self._config.query('onewire', 'ds18s20-int') ### DS2401 config ds2401_enabled = self._config.query('onewire', 'ds2401-en') ds2401_interval = self._config.query('onewire', 'ds2401-int') ### DS2438 config ds2438_enabled = self._config.query('onewire', 'ds2438-en') ds2438_interval = self._config.query('onewire', 'ds2438-int') ### DS2408 config ds2408_enabled = self._config.query('onewire', 'ds2408-en') ds2408_interval = self._config.query('onewire', 'ds2408-int') ### Open one wire network try: ow = OneWireNetwork(self.log, device, cache) self.ow = ow except OneWireException as e: self.log.error(e.value) print(e.value) self.force_leave() return ### DS18B20 support if ds18b20_enabled == "True": self.log.info("DS18B20 support enabled") ds18b20 = threading.Thread(None, ComponentDs18b20, "ds18b20", (self.log, ow, float(ds18b20_interval), ds18b20_resolution, self.send_xpl, self.get_stop()), {}) ds18b20.start() ### DS18S20 support if ds18s20_enabled == "True": self.log.info("DS18S20 support enabled") ds18s20 = threading.Thread(None, ComponentDs18s20, "ds18s20", (self.log, ow, float(ds18s20_interval), self.send_xpl, self.get_stop()), {}) ds18s20.start() ### DS2401 support if ds2401_enabled == "True": self.log.info("DS2401 support enabled") ds2401 = threading.Thread(None, ComponentDs2401, "ds2401", (self.log, ow, float(ds2401_interval), self.send_xpl, self.get_stop()), {}) ds2401.start() ### DS2438 support if ds2438_enabled == "True": self.log.info("DS2438 support enabled") ds2438 = threading.Thread(None, ComponentDs2438, "ds2438", (self.log, ow, float(ds2438_interval), self.send_xpl, self.get_stop()), {}) ds2438.start() ### DS2408 support if ds2408_enabled == "True": self.log.info("DS2408 support enabled") ds2408 = threading.Thread(None, ComponentDs2408, "ds2408", (self.log, ow, float(ds2408_interval), self.send_xpl, self.get_stop()), {}) ds2408.start() except: self.log.error("Plugin error : stopping plugin... Trace : %s" % traceback.format_exc()) print(traceback.format_exc()) self.force_leave() self.enable_hbeat() def send_xpl(self, type, data): """ Send data on xPL network @param data : data to send (dict) """ msg = XplMessage() msg.set_type(type) msg.set_schema("sensor.basic") for element in data: msg.add_data({element : data[element]}) self.log.debug("Send xpl message...") self.myxpl.send(msg) def read_xpl(self, message): switch = None device = None data = None if 'switch' in message.data: switch = message.data['switch'] if 'device' in message.data: device = message.data['device'] if 'data' in message.data: data = message.data['data'] print("Message XPL %s" %message) if (switch != None and device != None and data != None): r = self.ow.write(device, switch, data) mess = XplMessage() mess.set_type("xpl-trig") mess.set_schema("sensor.basic") mess.add_data({"device" : device}) mess.add_data({"command" : "switch"+switch}) self.myxpl.send(mess) print("Setting PIO "+switch+"="+data+" for device "+device) mess2 = XplMessage() mess2.set_type("xpl-trig") mess2.set_schema("sensor.basic") mess2.add_data({"device" : device}) mess2.add_data({"data"+switch : r }) mess2.add_data({"type" : "PIO_ALL"}) self.myxpl.send(mess2)
class OZwave(XplHlpPlugin): """ Implement a listener for Zwave command messages and launch background manager to listening zwave events by callback """ def __init__(self): """ Create listener and background zwave manager """ XplHlpPlugin.__init__(self, name = 'ozwave') # Récupère la config # - device self._config = Query(self.myxpl, self.log) device = self._config.query('ozwave', 'device') ozwlogConf = self._config.query('ozwave', 'ozwlog') self._config = Query(self.myxpl, self.log) print ('Mode log openzwave :', ozwlogConf) # Recupère l'emplacement des fichiers de configuration OZW pathUser = self.get_data_files_directory() +'/' pathConfig = self._config.query('ozwave', 'configpath') + '/' # Initialise le manager Open zwave try: self.myzwave = OZWavemanager(self._config, self.send_xPL, self.sendxPL_trig, self.get_stop(), self.log, configPath = pathConfig, userPath = pathUser, ozwlog = ozwlogConf) except OZwaveException as e: self.log.error(e.value) print e.value self.force_leave() return self.log.debug("__init__ : Enable heplers") self.helpers = \ { "infostate" : { "cb" : self.myzwave.GetPluginInfo, "desc" : "Show Info status. Experimental.", "usage" : "memory", } } self.enable_helper() # Crée le listener pour les messages de commande xPL traités par les devices zwave Listener(self.ozwave_cmd_cb, self.myxpl,{'schema': 'ozwave.basic', 'xpltype': 'xpl-cmnd'}) # Validation avant l'ouverture du controleur, la découverte du réseaux zwave prends trop de temps -> RINOR Timeout self.add_stop_cb(self.myzwave.stop) self.enable_hbeat() # Ouverture du controleur principal self.myzwave.openDevice(device) def __sizeof__(self): return XplHlpPlugin.__sizeof__(self) + sum(sys.getsizeof(v) for v in self.__dict__.values()) def ozwave_cmd_cb(self, message): """" Envoie la cmd xpl vers le OZWmanager""" print ("commande xpl recue") print message self.log.debug(message) if 'command' in message.data: if 'group'in message.data: # en provenance de l'UI spéciale self.ui_cmd_cb(message) else : cmd = message.data['command'] device = message.data['device'] if cmd == 'level' : print ("appel envoi zwave command %s" %cmd) lvl = message.data['level'] self.myzwave.sendNetworkZW(cmd, device, lvl) elif cmd == "on" or cmd == "off" : print ("appel envoi zwave command %s" %cmd) self.myzwave.sendNetworkZW(cmd, device) else: self.myzwave.sendNetworkZW(cmd, device) def getdict2UIdata(self, UIdata): """ retourne un format dict en provenance de l'UI (passage outre le format xPL)""" retval = UIdata.replace('"', '"').replace('&squot;', "'").replace("&ouvr;", '{').replace("&ferm;", '}') ; try : return eval(retval) except OZwaveException as e: print retval self.log.debug ("Format data to UI : eval in getdict2UIdata error : " + retval) return {'error': 'invalid format'} def getUIdata2dict(self, ddict): """Retourne le dict formatter pour UI (passage outre le format xPL)""" print "conversion pour transfertvers UI , " , str(ddict) for k in ddict : # TODO: pour passer les 1452 chars dans RINOR, à supprimer quand MQ OK, if isinstance(ddict[k], str) : ddict[k] = ddict[k].replace("'", "&squot;") # remplace les caractères interdits pour rinor if len(str(ddict[k])) >800 : ddict[k] = ddict[k][:800] print("value raccourccis : ", k, ddict[k]) self.log.debug ("Format data to UI : value to large, cut to 800, key : %s, value : %s" % (str(k), str(ddict[k]))) return str(ddict).replace('{', '&ouvr;').replace('}', '&ferm;').replace('"','"').replace("'",'"').replace('False', 'false').replace('True', 'true').replace('None', '""') def ui_cmd_cb(self, message): """xpl en provenace de l'UI (config/special)""" response = True info = "essais" request = self.getdict2UIdata(message.data['value']) print("Commande UI") if message.data['group'] =='UI' : mess = XplMessage() mess.set_type('xpl-trig') mess.set_schema('ozwave.basic') if request['request'] == 'ctrlAction' : action = dict(request) del action['request'] report = self.myzwave.handle_ControllerAction(action) info = self.getUIdata2dict(report) mess.add_data({'command' : 'Refresh-ack', 'group' :'UI', 'ctrlaction' : request['action'], 'data': info}) if request['cmd'] =='getState' and report['cmdstate'] != 'stop' : response = False elif request['request'] == 'ctrlSoftReset' : info = self.getUIdata2dict(self.myzwave.handle_ControllerSoftReset()) mess.add_data({'command' : 'Refresh-ack', 'group' :'UI', 'data': info}) elif request['request'] == 'ctrlHardReset' : info = self.getUIdata2dict(self.myzwave.handle_ControllerHardReset()) mess.add_data({'command' : 'Refresh-ack', 'group' :'UI', 'data': info}) elif request['request'] == 'GetPluginInfo' : info = self.getUIdata2dict(self.myzwave.GetPluginInfo()) mess.add_data({'command' : 'Refresh-ack', 'group' :'UI', 'node' : 0, 'data': info}) else : mess.add_data({'command' : 'Refresh-ack', 'group' :'UI', 'data': "unknown request", 'error': "unknown request"}) print "commande inconnue" if response : self.myxpl.send(mess) def send_xPL(self, xPLmsg, args = None): """ Envoie une commande ou message zwave vers xPL""" mess = XplMessage() mess.set_type(xPLmsg['type']) mess.set_schema(xPLmsg['schema']) if xPLmsg.has_key('data') : mess.add_data(xPLmsg['data']) print '********************* Dans send_xPL *****************' if args : mess.add_data({'data': self.getUIdata2dict(args)}) print mess self.myxpl.send(mess) def sendxPL_trig(self, msgtrig): """Envoie un message trig sur le hub xPL""" mess = XplMessage() if 'info' in msgtrig: self.log.error ("Error : Node %s unreponsive" % msgtrig['node']) elif 'Find' in msgtrig: print("node enregistré : %s" % msgtrig['Find']) elif 'typexpl' in msgtrig: mess.set_type(msgtrig['typexpl']) mess.set_schema(msgtrig['schema']) if msgtrig['genre'] == 'actuator' : if msgtrig['level'] in [0, 'False', False] : cmd ="off" elif msgtrig['level'] in [255, 'True', True]: cmd ="on" else: cmd ='level' mess.add_data({'device' : msgtrig['device'], 'command' : cmd, 'level': msgtrig['level']}) if msgtrig.has_key('type'): mess.add_data({'type' : msgtrig['type'] }) elif msgtrig['genre'] == 'sensor' : # tout sensor if msgtrig['type'] =='status' : # gestion du sensor binary pour widget binary mess.add_data({'device' : msgtrig['device'], 'type' : msgtrig['type'] , 'current' : 'true' if msgtrig['value'] else 'false'}) else : mess.add_data({'device' : msgtrig['device'], 'type' : msgtrig['type'] , 'current' : msgtrig['value'] }) if msgtrig.has_key('units') and msgtrig['units'] !='' : mess.add_data({'units' : msgtrig['units'] }) print mess self.myxpl.send(mess) elif 'command' in msgtrig and msgtrig['command'] == 'Info': print("Home ID is %s" % msgtrig['Home ID'])
class GAgendaListener(XplPlugin): """ Listen for xPL messages to get infos from agenda """ def __init__(self): """ Create lister for google agenda requets """ XplPlugin.__init__(self, name='gagenda') # Create logger self.log.debug("Listener for Google agenda created") # Get config self._config = Query(self.myxpl, self.log) self._email = self._config.query('gagenda', 'email') self._password = self._config.query('gagenda', 'password') self._calendar_name = self._config.query('gagenda', 'calendarname') # Create object self._gagenda_manager = GAgenda(self.log, \ self._email, \ self._password, \ self._calendar_name, \ self._broadcast_events) # Create listener for today Listener( self.gagenda_cb, self.myxpl, { 'schema': 'calendar.request', 'xpltype': 'xpl-cmnd', 'command': 'REQUEST' }) self.enable_hbeat() def gagenda_cb(self, message): """ Call google agenda lib @param message : xlp message received """ self.log.debug("Call gagenda_cb") if 'command' in message.data: command = message.data['command'] if 'date' in message.data: date = message.data['date'] # if it is a request command if command == "REQUEST": self.log.debug("Google agende request command received for " + \ str(date)) if date == "TODAY": self._gagenda_manager.get_today_events() elif date == "TOMORROW": self._gagenda_manager.get_tomorrow_events() else: self._gagenda_manager.get_events_at_date(date) def _broadcast_events(self, events): """ Send xPL message on network @param events : list of events """ for entry in events: my_temp_message = XplMessage() my_temp_message.set_type("xpl-trig") my_temp_message.set_schema("calendar.basic") print("entry = ") print(entry) my_temp_message.add_data({"object": entry["object"]}) my_temp_message.add_data({"startdate": entry["startdate"]}) self.myxpl.send(my_temp_message)
class Proxy(XplPlugin): """ REST Proxy - create a HTTP server - process REST proxy requests """ def __init__(self, proxy_ip, proxy_port): """ Initiate properties Then, start HTTP server and give it initialized data @param proxy_ip : ip of the proxy server @param proxy_port : port of proxy server """ XplPlugin.__init__(self, name = 'proxy', reload_cb = self.reload_config) # logging initialization self.log.info("Proxy initialisation ...") self.log.debug("locale : %s %s" % locale.getdefaultlocale()) self._config = Query(self.myxpl, self.log) self.server = None self.server_process = None self.proxy_ip = None self.proxy_port = None self.use_ssl = False self.ssl_certificate = None self.server_ip = None self.server_port = None self.auth_method = None self.username = None self.password = None self.add_stop_cb(self.stop_http) self.enable_hbeat() self.reload_config() #self.log.info("Proxy initialisation done") def reload_config(self): ''' Load configuration an start proxy server ''' if self.server != None: self.stop_http() self.server = None self.server_process = None try: cfg_rest = Loader('rest') config_rest = cfg_rest.load() conf_rest = dict(config_rest[1]) self.server_ip = conf_rest['rest_server_ip'] self.server_port = conf_rest['rest_server_port'] except KeyError: self.log.error("Can't retrieve REST configuration from domogik.cfg. Leave plugin.") self.force_leave() try: self.proxy_ip = self._config.query('proxy', 'proxy-ip') self.proxy_port = self._config.query('proxy', 'proxy-port') except: self.log.warning("Can't get proxy address configuration from XPL. Use default value.") finally: if self.proxy_ip == None: self.proxy_ip = self.server_ip try : self.proxy_port = int(self.proxy_port) except: self.proxy_port = str(int(self.server_port)+1) try: self.auth_method = self._config.query('proxy', 'auth-method') except: self.log.warning("Can't get authentification method from XPL. Use basic by default.") finally: if self.auth_method == None: self.auth_method = "basic" try: self.username = self._config.query('proxy', 'username') self.password = self._config.query('proxy', 'password') except: self.log.warning("Can't get username/password from XPL. Use defaults.") finally: if self.username == None or self.username == "None" : self.username = "******" if self.password == None or self.password == "None" : self.password = "******" try: boo = self._config.query('proxy', 'use-ssl') #print boo self.use_ssl = True if boo == "True" else False if self.use_ssl: cfg_rest = Loader('rest') config_rest = cfg_rest.load() conf_rest = dict(config_rest[1]) self.ssl_certificate = conf_rest['rest_ssl_certificate'] except KeyError: self.log.warning("Can't get ssl configuration from XPL. Do not use it.") self.use_ssl = False self.ssl_certificate = None self.log.info("Proxy configuration : ip:port = %s:%s" % (self.proxy_ip, self.proxy_port)) if self.use_ssl == True: self.log.info("Proxy configuration : SSL support activated (certificate : %s)" % self.ssl_certificate) else: self.log.info("Proxy configuration : SSL support not activated") self.log.info("Proxy authentification : %s" % (self.auth_method)) self.log.info("Rest configuration : ip:port = %s:%s" % (self.server_ip, self.server_port)) try: self.start_http() except : self.log.error("Can't start proxy. Leave plugin.") self.log.error("%s" % str(traceback.format_exc()).replace('"', "'")) self.force_leave() def start_http(self): """ Start HTTP proxy """ # Start HTTP proxy self.log.info("Start HTTP proxy on %s:%s..." % (self.proxy_ip, self.proxy_port)) if self.use_ssl: self.server = HTTPSServerWithParam((self.proxy_ip, int(self.proxy_port)), \ (self.server_ip, int(self.server_port)), \ self.get_stop(), self.log, self.auth_method, \ self.username, self.password, \ ProxyHandler, bind_and_activate=True, handler_params = [self]) else: self.server = HTTPServerWithParam((self.proxy_ip, int(self.proxy_port)), \ (self.server_ip, int(self.server_port)), \ self.get_stop(), self.log, self.auth_method, \ self.username, self.password, \ ProxyHandler, bind_and_activate=True, handler_params = [self]) self.server.serve_forever() #self.log.info("HTTP proxy started.") #self.server.server_bind() #self.server.server_activate() #self.server_process = threading.Thread(None, # self.server.serve_forever(), # "rest_proxy", # (), # {}) #self.log.info("HTTP proxy started.") #self.server_process.start() def stop_http(self): """ Stop HTTP proxy """ if self.server != None: self.server.stop_handling()
class PlcBusMain(XplPlugin): ''' Manage PLCBus technology, send and receive order/state ''' def __init__(self): ''' Create the plcbusMain class This class is used to connect PLCBUS to the xPL Network ''' # Load config XplPlugin.__init__(self, name = 'plcbus') # Create listeners Listener(self._plcbus_cmnd_cb, self.myxpl, { 'schema': 'plcbus.basic', 'xpltype': 'xpl-cmnd', }) self._config = Query(self.myxpl, self.log) device = self._config.query('plcbus', 'device') self._usercode = self._config.query('plcbus', 'usercode') self._probe_inter = int( self._config.query('plcbus', 'probe-interval')) self._probe_list = self._config.query('plcbus', 'probe-list') # Create log instance self.api = PLCBUSAPI(self.log, device, self._command_cb, self._message_cb) self.add_stop_cb(self.api.stop) if self._probe_inter == 0: self.log.warning("The probe interval has been set to 0. This is not correct. The plugin will use a probe interval of 5 seconds") self._probe_inter = 5 self._probe_status = {} self._probe_thr = XplTimer(self._probe_inter, self._send_probe, self.myxpl) self._probe_thr.start() # self.register_timer(self._probe_thr) self.enable_hbeat() def _send_probe(self): """ Send probe message """ for h in self._probe_list: self.log.debug("send get_all_id") self.api.send("GET_ALL_ID_PULSE", h, self._usercode, 0, 0) time.sleep(1) self.log.debug("send get_all_on_id") self.api.send("GET_ALL_ON_ID_PULSE", h, self._usercode, 0, 0) time.sleep(1) def _plcbus_cmnd_cb(self, message): ''' General callback for all command messages ''' cmd = None dev = None user = '******' level = 0 rate = 0 if 'command' in message.data: cmd = message.data['command'] if 'device' in message.data: dev = message.data['device'].upper() if 'usercode' in message.data: user = message.data['usercode'] else: user = self._usercode if 'data1' in message.data: level = message.data['data1'] if 'data2' in message.data: rate = message.data['data2'] self.log.debug("%s received : device = %s, user code = %s, level = "\ "%s, rate = %s" % (cmd.upper(), dev, user, level, rate)) # if cmd == 'GET_ALL_ON_ID_PULSE': # self.api.get_all_on_id(user, dev) # else: self.api.send(cmd.upper(), dev, user, level, rate) # Workaround to send an ON command when dimmer = 0 if cmd == 'PRESET_DIM' and level == 0: print("cmd : %s " % cmd) print("level : %s " % level) self.api.send("OFF", dev, user) if cmd == 'PRESET_DIM' and level != 0: print('WORKAROUD : on fait suivre le DIM d un ON pour garder les widgets switch allumes') print("DEBUG cmd : %s " % cmd) print("DEBUG level : %s " % level) self.api.send("ON", dev, user) def _command_cb(self, f): ''' Called by the plcbus library when a command has been sent. If the commands need an ack, this callback will be called only after the ACK has been received @param : plcbus frame as an array ''' if f["d_command"] == "GET_ALL_ID_PULSE": data = int("%s%s" % (f["d_data1"], f["d_data2"])) house = f["d_home_unit"][0] for i in range(0,16): unit = data >> i & 1 code = "%s%s" % (house, i+1) if unit and not code in self._probe_status: self._probe_status[code] = "" self.log.info("New device discovered : %s" % code) elif (not unit) and code in self._probe_status: del self._probe_status[code] elif f["d_command"] == "GET_ALL_ON_ID_PULSE": data = "%s%s" % (bin(f["d_data1"])[2:].zfill(8), bin(f["d_data2"])[2:].zfill(8)) print("f : %s" % f) print("data : %s" % data) house = f["d_home_unit"][0] item = 16 for c in data: unit=int(c) code = "%s%s" % (house, item) print("Etat : %s " % code, unit) if code in self._probe_status and (self._probe_status[code] != str(unit)): print('DEBUG in rentre dans le IF detection GET_ALL_ON') self._probe_status[code] = str(unit) if unit == 1: command = "ON" else: command ="OFF" mess = XplMessage() mess.set_type('xpl-trig') mess.set_schema('plcbus.basic') mess.add_data({"usercode" : f["d_user_code"], "device": code, "command": command}) self.myxpl.send(mess) item = item - 1 else: mess = XplMessage() mess.set_type('xpl-trig') mess.set_schema('plcbus.basic') mess.add_data({"usercode" : f["d_user_code"], "device": f["d_home_unit"], "command": f["d_command"], "data1": f["d_data1"], "data2": f["d_data2"]}) self.myxpl.send(mess) # Workaround to for switch widget go ON when dimmer is send # if f["d_command"] == 'PRESET_DIM' and f["d_data1"] != 0 : # print('WORKAROUD : on fait suivre le DIM d un ON pour garder les widgets switch allumes') #print("data1 : %s " % f["d_data1"]) # mess = XplMessage() # mess.set_type('xpl-stat') # mess.set_schema('plcbus.basic') # mess.add_data({"usercode" : f["d_user_code"], "device": f["d_home_unit"], "command": 'ON'}) # self.myxpl.send(mess) def _message_cb(self, message): print("Message : %s " % message)
class NBZNotificationListener(XplPlugin): """ Create listener for xPL messages about Nabaztag TTS notification """ def __init__(self): """ Create listener for Nabaztag TTS notification """ XplPlugin.__init__(self, name='nbz_tts') # Create logger self.log.debug("Listener for Nabaztag TTS notification created") # Configuration : list of nabaztag whith serial, token and voice self.alias_list = {} num = 1 loop = True self._config = Query(self.myxpl, self.log) while loop == True: nabaztag = self._config.query('nbz_tts', 'name-%s' % str(num)) serial = self._config.query('nbz_tts', 'serial-%s' % str(num)) token = self._config.query('nbz_tts', 'token-%s' % str(num)) voice = self._config.query('nbz_tts', 'voice-%s' % str(num)) if nabaztag != None: mess = "Configuration : nabaztag=" + str( nabaztag) + " , serial=" + str(serial) + ", token=" + str( token) + ", voice=" + str(voice) self.log.info(mess) print(mess) self.alias_list[nabaztag] = { "nabaztag": nabaztag, "serial": serial, "token": token, "voice": voice } num += 1 else: loop = False # no nabaztag configured if num == 1: msg = "No nabaztag configured. Exiting plugin" self.log.info(msg) print(msg) self.force_leave() return # Check serial for alias in self.alias_list: if str(self.alias_list[alias]['serial']) != "None": self.log.debug("Serial for nabaztag " + str(self.alias_list[alias]['nabaztag']) + " is " + str(self.alias_list[alias]['serial'])) else: self.log.error( "Can't find the serial for the nabaztag " + str(self.alias_list[alias]['nabaztag']) + " , please check the configuration page of this plugin") self.force_leave() return # Check token for alias in self.alias_list: if str(self.alias_list[alias]['token']) != "None": self.log.debug("Token for nabaztag " + str(self.alias_list[alias]['nabaztag']) + " is " + str(self.alias_list[alias]['token'])) else: self.log.error( "Can't find the Token for the nabaztag " + str(self.alias_list[alias]['nabaztag']) + " , please check the configuration page of this plugin") self.force_leave() return # Check voice for alias in self.alias_list: if str(self.alias_list[alias]['voice']) != "None": self.log.debug("Voice for nabaztag " + str(self.alias_list[alias]['nabaztag']) + " is " + str(self.alias_list[alias]['voice'])) else: self.log.error( "Can't find the Voice for the nabaztag " + str(self.alias_list[alias]['nabaztag']) + " , please check the configuration page of this plugin") self.force_leave() return # Create NBZNotification object self.nbz_notification_manager = NBZNotification(self.log) # Create listeners Listener(self.nbz_notification_cb, self.myxpl, { 'schema': 'sendmsg.push', 'xpltype': 'xpl-cmnd' }) self.enable_hbeat() def nbz_notification_cb(self, message): """ Call Nabaztag TTS lib @param message : message to send """ self.log.debug("Call nbz_notification_cb") # mandatory keys if 'to' in message.data: to = message.data['to'] for alias in self.alias_list: try: if str(self.alias_list[alias]['nabaztag']) == str(to): serialkey = self.alias_list[alias]['serial'] tokenkey = self.alias_list[alias]['token'] voicekey = self.alias_list[alias]['voice'] except: self.log.debug( "Can't find the recipient, please check the configuration page of this plugin" ) self.force_leave() return else: self.log.warning("No recipient was found in the xpl message") return if 'body' in message.data: body = message.data['body'] else: self.log.warning("No message was found in the xpl message") return self.log.debug("Call send_tts with following parameters : serial=" + serialkey + ", token=" + tokenkey + ", message=" + body + ", voice=" + voicekey) self.nbz_notification_manager.send_tts(serialkey, tokenkey, body, voicekey)
class Rest(XplPlugin): """ REST Server - create a HTTP server - process REST requests """ def __init__(self, server_ip, server_port): """ Initiate DbHelper, Logs and config Then, start HTTP server and give it initialized data @param server_ip : ip of HTTP server @param server_port : port of HTTP server """ XplPlugin.__init__(self, name='rest') # logging initialization self.log.info("Rest Server initialisation...") self.log.debug("locale : %s %s" % locale.getdefaultlocale()) # logging Queue activities log_queue = logger.Logger('rest-queues') self.log_queue = log_queue.get_logger('rest-queues') self.log_queue.info("Rest's queues activities...") # logging data manipulation initialization log_dm = logger.Logger('rest-dm') self.log_dm = log_dm.get_logger('rest-dm') self.log_dm.info("Rest Server Data Manipulation...") # API version self._rest_api_version = REST_API_VERSION # Hosts list self._hosts_list = { self.get_sanitized_hostname(): { "id": self.get_sanitized_hostname(), "status": "on", "primary": True, "last_seen": time.time(), "ip": "", "interval": "1" } } try: ### Config # directory data cfg = Loader('domogik') config = cfg.load() conf = dict(config[1]) self.log_dir_path = conf['log_dir_path'] # plugin installation path if conf.has_key('package_path'): self._package_path = conf['package_path'] self._src_prefix = None self.log.info("Set package path to '%s' " % self._package_path) print("Set package path to '%s' " % self._package_path) self._design_dir = "%s/domogik_packages/design/" % self._package_path self.package_mode = True else: self.log.info("No package path defined in config file") self._package_path = None self._src_prefix = conf['src_prefix'] self._design_dir = "%s/share/domogik/design/" % conf[ 'src_prefix'] self.package_mode = False # HTTP server ip and port try: cfg_rest = Loader('rest') config_rest = cfg_rest.load() conf_rest = dict(config_rest[1]) self.server_ip = conf_rest['rest_server_ip'] self.server_port = conf_rest['rest_server_port'] except KeyError: # default parameters self.server_ip = server_ip self.server_port = server_port self.log.info("Configuration : ip:port = %s:%s" % (self.server_ip, self.server_port)) # SSL configuration try: cfg_rest = Loader('rest') config_rest = cfg_rest.load() conf_rest = dict(config_rest[1]) self.use_ssl = conf_rest['rest_use_ssl'] if self.use_ssl == "True": self.use_ssl = True else: self.use_ssl = False self.ssl_certificate = conf_rest['rest_ssl_certificate'] except KeyError: # default parameters self.use_ssl = USE_SSL self.ssl_certificate = SSL_CERTIFICATE if self.use_ssl == True: self.log.info( "Configuration : SSL support activated (certificate : %s)" % self.ssl_certificate) else: self.log.info("Configuration : SSL support not activated") # File repository try: cfg_rest = Loader('rest') config_rest = cfg_rest.load() conf_rest = dict(config_rest[1]) self.repo_dir = conf_rest['rest_repository'] except KeyError: # default parameters self.repo_dir = DEFAULT_REPO_DIR # Gloal Queues config self.log.debug("Get queues configuration") self._config = Query(self.myxpl, self.log) self._queue_timeout = self._config.query('rest', 'q-timeout') if self._queue_timeout == None: self._queue_timeout = QUEUE_TIMEOUT self._queue_timeout = float(self._queue_timeout) self._queue_package_size = self._config.query('rest', 'q-pkg-size') if self._queue_package_size == None: self._queue_package_size = QUEUE_PACKAGE_SIZE self._queue_package_size = float(self._queue_package_size) self._queue_size = self._config.query('rest', 'q-size') if self._queue_size == None: self._queue_size = QUEUE_SIZE self._queue_size = float(self._queue_size) self._queue_life_expectancy = self._config.query( 'rest', 'q-life-exp') if self._queue_life_expectancy == None: self._queue_life_expectancy = QUEUE_LIFE_EXPECTANCY self._queue_life_expectancy = float(self._queue_life_expectancy) self._queue_sleep = self._config.query('rest', 'q-sleep') if self._queue_sleep == None: self._queue_sleep = QUEUE_SLEEP self._queue_sleep = float(self._queue_sleep) # /command Queues config self._queue_command_size = self._config.query('rest', 'q-cmd-size') if self._queue_command_size == None: self._queue_command_size = QUEUE_COMMAND_SIZE self._queue_command_size = float(self._queue_command_size) # /event Queues config self._event_timeout = self._config.query('rest', 'evt-timeout') if self._event_timeout == None: self._event_timeout = EVENT_TIMEOUT self._event_timeout = float(self._event_timeout) self._queue_event_size = self._config.query('rest', 'q-evt-size') if self._queue_event_size == None: self._queue_event_size = QUEUE_EVENT_SIZE self._queue_event_size = float(self._queue_event_size) self._queue_event_timeout = self._config.query( 'rest', 'q-evt-timeout') if self._queue_event_timeout == None: self._queue_event_timeout = QUEUE_EVENT_TIMEOUT self._queue_event_timeout = float(self._queue_event_timeout) self._queue_event_life_expectancy = self._config.query( 'rest', 'q-evt-life-exp') if self._queue_event_life_expectancy == None: self._queue_event_life_expectancy = QUEUE_EVENT_LIFE_EXPECTANCY self._queue_event_life_expectancy = float( self._queue_event_life_expectancy) # Queues for xPL # Queues for packages management self._queue_package = Queue(self._queue_package_size) # Queues for domogik system actions self._queue_system_list = Queue(self._queue_size) self._queue_system_detail = Queue(self._queue_size) self._queue_system_start = Queue(self._queue_size) self._queue_system_stop = Queue(self._queue_size) # Queues for /command self._queue_command = Queue(self._queue_command_size) # Queues for /events/domogik self._queue_event_dmg = Queue(self._queue_event_size) # Queues for /events/request # this queue will be fill by stat manager self._event_requests = RequestEvents( self.get_stop, self.log, self._event_timeout, self._queue_event_size, self._queue_event_timeout, self._queue_event_life_expectancy) self.add_stop_cb(self._event_requests.set_stop_clean) # Queues for /events/domogik # this queue will be fill by stat manager self._event_dmg = DmgEvents(self.get_stop, self.log, self._event_timeout, self._queue_event_size, self._queue_event_timeout, self._queue_event_life_expectancy) # notice : adding data in queue is made in _add_to_queue_system_list self.add_stop_cb(self._event_dmg.set_stop_clean) # define listeners for queues self.log.debug("Create listeners") if self.package_mode == True: Listener(self._list_installed_packages, self.myxpl, \ {'schema': 'domogik.package', 'xpltype': 'xpl-trig', 'command' : 'installed-packages-list'}) Listener(self._add_to_queue_package, self.myxpl, \ {'schema': 'domogik.package', 'xpltype': 'xpl-trig'}) Listener(self._add_to_queue_system_list, self.myxpl, \ {'schema': 'domogik.system', 'xpltype': 'xpl-trig', 'command' : 'list'}) Listener(self._add_to_queue_system_list, self.myxpl, \ {'schema': 'domogik.system', 'xpltype': 'xpl-trig', 'command' : 'enable'}) Listener(self._add_to_queue_system_list, self.myxpl, \ {'schema': 'domogik.system', 'xpltype': 'xpl-trig', 'command' : 'disable'}) Listener(self._add_to_queue_system_detail, self.myxpl, \ {'schema': 'domogik.system', 'xpltype': 'xpl-trig', 'command' : 'detail'}) Listener(self._add_to_queue_system_start, self.myxpl, \ {'schema': 'domogik.system', 'xpltype': 'xpl-trig', 'command' : 'start'}) Listener(self._add_to_queue_system_stop, self.myxpl, \ {'schema': 'domogik.system', 'xpltype': 'xpl-trig', 'command' : 'stop'}) Listener(self._add_to_queue_command, self.myxpl, \ {'xpltype': 'xpl-trig'}) # Listener for hosts list Listener(self._list_hosts, self.myxpl, \ {'schema': 'hbeat.app', 'xpltype': 'xpl-stat'}) # Background process to check if hosts has disappeared thr_hbeat = XplTimer(10, \ self._refresh_status_for_list_hosts, \ self.myxpl) thr_hbeat.start() self._discover_hosts() # Enable hbeat self.enable_hbeat() # Ask for installed packages on all hosts # Semaphore init for installed package list update self.sema_installed = Semaphore(value=1) self._installed_packages = {} if self.package_mode == True: self._get_installed_packages_from_manager() # Launch server, stats self.log.info("REST Initialisation OK") self.add_stop_cb(self.stop_http) self.server = None self.start_stats() self.start_http() except: self.log.error("%s" % self.get_exception()) def _add_to_queue_package(self, message): """ Add data in a queue """ self._put_in_queue(self._queue_package, message) def _add_to_queue_system_list(self, message): """ Add data in a queue """ self._put_in_queue(self._queue_system_list, message) current_date = calendar.timegm(time.gmtime()) self._event_dmg.add_in_queues({ "timestamp": current_date, "data": "plugin-list-updated" }) def _add_to_queue_system_detail(self, message): """ Add data in a queue """ self._put_in_queue(self._queue_system_detail, message) def _add_to_queue_system_start(self, message): """ Add data in a queue """ self._put_in_queue(self._queue_system_start, message) def _add_to_queue_system_stop(self, message): """ Add data in a queue """ self._put_in_queue(self._queue_system_stop, message) def _add_to_queue_command(self, message): """ Add data in a queue """ self._put_in_queue(self._queue_command, message) def _get_from_queue(self, my_queue, filter_type=None, filter_schema=None, filter_data=None, nb_rec=0, timeout=None): """ Encapsulation for _get_from_queue_in If timeout not elapsed and _get_from_queue didn't find a valid data call again _get_from_queue until timeout This encapsulation is used to process case where queue is not empty but there is no valid data in it and we want to wait for timeout """ if timeout == None: timeout = self._queue_timeout start_time = time.time() while time.time() - start_time < timeout: try: return self._get_from_queue_without_waiting( my_queue, filter_type, filter_schema, filter_data, nb_rec, timeout) except Empty: # no data in queue for us.... let's continue until time elapsed # in order not rest not working so much, let it make a pause time.sleep(self._queue_sleep) # time elapsed... we can raise the Empty exception raise Empty def _get_from_queue_without_waiting(self, my_queue, filter_type=None, filter_schema=None, filter_data=None, nb_rec=0, timeout=None): """ Get an item from queue (recursive function) Checks are made on : - life expectancy of message - filter given - size of queue If necessary, each item of queue is read. @param my_queue : queue to get data from @param filter_type : filter on a schema type @param filter_schema : filter on a specific schema @param filter_data : dictionnay of filters. Examples : - {"command" : "start", ...} - {"plugin" : "wol%", ...} : here "%" indicate that we search for something starting with "wol" @param nb_rec : internal parameter (do not use it for first call). Used to check recursivity VS queue size @param timeout : to use a different timeout from default one """ if timeout == None: timeout = self._queue_timeout self.log_queue.debug("Get from queue : %s (recursivity deepth : %s)" % (str(my_queue), nb_rec)) # check if recursivity doesn't exceed queue size if nb_rec > my_queue.qsize(): self.log_queue.warning( "Get from queue %s : number of call exceed queue size (%s) : return None" % (str(my_queue), my_queue.qsize())) # we raise an "Empty" exception because we consider that if we don't find # the good data, it is as if it was "empty" raise Empty msg_time, message = my_queue.get(True, timeout) # if message not too old, we process it if time.time() - msg_time < self._queue_life_expectancy: # no filter defined if filter_type == None and filter_schema == None and filter_data == None: self.log_queue.debug("Get from queue %s : return %s" % (str(my_queue), str(message))) return message # we want to filter data else: keep_data = True if filter_type != None and filter_type.lower( ) != message.type.lower(): keep_data = False if filter_schema != None and filter_schema.lower( ) != message.schema.lower(): keep_data = False if filter_data != None and keep_data == True: # data self.log_queue.debug("Filter on message %s WITH %s" % (message.data, filter_data)) for key in filter_data: # take care of final "%" in order to search data starting by filter_data[key] if filter_data[key][-1] == "%": if message.data.has_key(key): msg_data = str(message.data[key]) my_filter_data = str(filter_data[key]) len_data = len(my_filter_data) - 1 if msg_data[0:len_data] != my_filter_data[0:-1]: keep_data = False else: keep_data = False # normal search else: if message.data.has_key(key): if message.data[key].lower( ) != filter_data[key].lower(): keep_data = False else: keep_data = False # if message is ok for us, return it if keep_data == True: self.log_queue.debug("Get from queue %s : return %s" % (str(my_queue), str(message))) return message # else, message get back in queue and get another one else: self.log_queue.debug( "Get from queue %s : bad data, check another one..." % (str(my_queue))) self._put_in_queue(my_queue, message) return self._get_from_queue_without_waiting( my_queue, filter_type, filter_schema, filter_data, nb_rec + 1, timeout) # if message too old : get an other message else: self.log_queue.debug( "Get from queue %s : data too old, check another one..." % (str(my_queue))) return self._get_from_queue_without_waiting( my_queue, filter_type, filter_schema, filter_data, nb_rec + 1, timeout) def _put_in_queue(self, my_queue, message): """ put a message in a named queue @param my_queue : queue @param message : data to put in queue """ self.log_queue.debug("Put in queue %s : %s" % (str(my_queue), str(message))) try: my_queue.put((time.time(), message), True, self._queue_timeout) # Clean queue to make space except Full: msg = "Queue '%s' is full : cleaning it to make some space..." % my_queue self.log_queue.debug(msg) print(msg) # queue is full : start cleaning it nb_ck = 0 while nb_ck < my_queue.qsize(): (q_time, q_data) = my_queue.get() # data to keep if time.time() - self._queue_life_expectancy < q_time: my_queue.put((q_time, q_data), True, self._queue_timeout) nb_ck += 1 my_queue.put((time.time(), message), True, self._queue_timeout) self.log_queue.debug("Cleaning finished") def _discover_hosts(self): """ Send a hbeat.request to discover managers """ mess = XplMessage() mess.set_type('xpl-cmnd') mess.set_target("*") mess.set_schema('hbeat.request') mess.add_data({'command': 'request'}) self.myxpl.send(mess) def _list_hosts(self, message): """ Maintain list of Domogik hosts @param message : hbeat.app xpl message """ tmp1 = message.source.split(".") tmp2 = tmp1[0].split("-") vendor = tmp2[0] device = tmp2[1] instance = tmp1[1] if vendor == "domogik" and device == "manager": # host not in the list if self._hosts_list.has_key(instance) == False: self._hosts_list[instance] = {"primary": False} self._hosts_list[instance]["status"] = "on" self._hosts_list[instance]["last_seen"] = time.time() self._hosts_list[instance]["interval"] = 60 * int( message.data["interval"]) self._hosts_list[instance]["ip"] = message.data["remote-ip"] self._hosts_list[instance]["id"] = instance def _refresh_status_for_list_hosts(self): """ Check if hosts has disappeared """ now = time.time() for instance in self._hosts_list: if (now - self._hosts_list[instance]["last_seen"] > self._hosts_list[instance]["interval"]): self._hosts_list[instance]["status"] = "off" def _get_installed_packages_from_manager(self): """ Send a xpl message to all managers to get installed packages list """ ### Send xpl message to get list message = XplMessage() message.set_type("xpl-cmnd") message.set_schema("domogik.package") message.add_data({"command": "installed-packages-list"}) message.add_data({"host": "*"}) self.myxpl.send(message) def get_installed_packages(self): """ return list of installed packages There is a semaphore in order not to return the list when it is updated (may be incomplete) """ # developper mode : all plugins are installed # TODO : remove log lines after tests self.log.debug("*** get_installed_packages") self.sema_installed.acquire() self.log.debug("*** sema acquired") ret = self._installed_packages self.sema_installed.release() self.log.debug("*** sema released") return ret def _list_installed_packages(self, message): """ Called when a list of installed packages is received @param host : host @param pkg_type : type of package """ print("Get new installed packages list") self.log.debug("Get new installed packages list") self.sema_installed.acquire() self.log.debug("*** sema acquired") self.log.debug("*** msg = %s" % message) # process message host = message.data["host"] self._installed_packages[host] = {} pkg_mgr = PackageManager() idx = 0 loop_again = True self.log.debug("*** before while") while loop_again: try: self.log.debug("*** in while : idx=%s" % idx) pkg_type = message.data["type" + str(idx)] if message.data["enabled" + str(idx)].lower() == "yes": enabled = True else: enabled = False data = { "fullname": message.data["fullname" + str(idx)], "id": message.data["id" + str(idx)], "version": message.data["version" + str(idx)], "type": message.data["type" + str(idx)], #"source" : message.data["source"+str(idx)], "enabled": enabled } self.log.debug("*** call get_available_updates(%s, %s, %s)" % (data["type"], data["id"], data["version"])) updates = pkg_mgr.get_available_updates( data["type"], data["id"], data["version"]) self.log.debug("*** after get_available_updates") data["updates"] = updates if self._installed_packages[host].has_key(pkg_type) == False: self._installed_packages[host][pkg_type] = [] self._installed_packages[host][pkg_type].append(data) self.log.debug("*** before idx += 1") idx += 1 except KeyError: self.log.debug("*** except keyerror") loop_again = False except: self.log.debug("*** except global") self.log.error( "Error while creating list of installed packages : %s" % traceback.format_exc()) loop_again = False self.log.debug("*** before release") self.sema_installed.release() self.log.debug("*** sema released") def start_http(self): """ Start HTTP Server """ # Start HTTP server self.log.info("Start HTTP Server on %s:%s..." % (self.server_ip, self.server_port)) if self.use_ssl: self.server = HTTPSServerWithParam((self.server_ip, int(self.server_port)), RestHandler, \ handler_params = [self]) else: self.server = HTTPServerWithParam((self.server_ip, int(self.server_port)), RestHandler, \ handler_params = [self]) self.server.serve_forever() def stop_http(self): """ Stop HTTP Server """ self.server.stop_handling() def start_stats(self): """ Start Statistics manager """ print("Start Stats") self.log.info( "Starting statistics manager. Its logs will be in a dedicated log file" ) self.stat_mgr = StatsManager(handler_params=[self], xpl=self.myxpl) self.stat_mgr.load() self.log.info("Stat manager started") def reload_stats(self): """ Reload Statistics manager """ time.sleep(1) print("Reload Stats") self.log.info( "Reloading statistics manager. Its logs will be in a dedicated log file" ) self.stat_mgr.load() def get_exception(self): """ Get exception and display it on stdout """ my_exception = str(traceback.format_exc()).replace('"', "'") print("==== Error in REST ====") print(my_exception) print("=======================") return my_exception
class DemoDataManager(XplPlugin): """ Sends demo data over xPL """ def __init__(self): """ Init plugin """ XplPlugin.__init__(self, name='demodata') ### Get config self._config = Query(self.myxpl, self.log) port = self._config.query('demodata', 'port') if port == None: port = DEFAULT_PORT else: port = int(port) self.log.info("Listen port is %s" % port) self.log.info("Start creating the listeners") ### Create listeners for the fake actuator devices # RGB controller Listener(self.cmd_arduino_rgb, self.myxpl, { 'schema': 'arduino.rgb', 'xpltype': 'xpl-cmnd', }) # Switch # Dimmer Listener(self.cmd_lighting_basic, self.myxpl, { 'schema': 'lighting.basic', 'xpltype': 'xpl-cmnd', }) self.log.info("All listeners are created") ### Call the data creators self.log.info("Start all the data creator threads") demo = DemoData(self.log, self.send_sensor_basic, \ self.send_teleinfo_basic) # weather data each minute self._weather_thr = XplTimer(60, \ demo.weather_data, \ self.myxpl) self._weather_thr.start() # teleinfo data each 10min self._teleinfo_thr = XplTimer(600, \ demo.teleinfo_data, \ self.myxpl) self._teleinfo_thr.start() # tank data each 1min self._tank_thr = XplTimer(60, \ demo.tank_data, \ self.myxpl) self._tank_thr.start() # water data each 1min self._water_thr = XplTimer(60, \ demo.water_data, \ self.myxpl) self._water_thr.start() self.log.info("All the data creator threads created") self.enable_hbeat() # Launch the web UI #demo_ui = DemoUI() msg = "Launch the Web UI on port %s" % port print(msg) self.log.info(msg) self.add_stop_cb(self.stop_http) self.server = None self.server_ip = '' self.server_port = port self.start_http() def start_http(self): """ Start HTTP Server """ self.server = HTTPServerWithParam((self.server_ip, int(self.server_port)), UIHandler, \ handler_params = [self]) self.server.serve_forever() def stop_http(self): """ Stop HTTP Server """ self.server.stop_handling() def send_sensor_basic(self, device, type, current, units = None): """ Send sensor.basic xPL schema @param device : device @param type : type @param current : current """ mess = "sensor.basic { device=%s, type=%s, current=%s}" % (device, type, current) print(mess) self.log.debug(mess) if current == "": return msg = XplMessage() msg.set_type("xpl-stat") msg.set_schema("sensor.basic") msg.add_data({"device" : device}) msg.add_data({"type" : type}) msg.add_data({"current" : current}) if units != None: msg.add_data({"units" : units}) self.myxpl.send(msg) def send_teleinfo_basic(self, frame): ''' Send a frame from teleinfo device to xpl @param frame : a dictionnary mapping teleinfo informations ''' mess = "teleinfo.basic : %s" % frame print(mess) self.log.debug(mess) msg = XplMessage() msg.set_type("xpl-stat") msg.set_schema("teleinfo.basic") for key in frame: msg.add_data({ key : frame[key] }) self.myxpl.send(msg) # RGB controller def cmd_arduino_rgb(self, message): device = message.data['device'] command = message.data['command'] color = message.data['color'] # send symetric answer to simulate the device self.send_arduino_rgb(device, command, color) def send_arduino_rgb(self, device, command, color): mess = "arduino.rgb : device=%s, command=%s, color=%s" % (device, command, color) print(mess) self.log.debug(mess) msg = XplMessage() msg.set_type("xpl-trig") msg.set_schema("arduino.rgb") msg.add_data({ 'device' : device }) msg.add_data({ 'command' : command }) msg.add_data({ 'color' : color }) self.myxpl.send(msg) # Switch # Dimmer def cmd_lighting_basic(self, message): device = message.data['device'] command = message.data['command'] if message.data.has_key('fade-rate'): fade_rate = message.data['fade-rate'] else: fade_rate = None if message.data.has_key('level'): level = message.data['level'] else: level = None # send symetric answer to simulate the device self.send_lighting_device(device, command, level, fade_rate) def send_lighting_device(self, device, command, level = None, fade_rate = None): mess = "lighting.device : device=%s, command=%s, level=%s, fade_rate=%s" % (device, command, level, fade_rate) print(mess) self.log.debug(mess) msg = XplMessage() msg.set_type("xpl-trig") msg.set_schema("lighting.device") msg.add_data({ 'device' : device }) if level != None: msg.add_data({ 'level' : level }) if fade_rate != None: msg.add_data({ 'fade-rate' : fade_rate }) self.myxpl.send(msg) # Caller id def send_cid_basic(self, device, calltype, phone_number): # Notice that device is not used in this xpl schema mess = "cid.basic : calltype=%s, phone=%s" % (calltype, phone_number) print(mess) self.log.debug(mess) msg = XplMessage() msg.set_type("xpl-trig") msg.set_schema("cid.basic") msg.add_data({ 'calltype' : calltype }) msg.add_data({ 'phone' : phone_number }) self.myxpl.send(msg)
class IPXManager(XplPlugin): """ Implements a listener for IPX command messages and launch background listening for relay board status """ def __init__(self): """ Create lister and launch bg listening """ XplPlugin.__init__(self, name='ipx800') # Configuration : list of IPX800 self.ipx_list = {} num = 1 loop = True self._config = Query(self.myxpl, self.log) while loop == True: model = self._config.query('ipx800', 'model-%s' % str(num)) login = self._config.query('ipx800', 'login-%s' % str(num)) password = self._config.query('ipx800', 'password-%s' % str(num)) name = self._config.query('ipx800', 'name-%s' % str(num)) address = self._config.query('ipx800', 'ip-%s' % str(num)) inter = self._config.query('ipx800', 'int-%s' % str(num)) if name != None: self.log.info( "Configuration : login=%s, password=***, name=%s, ip=%s, interval=%s" % (login, name, address, inter)) self.ipx_list[name] = { "login": login, "password": password, "model": model, "ip": address, "interval": float(inter) } num += 1 else: loop = False # no ipx configured if num == 1: msg = "No ipx800 board configured. Exiting plugin" self.log.info(msg) print(msg) self.force_leave() return ### Create IPX objects num_ok = 0 for ipx in self.ipx_list: self.ipx_list[ipx]['obj'] = IPX(self.log, self.send_xpl, self.get_stop()) try: self.log.info("Opening IPX800 named '%s' (ip : %s)" % (ipx, self.ipx_list[ipx]['ip'])) self.ipx_list[ipx]['obj'].open(ipx, self.ipx_list[ipx]['ip'], self.ipx_list[ipx]['model'], self.ipx_list[ipx]['login'], self.ipx_list[ipx]['password']) except: self.log.error("Error opening board '%s' : %s " % (ipx, traceback.format_exc())) print("Error opening board '%s' : check logs" % ipx) else: num_ok += 1 # no valid ipx800 board detected if num_ok == 0: msg = "No valid IPX800 board configured. Exiting plugin..." self.log.info(msg) print(msg) self.force_leave() return ### Start listening each IPX800 for ipx in self.ipx_list: try: self.log.info("Start listening to IPX800 named '%s'" % ipx) ipx_listen = threading.Thread( None, self.ipx_list[ipx]['obj'].listen, "listen_ipx", (self.ipx_list[ipx]['interval'], ), {}) ipx_listen.start() except IPXException as err: self.log.error(err.value) print(err.value) # we don't quit plugin if an error occured # we can loose a board for a little time #self.force_leave() #return ### Create listeners for commands self.log.info("Creating listener for IPX 800") #Listener(self.ipx_command, self.myxpl, {'schema': 'control.basic', # 'xpltype': 'xpl-cmnd', 'type': ['output', 'count']}) Listener(self.ipx_command, self.myxpl, { 'schema': 'control.basic', 'xpltype': 'xpl-cmnd', 'type': 'output' }) self.enable_hbeat() self.log.info("Plugin ready :)") def send_xpl(self, msg_device, msg_current, msg_type): """ Send xpl-trig to give status change @param msg_device : device @param msg_current : device's value @param msg_type : device's type """ msg = XplMessage() msg.set_type("xpl-trig") msg.set_schema('sensor.basic') msg.add_data({'device': msg_device}) if msg_type != None: msg.add_data({'type': msg_type}) msg.add_data({'current': msg_current}) self.myxpl.send(msg) def ipx_command(self, message): """ Call ipx800 lib function in function of given xpl message @param message : xpl message """ if 'device' in message.data: msg_device = message.data['device'] if 'type' in message.data: msg_type = message.data['type'].lower() if 'current' in message.data: msg_current = message.data['current'].lower() data = "device=%s, type=%s, current=%s" % (msg_device, msg_type, msg_current) print data data_name = msg_device.split("-") ipx_name = data_name[0] elt = data_name[1][0:-1] num = int(data_name[1][-1]) if not ipx_name in self.ipx_list: self.log.warning("No IPX800 board called '%s' defined" % ipx_name) return # check data if elt == 'led' and msg_current not in ['high', 'low', 'pulse'] \ and msg_type != 'output': self.log.warning("Bad data : %s" % data) return # TODO in a next release : other checks : counter # action in function of type if elt == 'led' and msg_type == 'output' and msg_current in [ 'high', 'low' ]: self.ipx_list[ipx_name]['obj'].set_relay(num, msg_current) elif elt == 'led' and msg_type == 'output' and msg_current == 'pulse': self.ipx_list[ipx_name]['obj'].pulse_relay(num)
class Lighting(XplPlugin): ''' Manage lighting schema over XPL ''' def __init__(self): """ Create the lighting class """ XplPlugin.__init__(self, name = 'lighting') self.log.debug("lighting.__init__ : Start ...") self._config = Query(self.myxpl, self.log) self.log.debug("lighting.__init__ : Try to get configuration from XPL") try: #self.use_cron = bool(self._config.query('lighting', 'usecron')) self.broadcast = bool(self._config.query('lighting', 'broadcast')) #self.presence = bool(self._config.query('lighting', 'presence')) except: error = "Can't get configuration from XPL : %s" % \ (traceback.format_exc()) self.log.exception("lighting.__init__ : " + error) #self.use_cron = True self.broadcast = True #self.presence = True raise LightingException(error) self.log.debug("lighting.__init__ : Try to start the lighting librairy") try: self._mylighting = LightingAPI(self.broadcast, \ self.myxpl, self.log, self.get_data_files_directory()) except: error = "Something went wrong during lightingAPI init : %s" % \ (traceback.format_exc()) self.log.error("lighting.__init__ : "+error) self.force_leave() raise LightingException(error) self.log.debug("lighting.__init__ : Try to create listeners") Listener(self.lighting_config_cmnd, self.myxpl, {'schema': 'lighting.config', 'xpltype': 'xpl-cmnd'}) Listener(self.lighting_basic_cmnd, self.myxpl, {'schema': 'lighting.basic', 'xpltype': 'xpl-cmnd'}) # Listener(self.lighting_basic_trig, self.myxpl, # {'schema': 'lighting.basic', 'xpltype': 'xpl-trig'}) self.enable_hbeat() self._mylighting.reload_config() self.log.info("Plugin lighting correctly started.") def lighting_basic_trig(self, message): """ General callback for all command messages @param message : an XplMessage object """ self.log.debug("lighting_basic_trig() : Start ...") self._mylighting.basic_trig_listener(message) self.log.debug("lighting_basic_trig() : Done :)") def lighting_config_cmnd(self, message): """ General callback for all command messages @param message : an XplMessage object """ self.log.debug("lighting_config_cmnd() : Start ...") self._mylighting.config_cmnd_listener(message) self.log.debug("lighting_config_cmnd() : Done :)") def lighting_basic_cmnd(self, message): """ General callback for all command messages @param message : an XplMessage object """ self.log.debug("lighting_basic_cmnd() : Start ...") self._mylighting.basic_cmnd_listener(message) self.log.debug("lighting_basic_cmnd() : Done :)")
class Telldus(XplHlpPlugin): ''' Manage chacon devices through the TellStick device ''' def __init__(self): """ Create the telldus class This class is used to connect devices (through telldus) to the xPL Network """ XplHlpPlugin.__init__(self, name='telldus', reload_cb=self.telldus_reload_config_cb) self.log.debug("telldus.__init__ : Start ...") self._device = "/dev/tellstick" #Check if the device exists if not os.path.exists(self._device): self.log.warning(self._device + " is not present but Tellstick Duo don't use it.") else: self.log.debug("Device present as " + self._device) self._config = Query(self.myxpl, self.log) self.log.debug("telldus.__init__ : Try to load API") try: self._mytelldus = TelldusAPI(self, self.send_xpl, self.log, self._config, self.get_data_files_directory(), self.myxpl) except Exception: self.log.error("Something went wrong during telldus API init.") self.log.error("%s" % (traceback.format_exc())) self.force_leave() exit(1) self.add_stop_cb(self._mytelldus.unregister) self.log.debug("telldus.__init__ : Create listeners") Listener(self.telldus_cmnd_cb, self.myxpl, { 'schema': 'telldus.basic', 'xpltype': 'xpl-cmnd' }) Listener( self.telldus_reload_config_cb, self.myxpl, { 'schema': 'domogik.system', 'xpltype': 'xpl-cmnd', 'command': 'reload', 'plugin': 'telldus' }) self.enable_hbeat() try: boo = self._config.query('telldus', 'lightext') if boo == None: boo = "False" self.lightext = eval(boo) except: self.log.warning( "Can't get delay configuration from XPL. Disable lighting extensions." ) self.lightext = False if self.lightext == True: self.log.debug( "telldus.__init__ : Try to load the lighting extension.") self.lighting = LightingExtension(self, self._name, \ self._mytelldus.lighting_activate_device, \ self._mytelldus.lighting_deactivate_device, \ self._mytelldus.lighting_valid_device) self.helpers = \ { "list" : { "cb" : self._mytelldus.helper.helper_list, "desc" : "List devices in telldus daemon.", "usage" : "list [devicetype]", "param-list" : "devicetype", "min-args" : 0, "devicetype" : "the type of device to find", }, "info" : { "cb" : self._mytelldus.helper.helper_info, "desc" : "Display device information.", "usage" : "info <device>", "param-list" : "device", "min-args" : 1, "device" : "device address", }, "memory" : { "cb" : self._mytelldus.helper.helper_memory, "desc" : "Show memory usage of variables. Experimental.", "usage" : "memory", "param-list" : "", "min-args" : 0, }, } if self.lightext == True: self.log.debug( "telldus.__init__ : Try to enable the lighting extension.") self.lighting.enable_lighting() self.log.debug("telldus.__init__ : Try to load the helpers.") self.enable_helper() self.log.info("Telldus plugin correctly started") def telldus_cmnd_cb(self, message): """ General callback for all command messages @param message : an XplMessage object """ self.log.debug("telldus.telldus_cmnd_cb : Receive message.") commands = { 'on': lambda hu, l, f: self._mytelldus.send_on(hu), 'off': lambda hu, l, f: self._mytelldus.send_off(hu), 'dim': lambda hu, l, f: self._mytelldus.send_dim(hu, l), 'bright': lambda hu, l, f: self._mytelldus.send_bright(hu, l, f), 'shine': lambda hu, l, f: self._mytelldus.send_shine(hu, l, f), 'change': lambda hu, l, f: self._mytelldus.send_change(hu, l, f), 'up': lambda hu, l, f: self._mytelldus.send_up(hu), 'down': lambda hu, l, f: self._mytelldus.send_down(hu), 'stop': lambda hu, l, f: self._mytelldus.send_stop(hu), 'shut': lambda hu, l, f: self._mytelldus.send_shut(hu, l), } try: cmd = None if 'command' in message.data: cmd = message.data['command'] device = None if 'device' in message.data: device = message.data['device'] level = "0" if 'level' in message.data: level = message.data['level'] faderate = "0" if 'faderate' in message.data: faderate = message.data['faderate'] self.log.debug("%s received : device= %s, level=%s, faderate=%s" % (cmd, device, level, faderate)) commands[cmd](device, level, faderate) except Exception: self.log.error("action _ %s _ unknown." % (cmd)) error = "Exception : %s" % (traceback.format_exc()) self.log.info("TelldusException : " + error) def telldus_reload_config_cb(self): """ Callback for telldus reload config @param message : xpl message """ self.log.debug("Telldus reload config received") self._mytelldus.reload_config() def send_xpl(self, message): """ Callback for sending xpl @param add : address of the module @param order : the order sent to the unit """ self.log.debug("Telldus send_xpl") self.myxpl.send(message)
class SamsungTVManager(XplPlugin): """ Manage Samsung televisions """ def __init__(self): """ Init manager """ XplPlugin.__init__(self, name='tv_samsg') # Configuration : list of televisions self.televisions = {} num = 1 loop = True self._config = Query(self.myxpl, self.log) while loop == True: name = self._config.query('tv_samsg', 'tv-%s-name' % str(num)) device = self._config.query('tv_samsg', 'tv-%s-device' % str(num)) if name != None: self.log.info("Configuration : name=%s, device=%s" % (name, device)) self.televisions[name] = {"device": device} else: loop = False num += 1 ### Create SamsungTV objects for television in self.televisions: self.televisions[television]['obj'] = SamsungTV(self.log) try: self.log.info( "Opening Samsung Television named '%s' (device : %s)" % (television, self.televisions[television]['device'])) self.televisions[television]['obj'].open( self.televisions[television]['device']) except SamsungTVException as err: self.log.error(err.value) print(err.value) self.force_leave() return # Create listener Listener(self.television_cb, self.myxpl, { 'schema': 'control.basic', 'xpltype': 'xpl-cmnd', 'type': 'television' }) self.log.debug("Listener for tv_samsg created") self.enable_hbeat() def television_cb(self, message): """ Call tv_samsg lib @param message : xPL message detected by listener """ # device contains name of television which will be used to get device if 'device' in message.data: name = message.data['device'] if 'current' in message.data: command = message.data['current'] else: self._log.warning("Xpl message : missing 'current' attribute") return if 'data1' in message.data: data1 = int(message.data['data1']) else: data1 = None try: device = self.televisions[name]["device"] except KeyError: self.log.warning("Television named '%s' is not defined" % name) return self.log.info("Television command received for '%s' on '%s'" % (name, device)) status = self.televisions[name]['obj'].send(command, data1) # Send xpl-trig to say plugin receive command print("S=%s" % status) if status == True: mess = XplMessage() mess.set_type('xpl-trig') mess.set_schema('sensor.basic') mess.add_data({'device': device}) mess.add_data({'type': 'television'}) mess.add_data({'current': command}) if data1 != None: mess.add_data({'data1': data1}) print(mess) self.myxpl.send(mess)
class WolPing(XplPlugin): """ Implements a listener for wol messages on xPL network """ def __init__(self): """ Create listener for wake on lan """ XplPlugin.__init__(self, name = 'wol_ping') # Configuration : interval between each ping self._config = Query(self.myxpl, self.log) interval = self._config.query('wol_ping', 'ping-interval') if interval == None: interval = 60 # Configuration : list of computers self.computers = {} num = 1 loop = True while loop == True: name = self._config.query('wol_ping', 'name-%s' % str(num)) ip = self._config.query('wol_ping', 'ip-%s' % str(num)) mac = self._config.query('wol_ping', 'mac-%s' % str(num)) mac_port = self._config.query('wol_ping', 'wol-port-%s' % str(num)) if mac_port == None: mac_port = 7 if name != None: self.log.info("Configuration : name=%s, ip=%s, mac=%s, mac port=%s" % (name, ip, mac, mac_port)) self.computers[name] = {"ip" : ip, "mac" : mac, "mac_port" : mac_port} else: loop = False num += 1 ### Create WOL object self._wolmanager = WOL(self.log) # Create listeners Listener(self.wol_cb, self.myxpl, {'schema': 'control.basic', 'xpltype': 'xpl-cmnd', 'type': 'wakeonlan', 'current': 'high'}) self.log.debug("Listener for wake on lan created") ### Create Ping object self._pingmanager = Ping(self.myxpl, self.log, self.ping_cb, float(interval), self.computers) self.enable_hbeat() self._pingmanager.ping() def wol_cb(self, message): """ Call wake on lan lib @param message : xPL message detected by listener """ if 'device' in message.data: device = message.data['device'] try: mac = self.computers[device]["mac"] port = int(self.computers[device]["mac_port"]) except KeyError: self.log.warning("Computer named '%s' is not defined" % device) return self.log.info("Wake on lan command received for '%s' on port '%s'" % (mac, port)) #status = self._wolmanager.wake_up(mac, port) status = self._wolmanager.wake_up(mac, port) # Send xpl-trig to say plugin receive command if status == True: mess = XplMessage() mess.set_type('xpl-trig') mess.set_schema('sensor.basic') mess.add_data({'device' : device}) mess.add_data({'type' : 'wakeonlan'}) mess.add_data({'current' : 'high'}) self.myxpl.send(mess) def ping_cb(self, type, computer, status): # Send xpl-trig to say plugin receive command msg = XplMessage() msg.set_type(type) msg.set_schema('sensor.basic') msg.add_data({'device' : computer}) msg.add_data({'type' : 'ping'}) msg.add_data({'current' : status}) self.myxpl.send(msg)
class APushNotificationListener(XplPlugin): """ Create listener for xPL messages about Android push notification """ def __init__(self): """ Create listener for Android push notification """ XplPlugin.__init__(self, name = 'apushnot') # Create logger self.log.debug("Listener for Android push notification created") # Configuration : list of recipient and source key self.alias_list = {} num = 1 loop = True self._config = Query(self.myxpl, self.log) while loop == True: recipient = self._config.query('apushnot', 'name-%s' % str(num)) source = self._config.query('apushnot', 'source-%s' % str(num)) dfltitle = self._config.query('apushnot', 'default-title-%s' % str(num)) if recipient != None: mess="Configuration : recipient=" + str(recipient) + " , source=" + str(source) + ", default title=" + str(dfltitle) self.log.info(mess) print(mess) self.alias_list[recipient] = {"recipient" : recipient, "source" : source, "dfltitle" : dfltitle} num += 1 else: loop = False # no recipient configured if num == 1: msg = "No recipient configured. Exiting plugin" self.log.info(msg) print(msg) self.force_leave() return # Check title for alias in self.alias_list: if str(self.alias_list[alias]['dfltitle']) != "None": self.log.debug("default title for recipient " + str(self.alias_list[alias]['recipient']) + " is " + str(self.alias_list[alias]['dfltitle'])) else: self.log.error("Can't find the default title for the recipient " + str(self.alias_list[alias]['recipient']) + " , please check the configuration page of this plugin") self.force_leave() return # Create APushNotification object self.apn_notification_manager = APushNotification(self.log) # Create listeners Listener(self.apn_notification_cb, self.myxpl, {'schema': 'sendmsg.push', 'xpltype': 'xpl-cmnd'}) self.enable_hbeat() def apn_notification_cb(self, message): """ Call Android notification lib @param message : message from xpl """ self.log.debug("Call apn_notification_cb") # mandatory keys if 'to' in message.data: to = message.data['to'] for alias in self.alias_list: try: if str(self.alias_list[alias]['recipient']) == str(to): sourcekey = self.alias_list[alias]['source'] except : self.log.debug("Can't find the recipient, please check the configuration page of this plugin") self.force_leave() return else: self.log.warning("No recipient was found in the xpl message") return if 'body' in message.data: body = message.data['body'] else: self.log.warning("No message was found in the xpl message") return # optionnal keys if 'title' in message.data: title = message.data['title'] else: for alias in self.alias_list: if str(self.alias_list[alias]['recipient']) == str(to): title = self.alias_list[alias]['dfltitle'] self.log.info("No title was found in the xpl message, so the default title " + title + "is used") self.log.debug("Call send_apn with following parameters : sourcekey=" + sourcekey + ", title=" + title + ", message=" + body) self.apn_notification_manager.send_apn(sourcekey, title, body)
class Telldus(XplHlpPlugin): ''' Manage chacon devices through the TellStick device ''' def __init__(self): """ Create the telldus class This class is used to connect devices (through telldus) to the xPL Network """ XplHlpPlugin.__init__(self, name = 'telldus', reload_cb = self.telldus_reload_config_cb) self.log.debug("telldus.__init__ : Start ...") self._device = "/dev/tellstick" #Check if the device exists if not os.path.exists(self._device): self.log.warning(self._device + " is not present but Tellstick Duo don't use it.") else: self.log.debug("Device present as "+self._device) self._config = Query(self.myxpl, self.log) self.log.debug("telldus.__init__ : Try to load API") try: self._mytelldus = TelldusAPI(self, self.send_xpl, self.log, self._config,self.get_data_files_directory(), self.myxpl) except Exception: self.log.error("Something went wrong during telldus API init.") self.log.error("%s" % (traceback.format_exc())) self.force_leave() exit(1) self.add_stop_cb(self._mytelldus.unregister) self.log.debug("telldus.__init__ : Create listeners") Listener(self.telldus_cmnd_cb, self.myxpl, {'schema': 'telldus.basic', 'xpltype': 'xpl-cmnd'}) Listener(self.telldus_reload_config_cb, self.myxpl, {'schema': 'domogik.system', 'xpltype': 'xpl-cmnd', 'command': 'reload', 'plugin': 'telldus'}) self.enable_hbeat() try: boo = self._config.query('telldus', 'lightext') if boo == None: boo = "False" self.lightext = eval(boo) except: self.log.warning("Can't get delay configuration from XPL. Disable lighting extensions.") self.lightext = False if self.lightext == True: self.log.debug("telldus.__init__ : Try to load the lighting extension.") self.lighting = LightingExtension(self, self._name, \ self._mytelldus.lighting_activate_device, \ self._mytelldus.lighting_deactivate_device, \ self._mytelldus.lighting_valid_device) self.helpers = \ { "list" : { "cb" : self._mytelldus.helper.helper_list, "desc" : "List devices in telldus daemon.", "usage" : "list [devicetype]", "param-list" : "devicetype", "min-args" : 0, "devicetype" : "the type of device to find", }, "info" : { "cb" : self._mytelldus.helper.helper_info, "desc" : "Display device information.", "usage" : "info <device>", "param-list" : "device", "min-args" : 1, "device" : "device address", }, "memory" : { "cb" : self._mytelldus.helper.helper_memory, "desc" : "Show memory usage of variables. Experimental.", "usage" : "memory", "param-list" : "", "min-args" : 0, }, } if self.lightext == True: self.log.debug("telldus.__init__ : Try to enable the lighting extension.") self.lighting.enable_lighting() self.log.debug("telldus.__init__ : Try to load the helpers.") self.enable_helper() self.log.info("Telldus plugin correctly started") def telldus_cmnd_cb(self, message): """ General callback for all command messages @param message : an XplMessage object """ self.log.debug("telldus.telldus_cmnd_cb : Receive message.") commands = { 'on': lambda hu, l, f: self._mytelldus.send_on(hu), 'off': lambda hu, l, f: self._mytelldus.send_off(hu), 'dim': lambda hu, l, f: self._mytelldus.send_dim(hu, l), 'bright': lambda hu, l, f: self._mytelldus.send_bright(hu, l, f), 'shine': lambda hu, l, f: self._mytelldus.send_shine(hu, l, f), 'change': lambda hu, l, f: self._mytelldus.send_change(hu, l, f), 'up': lambda hu, l, f: self._mytelldus.send_up(hu), 'down': lambda hu, l, f: self._mytelldus.send_down(hu), 'stop': lambda hu, l, f: self._mytelldus.send_stop(hu), 'shut': lambda hu, l, f: self._mytelldus.send_shut(hu, l), } try : cmd = None if 'command' in message.data: cmd = message.data['command'] device = None if 'device' in message.data: device = message.data['device'] level = "0" if 'level' in message.data: level = message.data['level'] faderate = "0" if 'faderate' in message.data: faderate = message.data['faderate'] self.log.debug("%s received : device= %s, level=%s, faderate=%s" % (cmd, device, level, faderate)) commands[cmd](device, level, faderate) except Exception: self.log.error("action _ %s _ unknown." % (cmd)) error = "Exception : %s" % (traceback.format_exc()) self.log.info("TelldusException : "+error) def telldus_reload_config_cb(self): """ Callback for telldus reload config @param message : xpl message """ self.log.debug("Telldus reload config received") self._mytelldus.reload_config() def send_xpl(self, message): """ Callback for sending xpl @param add : address of the module @param order : the order sent to the unit """ self.log.debug("Telldus send_xpl") self.myxpl.send(message)
class YWeatherManager(XplPlugin): """ Get data from Yahoo weather and send them on xPL """ def __init__(self): """ Init plugin """ XplPlugin.__init__(self, name='yweather') # Get config self._config = Query(self.myxpl, self.log) unit = self._config.query('yweather', 'unit' ) if unit == None: self.log.error("Unit not configured : exiting") print("Unit not configured : exiting") self.force_leave() return unit = unit.lower() self.enable_current = self._config.query('yweather', 'en-current' ) self.enable_previsionnal = self._config.query('yweather', 'en-prev' ) self.cities = {} num = 1 loop = True while loop == True: city_code = self._config.query('yweather', 'city-%s' % str(num)) device = self._config.query('yweather', 'device-%s' % str(num)) if city_code != None: self.cities[city_code] = { "device" : device } num = num + 1 else: loop = False # Open weather for cities for city in self.cities: self.cities[city]["obj"] = YWeather(self.log, self.send_xpl) try: self.log.info("Init weather for '%s'" % city) self.cities[city]["obj"].open(city, unit, self.cities[city]["device"]) except YWeatherException as err: self.log.error(err.value) print(err.value) self.force_leave() return # Start listening for weather for city in self.cities: try: self.log.info("Start listening weather for '%s'" % city) self._listen_thr = XplTimer(TIME_BETWEEN_EACH_WEATHER_READ, \ self.cities[city]["obj"].get, \ self.myxpl) self._listen_thr.start() self.enable_hbeat() except YWeatherException as err: self.log.error(err.value) print(err.value) self.force_leave() return self.enable_hbeat() def send_xpl(self, device, weather): """ Send xPL message on network @param device : device (address set by user in config page) @param weather : weather data """ # current part (sensor.basic) if self.enable_current == 'True': self._send_current(device, weather, "current", "temperature", "temp", units = weather["units"]["temperature"]) self._send_current(device, weather, "atmosphere", "pressure", "pressure", units = weather["units"]["pressure"]) self._send_current(device, weather, "atmosphere", "humidity", "humidity", units = "%") self._send_current(device, weather, "atmosphere", "visibility", "visibility", units = weather["units"]["distance"]) self._send_current(device, weather, "atmosphere", "rising", "rising") self._send_current(device, weather, "wind", "chill", "chill") self._send_current(device, weather, "wind", "direction", "direction") self._send_current(device, weather, "wind", "speed", "speed", units = weather["units"]["speed"]) self._send_current(device, weather, "current", "code", "condition-code") self._send_current(device, weather, "current", "text", "condition-text") # previsionnal part if self.enable_previsionnal == 'True': common = { "city" : weather["location"]["city"], "region" : weather["location"]["region"], "country" : weather["location"]["country"], "unit-distance" : weather["units"]["distance"], "unit-pressure" : weather["units"]["pressure"], "unit-speed" : weather["units"]["speed"], "unit-temperature" : weather["units"]["temperature"] } my_today = datetime.date.today().isoformat() today = { "day" : my_today, "condition-code" : weather["today"]["code"], "condition-text" : weather["today"]["text"], "temperature-low" : weather["today"]["temperature_low"], "temperature-high" : weather["today"]["temperature_high"], } my_tomorrow = (datetime.date.today() + \ datetime.timedelta(days = 1)).isoformat() tomorrow = { "day" : my_tomorrow, "condition-code" : weather["tomorrow"]["code"], "condition-text" : weather["tomorrow"]["text"], "temperature-low" : weather["tomorrow"]["temperature_low"], "temperature-high" : weather["tomorrow"]["temperature_high"], } today.update(common) tomorrow.update(common) self._send_previsionnal(device, today) self._send_previsionnal(device, tomorrow) def _send_current(self, device, weather, category, key, xpl_type, units = None): """ Check if data exists and sent it over xpl @param device : device (address set by user in config page) @param weather : weather struc @param category : category of data (atmosphere, today, tomorrow...) @param key : key in category @param xpl_type : type to use in xpl schema @param units : unit for value """ try: self._send_sensor_basic(device = device, type = xpl_type, current = weather[category][key], units = units) except KeyError: # no data : pass print("No data for %s>%s" % (category, key)) pass def _send_sensor_basic(self, device, type, current, units = None): """ Send sensor.basic xPL schema @param device : device @param type : type @param current : current """ print("D=%s, T=%s, C=%s" % (device, type, current)) if current == "": return msg = XplMessage() msg.set_type("xpl-stat") msg.set_schema("sensor.basic") msg.add_data({"device" : device}) msg.add_data({"type" : type}) msg.add_data({"current" : current}) if units != None: msg.add_data({"units" : units}) self.myxpl.send(msg) def _send_previsionnal(self, device, data): """ Send weather.basic xPL schema @param device : device @param data : dictionnary of data to send """ print("D=%s, %s" % (device, data)) msg = XplMessage() msg.set_type("xpl-stat") msg.set_schema("weather.basic") msg.add_data({"device" : device}) for key in data: if data[key] != "": msg.add_data({key : data[key]}) self.myxpl.send(msg)
class DiskManager(XplPlugin): """ Get disk free size over xPL """ def __init__(self): """ Init plugin """ XplPlugin.__init__(self, name='diskfree') # Global config : probe interval self._config = Query(self.myxpl, self.log) interval = self._config.query('diskfree', 'interval') if interval != None: interval = float(interval) else: msg = "Interval not configured. Exiting plugin" self.log.info(msg) print(msg) self.force_leave() return # Configuration : list of path to check self.path_list = {} num = 1 loop = True while loop == True: path = self._config.query('diskfree', 'path-%s' % str(num)) if path != None: self.log.info("Configuration : path=%s" % path) num += 1 # init object list for path to None self.path_list[path] = None else: loop = False # no path configured if num == 1: msg = "No path configured. Exiting plugin" self.log.info(msg) print(msg) self.force_leave() return ### Start listening each path for path in self.path_list: try: self.path_list[path] = Disk(self.log, self.send_xpl, self.get_stop()) self.log.info("Start listening for '%s'" % path) path_listen = threading.Thread(None, self.path_list[path].listen, "listen_diskfree", ( path, interval, ), {}) path_listen.start() except: self.log.error(traceback.format_exc()) print(traceback.format_exc()) # we don't quit plugin if an error occured # a disk can have been unmounted for a while #self.force_leave() #return self.enable_hbeat() self.log.info("Plugin ready :)") def send_xpl(self, path, du_type, du_value): """ Send xPL message on network """ print("path:%s, %s:%s" % (path, du_type, du_value)) msg = XplMessage() msg.set_type("xpl-stat") msg.set_schema("sensor.basic") msg.add_data({"device": path}) msg.add_data({"type": du_type}) msg.add_data({"current": du_value}) self.myxpl.send(msg)
class YWeatherManager(XplPlugin): """ Get data from Yahoo weather and send them on xPL """ def __init__(self): """ Init plugin """ XplPlugin.__init__(self, name='yweather') # Get config self._config = Query(self.myxpl, self.log) unit = self._config.query('yweather', 'unit') if unit == None: self.log.error("Unit not configured : exiting") print("Unit not configured : exiting") self.force_leave() return unit = unit.lower() self.enable_current = self._config.query('yweather', 'en-current') self.enable_previsionnal = self._config.query('yweather', 'en-prev') self.cities = {} num = 1 loop = True while loop == True: city_code = self._config.query('yweather', 'city-%s' % str(num)) device = self._config.query('yweather', 'device-%s' % str(num)) if city_code != None: self.cities[city_code] = {"device": device} num = num + 1 else: loop = False # Open weather for cities for city in self.cities: self.cities[city]["obj"] = YWeather(self.log, self.send_xpl) try: self.log.info("Init weather for '%s'" % city) self.cities[city]["obj"].open(city, unit, self.cities[city]["device"]) except YWeatherException as err: self.log.error(err.value) print(err.value) self.force_leave() return # Start listening for weather for city in self.cities: try: self.log.info("Start listening weather for '%s'" % city) self._listen_thr = XplTimer(TIME_BETWEEN_EACH_WEATHER_READ, \ self.cities[city]["obj"].get, \ self.myxpl) self._listen_thr.start() self.enable_hbeat() except YWeatherException as err: self.log.error(err.value) print(err.value) self.force_leave() return self.enable_hbeat() def send_xpl(self, device, weather): """ Send xPL message on network @param device : device (address set by user in config page) @param weather : weather data """ # current part (sensor.basic) if self.enable_current == 'True': self._send_current(device, weather, "current", "temperature", "temp", units=weather["units"]["temperature"]) self._send_current(device, weather, "atmosphere", "pressure", "pressure", units=weather["units"]["pressure"]) self._send_current(device, weather, "atmosphere", "humidity", "humidity", units="%") self._send_current(device, weather, "atmosphere", "visibility", "visibility", units=weather["units"]["distance"]) self._send_current(device, weather, "atmosphere", "rising", "rising") self._send_current(device, weather, "wind", "chill", "chill") self._send_current(device, weather, "wind", "direction", "direction") self._send_current(device, weather, "wind", "speed", "speed", units=weather["units"]["speed"]) self._send_current(device, weather, "current", "code", "condition-code") self._send_current(device, weather, "current", "text", "condition-text") # previsionnal part if self.enable_previsionnal == 'True': common = { "city": weather["location"]["city"], "region": weather["location"]["region"], "country": weather["location"]["country"], "unit-distance": weather["units"]["distance"], "unit-pressure": weather["units"]["pressure"], "unit-speed": weather["units"]["speed"], "unit-temperature": weather["units"]["temperature"] } my_today = datetime.date.today().isoformat() today = { "day": my_today, "condition-code": weather["today"]["code"], "condition-text": weather["today"]["text"], "temperature-low": weather["today"]["temperature_low"], "temperature-high": weather["today"]["temperature_high"], } my_tomorrow = (datetime.date.today() + \ datetime.timedelta(days = 1)).isoformat() tomorrow = { "day": my_tomorrow, "condition-code": weather["tomorrow"]["code"], "condition-text": weather["tomorrow"]["text"], "temperature-low": weather["tomorrow"]["temperature_low"], "temperature-high": weather["tomorrow"]["temperature_high"], } today.update(common) tomorrow.update(common) self._send_previsionnal(device, today) self._send_previsionnal(device, tomorrow) def _send_current(self, device, weather, category, key, xpl_type, units=None): """ Check if data exists and sent it over xpl @param device : device (address set by user in config page) @param weather : weather struc @param category : category of data (atmosphere, today, tomorrow...) @param key : key in category @param xpl_type : type to use in xpl schema @param units : unit for value """ try: self._send_sensor_basic(device=device, type=xpl_type, current=weather[category][key], units=units) except KeyError: # no data : pass print("No data for %s>%s" % (category, key)) pass def _send_sensor_basic(self, device, type, current, units=None): """ Send sensor.basic xPL schema @param device : device @param type : type @param current : current """ print("D=%s, T=%s, C=%s" % (device, type, current)) if current == "": return msg = XplMessage() msg.set_type("xpl-stat") msg.set_schema("sensor.basic") msg.add_data({"device": device}) msg.add_data({"type": type}) msg.add_data({"current": current}) if units != None: msg.add_data({"units": units}) self.myxpl.send(msg) def _send_previsionnal(self, device, data): """ Send weather.basic xPL schema @param device : device @param data : dictionnary of data to send """ print("D=%s, %s" % (device, data)) msg = XplMessage() msg.set_type("xpl-stat") msg.set_schema("weather.basic") msg.add_data({"device": device}) for key in data: if data[key] != "": msg.add_data({key: data[key]}) self.myxpl.send(msg)
class Rest(XplPlugin): """ REST Server - create a HTTP server - process REST requests """ def __init__(self, server_ip, server_port): """ Initiate DbHelper, Logs and config Then, start HTTP server and give it initialized data @param server_ip : ip of HTTP server @param server_port : port of HTTP server """ XplPlugin.__init__(self, name = 'rest') # logging initialization self.log.info("Rest Server initialisation...") self.log.debug("locale : %s %s" % locale.getdefaultlocale()) # logging Queue activities log_queue = logger.Logger('rest-queues') self.log_queue = log_queue.get_logger('rest-queues') self.log_queue.info("Rest's queues activities...") # logging data manipulation initialization log_dm = logger.Logger('rest-dm') self.log_dm = log_dm.get_logger('rest-dm') self.log_dm.info("Rest Server Data Manipulation...") # API version self._rest_api_version = REST_API_VERSION # Hosts list self._hosts_list = {self.get_sanitized_hostname() : {"id" : self.get_sanitized_hostname(), "status" : "on", "primary" : True, "last_seen" : time.time(), "ip" : "", "interval" : "1"}} try: ### Config # directory data cfg = Loader('domogik') config = cfg.load() conf = dict(config[1]) self.log_dir_path = conf['log_dir_path'] # plugin installation path if conf.has_key('package_path'): self._package_path = conf['package_path'] self._src_prefix = None self.log.info("Set package path to '%s' " % self._package_path) print("Set package path to '%s' " % self._package_path) self._design_dir = "%s/domogik_packages/design/" % self._package_path self.package_mode = True else: self.log.info("No package path defined in config file") self._package_path = None self._src_prefix = conf['src_prefix'] self._design_dir = "%s/share/domogik/design/" % conf['src_prefix'] self.package_mode = False # HTTP server ip and port try: cfg_rest = Loader('rest') config_rest = cfg_rest.load() conf_rest = dict(config_rest[1]) self.server_ip = conf_rest['rest_server_ip'] self.server_port = conf_rest['rest_server_port'] except KeyError: # default parameters self.server_ip = server_ip self.server_port = server_port self.log.info("Configuration : ip:port = %s:%s" % (self.server_ip, self.server_port)) # SSL configuration try: cfg_rest = Loader('rest') config_rest = cfg_rest.load() conf_rest = dict(config_rest[1]) self.use_ssl = conf_rest['rest_use_ssl'] if self.use_ssl == "True": self.use_ssl = True else: self.use_ssl = False self.ssl_certificate = conf_rest['rest_ssl_certificate'] except KeyError: # default parameters self.use_ssl = USE_SSL self.ssl_certificate = SSL_CERTIFICATE if self.use_ssl == True: self.log.info("Configuration : SSL support activated (certificate : %s)" % self.ssl_certificate) else: self.log.info("Configuration : SSL support not activated") # File repository try: cfg_rest = Loader('rest') config_rest = cfg_rest.load() conf_rest = dict(config_rest[1]) self.repo_dir = conf_rest['rest_repository'] except KeyError: # default parameters self.repo_dir = DEFAULT_REPO_DIR # Gloal Queues config self.log.debug("Get queues configuration") self._config = Query(self.myxpl, self.log) self._queue_timeout = self._config.query('rest', 'q-timeout') if self._queue_timeout == None: self._queue_timeout = QUEUE_TIMEOUT self._queue_timeout = float(self._queue_timeout) self._queue_package_size = self._config.query('rest', 'q-pkg-size') if self._queue_package_size == None: self._queue_package_size = QUEUE_PACKAGE_SIZE self._queue_package_size = float(self._queue_package_size) self._queue_size = self._config.query('rest', 'q-size') if self._queue_size == None: self._queue_size = QUEUE_SIZE self._queue_size = float(self._queue_size) self._queue_life_expectancy = self._config.query('rest', 'q-life-exp') if self._queue_life_expectancy == None: self._queue_life_expectancy = QUEUE_LIFE_EXPECTANCY self._queue_life_expectancy = float(self._queue_life_expectancy) self._queue_sleep = self._config.query('rest', 'q-sleep') if self._queue_sleep == None: self._queue_sleep = QUEUE_SLEEP self._queue_sleep = float(self._queue_sleep) # /command Queues config self._queue_command_size = self._config.query('rest', 'q-cmd-size') if self._queue_command_size == None: self._queue_command_size = QUEUE_COMMAND_SIZE self._queue_command_size = float(self._queue_command_size) # /event Queues config self._event_timeout = self._config.query('rest', 'evt-timeout') if self._event_timeout == None: self._event_timeout = EVENT_TIMEOUT self._event_timeout = float(self._event_timeout) self._queue_event_size = self._config.query('rest', 'q-evt-size') if self._queue_event_size == None: self._queue_event_size = QUEUE_EVENT_SIZE self._queue_event_size = float(self._queue_event_size) self._queue_event_timeout = self._config.query('rest', 'q-evt-timeout') if self._queue_event_timeout == None: self._queue_event_timeout = QUEUE_EVENT_TIMEOUT self._queue_event_timeout = float(self._queue_event_timeout) self._queue_event_life_expectancy = self._config.query('rest', 'q-evt-life-exp') if self._queue_event_life_expectancy == None: self._queue_event_life_expectancy = QUEUE_EVENT_LIFE_EXPECTANCY self._queue_event_life_expectancy = float(self._queue_event_life_expectancy) # Queues for xPL # Queues for packages management self._queue_package = Queue(self._queue_package_size) # Queues for domogik system actions self._queue_system_list = Queue(self._queue_size) self._queue_system_detail = Queue(self._queue_size) self._queue_system_start = Queue(self._queue_size) self._queue_system_stop = Queue(self._queue_size) # Queues for /command self._queue_command = Queue(self._queue_command_size) # Queues for /events/domogik self._queue_event_dmg = Queue(self._queue_event_size) # Queues for /events/request # this queue will be fill by stat manager self._event_requests = RequestEvents(self.get_stop, self.log, self._event_timeout, self._queue_event_size, self._queue_event_timeout, self._queue_event_life_expectancy) self.add_stop_cb(self._event_requests.set_stop_clean) # Queues for /events/domogik # this queue will be fill by stat manager self._event_dmg = DmgEvents(self.get_stop, self.log, self._event_timeout, self._queue_event_size, self._queue_event_timeout, self._queue_event_life_expectancy) # notice : adding data in queue is made in _add_to_queue_system_list self.add_stop_cb(self._event_dmg.set_stop_clean) # define listeners for queues self.log.debug("Create listeners") if self.package_mode == True: Listener(self._list_installed_packages, self.myxpl, \ {'schema': 'domogik.package', 'xpltype': 'xpl-trig', 'command' : 'installed-packages-list'}) Listener(self._add_to_queue_package, self.myxpl, \ {'schema': 'domogik.package', 'xpltype': 'xpl-trig'}) Listener(self._add_to_queue_system_list, self.myxpl, \ {'schema': 'domogik.system', 'xpltype': 'xpl-trig', 'command' : 'list'}) Listener(self._add_to_queue_system_list, self.myxpl, \ {'schema': 'domogik.system', 'xpltype': 'xpl-trig', 'command' : 'enable'}) Listener(self._add_to_queue_system_list, self.myxpl, \ {'schema': 'domogik.system', 'xpltype': 'xpl-trig', 'command' : 'disable'}) Listener(self._add_to_queue_system_detail, self.myxpl, \ {'schema': 'domogik.system', 'xpltype': 'xpl-trig', 'command' : 'detail'}) Listener(self._add_to_queue_system_start, self.myxpl, \ {'schema': 'domogik.system', 'xpltype': 'xpl-trig', 'command' : 'start'}) Listener(self._add_to_queue_system_stop, self.myxpl, \ {'schema': 'domogik.system', 'xpltype': 'xpl-trig', 'command' : 'stop'}) Listener(self._add_to_queue_command, self.myxpl, \ {'xpltype': 'xpl-trig'}) # Listener for hosts list Listener(self._list_hosts, self.myxpl, \ {'schema': 'hbeat.app', 'xpltype': 'xpl-stat'}) # Background process to check if hosts has disappeared thr_hbeat = XplTimer(10, \ self._refresh_status_for_list_hosts, \ self.myxpl) thr_hbeat.start() self._discover_hosts() # Enable hbeat self.enable_hbeat() # Ask for installed packages on all hosts # Semaphore init for installed package list update self.sema_installed = Semaphore(value=1) self._installed_packages = {} if self.package_mode == True: self._get_installed_packages_from_manager() # Launch server, stats self.log.info("REST Initialisation OK") self.add_stop_cb(self.stop_http) self.server = None self.start_stats() self.start_http() except : self.log.error("%s" % self.get_exception()) def _add_to_queue_package(self, message): """ Add data in a queue """ self._put_in_queue(self._queue_package, message) def _add_to_queue_system_list(self, message): """ Add data in a queue """ self._put_in_queue(self._queue_system_list, message) current_date = calendar.timegm(time.gmtime()) self._event_dmg.add_in_queues({"timestamp" : current_date, "data" : "plugin-list-updated"}) def _add_to_queue_system_detail(self, message): """ Add data in a queue """ self._put_in_queue(self._queue_system_detail, message) def _add_to_queue_system_start(self, message): """ Add data in a queue """ self._put_in_queue(self._queue_system_start, message) def _add_to_queue_system_stop(self, message): """ Add data in a queue """ self._put_in_queue(self._queue_system_stop, message) def _add_to_queue_command(self, message): """ Add data in a queue """ self._put_in_queue(self._queue_command, message) def _get_from_queue(self, my_queue, filter_type = None, filter_schema = None, filter_data = None, nb_rec = 0, timeout = None): """ Encapsulation for _get_from_queue_in If timeout not elapsed and _get_from_queue didn't find a valid data call again _get_from_queue until timeout This encapsulation is used to process case where queue is not empty but there is no valid data in it and we want to wait for timeout """ if timeout == None: timeout = self._queue_timeout start_time = time.time() while time.time() - start_time < timeout: try: return self._get_from_queue_without_waiting(my_queue, filter_type, filter_schema, filter_data, nb_rec, timeout) except Empty: # no data in queue for us.... let's continue until time elapsed # in order not rest not working so much, let it make a pause time.sleep(self._queue_sleep) # time elapsed... we can raise the Empty exception raise Empty def _get_from_queue_without_waiting(self, my_queue, filter_type = None, filter_schema = None, filter_data = None, nb_rec = 0, timeout = None): """ Get an item from queue (recursive function) Checks are made on : - life expectancy of message - filter given - size of queue If necessary, each item of queue is read. @param my_queue : queue to get data from @param filter_type : filter on a schema type @param filter_schema : filter on a specific schema @param filter_data : dictionnay of filters. Examples : - {"command" : "start", ...} - {"plugin" : "wol%", ...} : here "%" indicate that we search for something starting with "wol" @param nb_rec : internal parameter (do not use it for first call). Used to check recursivity VS queue size @param timeout : to use a different timeout from default one """ if timeout == None: timeout = self._queue_timeout self.log_queue.debug("Get from queue : %s (recursivity deepth : %s)" % (str(my_queue), nb_rec)) # check if recursivity doesn't exceed queue size if nb_rec > my_queue.qsize(): self.log_queue.warning("Get from queue %s : number of call exceed queue size (%s) : return None" % (str(my_queue), my_queue.qsize())) # we raise an "Empty" exception because we consider that if we don't find # the good data, it is as if it was "empty" raise Empty msg_time, message = my_queue.get(True, timeout) # if message not too old, we process it if time.time() - msg_time < self._queue_life_expectancy: # no filter defined if filter_type == None and filter_schema == None and filter_data == None: self.log_queue.debug("Get from queue %s : return %s" % (str(my_queue), str(message))) return message # we want to filter data else: keep_data = True if filter_type != None and filter_type.lower() != message.type.lower(): keep_data = False if filter_schema != None and filter_schema.lower() != message.schema.lower(): keep_data = False if filter_data != None and keep_data == True: # data self.log_queue.debug("Filter on message %s WITH %s" % (message.data, filter_data)) for key in filter_data: # take care of final "%" in order to search data starting by filter_data[key] if filter_data[key][-1] == "%": if message.data.has_key(key): msg_data = str(message.data[key]) my_filter_data = str(filter_data[key]) len_data = len(my_filter_data) - 1 if msg_data[0:len_data] != my_filter_data[0:-1]: keep_data = False else: keep_data = False # normal search else: if message.data.has_key(key): if message.data[key].lower() != filter_data[key].lower(): keep_data = False else: keep_data = False # if message is ok for us, return it if keep_data == True: self.log_queue.debug("Get from queue %s : return %s" % (str(my_queue), str(message))) return message # else, message get back in queue and get another one else: self.log_queue.debug("Get from queue %s : bad data, check another one..." % (str(my_queue))) self._put_in_queue(my_queue, message) return self._get_from_queue_without_waiting(my_queue, filter_type, filter_schema, filter_data, nb_rec + 1, timeout) # if message too old : get an other message else: self.log_queue.debug("Get from queue %s : data too old, check another one..." % (str(my_queue))) return self._get_from_queue_without_waiting(my_queue, filter_type, filter_schema, filter_data, nb_rec + 1, timeout) def _put_in_queue(self, my_queue, message): """ put a message in a named queue @param my_queue : queue @param message : data to put in queue """ self.log_queue.debug("Put in queue %s : %s" % (str(my_queue), str(message))) try: my_queue.put((time.time(), message), True, self._queue_timeout) # Clean queue to make space except Full: msg = "Queue '%s' is full : cleaning it to make some space..." % my_queue self.log_queue.debug(msg) print(msg) # queue is full : start cleaning it nb_ck = 0 while nb_ck < my_queue.qsize(): (q_time, q_data) = my_queue.get() # data to keep if time.time() - self._queue_life_expectancy < q_time: my_queue.put((q_time, q_data), True, self._queue_timeout) nb_ck += 1 my_queue.put((time.time(), message), True, self._queue_timeout) self.log_queue.debug("Cleaning finished") def _discover_hosts(self): """ Send a hbeat.request to discover managers """ mess = XplMessage() mess.set_type('xpl-cmnd') mess.set_target("*") mess.set_schema('hbeat.request') mess.add_data({'command' : 'request'}) self.myxpl.send(mess) def _list_hosts(self, message): """ Maintain list of Domogik hosts @param message : hbeat.app xpl message """ tmp1 = message.source.split(".") tmp2 = tmp1[0].split("-") vendor = tmp2[0] device = tmp2[1] instance = tmp1[1] if vendor == "domogik" and device == "manager": # host not in the list if self._hosts_list.has_key(instance) == False: self._hosts_list[instance] = {"primary" : False} self._hosts_list[instance]["status"] = "on" self._hosts_list[instance]["last_seen"] = time.time() self._hosts_list[instance]["interval"] = 60 * int(message.data["interval"]) self._hosts_list[instance]["ip"] = message.data["remote-ip"] self._hosts_list[instance]["id"] = instance def _refresh_status_for_list_hosts(self): """ Check if hosts has disappeared """ now = time.time() for instance in self._hosts_list: if (now - self._hosts_list[instance]["last_seen"] > self._hosts_list[instance]["interval"]): self._hosts_list[instance]["status"] = "off" def _get_installed_packages_from_manager(self): """ Send a xpl message to all managers to get installed packages list """ ### Send xpl message to get list message = XplMessage() message.set_type("xpl-cmnd") message.set_schema("domogik.package") message.add_data({"command" : "installed-packages-list"}) message.add_data({"host" : "*"}) self.myxpl.send(message) def get_installed_packages(self): """ return list of installed packages There is a semaphore in order not to return the list when it is updated (may be incomplete) """ # developper mode : all plugins are installed # TODO : remove log lines after tests self.log.debug("*** get_installed_packages") self.sema_installed.acquire() self.log.debug("*** sema acquired") ret = self._installed_packages self.sema_installed.release() self.log.debug("*** sema released") return ret def _list_installed_packages(self, message): """ Called when a list of installed packages is received @param host : host @param pkg_type : type of package """ print("Get new installed packages list") self.log.debug("Get new installed packages list") self.sema_installed.acquire() self.log.debug("*** sema acquired") self.log.debug("*** msg = %s" % message) # process message host = message.data["host"] self._installed_packages[host] = {} pkg_mgr = PackageManager() idx = 0 loop_again = True self.log.debug("*** before while") while loop_again: try: self.log.debug("*** in while : idx=%s" % idx) pkg_type = message.data["type"+str(idx)] if message.data["enabled"+str(idx)].lower() == "yes": enabled = True else: enabled = False data = {"fullname" : message.data["fullname"+str(idx)], "id" : message.data["id"+str(idx)], "version" : message.data["version"+str(idx)], "type" : message.data["type"+str(idx)], #"source" : message.data["source"+str(idx)], "enabled" : enabled} self.log.debug("*** call get_available_updates(%s, %s, %s)" % (data["type"], data["id"], data["version"])) updates = pkg_mgr.get_available_updates(data["type"], data["id"], data["version"]) self.log.debug("*** after get_available_updates") data["updates"] = updates if self._installed_packages[host].has_key(pkg_type) == False: self._installed_packages[host][pkg_type] = [] self._installed_packages[host][pkg_type].append(data) self.log.debug("*** before idx += 1") idx += 1 except KeyError: self.log.debug("*** except keyerror") loop_again = False except: self.log.debug("*** except global") self.log.error("Error while creating list of installed packages : %s" % traceback.format_exc()) loop_again = False self.log.debug("*** before release") self.sema_installed.release() self.log.debug("*** sema released") def start_http(self): """ Start HTTP Server """ # Start HTTP server self.log.info("Start HTTP Server on %s:%s..." % (self.server_ip, self.server_port)) if self.use_ssl: self.server = HTTPSServerWithParam((self.server_ip, int(self.server_port)), RestHandler, \ handler_params = [self]) else: self.server = HTTPServerWithParam((self.server_ip, int(self.server_port)), RestHandler, \ handler_params = [self]) self.server.serve_forever() def stop_http(self): """ Stop HTTP Server """ self.server.stop_handling() def start_stats(self): """ Start Statistics manager """ print("Start Stats") self.log.info("Starting statistics manager. Its logs will be in a dedicated log file") self.stat_mgr = StatsManager(handler_params = [self], xpl = self.myxpl) self.stat_mgr.load() self.log.info("Stat manager started") def reload_stats(self): """ Reload Statistics manager """ time.sleep(1) print("Reload Stats") self.log.info("Reloading statistics manager. Its logs will be in a dedicated log file") self.stat_mgr.load() def get_exception(self): """ Get exception and display it on stdout """ my_exception = str(traceback.format_exc()).replace('"', "'") print("==== Error in REST ====") print(my_exception) print("=======================") return my_exception
class Proxy(XplPlugin): """ REST Proxy - create a HTTP server - process REST proxy requests """ def __init__(self, proxy_ip, proxy_port): """ Initiate properties Then, start HTTP server and give it initialized data @param proxy_ip : ip of the proxy server @param proxy_port : port of proxy server """ XplPlugin.__init__(self, name='proxy', reload_cb=self.reload_config) # logging initialization self.log.info("Proxy initialisation ...") self.log.debug("locale : %s %s" % locale.getdefaultlocale()) self._config = Query(self.myxpl, self.log) self.server = None self.server_process = None self.proxy_ip = None self.proxy_port = None self.use_ssl = False self.ssl_certificate = None self.server_ip = None self.server_port = None self.auth_method = None self.username = None self.password = None self.add_stop_cb(self.stop_http) self.enable_hbeat() self.reload_config() #self.log.info("Proxy initialisation done") def reload_config(self): ''' Load configuration an start proxy server ''' if self.server != None: self.stop_http() self.server = None self.server_process = None try: cfg_rest = Loader('rest') config_rest = cfg_rest.load() conf_rest = dict(config_rest[1]) self.server_ip = conf_rest['rest_server_ip'] self.server_port = conf_rest['rest_server_port'] except KeyError: self.log.error( "Can't retrieve REST configuration from domogik.cfg. Leave plugin." ) self.force_leave() try: self.proxy_ip = self._config.query('proxy', 'proxy-ip') self.proxy_port = self._config.query('proxy', 'proxy-port') except: self.log.warning( "Can't get proxy address configuration from XPL. Use default value." ) finally: if self.proxy_ip == None: self.proxy_ip = self.server_ip try: self.proxy_port = int(self.proxy_port) except: self.proxy_port = str(int(self.server_port) + 1) try: self.auth_method = self._config.query('proxy', 'auth-method') except: self.log.warning( "Can't get authentification method from XPL. Use basic by default." ) finally: if self.auth_method == None: self.auth_method = "basic" try: self.username = self._config.query('proxy', 'username') self.password = self._config.query('proxy', 'password') except: self.log.warning( "Can't get username/password from XPL. Use defaults.") finally: if self.username == None or self.username == "None": self.username = "******" if self.password == None or self.password == "None": self.password = "******" try: boo = self._config.query('proxy', 'use-ssl') #print boo self.use_ssl = True if boo == "True" else False if self.use_ssl: cfg_rest = Loader('rest') config_rest = cfg_rest.load() conf_rest = dict(config_rest[1]) self.ssl_certificate = conf_rest['rest_ssl_certificate'] except KeyError: self.log.warning( "Can't get ssl configuration from XPL. Do not use it.") self.use_ssl = False self.ssl_certificate = None self.log.info("Proxy configuration : ip:port = %s:%s" % (self.proxy_ip, self.proxy_port)) if self.use_ssl == True: self.log.info( "Proxy configuration : SSL support activated (certificate : %s)" % self.ssl_certificate) else: self.log.info("Proxy configuration : SSL support not activated") self.log.info("Proxy authentification : %s" % (self.auth_method)) self.log.info("Rest configuration : ip:port = %s:%s" % (self.server_ip, self.server_port)) try: self.start_http() except: self.log.error("Can't start proxy. Leave plugin.") self.log.error("%s" % str(traceback.format_exc()).replace('"', "'")) self.force_leave() def start_http(self): """ Start HTTP proxy """ # Start HTTP proxy self.log.info("Start HTTP proxy on %s:%s..." % (self.proxy_ip, self.proxy_port)) if self.use_ssl: self.server = HTTPSServerWithParam((self.proxy_ip, int(self.proxy_port)), \ (self.server_ip, int(self.server_port)), \ self.get_stop(), self.log, self.auth_method, \ self.username, self.password, \ ProxyHandler, bind_and_activate=True, handler_params = [self]) else: self.server = HTTPServerWithParam((self.proxy_ip, int(self.proxy_port)), \ (self.server_ip, int(self.server_port)), \ self.get_stop(), self.log, self.auth_method, \ self.username, self.password, \ ProxyHandler, bind_and_activate=True, handler_params = [self]) self.server.serve_forever() #self.log.info("HTTP proxy started.") #self.server.server_bind() #self.server.server_activate() #self.server_process = threading.Thread(None, # self.server.serve_forever(), # "rest_proxy", # (), # {}) #self.log.info("HTTP proxy started.") #self.server_process.start() def stop_http(self): """ Stop HTTP proxy """ if self.server != None: self.server.stop_handling()
class ZiBaseMain(XplPlugin): '''Manage ZiBase ''' def __init__(self): """ Create lister and launch bg listening """ XplPlugin.__init__(self, name='zibase') self._config = Query(self.myxpl, self.log) self.address = self._config.query('zibase', 'ip') self.inter = self._config.query('zibase', 'interface') self.port = int(self._config.query('zibase', 'port')) self.valvar = self._config.query('zibase', 'envar') self.interv = int(self._config.query('zibase', 'interv')) self.log.info("Creating listener for ZiBase") Listener(self.zibase_command, self.myxpl, { 'schema': 'zibase.basic', 'xpltype': 'xpl-cmnd' }) try: self.ip_host = get_ip_address(self.inter) self.log.debug("Adress IP Host=%s" % (self.ip_host)) except: self.log.error("IP Host not found=%s" % (traceback.format_exc())) return try: self.api = APIZiBase(self.log, self.address) except: self.log.error("API ZiBase error=%s" % (traceback.format_exc())) return try: self.th = ServerZiBase(self.log, self.ip_host, self.port, self.myxpl) self.th.start() except: self.log.error("Server ZiBase error=%s" % (traceback.format_exc())) self.stop() try: self.api.Connect(self.ip_host, self.port) except: self.log.error("Connection ZiBase error=%s" % (traceback.format_exc())) self.stop() if self.valvar == "True": try: self.log.info("Start reading internal variables") var_read = XplTimer(self.interv, self.zibase_read_var, self.myxpl) var_read.start() except: self.log.error("reading internal variables error") return self.add_stop_cb(self.stop) self.enable_hbeat() self.log.info("Plugin ready :)") def zibase_command(self, message): """ Call zibase lib function in function of given xpl message @param message : xpl message """ commands = { 'off': 0, 'on': 1, 'preset-dim': 2, } protocols = { 'PRESET': 0, 'VISONIC433': 1, 'VISONIC868': 2, 'CHACON': 3, 'DOMIA': 4, 'X10': 5, 'ZWAVE': 6, 'RFS10': 7, 'XDD433AL': 8, 'XDD868AL': 9, 'XDD868INSH': 10, 'XDD868PILOT': 11, 'XDD868BOAC': 12, } cmd = None dev = None protocol = None preset_dim = 0 if 'command' in message.data: cmd = message.data['command'] if 'device' in message.data: chaine = message.data['device'].split(':') try: dev = chaine[0].upper() protocol = chaine[1].upper() except: self.log.error("Syntax device not valid") if 'preset-dim' in message.data: preset_dim = message.data['preset-dim'] self.log.debug(message.data) if protocol == None: self.log.warning("Protocol not specified") return else: self.log.debug( "%s received : device = %s protocol = %s number protocol=%s preset=%s" % (cmd, dev, protocol, protocols[protocol], str(preset_dim))) try: self.api.sendCommand(dev, commands[cmd], protocols[protocol], int(preset_dim)) except: self.log.error("Sendcommand error") return self.th.send_xpl_cmd(message.data['device'], cmd, preset_dim) def stop(self): self.log.debug("Stop plugin in progress...") self.var_read.stop() self.api.Disconnect(self.ip_host, self.port) self.th.stop() return def zibase_read_var(self): try: datas = self.api.getVariables() for data in datas: elmt = data.split(':') stats = ['sta:' + elmt[1]] self.th.send_xpl_sensor(stats, elmt[0], 'xpl-stat') except: self.log.error("Read var error=%s" % (traceback.format_exc()))
class RfxcomUsbManager(XplPlugin): """ Manage the Rfxcom Usb device and connect it to xPL """ def __init__(self): """ Init plugin """ XplPlugin.__init__(self, name='rfxcom') # Get config # - device self._config = Query(self.myxpl, self.log) device = self._config.query('rfxcom', 'device') if device == None: self.log.error('Device is not configured, exiting') print('Device is not configured, exiting') self.force_leave() return # Init RFXCOM self.rfxcom = RfxcomUsb(self.log, self.send_xpl, self.send_trig, self.get_stop()) # Create a listener for all messages used by RFXCOM # TODO !!!!! # Create listeners Listener(self.process_x10_basic, self.myxpl, {'schema': 'x10.basic', 'xpltype': 'xpl-cmnd'}) Listener(self.process_x10_security, self.myxpl, {'schema': 'x10.securiy', 'xpltype': 'xpl-cmnd'}) Listener(self.process_ac_basic, self.myxpl, {'schema': 'ac.basic', 'xpltype': 'xpl-cmnd'}) Listener(self.process_remote_basic, self.myxpl, {'schema': 'remote.basic', 'xpltype': 'xpl-cmnd'}) Listener(self.process_control_basic, self.myxpl, {'schema': 'control.basic', 'xpltype': 'xpl-cmnd'}) # Open RFXCOM try: self.rfxcom.open(device) except RfxcomException as e: self.log.error(e.value) print(e.value) self.force_leave() return # Start reading RFXCOM rfxcom_process = threading.Thread(None, self.rfxcom.listen, "rfxcom-process-reader", (self.get_stop(),), {}) self.register_thread(rfxcom_process) rfxcom_process.start() self.enable_hbeat() # lighting1 def process_x10_basic(self, message): """ Process command xpl message and call the librairy for processing command @param message : xpl message """ address = message.data["device"].lower() command = message.data["command"].lower() if message.data.has_key("level"): level = message.data["level"].lower() else: level = 0 if message.data.has_key("protocol"): protocol = message.data["protocol"].lower() else: protocol = "x10" # Prepare xpl-trig to send if success trig_msg = message trig_msg.set_type("xpl-trig") # call appropriate function if protocol in ("x10", "arc", "elro", "waveman", "chacon", "impuls"): self.rfxcom.command_10(address, command, protocol, trig_msg) elif protocol in ("koppla"): self.rfxcom.command_12(address, command, level, protocol, trig_msg) elif protocol in ("harrison"): self.rfxcom.command_18(address, command, protocol, trig_msg) def process_x10_security(self, message): """ Process command xpl message and call the librairy for processing command @param message : xpl message """ address = message.data["device"].lower() command = message.data["command"].lower() if message.data.has_key("delay"): delay = message.data["delay"].lower() else: delay = None # Prepare xpl-trig to send if success trig_msg = message trig_msg.set_type("xpl-trig") self.rfxcom.command_20(address, command, delay, trig_msg) def process_ac_basic(self, message): """ Process command xpl message and call the librairy for processing command @param message : xpl message """ # TODO : finish address = message.data["address"].lower() unit = message.data["unit"] if unit.lower() == "group": unit = 0 group = True else: unit = int(unit) group = False command = message.data["command"].lower() if command == "preset": level = int(message.data["level"]) else: level = 0 if message.data.has_key("eu"): eu = message.data["eu"] else: eu = False # Prepare xpl-trig to send if success trig_msg = message trig_msg.set_type("xpl-trig") self.rfxcom.command_11(address, unit, command, level, eu, group, trig_msg) def process_remote_basic(self, message): """ Process command xpl message and call the librairy for processing command @param message : xpl message """ # TODO pass def process_control_basic(self, message): """ Process command xpl message and call the librairy for processing command @param message : xpl message """ msg_type = message.data["type"] msg_current = message.data["current"] msg_device = message.data["current"] self.log.debug("CONTROL.BASIC received : device = %s, type = %s, current = %s" % (msg_device, msg_type, msg_current)) self.rfxcom.xplcmd_control_basic(device = msg_device, type = msg_type, current = msg_current) def send_xpl(self, schema, data = {}): """ Send xPL message on network """ print("schema:%s, data:%s" % (schema, data)) self.log.debug("schema:%s, data:%s" % (schema, data)) msg = XplMessage() msg.set_type("xpl-trig") msg.set_schema(schema) for key in data: msg.add_data({key : data[key]}) self.myxpl.send(msg) def send_trig(self, message): """ Send xpl-trig given message @param message : xpl-trig message """ self.myxpl.send(message)
class NBZNotificationListener(XplPlugin): """ Create listener for xPL messages about Nabaztag TTS notification """ def __init__(self): """ Create listener for Nabaztag TTS notification """ XplPlugin.__init__(self, name="nbz_tts") # Create logger self.log.debug("Listener for Nabaztag TTS notification created") # Configuration : list of nabaztag whith serial, token and voice self.alias_list = {} num = 1 loop = True self._config = Query(self.myxpl, self.log) while loop == True: nabaztag = self._config.query("nbz_tts", "name-%s" % str(num)) serial = self._config.query("nbz_tts", "serial-%s" % str(num)) token = self._config.query("nbz_tts", "token-%s" % str(num)) voice = self._config.query("nbz_tts", "voice-%s" % str(num)) if nabaztag != None: mess = ( "Configuration : nabaztag=" + str(nabaztag) + " , serial=" + str(serial) + ", token=" + str(token) + ", voice=" + str(voice) ) self.log.info(mess) print(mess) self.alias_list[nabaztag] = {"nabaztag": nabaztag, "serial": serial, "token": token, "voice": voice} num += 1 else: loop = False # no nabaztag configured if num == 1: msg = "No nabaztag configured. Exiting plugin" self.log.info(msg) print(msg) self.force_leave() return # Check serial for alias in self.alias_list: if str(self.alias_list[alias]["serial"]) != "None": self.log.debug( "Serial for nabaztag " + str(self.alias_list[alias]["nabaztag"]) + " is " + str(self.alias_list[alias]["serial"]) ) else: self.log.error( "Can't find the serial for the nabaztag " + str(self.alias_list[alias]["nabaztag"]) + " , please check the configuration page of this plugin" ) self.force_leave() return # Check token for alias in self.alias_list: if str(self.alias_list[alias]["token"]) != "None": self.log.debug( "Token for nabaztag " + str(self.alias_list[alias]["nabaztag"]) + " is " + str(self.alias_list[alias]["token"]) ) else: self.log.error( "Can't find the Token for the nabaztag " + str(self.alias_list[alias]["nabaztag"]) + " , please check the configuration page of this plugin" ) self.force_leave() return # Check voice for alias in self.alias_list: if str(self.alias_list[alias]["voice"]) != "None": self.log.debug( "Voice for nabaztag " + str(self.alias_list[alias]["nabaztag"]) + " is " + str(self.alias_list[alias]["voice"]) ) else: self.log.error( "Can't find the Voice for the nabaztag " + str(self.alias_list[alias]["nabaztag"]) + " , please check the configuration page of this plugin" ) self.force_leave() return # Create NBZNotification object self.nbz_notification_manager = NBZNotification(self.log) # Create listeners Listener(self.nbz_notification_cb, self.myxpl, {"schema": "sendmsg.push", "xpltype": "xpl-cmnd"}) self.enable_hbeat() def nbz_notification_cb(self, message): """ Call Nabaztag TTS lib @param message : message to send """ self.log.debug("Call nbz_notification_cb") # mandatory keys if "to" in message.data: to = message.data["to"] for alias in self.alias_list: try: if str(self.alias_list[alias]["nabaztag"]) == str(to): serialkey = self.alias_list[alias]["serial"] tokenkey = self.alias_list[alias]["token"] voicekey = self.alias_list[alias]["voice"] except: self.log.debug("Can't find the recipient, please check the configuration page of this plugin") self.force_leave() return else: self.log.warning("No recipient was found in the xpl message") return if "body" in message.data: body = message.data["body"] else: self.log.warning("No message was found in the xpl message") return self.log.debug( "Call send_tts with following parameters : serial=" + serialkey + ", token=" + tokenkey + ", message=" + body + ", voice=" + voicekey ) self.nbz_notification_manager.send_tts(serialkey, tokenkey, body, voicekey)