Example #1
0
    def _create_set_property_msg(self, prop, cmd, val):
        """Create an extended message to set a property.

        Create an extended message with:
            cmd1: 0x2e
            cmd2: 0x00
            flags: Direct Extended
            d1: group
            d2: cmd
            d3: val
            d4 - d14: 0x00

        Parameters:
            prop: Property name to update
            cmd: Command value
                0x02: on mask
                0x03: off mask
                0x04: x10 house code
                0x05: ramp rate
                0x06: on level
                0x07: LED brightness
                0x08: Non-Toggle mask
                0x09: LED bit mask (Do not use in this class. Use LED class)
                0x0a: X10 All bit mask
                0x0c: Trigger group bit mask
            val: New property value

        """
        user_data = Userdata({'d1': self.group, 'd2': cmd, 'd3': val})
        msg = ExtendedSend(self._address, COMMAND_EXTENDED_GET_SET_0X2E_0X00,
                           user_data)
        msg.set_checksum()
        self._set_sent_property(prop, val)
        return msg
def test_extended_ack():
    """Test extended ack."""
    callbacks = MockCallbacks()
    callbacks.callbackvalue1 = "Callback 1"
    callbacks.callbackvalue2 = "Callback 2"
    message_callbacks = MessageCallback()
    address = '1a2b3c'

    template_ext_ack = ExtendedSend.template(address, acknak=MESSAGE_ACK)
    template_std_ack = StandardSend.template(address, acknak=MESSAGE_ACK)

    message_callbacks.add(template_ext_ack, callbacks.callbackvalue1)
    message_callbacks.add(template_std_ack, callbacks.callbackvalue2)
    extmsg = ExtendedSend(address,
                          COMMAND_LIGHT_ON_0X11_NONE, {'d1': 0x02},
                          cmd2=0xff,
                          acknak=MESSAGE_ACK)
    stdmsg = StandardSend(address,
                          COMMAND_LIGHT_ON_0X11_NONE,
                          cmd2=0xff,
                          acknak=MESSAGE_ACK)
    result1 = message_callbacks.get_callbacks_from_message(extmsg)
    result2 = message_callbacks.get_callbacks_from_message(stdmsg)

    assert result2 == [callbacks.callbackvalue2]
    assert result1 == [callbacks.callbackvalue1]
Example #3
0
 def off(self):
     """Turn off the fan."""
     off_command = ExtendedSend(self._address, COMMAND_LIGHT_OFF_0X13_0X00,
                                self._udata)
     off_command.set_checksum()
     self._send_method(off_command, self._off_message_received)
     _LOGGER.debug("Ending DimmableSwitch_Fan.off")
Example #4
0
    def set(self, mode):
        """Set the thermostat mode.

        Mode optons:
            OFF = 0x00,
            HEAT = 0x01,
            COOL = 0x02,
            AUTO = 0x03,
            FAN_AUTO = 0x04,
            FAN_ALWAYS_ON = 0x8
        """
        new_mode = None
        if mode == ThermostatMode.OFF:
            new_mode = COMMAND_THERMOSTAT_CONTROL_OFF_ALL_0X6B_0X09
        elif mode == ThermostatMode.HEAT:
            new_mode = COMMAND_THERMOSTAT_CONTROL_ON_HEAT_0X6B_0X04
        elif mode == ThermostatMode.COOL:
            new_mode = COMMAND_THERMOSTAT_CONTROL_ON_COOL_0X6B_0X05
        elif mode == ThermostatMode.AUTO:
            new_mode = COMMAND_THERMOSTAT_CONTROL_ON_AUTO_0X6B_0X06
        if new_mode:
            msg = ExtendedSend(address=self._address,
                               commandtuple=new_mode,
                               userdata=Userdata())
            msg.set_checksum()
            self._send_method(msg, self._mode_change_ack)
Example #5
0
 def on(self):
     """Send an ON message to device group."""
     on_command = ExtendedSend(self._address,
                               COMMAND_LIGHT_ON_0X11_NONE,
                               self._udata,
                               cmd2=0xff)
     on_command.set_checksum()
     self._send_method(on_command, self._on_message_received)
Example #6
0
 def on(self):
     """Turn on the fan."""
     on_command = ExtendedSend(self._address,
                               COMMAND_LIGHT_ON_0X11_NONE,
                               self._udata,
                               cmd2=FAN_SPEED_MEDIUM)
     on_command.set_checksum()
     self._send_method(on_command, self._on_message_received)
Example #7
0
 def extended_status_request(self):
     """Send status request for group/button."""
     self._status_received = False
     user_data = Userdata({'d1': self.group, 'd2': 0x00})
     cmd = ExtendedSend(self._address,
                        COMMAND_EXTENDED_GET_SET_0X2E_0X00,
                        userdata=user_data)
     cmd.set_checksum()
     self._send_method(cmd, self._status_message_received, True)
Example #8
0
 def set(self, val):
     """Set the heat set point."""
     msg = ExtendedSend(
         address=self._address,
         commandtuple=COMMAND_THERMOSTAT_SET_HEAT_SETPOINT_0X6D_NONE,
         cmd2=int(val * 2),
         userdata=Userdata())
     msg.set_checksum()
     self._send_method(msg, self._set_heat_point_ack)
Example #9
0
    async def _send_led_on_off_request(self, group, val):
        _LOGGER.debug("OnOffKeypadLed._send_led_on_off_request was called")
        await self._send_led_change_lock
        self._new_value = set_bit(self._value, group, bool(val))

        user_data = Userdata({'d1': 0x01, 'd2': 0x09, 'd3': self._new_value})
        msg = ExtendedSend(self._address, COMMAND_EXTENDED_GET_SET_0X2E_0X00,
                           user_data)
        msg.set_checksum()
        self._send_method(msg, self._on_off_ack_received, True)
Example #10
0
 def set_level(self, val):
     """Set the fan speed."""
     speed = self._value_to_fan_speed(val)
     if val == 0:
         self.off()
     else:
         set_command = ExtendedSend(self._address,
                                    COMMAND_LIGHT_ON_0X11_NONE,
                                    self._udata,
                                    cmd2=speed)
         set_command.set_checksum()
         self._send_method(set_command, self._on_message_received)
Example #11
0
def test_extendedSend():
    """Test ExtendedSend."""
    address = bytearray([0x11, 0x22, 0x33])
    flags = 0x44 | 0x10
    cmd1 = 0x55
    cmd2 = 0x66
    userdata = {}
    ack = 0x06
    nak = 0x15

    for i in range(1, 15):
        key = 'd' + str(i)
        val = 0xe0 + i
        userdata.update({key: val})

    msg = ExtendedSend(address, {
        'cmd1': cmd1,
        'cmd2': cmd2
    },
                       userdata,
                       flags=flags)
    assert msg.hex == hexmsg(0x02, 0x62, Address(address), flags | 0x10, cmd1,
                             cmd2, userdata)
    assert not msg.isack
    assert not msg.isnak
    assert len(msg.hex) / 2 == msg.sendSize

    msg = ExtendedSend(address, {
        'cmd1': cmd1,
        'cmd2': cmd2
    },
                       userdata,
                       flags=flags,
                       acknak=ack)
    assert msg.hex == hexmsg(0x02, 0x62, Address(address), flags | 0x10, cmd1,
                             cmd2, userdata, ack)
    assert msg.isack
    assert not msg.isnak
    assert len(msg.hex) / 2 == msg.receivedSize

    msg = ExtendedSend(address, {
        'cmd1': cmd1,
        'cmd2': cmd2
    },
                       userdata,
                       flags=flags,
                       acknak=nak)
    assert msg.hex == hexmsg(0x02, 0x62, Address(address), flags | 0x10, cmd1,
                             cmd2, userdata, nak)
    assert not msg.isack
    assert msg.isnak
    assert len(msg.hex) / 2 == msg.receivedSize
Example #12
0
 def async_refresh_state(self):
     """Request each state to provide status update."""
     _LOGGER.debug('Setting up extended status')
     ext_status = ExtendedSend(
         address=self._address,
         commandtuple=COMMAND_EXTENDED_GET_SET_0X2E_0X00,
         cmd2=0x02,
         userdata=Userdata())
     ext_status.set_crc()
     _LOGGER.debug('Sending ext status: %s', ext_status)
     self._send_msg(ext_status)
     _LOGGER.debug('Sending temp status request')
     self.temperature.async_refresh_state()
Example #13
0
 def scene_off(self):
     """Trigger group/scene to OFF level."""
     user_data = Userdata({
         'd1': self._group,
         'd2': 0x00,
         'd3': 0x00,
         'd4': 0x13,
         'd5': 0x00,
         'd6': 0x00
     })
     self._set_sent_property(DIMMABLE_KEYPAD_SCENE_ON_LEVEL, 0x00)
     cmd = ExtendedSend(self._address,
                        COMMAND_EXTENDED_TRIGGER_ALL_LINK_0X30_0X00,
                        user_data)
     cmd.set_checksum()
     self._send_method(cmd, self._received_scene_triggered)
Example #14
0
 def scene_on(self):
     """Trigger group/scene to ON level."""
     user_data = Userdata({
         "d1": self._group,
         "d2": 0x00,
         "d3": 0x00,
         "d4": 0x11,
         "d5": 0xFF,
         "d6": 0x00,
     })
     self._set_sent_property(DIMMABLE_KEYPAD_SCENE_ON_LEVEL, 0xFF)
     cmd = ExtendedSend(self._address,
                        COMMAND_EXTENDED_TRIGGER_ALL_LINK_0X30_0X00,
                        user_data)
     cmd.set_checksum()
     _LOGGER.debug("Calling scene_on and sending response to "
                   "_received_scene_triggered")
     self._send_method(cmd, self._received_scene_triggered)
Example #15
0
 def scene_on(self):
     """Trigger group/scene to ON level."""
     user_data = Userdata({
         'd1': self._group,
         'd2': 0x00,
         'd3': 0x00,
         'd4': 0x11,
         'd5': 0xff,
         'd6': 0x00
     })
     self._set_sent_property(DIMMABLE_KEYPAD_SCENE_ON_LEVEL, 0xff)
     cmd = ExtendedSend(self._address,
                        COMMAND_EXTENDED_TRIGGER_ALL_LINK_0X30_0X00,
                        user_data)
     cmd.set_checksum()
     _LOGGER.debug('Calling scene_on and sending response to '
                   '_received_scene_triggered')
     self._send_method(cmd, self._received_scene_triggered)
Example #16
0
 def scene_level(self, level):
     """Trigger group/scene to input level."""
     if level == 0:
         self.scene_off()
     else:
         user_data = Userdata({
             "d1": self._group,
             "d2": 0x00,
             "d3": 0x00,
             "d4": 0x11,
             "d5": level,
             "d6": 0x00,
         })
         self._set_sent_property(DIMMABLE_KEYPAD_SCENE_ON_LEVEL, level)
         cmd = ExtendedSend(self._address,
                            COMMAND_EXTENDED_TRIGGER_ALL_LINK_0X30_0X00,
                            user_data)
         cmd.set_checksum()
         self._send_method(cmd, self._received_scene_triggered)
Example #17
0
 def from_raw_message(cls, rawmessage):
     """Create a message from a raw byte stream."""
     if (rawmessage[5] &
             MESSAGE_FLAG_EXTENDED_0X10) == MESSAGE_FLAG_EXTENDED_0X10:
         if len(rawmessage) >= ExtendedSend.receivedSize:
             msg = ExtendedSend.from_raw_message(rawmessage)
         else:
             msg = None
     else:
         msg = StandardSend(rawmessage[2:5],
                            {'cmd1': rawmessage[6],
                             'cmd2': rawmessage[7]},
                            flags=rawmessage[5],
                            acknak=rawmessage[8:9])
     return msg
Example #18
0
 def write_record(self,
                  mem_addr: int,
                  mode: str,
                  group: int,
                  target,
                  data1=0x00,
                  data2=0x00,
                  data3=0x00):
     """Write an All-Link database record."""
     if not (self._have_first_record() and self._have_last_record()):
         self.log.error('Must load the ALDB before writing to it')
     else:
         self._prior_status = self._status
         self._status = ALDBStatus.LOADING
         mem_hi = mem_addr >> 8
         mem_lo = mem_addr & 0xff
         controller = True if mode == 'c' else False
         control_flag = ControlFlags(True, controller, True, False, False)
         addr = Address(target)
         addr_lo = addr.bytes[0]
         addr_mid = addr.bytes[1]
         addr_hi = addr.bytes[2]
         chksum = 0xff - (
             (0x2f + 0x02 + mem_hi + mem_lo + 0x08 + control_flag.byte +
              addr_lo + addr_mid + addr_hi + group + data1 + data2 + data3)
             & 0xff) + 1
         userdata = Userdata({
             'd1': 0,
             'd2': 0x02,
             'd3': mem_hi,
             'd4': mem_lo,
             'd5': 0x08,
             'd6': control_flag.byte,
             'd7': group,
             'd8': addr_lo,
             'd9': addr_mid,
             'd10': addr_hi,
             'd11': data1,
             'd12': data2,
             'd13': data3,
             'd14': chksum
         })
         msg = ExtendedSend(self._address,
                            COMMAND_EXTENDED_READ_WRITE_ALDB_0X2F_0X00,
                            userdata=userdata)
         self.log.info('writing message %s', msg)
         self._send_method(msg, self._handle_write_aldb_ack, True)
         self._load_action = LoadAction(mem_addr, 1, 0)
Example #19
0
    def load(self, mem_addr=0x0000, rec_count=0, retry=0):
        """Read the device database and load."""
        if self._version == ALDBVersion.Null:
            self._status = ALDBStatus.LOADED
            self.log.debug('Device has no ALDB')
        else:
            self._status = ALDBStatus.LOADING
            self.log.debug('Tring to lock from load')
            yield from self._rec_mgr_lock
            self.log.debug('load yielded lock')

            mem_hi = mem_addr >> 8
            mem_lo = mem_addr & 0xff
            log_output = 'ALDB read'
            max_retries = 0
            if rec_count:
                max_retries = ALDB_RECORD_RETRIES
                if mem_addr == 0x0000:
                    log_output = '{:s} first record'.format(log_output)
                else:
                    log_output = '{:s} record {:04x}'.format(
                        log_output, mem_addr)
            else:
                max_retries = ALDB_ALL_RECORD_RETRIES
                log_output = '{:s} all records'.format(log_output)

            if retry:
                log_output = '{:s} retry {:d} of {:d}'.format(
                    log_output, retry, max_retries)
            self.log.info(log_output)
            chksum = 0xff - ((0x2f + mem_hi + mem_lo + 1) & 0xff) + 1
            userdata = Userdata({
                'd1': 0,
                'd2': 0,
                'd3': mem_hi,
                'd4': mem_lo,
                'd5': rec_count,
                'd14': chksum
            })
            msg = ExtendedSend(self._address,
                               COMMAND_EXTENDED_READ_WRITE_ALDB_0X2F_0X00,
                               userdata=userdata)
            self._send_method(msg, self._handle_read_aldb_ack, True)

            if not self._load_action:
                self._set_load_action(mem_addr, rec_count, -1, False)
Example #20
0
 def del_record(self, mem_addr: int):
     """Write an All-Link database record."""
     record = self._records.get(mem_addr)
     if not record:
         self.log.error('Must load the ALDB record before deleting it')
     else:
         self._prior_status = self._status
         self._status = ALDBStatus.LOADING
         mem_hi = mem_addr >> 8
         mem_lo = mem_addr & 0xff
         controller = record.control_flags.is_controller
         control_flag = ControlFlags(False, controller, True, False, False)
         addr = record.address
         addr_lo = addr.bytes[0]
         addr_mid = addr.bytes[1]
         addr_hi = addr.bytes[2]
         group = record.group
         data1 = record.data1
         data2 = record.data2
         data3 = record.data3
         chksum = 0xff - (
             (0x2f + 0x02 + mem_hi + mem_lo + 0x08 + control_flag.byte +
              addr_lo + addr_mid + addr_hi + group + data1 + data2 + data3)
             & 0xff) + 1
         userdata = Userdata({
             'd1': 0,
             'd2': 0x02,
             'd3': mem_hi,
             'd4': mem_lo,
             'd5': 0x08,
             'd6': control_flag.byte,
             'd7': group,
             'd8': addr_lo,
             'd9': addr_mid,
             'd10': addr_hi,
             'd11': data1,
             'd12': data2,
             'd13': data3,
             'd14': chksum
         })
         msg = ExtendedSend(self._address,
                            COMMAND_EXTENDED_READ_WRITE_ALDB_0X2F_0X00,
                            userdata=userdata)
         self.log.info('writing message %s', msg)
         self._send_method(msg, self._handle_write_aldb_ack, True)
         self._load_action = LoadAction(mem_addr, 1, 0)
Example #21
0
 def off(self):
     """Send an OFF message to device group."""
     off_command = ExtendedSend(self._address, COMMAND_LIGHT_OFF_0X13_0X00,
                                self._udata)
     off_command.set_checksum()
     self._send_method(off_command, self._off_message_received)
Example #22
0
 def off(self):
     """Turn off the fan."""
     off_command = ExtendedSend(self._address, COMMAND_LIGHT_OFF_0X13_0X00,
                                self._udata)
     self._send_method(off_command, self._off_message_received)
     self.log.debug('Ending DimmableSwitch_Fan.off')
    async def run_test(loop):
        """Asyncio test method."""
        plm = MockPLM(loop)
        callbacks = MockCallbacks()

        address = '1a2b3c'
        target = '4d5e6f'
        cat = 0x02
        subcat = 0x0d
        product_key = None
        description = 'ToggleLinc Relay'
        model = '2466S'

        device = SwitchedLightingControl_2663_222(plm, address, cat, subcat,
                                                  product_key, description,
                                                  model)
        plm.devices[address] = device
        assert device.address.hex == address
        assert device.cat == cat
        assert device.subcat == subcat
        assert device.product_key == 0x00  # Product key should not be None
        assert device.description == description
        assert device.model == model
        assert device.id == address

        device.states[0x01].register_updates(callbacks.callbackmethod1)
        device.states[0x02].register_updates(callbacks.callbackmethod2)

        device.states[0x01].on()
        await asyncio.sleep(.1, loop=loop)
        sentmsg = StandardSend(address, COMMAND_LIGHT_ON_0X11_NONE, cmd2=0xff)
        assert plm.sentmessage == sentmsg.hex
        receivedmsg = StandardSend(address,
                                   COMMAND_LIGHT_ON_0X11_NONE,
                                   cmd2=0xff,
                                   acknak=MESSAGE_ACK)
        plm.message_received(receivedmsg)
        await asyncio.sleep(.1, loop=loop)
        receivedmsg = StandardReceive(address,
                                      target, {
                                          'cmd1': 0x09,
                                          'cmd2': 0xff
                                      },
                                      flags=MessageFlags.create(
                                          MESSAGE_TYPE_DIRECT_MESSAGE_ACK, 0,
                                          2, 3))
        plm.message_received(receivedmsg)
        await asyncio.sleep(.1, loop=loop)
        assert callbacks.callbackvalue1 == 0xff

        device.states[0x02].on()
        await asyncio.sleep(.1, loop=loop)
        receivedmsg = ExtendedSend(address,
                                   COMMAND_LIGHT_ON_0X11_NONE, {'d1': 0x02},
                                   cmd2=0xff,
                                   acknak=MESSAGE_ACK)
        plm.message_received(receivedmsg)
        await asyncio.sleep(.1, loop=loop)
        receivedmsg = StandardReceive(address,
                                      target, {
                                          'cmd1': 0x09,
                                          'cmd2': 0xff
                                      },
                                      flags=MessageFlags.create(
                                          MESSAGE_TYPE_DIRECT_MESSAGE_ACK, 0,
                                          2, 3))
        plm.message_received(receivedmsg)
        await asyncio.sleep(.1, loop=loop)
        sentmsg = ExtendedSend(address,
                               COMMAND_LIGHT_ON_0X11_NONE, {'d1': 0x02},
                               cmd2=0xff)
        sentmsg.set_checksum()
        assert plm.sentmessage == sentmsg.hex
        assert callbacks.callbackvalue2 == 0xff

        device.states[0x01].off()
        await asyncio.sleep(.1, loop=loop)
        sentmsg = StandardSend(address, COMMAND_LIGHT_OFF_0X13_0X00)
        assert plm.sentmessage == sentmsg.hex
        receivedmsg = StandardSend(address,
                                   COMMAND_LIGHT_OFF_0X13_0X00,
                                   acknak=MESSAGE_ACK)
        plm.message_received(receivedmsg)
        await asyncio.sleep(.1, loop=loop)
        receivedmsg = StandardReceive(address,
                                      target, {
                                          'cmd1': 0x09,
                                          'cmd2': 0x00
                                      },
                                      flags=MessageFlags.create(
                                          MESSAGE_TYPE_DIRECT_MESSAGE_ACK, 0,
                                          2, 3))
        plm.message_received(receivedmsg)
        await asyncio.sleep(.1, loop=loop)
        sentmsg = StandardSend(address, COMMAND_LIGHT_OFF_0X13_0X00)
        assert plm.sentmessage == sentmsg.hex
        assert callbacks.callbackvalue1 == 0x00

        device.states[0x02].off()
        await asyncio.sleep(.1, loop=loop)
        receivedmsg = ExtendedSend(address,
                                   COMMAND_LIGHT_OFF_0X13_0X00, {'d1': 0x02},
                                   acknak=MESSAGE_ACK)
        plm.message_received(receivedmsg)
        await asyncio.sleep(.1, loop=loop)
        receivedmsg = StandardReceive(address,
                                      target, {
                                          'cmd1': 0x09,
                                          'cmd2': 0x00
                                      },
                                      flags=MessageFlags.create(
                                          MESSAGE_TYPE_DIRECT_MESSAGE_ACK, 0,
                                          2, 3))
        plm.message_received(receivedmsg)
        await asyncio.sleep(.1, loop=loop)
        sentmsg = ExtendedSend(address, COMMAND_LIGHT_OFF_0X13_0X00,
                               {'d1': 0x02})
        sentmsg.set_checksum()
        assert plm.sentmessage == sentmsg.hex
        assert callbacks.callbackvalue2 == 0x00
Example #24
0
    async def run_test(loop):
        mockPLM = MockPLM(loop)
        linkcode = 0x01
        group = 0x00
        address = '112233'
        cat = 0x02
        subcat = 0x39
        firmware = 0x44
        # Create OutletLinc
        device = insteonplm.devices.create(mockPLM, address, cat, subcat,
                                           firmware)

        # Start the process with an All-Link complete message with
        # the IM as a controller of Group 0x00
        msg = AllLinkComplete(linkcode, group, address, cat, subcat, firmware)
        device.receive_message(msg)
        await asyncio.sleep(.1, loop=loop)

        # The device should start linking based on the groups in
        # self.states
        assert mockPLM.sentmessage == StandardSend(
            device.address, COMMAND_ENTER_LINKING_MODE_0X09_NONE,
            cmd2=0x01).hex
        msg = StandardSend(device.address,
                           COMMAND_ENTER_LINKING_MODE_0X09_NONE,
                           cmd2=0x01,
                           acknak=MESSAGE_ACK)
        device.receive_message(msg)
        await asyncio.sleep(.1, loop=loop)
        # Confirm that the link attempt to group 0x01 completed
        msg = AllLinkComplete(0x00, 0x01, address, cat, subcat, firmware)
        device.receive_message(msg)
        await asyncio.sleep(.1, loop=loop)

        # The device should then start linking to group 0x02
        assert mockPLM.sentmessage == StandardSend(
            device.address, COMMAND_ENTER_LINKING_MODE_0X09_NONE,
            cmd2=0x02).hex
        await asyncio.sleep(1, loop=loop)
        # Confirm that the link attempt to group 0x02 completed
        msg = AllLinkComplete(0x00, 0x01, address, cat, subcat, firmware)
        device.receive_message(msg)
        await asyncio.sleep(.1, loop=loop)

        # The device will now attempt to read the ALDB
        msg = ExtendedSend(address,
                           COMMAND_EXTENDED_READ_WRITE_ALDB_0X2F_0X00,
                           userdata=Userdata())
        msg.set_checksum()
        assert mockPLM.sentmessage == msg.hex
        # Send a dummy ALDB record as a high water mark to end the process
        msg = ExtendedReceive(
            address,
            '111111',
            commandtuple=COMMAND_EXTENDED_READ_WRITE_ALDB_0X2F_0X00,
            userdata=Userdata({
                'd1': 0,
                'd2': 0x01,
                'd3': 0xff,
                'd4': 0x77,
                'd5': 0,
                'd6': 0,
                'd7': 0,
                'd8': 0,
                'd9': 0,
                'd10': 0,
                'd11': 0,
                'd12': 0,
                'd13': 0,
                'd14': 0x3b
            }))
        device.receive_message(msg)
        await asyncio.sleep(1, loop=loop)