class plcbus(Helper): def __init__(self): self._event = Event() self.liste_found = [] self.commands = \ { "all" : { "cb" : self.all, "desc" : "Show all devices found on plcbus network", "min_args" : 2, "usage" : "find device for specified house code <house code> and user code <user code>." }, "detail" : { "cb" : self.detail, "desc" : "Show device detail ", "min_args" : 2, "usage" : "show status for specified device <device code> and user code <user code>" } } log = logger.Logger('plcbus-helper') self._log = log.get_logger('plcbus-helper') device = '/dev/plcbus' self.api1 = PLCBUSAPI(self._log, device, self._command_cb, self._message_cb) def detail(self, args = None): self._usercode = args[1] self._devicecode = args[0].upper() self.api1.send("STATUS_REQUEST", self._devicecode , self._usercode ) #time.sleep(3) self._event.wait() self._event.clear() self.api1.stop() return self.liste_found def all(self, args = None): self._usercode = args[1] self._homecode = args[0].upper() self.api1.send("GET_ALL_ID_PULSE", self._homecode , self._usercode ) time.sleep(1) self.api1.send("GET_ALL_ON_ID_PULSE", self._homecode , self._usercode ) self._event.wait() self._event.clear() self.api1.stop() return self.liste_found def _command_cb(self, f): #print("DEBUG command : %s" % f["d_command"]) #print("DEBUG data1 : %s" % f["d_data1"]) #print("DEBUG data3 : %s" % f["d_data2"]) 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 == 1 : self.liste_found.append("%s" % (code)) if f["d_command"] == "GET_ALL_ON_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 code in self.liste_found: j = self.liste_found.index(code) #self.liste_found.append("%s%s" % (j,"DEBUG index")) if unit == 1: #self.liste_found.append("%s%s" % (code,"DEBUG ONNNNNN")) self.liste_found[j] = ("%s%s" % (self.liste_found[j]," ON")) else: #self.liste_found.append("%s%s" % (code,"DEBG OFFFFFF")) self.liste_found[j] = ("%s%s" % (self.liste_found[j]," OFF")) self._event.set() if f["d_command"] == "STATUS_ON": print("command StatusRequest : %s" % f["d_command"]) self.liste_found.append("%s%s%s%s%s" % (self._devicecode, " | Dimmer : ", f["d_data1"], " | Fading : ", f["d_data2"])) self._event.set() def _message_cb(self, message): print("Message : %s " % message)
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 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)