コード例 #1
0
    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
コード例 #2
0
 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
コード例 #3
0
    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
コード例 #4
0
 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
コード例 #5
0
 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
コード例 #6
0
    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))
コード例 #7
0
 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
コード例 #8
0
    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)