def send(self, command, timeout=None): # Push out self._send_command(command) # If the command does not expect a response, we're done if command._response is None: return DALI_NO_RESPONSE # Check for command responses counter1, = self.backend.read_regs(self._recvreg, 1) fe_counter1, = self.backend.read_regs(self._fereg, 1) try: for i in range(6): sleep(0.011) # Check for backward frames frame = self._read_returning_frame(counter1) if isinstance(frame, BackwardFrame) and command.response: return command.response(frame) # Check whether the command is a Compare command if self._reply_compare_frame(command, fe_counter1): return command.response(BackwardFrame(0xFF)) return command.response(None) except Exception: pass return DALI_NO_RESPONSE
def extract(self, data): if data == None: return None elif data[1] == HASSEB_DRIVER_NO_DATA_AVAILABLE: # 0: "No Data Available" self.logger.debug("No Data Available") return HassebDALIUSBNoDataAvailable() elif data[1] == HASSEB_DALI_FRAME: response_status = data[3] if response_status == HASSEB_DRIVER_NO_ANSWER: # 1: "No Answer" self.logger.debug("No Answer") return HassebDALIUSBNoAnswer() elif response_status == HASSEB_DRIVER_OK and data[4] == 1: # 2: "OK" return BackwardFrame(data[5]) elif response_status == HASSEB_DRIVER_INVALID_ANSWER: # 3: "Invalid Answer" return BackwardFrameError(255) elif response_status == HASSEB_DRIVER_TOO_EARLY: # 4: "Answer too early" self.logger.debug("Answer too early") return HassebDALIUSBAnswerTooEarly() elif response_status == HASSEB_DRIVER_SNIFFER_BYTE: # 5: "Sniffer byte" return HassebDALIUSBSnifferByte() elif response_status == HASSEB_DRIVER_SNIFFER_BYTE_ERROR: # 6: "Sniffer byte error" return HassebDALIUSBSnifferByteError() self.logger.error("Invalid Frame") return None
def _decode(self,frame, expected_header=None): header = header_from_int(frame[0]) data = frame[1:] d = {'header': header} if header == "TIMEFRAME_EXPIRED": d['status'] = data[0] d['status_d'] = _decode_status(data[0]) d['status_b'] = format(data[0], '#010b') elif header == "DALI_RCV_1BYTES": d['status'] = data[0] d['status_d'] = _decode_status(data[0]) d['status_b'] = format(data[0], '#010b') d['dali_frame'] = BackwardFrame(int.from_bytes(data[1:2],'little')) elif header == "DALI_RCV_2BYTES": d['status'] = data[0] d['status_d'] = _decode_status(data[0]) d['status_b'] = format(data[0], '#010b') d['dali_frame'] = ForwardFrame(16,[int.from_bytes(data[1:2],'little'),int.from_bytes(data[2:3],'little')]) elif header == "ECHO": d['echo_byte']=data[0] elif header == "INVALID_DALI_FRAME": d['status'] = data[0] d['status_d'] = _decode_status(data[0]) d['status_b'] = format(data[0], '#010b') self.log.debug('read serial frame:{}, decoded frame: {}.'.format(frame,d)) return d
def extract(self, data): """ ----- """ if data[0] == 0x100: return BackwardFrame(data[1]) if data[0] == 0x200: return ForwardFrame(16, [data[1] >> 8, data[1] & 0xff]) else: return DALI_NO_RESPONSE
def extract(self, data): """Frames from modbus data""" if data[0] == 0x100: return BackwardFrame(data[1]) if data[0] == 0x200: return ForwardFrame(16, [data[1] >> 8, data[1] & 0xFF]) else: return DALI_NO_RESPONSE
def test_send_with_compare_response(self): mock_command = mock.MagicMock(spec=Command) mock_frame = mock.MagicMock(spec=ForwardFrame) mock_frame.__len__.return_value = 16 mock_frame.as_byte_sequence = (1, 2) mock_command.frame = mock_frame mock_command.sendtwice = False mock_command._response = 1 mock_command._cmdval = 0xA9 self.mock_backend.read_regs.side_effect = [(1, ), (2, ), (3, 0x200, 0x11), (4, )] self.sync_driver.send(mock_command) mock_command.response.assert_called_with(BackwardFrame(0xFF))
def extract(self, data): if len(data) >= 2: response_status = data[0] if response_status == HASSEB_DRIVER_NO_DATA_AVAILABLE: # 0: "No Data Available" self.logger.debug("No Data Available") return HassebDALIUSBNoDataAvailable() elif response_status == HASSEB_DRIVER_NO_ANSWER: # 1: "No Answer" self.logger.debug("No Answer") return HassebDALIUSBNoAnswer() elif response_status == HASSEB_DRIVER_OK: # 2: "OK" return BackwardFrame(data[1]) elif response_status == HASSEB_DRIVER_INVALID_ANSWER: # 3: "Invalid Answer" return BackwardFrameError(255) self.logger.error("Invalid Frame") return None
def extract(self, data): """Raw data received from DALI USB: dr ty ?? ec ad cm st st sn .. .. .. .. .. .. .. 11 73 00 00 ff 93 ff ff 00 00 00 00 00 00 00 00 dr: direction 0x11 = DALI side 0x12 = USB side ty: type 0x71 = transfer no response 0x72 = transfer response 0x73 = transfer complete 0x74 = broadcast received (?) 0x77 = ? ec: ecommand ad: address cm: command also serves as response code for 72 st: status internal status code, value unknown sn: seqnum """ dr = data[0] ty = data[1] ec = data[3] ad = data[4] cm = data[5] st = struct.unpack('H', data[6:8])[0] sn = data[8] if self.debug: _log_frame(self.logger, DRIVER_EXTRACT, dr, ty, ec, ad, cm, st, sn) # DALI -> DALI if dr == DALI_USB_DIRECTION_DALI: if ty == DALI_USB_TYPE_COMPLETE: return ForwardFrame(16, [ad, cm]) elif ty == DALI_USB_TYPE_BROADCAST: return ForwardFrame(16, [ad, cm]) elif ty == DALI_USB_TYPE_RESPONSE: # request not from us, ignore response return else: msg = 'DALI -> DALI | Unknown type received: {}'.format( hex(ty)) self.logger.warning(msg) return # USB -> DALI elif dr == DALI_USB_DIRECTION_USB: if ty == DALI_USB_TYPE_NO_RESPONSE: return DALI_USB_NO_RESPONSE elif ty == DALI_USB_TYPE_RESPONSE: return BackwardFrame(cm) elif ty == DALI_USB_TYPE_COMPLETE: # XXX: Happens e.g after sending a DAPC command before # receiving a response. What should we do with it? # dispatch as ordinary forward frame? # return ForwardFrame(16, [ad, cm]) pass else: msg = 'USB -> DALI | Unknown type received: {}'.format(hex(ty)) self.logger.warning(msg) return # Unknown direction msg = 'Unknown direction received: {}'.format(hex(dr)) self.logger.warning(msg)