diff --git a/custom_components/visonic/client.py b/custom_components/visonic/client.py index 42555b1..eebaba4 100644 --- a/custom_components/visonic/client.py +++ b/custom_components/visonic/client.py @@ -122,7 +122,7 @@ # "trigger", #] -CLIENT_VERSION = "0.9.6.8" +CLIENT_VERSION = "0.9.6.9" MAX_CLIENT_LOG_ENTRIES = 300 diff --git a/custom_components/visonic/examples/complete_example.py b/custom_components/visonic/examples/complete_example.py index 705b246..12bf307 100644 --- a/custom_components/visonic/examples/complete_example.py +++ b/custom_components/visonic/examples/complete_example.py @@ -30,6 +30,8 @@ print("") sys.exit(0) +terminating_clean = "terminating_clean" + # config parameters for myconfig, just to make the defaults easier CONF_DOWNLOAD_CODE = "download_code" CONF_LANGUAGE = "language" @@ -667,8 +669,11 @@ def process_sensor(dev): if dev not in sensors: console.print("Adding Sensor " + str(dev)) sensors.append(dev) - #print("Sensor Update") - #self.sendSensor(dev) + if dev.isTriggered(): + console.print(f"Device {dev.getDeviceID()} Triggered") + else: + console.print(f"Device {dev.getDeviceID()} Settings have been updated, open = {dev.isOpen()}") + def process_x10(dev): if dev.enabled: @@ -826,7 +831,7 @@ def help(): elif command == 'q': # we are disconnected and so quit the program #print("Terminating program") - raise Exception('terminating_clean') + raise Exception(terminating_clean) elif not client.isSystemStarted() and command == 'c': if len(ar) > 1: mode=str(ar[1].strip()).lower() @@ -868,8 +873,8 @@ def help(): # Get current system exception ex_type, ex_value, ex_traceback = sys.exc_info() - if str(ex_value) != "terminating_clean": - print("Exception {0} {1}".format(len("terminating_clean"),len(ex_value))) + if str(ex_value) != terminating_clean: + print("Exception {0} {1}".format(len(terminating_clean),len(ex_value))) print("Exception: ") print(f" type : {ex_type.__name__}") print(f" message : {ex_value}") @@ -887,8 +892,9 @@ def help(): def handle_exception(loop, context): # context["message"] will always be there; but context["exception"] may not msg = context.get("exception", context["message"]) - #print(f"Caught exception: {msg}") - #print(f" {context}") + if str(msg) != terminating_clean: + print(f"Caught exception: {msg}") + print(f" {context}") asyncio.create_task(shutdown(loop)) async def shutdown(loop, signal=None): diff --git a/custom_components/visonic/pyhelper.py b/custom_components/visonic/pyhelper.py index b94a8d3..f1579aa 100644 --- a/custom_components/visonic/pyhelper.py +++ b/custom_components/visonic/pyhelper.py @@ -426,9 +426,9 @@ def onChange(self, callback : Callable = None): else: self._callback.append(callback) - def pushChange(self, s : AlSensorCondition): + def pushChange(self): for cb in self._callback: - cb(self, s) + cb(self) def getDeviceID(self): return self.id diff --git a/custom_components/visonic/pyvisonic.py b/custom_components/visonic/pyvisonic.py index ebd276b..529824f 100644 --- a/custom_components/visonic/pyvisonic.py +++ b/custom_components/visonic/pyvisonic.py @@ -215,7 +215,7 @@ def convertByteArray(s) -> bytearray: "CFG_1WKEYPADS" : ( 8, 8, 8, 8, 8, 8, 8, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 ), "CFG_2WKEYPADS" : ( 2, 2, 2, 2, 2, 2, 2, 8, 32, 32, 32, 32, 32, 32, 32, 32, 32 ), "CFG_SIRENS" : ( 2, 2, 2, 2, 2, 2, 2, 4, 8, 8, 8, 8, 8, 8, 8, 8, 8 ), - "CFG_USERCODES" : ( 8, 8, 8, 8, 8, 8, 8, 8, 48, 48, 48, 48, 48, 48, 48, 48, 48 ), + "CFG_USERCODES" : ( 8, 8, 8, 8, 8, 8, 8, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48 ), "CFG_PROXTAGS" : ( 0, 0, 8, 0, 8, 8, 0, 8, 32, 32, 32, 32, 32, 32, 32, 32, 32 ), "CFG_ZONECUSTOM" : ( 0, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5 ), "CFG_WIRELESS" : ( 28, 28, 28, 28, 28, 28, 29, 29, 62, 62, 62, 62, 62, 64, 62, 62, 64 ), # Wireless + Wired total 30 or 64 @@ -1484,8 +1484,8 @@ def _sendInterfaceResetCommand(self): while not self.suspendAllOperations and len(self.SendList) > 0: log.debug("[_sendInterfaceResetCommand] Waiting to empty send command queue") self._sendCommand(None) # Check send queue - #if self.ForceStandardMode and not self.pmGotPanelDetails: - if not self.pmGotPanelDetails: + if self.ForceStandardMode and not self.pmGotPanelDetails: + #if not self.pmGotPanelDetails: self._sendCommand("MSG_BUMP") def _gotoStandardMode(self): @@ -2238,10 +2238,10 @@ async def _sendPdu(self, instruction: VisonicListEntry): # First add header (PACKET_HEADER), then the packet, then crc and footer (PACKET_FOOTER) sData = b"\x0D" sData += data - #if self.PowerMaster is not None and self.PowerMaster: - # sData += self._calculateCRCAlt(data) - #else: - sData += self._calculateCRC(data) + if self.PowerMaster is not None and self.PowerMaster and data[0] == 0xB0: + sData += self._calculateCRCAlt(data) + else: + sData += self._calculateCRC(data) sData += b"\x0A" interval = self._getUTCTimeFunction() - self.pmLastTransactionTime @@ -4629,9 +4629,10 @@ def handle_msgtypeB0(self, data): # PowerMaster Message number_of_pops = data[6] log.debug(f"[handle_msgtypeB0] Received pop message {number_of_pops=}") - if data[5] == 0xFF and msglen - 5 == number_of_pops: # start of data marker and number_of_pops is 5 less than length - for i in range(0, number_of_pops): - self._sendCommand("MSG_POWERMASTER_S", options=[[2, int(data[i+7])]]) # This asks the panel to send the pop messages + if self.PanelMode == AlPanelMode.POWERLINK or self.PanelMode == AlPanelMode.STANDARD_PLUS: + if data[5] == 0xFF and msglen - 5 == number_of_pops: # start of data marker and number_of_pops is 5 less than length + for i in range(0, number_of_pops): + self._sendCommand("MSG_POWERMASTER_S", options=[[2, int(data[i+7])]]) # This asks the panel to send the pop messages # Panel state change ?????? # if self.PanelMode == AlPanelMode.POWERLINK or \ @@ -4680,7 +4681,7 @@ def handle_msgtypeB0(self, data): # PowerMaster Message o = 7 + (i * 5) self._decode_4B(i + self.beezero_024B_sensorcount, data[o:o+5]) else: # Assume PM10 - # Assume that when the PowerMaster panel has less than 32 sensors then it just sends this and not msgType == 0x02 and subType == 0x4B + # Assume that when the PowerMaster panel has less than 32 sensors then it just sends this and not msgType == 0x02, subType == 0x4B sensorcount = int(sensortotalbytes / 5) for i in range(0, sensorcount): o = 7 + (i * 5) @@ -4696,9 +4697,10 @@ def handle_msgtypeB0(self, data): # PowerMaster Message number_of_pops = data[6] log.debug(f"[handle_msgtypeB0] Received pop message {number_of_pops=}") - if data[5] == 0xFF and msglen - 5 == number_of_pops: # start of data marker and number_of_pops is 5 less than length - for i in range(0, number_of_pops): - self._sendCommand("MSG_POWERMASTER_S", options=[ [ 2, int(data[i+7]) ] ] ) # This asks the panel to send the pop messages + if self.PanelMode == AlPanelMode.POWERLINK or self.PanelMode == AlPanelMode.STANDARD_PLUS: + if data[5] == 0xFF and msglen - 5 == number_of_pops: # start of data marker and number_of_pops is 5 less than length + for i in range(0, number_of_pops): + self._sendCommand("MSG_POWERMASTER_S", options=[ [ 2, int(data[i+7]) ] ] ) # This asks the panel to send the pop messages elif experimental and msgType == 0x03 and subType == 0x54: pass