class UnknownDevice(Device):
    """Unknown Device Class.

    Unknown Device used when only the device address is known but no other
    information. Available methods:
        id_request()
        product_data_request()
        assign_to_all_link_group()
        delete_from_all_link_group()
        device_text_string_request()
        enter_linking_mode()
        enter_unlinking_mode()
        get_engine_version()
        ping()
        read_aldb()
        write_aldb()
    """

    def __init__(
        self,
        plm,
        address,
        cat=None,
        subcat=None,
        product_key=0x00,
        description="",
        model="",
    ):
        """Init the UnknownDevice Class."""
        super().__init__(plm, address, cat, subcat, product_key, description, model)
        self._aldb = ALDB(None, None, self._address, version=ALDBVersion.Null) class GeneralController(Device):
    """General Controller Device Class.

    Device cat: 0x00

    Example: ControLinc, RemoteLinc, SignaLinc, etc.
    """

    def __init__(
        self, plm, address, cat, subcat, product_key=0, description="", model=""
    ):
        """Init the GeneralController class."""
        super().__init__(plm, address, cat, subcat, product_key, description, model)
        self._aldb = ALDB(None, None, self._address, version=ALDBVersion.Null) class GeneralController_2342(Device):
    """INSTEON Device Mini-Remote - 1 Scene."""

    def __init__(
        self, plm, address, cat, subcat, product_key=0, description="", model=""
    ):
        """Init the GeneralController_2342 class."""
        super().__init__(plm, address, cat, subcat, product_key, description, model)

        self._stateList[0x01] = DimmableRemote(
            self._address,
            "remoteButton",
            0x01,
            self._send_msg,
            self._message_callbacks,
            0x00,
        ) class GeneralController_2342_4(Device):
    """INSTEON Device Mini-Remote - 4 Scene."""

    def __init__(
        self, plm, address, cat, subcat, product_key=0, description="", model=""
    ):
        """Init the GeneralController_2342_4 class."""
        super().__init__(plm, address, cat, subcat, product_key, description, model)

        button_list = {1: "A", 2: "B", 3: "C", 4: "D"}
        for group in button_list:
            self._stateList[group] = DimmableRemote(
                self._address,
                "remoteButton{}".format(button_list[group]),
                group,
                self._send_msg,
                self._message_callbacks,
                0x00,
            ) class GeneralController_2342_8(Device):
    """INSTEON Device Mini-Remote - 8 Scene."""

    def __init__(
        self, plm, address, cat, subcat, product_key=0, description="", model=""
    ):
        """Init the GeneralController_2342_8 class."""
        super().__init__(plm, address, cat, subcat, product_key, description, model)

        button_list = {1: "B", 2: "A", 3: "D", 4: "C", 5: "F", 6: "E", 7: "H", 8: "G"}
        for group in button_list:
            self._stateList[group] = DimmableRemote(
                self._address,
                "remoteButton{}".format(button_list[group]),
                group,
                self._send_msg,
                self._message_callbacks,
                0x00,
            ) class DimmableLightingControl(Device):
    """Dimmable Lighting Controller.

    INSTEON On/Off switch device class. Available device control options are:
        - light_on(onlevel=0xff)
        - light_on_fast(onlevel=0xff)
        - light_off()
        - light_off_fast()

    To monitor changes to the state of the device subscribe to the state
    monitor:
         - lightOnLevel.connect(callback)  (state='LightOnLevel')

    where callback defined as:
        - callback(self, device_id, state, state_value)
    """

    def __init__(
        self, plm, address, cat, subcat, product_key=None, description=None, model=None
    ):
        """Init the DimmableLightingControl Class."""
        Device.__init__(
            self, plm, address, cat, subcat, product_key, description, model
        )

        self._stateList[0x01] = DimmableSwitch(
            self._address,
            "lightOnLevel",
            0x01,
            self._send_msg,
            self._message_callbacks,
            0x00,
        ) class DimmableLightingControl_2475F(DimmableLightingControl):
    """FanLinc model 2475F Dimmable Lighting Control.

    Device Class 0x01 subcat 0x2e

    Two separate INSTEON On/Off switch devices are created with ID
        1) Ligth
            - ID: xxxxxx (where xxxxxx is the Insteon address of the device)
            - Controls:
                - light_on(onlevel=0xff)
                - light_on_fast(onlevel=0xff)
                - light_off()
                - light_off_fast()
            - Monitor: lightOnLevel.connect(callback)
        2) Fan
            - ID: xxxxxx_2  (where xxxxxx is the Insteon address of the device)
            - Controls:
                - fan_on(onlevel=0xff)
                - fan_off()
                - light_on(onlevel=0xff)  - Same as fan_on(onlevel=0xff)
                - light_off()  - Same as fan_off()
            - Monitor: fanSpeed.connect(callback)

    where callback defined as:
        - callback(self, device_id, state, state_value)
    """

    def __init__(
        self, plm, address, cat, subcat, product_key=None, description=None, model=None
    ):
        """Init the DimmableLightingControl_2475F Class."""
        super().__init__(plm, address, cat, subcat, product_key, description, model)

        self._stateList[0x01] = DimmableSwitch(
            self._address,
            "lightOnLevel",
            0x01,
            self._send_msg,
            self._message_callbacks,
            0x00,
        )
        self._stateList[0x02] = DimmableSwitch_Fan(
            self._address,
            "fanOnLevel",
            0x02,
            self._send_msg,
            self._message_callbacks,
            0x00,
        ) class DimmableLightingControl_2334_222_6(DimmableLightingControl_2334_222):
    """Dimmable 6 Button KeypadLinc Switched Lighting Control."""

    def __init__(
        self, plm, address, cat, subcat, product_key=None, description=None, model=None
    ):
        """Init the SwitchedLightingControl_2487S device class."""
        super().__init__(plm, address, cat, subcat, product_key, description, model)

        button_list = {3: "A", 4: "B", 5: "C", 6: "D"}
        self._add_buttons(button_list) class DimmableLightingControl_2334_222_8(DimmableLightingControl_2334_222):
    """Dimmable 8 Button KeypadLinc Switched Lighting Control."""

    def __init__(
        self, plm, address, cat, subcat, product_key=None, description=None, model=None
    ):
        """Init the SwitchedLightingControl_2487S device class."""
        super().__init__(plm, address, cat, subcat, product_key, description, model)

        button_list = {2: "B", 3: "C", 4: "D", 5: "E", 6: "F", 7: "G", 8: "H"}
        self._add_buttons(button_list) class SwitchedLightingControl(Device):
    """Switched Lighting Control.

    Device Class 0x02 subcat Any

    Available device control options are:
        - light_on()
        - light_on_fast()
        - light_off()
        - light_off_fast()
    To monitor the state of the device subscribe to the state monitor:
         - lightOnLevel.connect(callback)
    where callback defined as:
        - callback(self, device_id, state, state_value)
    """

    def __init__(
        self, plm, address, cat, subcat, product_key=0x00, description="", model=""
    ):
        """Init the SwitchedLightingControl device class."""
        super().__init__(plm, address, cat, subcat, product_key, description, model)

        self._stateList[0x01] = OnOffSwitch(
            self._address,
            "lightOnOff",
            0x01,
            self._send_msg,
            self._message_callbacks,
            0x00,
        ) class SwitchedLightingControl_2334_222_6(SwichedLightingControlKeypad):
    """On/Off KeypadLinc Switched Lighting Control."""

    def __init__(
        self, plm, address, cat, subcat, product_key=None, description=None, model=None
    ):
        """Init the SwitchedLightingControl_2487S device class."""
        super().__init__(plm, address, cat, subcat, product_key, description, model)

        button_list = {3: "A", 4: "B", 5: "C", 6: "D"}
        self._add_buttons(button_list) class SwitchedLightingControl_2334_222_8(SwichedLightingControlKeypad):
    """On/Off KeypadLinc Switched Lighting Control."""

    def __init__(
        self, plm, address, cat, subcat, product_key=None, description=None, model=None
    ):
        """Init the SwitchedLightingControl_2487S device class."""
        super().__init__(plm, address, cat, subcat, product_key, description, model)

        button_list = {2: "B", 3: "C", 4: "D", 5: "E", 6: "F", 7: "G", 8: "H"}
        self._add_buttons(button_list) class SwitchedLightingControl_2663_222(Device):
    """On/Off outlet model 2663-222 Switched Lighting Control.

    Device Class 0x02 subcat 0x39

    Two separate INSTEON On/Off switch devices are created with ID
        - 'address': Top Outlet
        - 'address_2': Bottom Outlet

    Available device control options are:
        - light_on()
        - light_on_fast()
        - light_off()
        - light_off_fast()
    To monitor the state of the device subscribe to the state monitor:
         - lightOnLevel.connect(callback)
    where callback defined as:
        - callback(self, device_id, state, state_value)
    """

    def __init__(
        self, plm, address, cat, subcat, product_key=None, description=None, model=None
    ):
        """Init the SwitchedLightingControl_2663_222 device class."""
        super().__init__(plm, address, cat, subcat, product_key, description, model)

        self._stateList[0x01] = OnOffSwitch_OutletTop(
            self._address,
            "outletTopOnOff",
            0x01,
            self._send_msg,
            self._message_callbacks,
            0x00,
        )
        self._stateList[0x02] = OnOffSwitch_OutletBottom(
            self._address,
            "outletBottomOnOff",
            0x02,
            self._send_msg,
            self._message_callbacks,
            0x00,
        ) class ClimateControl_2441th(Device):
    """Thermostat model 2441TH."""

    def __init__(
        self, plm, address, cat, subcat, product_key=None, description=None, model=None
    ):
        """Init the DimmableLightingControl Class."""
        Device.__init__(
            self, plm, address, cat, subcat, product_key, description, model
        )

        self._stateList[0x01] = CoolSetPoint(
            self._address,
            "coolSetPoint",
            0x01,
            self._send_msg,
            self._message_callbacks,
            0x00,
        )

        self._stateList[0x02] = HeatSetPoint(
            self._address,
            "heatSetPoint",
            0x02,
            self._send_msg,
            self._message_callbacks,
            0x00,
        )

        self._stateList[0xEF] = StatusReport(
            self._address,
            "statusReport",
            0xEF,
            self._send_msg,
            self._message_callbacks,
            0x00,
        )

        self._system_mode = SystemMode(
            self._address,
            "systemMode",
            0x10,
            self._send_msg,
            self._message_callbacks,
            0x00,
        )

        self._fan_mode = FanMode(
            self._address,
            "fanMode",
            0x11,
            self._send_msg,
            self._message_callbacks,
            0x00,
        )

        self._temp = Temperature(
            self._address,
            "temperature",
            0x12,
            self._send_msg,
            self._message_callbacks,
            0x00,
        )

        self._humidity = Humidity(
            self._address,
            "humidity",
            0x13,
            self._send_msg,
            self._message_callbacks,
            0x00,
        )

    @property
    def cool_set_point(self):
        """Return the cool set point state."""
        return self._stateList[0x01]

    @property
    def heat_set_point(self):
        """Return the heat set point state."""
        return self._stateList[0x02]

    @property
    def system_mode(self):
        """Return the mode state."""
        return self._system_mode

    @property
    def fan_mode(self):
        """Return the mode state."""
        return self._fan_mode

    @property
    def temperature(self):
        """Return the temperature state."""
        return self._temp

    @property
    def humidity(self):
        """Return the humidity state."""
        return self._humidity

    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()

    # pylint: disable=unused-argument
    def _mode_changed(self, addr, group, val):
        self.async_refresh_state() class SecurityHealthSafety(Device):
    """Security Health Safety Control Device Class.

    Device cat: 0x10 subcat: Any

    INSTEON Security Health Safety Control Device Class.
    These are typically binary sensors with On/Off status.
    There are no state change commands that can be sent to the device.

    To monitor the state of the device subscribe to the state monitor:
         - sensor.connect(callback)  (state='Sensor')
    where callback defined as:
        - callback(self, device_id, state, state_value)
    """

    def __init__(
        self, plm, address, cat, subcat, product_key=None, description=None, model=None
    ):
        """Init the SecurityHealthSafety device class."""
        super().__init__(plm, address, cat, subcat, product_key, description, model)

        self._product_data_in_aldb = True

        self._stateList[0x01] = VariableSensor(
            self._address,
            "generalSensor",
            0x01,
            self._send_msg,
            self._message_callbacks,
            0x00,
        ) class SecurityHealthSafety_2421(Device):
    """Security Health Safety Control Device Class.

    TriggerLinc model 2421.
    Device cat: 0x10 subcat: 0x02.

    INSTEON Security Health Safety Control Device Class.
    This device is a binary sensors with On/Off status.
    There are no state change commands that can be sent to the device.

    To monitor the state of the device subscribe to the state monitor:
         - sensor.connect(callback)  (state='Sensor')
    where callback defined as:
        - callback(self, device_id, state, state_value)
    """

    def __init__(
        self, plm, address, cat, subcat, product_key=None, description=None, model=None
    ):
        """Init the SecurityHealthSafety_2421 device class."""
        super().__init__(plm, address, cat, subcat, product_key, description, model)

        self._product_data_in_aldb = True

        self._stateList[0x01] = OnOffSensor(
            self._address,
            "openClosedSensor",
            0x01,
            self._send_msg,
            self._message_callbacks,
            0x00,
        ) class SecurityHealthSafety_2842_222(Device):
    """Security Health Safety Control Device Class.

    Moton Sensor model 2842-222.
    Device cat: 0x10 subcat: 0x01.

    INSTEON Security Health Safety Control Device Class.
    This device is a binary sensors with On/Off status.
    There are no state change commands that can be sent to the device.

    To monitor the state of the device subscribe to the state monitor:
         - sensor.connect(callback)  (state='Sensor')
    where callback defined as:
        - callback(self, device_id, state, state_value)
    """

    def __init__(
        self, plm, address, cat, subcat, product_key=None, description=None, model=None
    ):
        """Init the SecurityHealthSafety_2842_222 device class."""
        super().__init__(plm, address, cat, subcat, product_key, description, model)

        self._product_data_in_aldb = True

        self._stateList[0x01] = OnOffSensor(
            self._address,
            "motionSensor",
            0x01,
            self._send_msg,
            self._message_callbacks,
            0x00,
        )

        self._stateList[0x02] = OnOffSensor(
            self._address,
            "lightSensor",
            0x02,
            self._send_msg,
            self._message_callbacks,
            0x00,
        )

        self._stateList[0x03] = OnOffSensor(
            self._address,
            "batterySensor",
            0x03,
            self._send_msg,
            self._message_callbacks,
            0x00,
        ) class SecurityHealthSafety_2852_222(Device):
    """Security Health Safety Control Device Class.

    Water Leak Sensor model 2852-222.
    Device cat: 0x10 subcat: 0x08.

    INSTEON Security Health Safety Control Device Class.
    This device is a binary sensors with On/Off status.
    There are no state change commands that can be sent to the device.

    To monitor the state of the device subscribe to the state monitor:
         - sensor.connect(callback)  (state='Sensor')
    where callback defined as:
        - callback(self, device_id, state, state_value)
    """

    def __init__(
        self, plm, address, cat, subcat, product_key=None, description=None, model=None
    ):
        """Init the SecurityHealthSafety_2852_222 device class."""
        super().__init__(plm, address, cat, subcat, product_key, description, model)

        self._product_data_in_aldb = True

        self._stateList[0x01] = LeakSensorDryWet(
            self._address,
            "dryLeakSensor",
            0x01,
            self._send_msg,
            self._message_callbacks,
            defaultvalue=0x01,
            dry_wet=LeakSensorState.DRY,
        )
        self._stateList[0x02] = LeakSensorDryWet(
            self._address,
            "wetLeakSensor",
            0x02,
            self._send_msg,
            self._message_callbacks,
            defaultvalue=0x00,
            dry_wet=LeakSensorState.WET,
        )
        self._stateList[0x04] = LeakSensorHeartbeat(
            self._address,
            "heartbeatLeakSensor",
            0x04,
            self._send_msg,
            self._message_callbacks,
            defaultvalue=0x11,
        )

        self._stateList[0x01].register_dry_wet_callback(self._stateList[0x02].set_value)
        self._stateList[0x01].register_dry_wet_callback(self._stateList[0x04].set_value)

        self._stateList[0x02].register_dry_wet_callback(self._stateList[0x01].set_value)
        self._stateList[0x02].register_dry_wet_callback(self._stateList[0x04].set_value)

        self._stateList[0x04].register_dry_wet_callback(self._stateList[0x01].set_value)
        self._stateList[0x04].register_dry_wet_callback(self._stateList[0x02].set_value) class SecurityHealthSafety_2845_222(Device):
    """Security Health Safety Control Device Class.

    Hidden Door Sensor model 2845-222.
    Device cat: 0x10 subcat: 0x11.

    INSTEON Security Health Safety Control Device Class.
    This device is a binary sensors with On/Off status.
    There are no state change commands that can be sent to the device.

    To monitor the state of the device subscribe to the state monitor:
         - sensor.connect(callback)  (state='Sensor')
    where callback defined as:
        - callback(self, device_id, state, state_value)
    """

    def __init__(
        self, plm, address, cat, subcat, product_key=None, description=None, model=None
    ):
        """Init the SecurityHealthSafety_2845_222 device class."""
        super().__init__(plm, address, cat, subcat, product_key, description, model)

        self._product_data_in_aldb = True

        self._stateList[0x01] = OnOffSensor(
            self._address,
            "doorSensor",
            0x01,
            self._send_msg,
            self._message_callbacks,
            0x00,
        ) class SecurityHealthSafety_2982_222(Device):
    """Security Health Safety Control Device Class.

    Smoke Bridge model 2982-222
    Device cat: 0x10 subcat: 0x0a

    INSTEON Security Health Safety Control Device Class.
    This device is a variable sensors with the following values:
        0: All clear
        1: Smoke detected
        2: CO2 detected
        3: Test detected
        4: Unknown message detected
        5: All Clear detected
        6: Low Battery
        7: Sensor malfunction
    There are no state change commands that can be sent to the device.

    To monitor the state of the device subscribe to the state monitor:
         - sensor.connect(callback)  (state='Sensor')
    where callback defined as:
        - callback(self, device_id, state, state_value)
    """

    def __init__(
        self, plm, address, cat, subcat, product_key=None, description=None, model=None
    ):
        """Init the SecurityHealthSafety_2982_222 Class."""
        super().__init__(plm, address, cat, subcat, product_key, description, model)

        self._product_data_in_aldb = True

        self._stateList[0x01] = SmokeCO2Sensor(
            self._address,
            "smokeCO2Sensor",
            0x01,
            self._send_msg,
            self._message_callbacks,
            0x00,
        ) class SensorsActuators(Device):
    """Sensors And Actuator Device Class.

    Device cat: 0x07 subcat: Any

    There are 3 known device types in this category:
        1) I/O Linc [2450] & [2450-50-60]
        2) Smartenit IO devices (various input and output channels,
        see http://sandbox.smartenit.com/downloads/IoTxx_Command_Set.pdf)
        Including
            a) EZSns1W Sensor Interface Module
            b) EZIO8T I/O Module
            c) EZIO2X4
            d) EZIO8SA / IOT8
            e) EZSnsRF
            f) EZISnsRf
            g) EZIO6I
            h) EZIO4O
        3) SynchroLinc [2423A5]
        (http://cache.insteon.com/developer/2423A5dev-112010-en.pdf)

    Each device type is sufficiently different as to require their own device
    class. However, they all seem to have a common element of a relay and a
    sensor.
    """

    def __init__(
        self, plm, address, cat, subcat, product_key=0, description="", model=""
    ):
        """Init the SensorsActuators Class."""
        super().__init__(plm, address, cat, subcat, product_key, description, model)

        self._stateList[0x01] = OpenClosedRelay(
            self._address,
            "openClosedRelay",
            0x01,
            self._send_msg,
            self._message_callbacks,
            0x00,
        ) class SensorsActuators_2450(SensorsActuators):
    """I/O Linc [2450] & [2450-50-60] Device Class.

    I/O Linc model 2450 and 2450-50-60.
    Device cat: 0x07 subcat: 0x00

    Two separate INSTEON devices are created
        1) Relay
            - ID: xxxxxx (where xxxxxx is the Insteon address of the device)
            - Controls:
                - relay_close()
                - relay_open()
            - Monitor: relay.connect(callback)
                - Closed: 0x00
                - Open:   0xff
        2) Sensor
            - ID: xxxxxx_2  (where xxxxxx is the Insteon address of the device)
            - Controls: None
            - Monitor: sensor.connect(callback)
               - Closed: 0x00
               - Open:   0x01

    where callback defined as:
        - callback(self, device_id, state, state_value)
    """

    def __init__(
        self, plm, address, cat, subcat, product_key=None, description=None, model=None
    ):
        """Init the SensorsActuators_2450 Class."""
        super().__init__(plm, address, cat, subcat, product_key, description, model)

        self._stateList[0x01] = OpenClosedRelay(
            self._address,
            "openClosedRelay",
            0x01,
            self._send_msg,
            self._message_callbacks,
            0x00,
        )

        # Both the Relay and the Sensor are linked via group 1.
        # The sensor status updates are sent as group 1 updates.
        # The relay status is not relevent.
        self._stateList[0x02] = IoLincSensor(
            self._address,
            "ioLincSensor",
            0x02,
            self._send_msg,
            self._message_callbacks,
            0x00,
        ) class WindowCovering(Device):
    """Window Covering Controller.

    INSTEON Window Covering device class. Available device control options are:
        - open()
        - open_fast()
        - set_position(openlevel=0xff)
        - close()
        - close_fast()

    To monitor changes to the state of the device subscribe to the state
    monitor:
         - _states[0x01].connect(callback)  (state='LightOnLevel')

    where callback defined as:
        - callback(self, device_id, state, state_value)
    """

    def __init__(
        self, plm, address, cat, subcat, product_key=None, description=None, model=None
    ):
        """Init the WindowCovering Class."""
        Device.__init__(
            self, plm, address, cat, subcat, product_key, description, model
        )

        self._stateList[0x01] = Cover(
            self._address,
            "coverOpenLevel",
            0x01,
            self._send_msg,
            self._message_callbacks,
            0x00,
        ) class X10OnOff(X10Device):
    """General X10 On / Off Switch Device Class."""

    def __init__(self, plm, housecode, unitcode):
        """Init the X10OnOff class."""
        super().__init__(plm, housecode, unitcode)
        self._description = "X10 On / Off Device"

        self._stateList[0x01] = X10OnOffSwitch(
            self._address,
            "x10OnOffSwitch",
            0x01,
            self._send_msg,
            self._message_callbacks,
            0x00,
        ) class X10Dimmable(X10Device):
    """General X10 Dimmable Switch Device Class."""

    def __init__(self, plm, housecode, unitcode, dim_steps=22):
        """Init the X10Dimmable class."""
        super().__init__(plm, housecode, unitcode)
        self._description = "X10 Dimmable Device"

        self._stateList[0x01] = X10DimmableSwitch(
            self._address,
            "x10DimmableSwitch",
            0x01,
            self._send_msg,
            self._message_callbacks,
            0x00,
            dim_steps,
        ) class X10Sensor(X10Device):
    """General X10 On / Off Sensor Device Class."""

    def __init__(self, plm, housecode, unitcode):
        """Init the X10Sensor class."""
        super().__init__(plm, housecode, unitcode)
        self._description = "X10 On / Off Sensor Device"

        self._stateList[0x01] = X10OnOffSensor(
            self._address,
            "x10OnOffSensor",
            0x01,
            self._send_msg,
            self._message_callbacks,
            0x00,
        ) class X10AllUnitsOff(X10Device):
    """X10 All Units Off Device."""

    def __init__(self, plm, housecode, unitcode):
        """Init the X10AllUnitsOff class."""
        super().__init__(plm, housecode, 20)
        self._description = "X10 All Units Off Device"

        self._stateList[0x01] = X10AllUnitsOffSensor(
            self._address,
            "x10AllUnitsOffSensor",
            0x01,
            self._send_msg,
            self._message_callbacks,
            0xFF,
        )

        self._stateList[0x01].register_updates(self._reset_state)
        self._register_messages()

    # pylint: disable=unused-argument
    def _reset_state(self, addr, name, val):
        loop = self._plm.loop
        if val == 0x00:
            asyncio.ensure_future(self._reset_state_value(loop), loop=loop)

    async def _reset_state_value(self, loop):
        await asyncio.sleep(1, loop=loop)
        self._stateList[0x01].reset()

    def _register_messages(self):
        all_units_off_msg = X10Received.command_msg(
            self.address.x10_housecode, X10_COMMAND_ALL_UNITS_OFF
        )
        self._plm.message_callbacks.add(all_units_off_msg, self.receive_message) class X10AllLightsOn(X10Device):
    """X10 All Lights On Device."""

    def __init__(self, plm, housecode, unitcode):
        """Init the X10AllLightsOn class."""
        super().__init__(plm, housecode, 21)
        self._description = "X10 All Lights On Device"

        self._stateList[0x01] = X10AllLightsOnSensor(
            self._address,
            "X10AllLightsOnSensor",
            0x01,
            self._send_msg,
            self._message_callbacks,
            0x00,
        )

        self._stateList[0x01].register_updates(self._reset_state)
        self._register_messages()

    # pylint: disable=unused-argument
    def _reset_state(self, addr, name, val):
        loop = self._plm.loop
        if val == 0xFF:
            asyncio.ensure_future(self._reset_state_value(loop), loop=loop)

    async def _reset_state_value(self, loop):
        await asyncio.sleep(1, loop=loop)
        self._stateList[0x01].reset()

    def _register_messages(self):
        all_on_msg = X10Received.command_msg(
            self.address.x10_housecode, X10_COMMAND_ALL_LIGHTS_ON
        )
        self._plm.message_callbacks.add(all_on_msg, self.receive_message) class X10AllLightsOff(X10Device):
    """X10 All Lights Off Device."""

    def __init__(self, plm, housecode, unitcode):
        """Init the X10AllLightsOff class."""
        super().__init__(plm, housecode, 22)
        self._description = "X10 All Lights Off Device"

        self._stateList[0x01] = X10AllLightsOffSensor(
            self._address,
            "X10AllLightsOffSensor",
            0x01,
            self._send_msg,
            self._message_callbacks,
            0xFF,
        )

        self._stateList[0x01].register_updates(self._reset_state)
        self._register_messages()

    # pylint: disable=unused-argument
    def _reset_state(self, addr, name, val):
        loop = self._plm.loop
        if val == 0x00:
            asyncio.ensure_future(self._reset_state_value(loop), loop=loop)

    async def _reset_state_value(self, loop):
        await asyncio.sleep(1, loop=loop)
        self._stateList[0x01].reset()

    def _register_messages(self):
        all_off_msg = X10Received.command_msg(
            self.address.x10_housecode, X10_COMMAND_ALL_LIGHTS_OFF
        )
        self._plm.message_callbacks.add(all_off_msg, self.receive_message)
import logging
import collections
from insteonplm.devices.unknowndevice import UnknownDevice
from insteonplm.devices.generalController import (
    GeneralController,
    GeneralController_2342,
    GeneralController_2342_4,
    GeneralController_2342_8,
)
from insteonplm.devices.dimmableLightingControl import (
    DimmableLightingControl,
    DimmableLightingControl_2475F,
    DimmableLightingControl_2334_222_6,
    DimmableLightingControl_2334_222_8,
)
from insteonplm.devices.switchedLightingControl import (
    SwitchedLightingControl,
    SwitchedLightingControl_2334_222_6,
    SwitchedLightingControl_2334_222_8,
    SwitchedLightingControl_2663_222,
)
from insteonplm.devices.climateControl import ClimateControl_2441th
from insteonplm.devices.securityHealthSafety import (
    SecurityHealthSafety,
    SecurityHealthSafety_2421,
    SecurityHealthSafety_2842_222,
    SecurityHealthSafety_2852_222,
    SecurityHealthSafety_2845_222,
    SecurityHealthSafety_2982_222,
)
from insteonplm.devices.sensorsActuators import SensorsActuators, SensorsActuators_2450
from insteonplm.devices.windowCoverings import WindowCovering
from insteonplm.devices.x10 import (
    X10OnOff,
    X10Dimmable,
    X10Sensor,
    X10AllUnitsOff,
    X10AllLightsOn,
    X10AllLightsOff,
)
        Product(0x02, 0x0A, None, 'SwitchLinc Relay', '2476S', SwitchedLightingControl),
        Product(0x02, 0x0B, None, 'ICON On/Off Switch', '2876S', SwitchedLightingControl),
        Product(0x02, 0x0C, None, 'ICON Appliance Module', '2856S3B', SwitchedLightingControl),
        Product(0x02, 0x0D, None, 'ToggleLinc On/Off', '2466SW', SwitchedLightingControl),
        Product(0x02, 0x0E, None, 'SwitchLinc Relay Countdown Timer', '2476ST', SwitchedLightingControl),
        Product(0x02, 0x0F, None, 'KeypadLinc On/Off', '2486SWH6', SwitchedLightingControl_2334_222_6),
        Product(0x02, 0x0F, 0x000036, 'KeypadLinc On/Off', '2486SWH6', SwitchedLightingControl_2334_222_6),
        Product(0x02, 0x10, 0x00001B, 'In-LineLinc Relay', '2475S', SwitchedLightingControl),
        Product(0x02, 0x11, None, 'EZSwitch30', '', SwitchedLightingControl),
        Product(0x02, 0x12, 0x00003E, 'ICON In-LineLinc Relay', '2474S', SwitchedLightingControl),
        Product(0x02, 0x13, None, 'Icon SwitchLinc Relay (Lixar)', '2676R-B', SwitchedLightingControl),
        Product(0x02, 0x14, None, 'In-LineLinc Relay with Sense', '2475S2', SwitchedLightingControl),
        Product(0x02, 0x15, None, 'SwitchLinc Relay with Sense', '2476S', SwitchedLightingControl),
        Product(0x02, 0x16, None, 'ICON On/Off Switch', '2876S', SwitchedLightingControl),
        Product(0x02, 0x17, None, 'ICON Appliance Module', '2856S3B', SwitchedLightingControl),
        Product(0x02, 0x18, 0x000060, 'SwitchLinc 220V Relay', '2494S220', SwitchedLightingControl),
        Product(0x02, 0x19, None, 'SwitchLinc 220V Relay', '2494S220', SwitchedLightingControl),
        Product(0x02, 0x1A, 0x0000000, 'ToggleLinc On/Off', '2466SW', SwitchedLightingControl),
        Product(0x02, 0x1C, None, 'SwitchLinc Relay', '2476S', SwitchedLightingControl),
        Product(0x02, 0x1E, None, 'KeypadLinc On/Off', '2487S', SwitchedLightingControl_2334_222_6),
        Product(0x02, 0x1F, None, 'In-LineLinc On/Off', '2475SDB', SwitchedLightingControl),
        Product(0x02, 0x20, 0x00008A, 'Wall Keypad Switch', '4704', SwitchedLightingControl),
        Product(0x02, 0x21, 0x00008C, 'Outlet Switch', '4707', SwitchedLightingControl),
        Product(0x02, 0x22, 0x000093, 'In-Line Switch', '4713', SwitchedLightingControl),
        Product(0x02, 0x23, 0x000088, 'Wall Switch', '4702', SwitchedLightingControl),
        Product(0x02, 0x24, 0x0000A1, 'Wall Keypad Switch 277V', '4102', SwitchedLightingControl),
        Product(0x02, 0x25, None, 'Keypad Countdown Timer 8-button', '2484SWH8', SwitchedLightingControl),
        Product(0x02, 0x26, None, 'KeypadLinc Schedule Timer On/Off Switch', '2485SWH6', SwitchedLightingControl),
        Product(0x02, 0x29, None, 'SwitchLinc Relay Countdown Timer', '2476ST', SwitchedLightingControl),
        Product(0x02, 0x2A, None, 'SwitchLinc Relay (Dual-Band)', '2477S', SwitchedLightingControl),
        Product(0x02, 0x2B, None, 'In-LineLinc On/Off', '2475SDB-50', SwitchedLightingControl),
        Product(0x02, 0x2B, None, 'In-LineLinc On/Off)', '2475SDB-50', SwitchedLightingControl),
        Product(0x02, 0x2C, None, 'KeypadLinc On/Off', '2487S', SwitchedLightingControl_2334_222_6),
        Product(0x02, 0x2C, None, 'KeypadLinc On/Off', '2487S-50', SwitchedLightingControl_2334_222_6),
        Product(0x02, 0x2D, None, 'On/Off Module', '2633-422', SwitchedLightingControl),
        Product(0x02, 0x2E, None, 'DIN Rail On/Off', '2453-222', SwitchedLightingControl),
        Product(0x02, 0x2F, None, 'Micro On/Off', '2443-222', SwitchedLightingControl),
        Product(0x02, 0x30, None, 'On/Off Module', '2633-432', SwitchedLightingControl),
        Product(0x02, 0x31, None, 'Micro On/Off', '2443-422', SwitchedLightingControl),
        Product(0x02, 0x32, None, 'Micro On/Off', '2443-522', SwitchedLightingControl),
        Product(0x02, 0x33, None, 'DIN Rail On/Off', '2453-422', SwitchedLightingControl),
        Product(0x02, 0x34, None, 'DIN Rail On/Off', '2453-522', SwitchedLightingControl),
        Product(0x02, 0x35, None, 'On/Off Module', '2633-442', SwitchedLightingControl),
        Product(0x02, 0x36, None, 'On/Off Module', '2633-522', SwitchedLightingControl),
        Product(0x02, 0x37, None, 'On/Off Module', '2635-222', SwitchedLightingControl),
        Product(0x02, 0x38, None, 'On/Off Outdoor Module', '2634-222', SwitchedLightingControl),
        Product(0x02, 0x39, None, 'On/Off Outlet', '2663-222', SwitchedLightingControl_2663_222),

        Product(0x03, None, None, 'Generic Network Bridge Controller', '', None),
        Product(0x03, 0x01, None, 'PowerLinc Serial', '2414S', None),
        Product(0x03, 0x02, None, 'PowerLinc USB', '2414U', None),
        Product(0x03, 0x03, None, 'ICON PLC Serial', '', None),
        Product(0x03, 0x04, None, 'ICON PLC USB', '', None),
        Product(0x03, 0x05, 0x00000C, 'PowerLinc Serial Modem', '2412S', None),
        Product(0x03, 0x06, None, 'IRLinc Receiver', '2411R', None),
        Product(0x03, 0x07, None, 'IRLinc Transmitter', '2411T', None),
        Product(0x03, 0x0B, 0x000030, 'PowerLinc USB Modem', '2412U', None),
        Product(0x03, 0x0D, 0x000035, 'SimpleHomeNet EZX10RF', '', None),
        Product(0x03, 0x0F, 0x00003B, 'EZX10IR', '', None),
        Product(0x03, 0x10, None, 'SmartLinc', '2412N', None),
        Product(0x03, 0x11, None, 'PowerLinc Serial Modem', '2413S', None),
        Product(0x03, 0x13, 0x000030, 'PowerLinc USB Modem', '2412UH', None),
        Product(0x03, 0x14, 0x00000C, 'PowerLinc Serial Modem', '2412SH', None),
        Product(0x03, 0x15, None, 'PowerLinc USB Modem', '2413U', None),
        Product(0x03, 0x18, None, 'Central Controller', '2243-222', None),
        Product(0x03, 0x19, None, 'PowerLinc Serial Modem', '2413SH', None),
        Product(0x03, 0x1A, None, 'PowerLinc USB Modem', '2413UH', None),
        Product(0x03, 0x1B, None, 'iGateway', '2423A4', None),
        Product(0x03, 0x1F, 0x00007E, 'USB Adapter', '2448A7', None),
        Product(0x03, 0x20, 0x00007E, 'USB Adapter', '2448A7', None),
        Product(0x03, 0x21, 0x00008E, 'USB Adapter', '2448A7H', None),
        Product(0x03, 0x22, 0x00008F, 'Central Controller Interface', '4706A', None),
        Product(0x03, 0x23, 0x00008E, 'USB Adapter', '2448A7H', None),
        Product(0x03, 0x24, 0x0000A2, 'TouchLinc', '2448A7T', None),
        Product(0x03, 0x27, 0x0000A2, 'TouchLinc', '2448A7T', None),
        Product(0x03, 0x2B, None, 'Hub', '2242-222', None),
        Product(0x03, 0x2C, None, 'Central Controller', '2243-422', None),
        Product(0x03, 0x2C, None, 'Central Controller', '2243-442', None),
        Product(0x03, 0x2D, None, 'Central Controller', '2243-522', None),
        Product(0x03, 0x2E, None, 'Hub', '2242-422', None),
        Product(0x03, 0x2F, None, 'Hub', '2242-522', None),
        Product(0x03, 0x30, None, 'Hub', '2242-442', None),
        Product(0x03, 0x31, None, 'Hub', '2242-232', None),
        Product(0x03, 0x32, None, 'Hub', '2242-222', None),
        Product(0x03, 0x33, None, 'Hub', '2245-555', None),
        Product(0x03, 0x34, None, 'Hub', '2245-442', None),
        Product(0x03, 0x35, None, 'Hub', '2245-422', None),
        Product(0x03, 0x36, None, 'Hub', '2245-522', None),
        Product(0x03, 0x37, None, 'Hub', '', None),

        Product(0x04, None, None, 'Generic Irrigation Controler', '', None),
        Product(0x04, 0x00, 0x000001, 'Compacta EZRain Sprinkler Controller', '31270', None),

        Product(0x05, None, None, 'Generic Climate Controller', '', None),
        Product(0x05, 0x00, None, 'Broan SMSC080 Exhaust Fan', '', None),
        Product(0x05, 0x01, 0x000002, 'EZTherm', '', None),
        Product(0x05, 0x02, None, 'Broan SMSC110 Exhaust Fan', '', None),
        Product(0x05, 0x03, 0x00001F, 'Thermostat Adapter', '2441V', None),
        Product(0x05, 0x04, 0x000024, 'EZTherm', '', None),
        Product(0x05, 0x05, 0x000038, 'Broan, Venmar, BEST Rangehoods', '', None),
        Product(0x05, 0x07, None, 'Wireless Thermostat', '2441ZTH', ClimateControl_2441th),
        Product(0x05, 0x08, None, 'Thermostat', '2441TH', ClimateControl_2441th),
        Product(0x05, 0x09, 0x000094, '7 Day Thermostat', '4715', None),
        Product(0x05, 0x0A, None, 'Wireless Thermostat', '2441ZTH', ClimateControl_2441th),
        Product(0x05, 0x0B, None, 'Thermostat', '2441TH', ClimateControl_2441th),
        Product(0x05, 0x0E, None, 'Integrated Remote Control Thermostat', '2491T1E', None),
        Product(0x05, 0x0F, None, 'Thermostat', '2732-422', None),
        Product(0x05, 0x10, None, 'Thermostat', '2732-522', None),
        Product(0x05, 0x11, None, 'Wireless Thermostat', '2732-432', None),
        Product(0x05, 0x12, None, 'Wireless Thermostat', '2732-532', None),
        Product(0x05, 0x13, None, 'Thermostat Heat Pump', '2732-232', None),
        Product(0x05, 0x14, None, 'Thermostat Heat Pump', '2732-432', None),
        Product(0x05, 0x15, None, 'Thermostat Heat Pump', '2732-532', None),
        Product(0x05, 0x16, None, 'Insteon Thermostat', '2441TH', ClimateControl_2441th),
        Product(0x05, 0x17, None, 'Insteon Thermostat', '2732-422', None),
        Product(0x05, 0x18, None, 'Insteon Thermostat', '2732-522', None),

        Product(0x06, None, None, 'Generic Pool Controller', '', None),
        Product(0x06, 0x00, 0x000003, 'EZPool', '', None),


        Product(0x07, None, None, 'Generic Sensor Actuator', '', SensorsActuators),