diff --git a/homeassistant/components/zwave_js/discovery.py b/homeassistant/components/zwave_js/discovery.py index 7231d18e186..9379ab69b34 100644 --- a/homeassistant/components/zwave_js/discovery.py +++ b/homeassistant/components/zwave_js/discovery.py @@ -83,6 +83,12 @@ class ZWaveDiscoverySchema: allow_multi: bool = False +SWITCH_MULTILEVEL_CURRENT_VALUE_SCHEMA = ZWaveValueDiscoverySchema( + command_class={CommandClass.SWITCH_MULTILEVEL}, + property={"currentValue"}, + type={"number"}, +) + # For device class mapping see: # https://github.com/zwave-js/node-zwave-js/blob/master/packages/config/config/deviceClasses.json DISCOVERY_SCHEMAS = [ @@ -93,11 +99,7 @@ DISCOVERY_SCHEMAS = [ manufacturer_id={0x0039}, product_id={0x3131}, product_type={0x4944}, - primary_value=ZWaveValueDiscoverySchema( - command_class={CommandClass.SWITCH_MULTILEVEL}, - property={"currentValue"}, - type={"number"}, - ), + primary_value=SWITCH_MULTILEVEL_CURRENT_VALUE_SCHEMA, ), # GE/Jasco fan controllers using switch multilevel CC ZWaveDiscoverySchema( @@ -105,11 +107,7 @@ DISCOVERY_SCHEMAS = [ manufacturer_id={0x0063}, product_id={0x3034, 0x3131, 0x3138}, product_type={0x4944}, - primary_value=ZWaveValueDiscoverySchema( - command_class={CommandClass.SWITCH_MULTILEVEL}, - property={"currentValue"}, - type={"number"}, - ), + primary_value=SWITCH_MULTILEVEL_CURRENT_VALUE_SCHEMA, ), # Leviton ZW4SF fan controllers using switch multilevel CC ZWaveDiscoverySchema( @@ -117,50 +115,39 @@ DISCOVERY_SCHEMAS = [ manufacturer_id={0x001D}, product_id={0x0002}, product_type={0x0038}, - primary_value=ZWaveValueDiscoverySchema( - command_class={CommandClass.SWITCH_MULTILEVEL}, - property={"currentValue"}, - type={"number"}, - ), + primary_value=SWITCH_MULTILEVEL_CURRENT_VALUE_SCHEMA, ), # Fibaro Shutter Fibaro FGS222 ZWaveDiscoverySchema( platform="cover", - hint="fibaro_fgs222", manufacturer_id={0x010F}, product_id={0x1000}, product_type={0x0302}, - primary_value=ZWaveValueDiscoverySchema( - command_class={CommandClass.SWITCH_MULTILEVEL}, - property={"currentValue"}, - type={"number"}, - ), + primary_value=SWITCH_MULTILEVEL_CURRENT_VALUE_SCHEMA, ), # Qubino flush shutter ZWaveDiscoverySchema( platform="cover", - hint="fibaro_fgs222", manufacturer_id={0x0159}, product_id={0x0052}, product_type={0x0003}, - primary_value=ZWaveValueDiscoverySchema( - command_class={CommandClass.SWITCH_MULTILEVEL}, - property={"currentValue"}, - type={"number"}, - ), + primary_value=SWITCH_MULTILEVEL_CURRENT_VALUE_SCHEMA, ), # Graber/Bali/Spring Fashion Covers ZWaveDiscoverySchema( platform="cover", - hint="fibaro_fgs222", manufacturer_id={0x026E}, product_id={0x5A31}, product_type={0x4353}, - primary_value=ZWaveValueDiscoverySchema( - command_class={CommandClass.SWITCH_MULTILEVEL}, - property={"currentValue"}, - type={"number"}, - ), + primary_value=SWITCH_MULTILEVEL_CURRENT_VALUE_SCHEMA, + ), + # iBlinds v2 window blind motor + ZWaveDiscoverySchema( + platform="cover", + manufacturer_id={0x0287}, + product_id={0x000D}, + product_type={0x0003}, + primary_value=SWITCH_MULTILEVEL_CURRENT_VALUE_SCHEMA, ), # ====== START OF GENERIC MAPPING SCHEMAS ======= # locks @@ -248,11 +235,7 @@ DISCOVERY_SCHEMAS = [ "Multilevel Scene Switch", "Unused", }, - primary_value=ZWaveValueDiscoverySchema( - command_class={CommandClass.SWITCH_MULTILEVEL}, - property={"currentValue"}, - type={"number"}, - ), + primary_value=SWITCH_MULTILEVEL_CURRENT_VALUE_SCHEMA, ), # binary sensors ZWaveDiscoverySchema( @@ -370,11 +353,7 @@ DISCOVERY_SCHEMAS = [ "Motor Control Class C", "Multiposition Motor", }, - primary_value=ZWaveValueDiscoverySchema( - command_class={CommandClass.SWITCH_MULTILEVEL}, - property={"currentValue"}, - type={"number"}, - ), + primary_value=SWITCH_MULTILEVEL_CURRENT_VALUE_SCHEMA, ), # cover # motorized barriers @@ -400,11 +379,7 @@ DISCOVERY_SCHEMAS = [ hint="fan", device_class_generic={"Multilevel Switch"}, device_class_specific={"Fan Switch"}, - primary_value=ZWaveValueDiscoverySchema( - command_class={CommandClass.SWITCH_MULTILEVEL}, - property={"currentValue"}, - type={"number"}, - ), + primary_value=SWITCH_MULTILEVEL_CURRENT_VALUE_SCHEMA, ), ] diff --git a/tests/components/zwave_js/conftest.py b/tests/components/zwave_js/conftest.py index 31b7d795a60..02b11970376 100644 --- a/tests/components/zwave_js/conftest.py +++ b/tests/components/zwave_js/conftest.py @@ -164,6 +164,12 @@ def motorized_barrier_cover_state_fixture(): return json.loads(load_fixture("zwave_js/cover_zw062_state.json")) +@pytest.fixture(name="iblinds_v2_state", scope="session") +def iblinds_v2_state_fixture(): + """Load the iBlinds v2 node state fixture data.""" + return json.loads(load_fixture("zwave_js/cover_iblinds_v2_state.json")) + + @pytest.fixture(name="client") def mock_client_fixture(controller_state, version_state): """Mock a client.""" @@ -359,3 +365,11 @@ def motorized_barrier_cover_fixture(client, gdc_zw062_state): node = Node(client, gdc_zw062_state) client.driver.controller.nodes[node.node_id] = node return node + + +@pytest.fixture(name="iblinds_v2") +def iblinds_cover_fixture(client, iblinds_v2_state): + """Mock an iBlinds v2.0 window cover node.""" + node = Node(client, iblinds_v2_state) + client.driver.controller.nodes[node.node_id] = node + return node diff --git a/tests/components/zwave_js/test_discovery.py b/tests/components/zwave_js/test_discovery.py new file mode 100644 index 00000000000..f7d26f07d21 --- /dev/null +++ b/tests/components/zwave_js/test_discovery.py @@ -0,0 +1,14 @@ +"""Test discovery of entities for device-specific schemas for the Z-Wave JS integration.""" + + +async def test_iblinds_v2(hass, client, iblinds_v2, integration): + """Test that an iBlinds v2.0 multilevel switch value is discovered as a cover.""" + + node = iblinds_v2 + assert node.device_class.specific == "Unused" + + state = hass.states.get("light.window_blind_controller") + assert not state + + state = hass.states.get("cover.window_blind_controller") + assert state diff --git a/tests/fixtures/zwave_js/cover_iblinds_v2_state.json b/tests/fixtures/zwave_js/cover_iblinds_v2_state.json new file mode 100644 index 00000000000..7cb6f94a6f0 --- /dev/null +++ b/tests/fixtures/zwave_js/cover_iblinds_v2_state.json @@ -0,0 +1,359 @@ +{ + "nodeId": 54, + "index": 0, + "installerIcon": 6400, + "userIcon": 6400, + "status": 4, + "ready": true, + "deviceClass": { + "basic": "Routing Slave", + "generic": "Multilevel Switch", + "specific": "Unused", + "mandatorySupportedCCs": [ + "Basic", + "Multilevel Switch" + ], + "mandatoryControlCCs": [] + }, + "isListening": false, + "isFrequentListening": true, + "isRouting": true, + "maxBaudRate": 40000, + "isSecure": false, + "version": 4, + "isBeaming": true, + "manufacturerId": 647, + "productId": 13, + "productType": 3, + "firmwareVersion": "1.65", + "zwavePlusVersion": 1, + "nodeType": 0, + "roleType": 7, + "deviceConfig": { + "manufacturerId": 647, + "manufacturer": "HAB Home Intelligence, LLC", + "label": "IB2.0", + "description": "Window Blind Controller", + "devices": [ + { + "productType": "0x0003", + "productId": "0x000d" + } + ], + "firmwareVersion": { + "min": "0.0", + "max": "255.255" + }, + "paramInformation": { + "_map": {} + } + }, + "label": "IB2.0", + "neighbors": [ + 1, + 2, + 3, + 7, + 8, + 11, + 15, + 18, + 19, + 22, + 26, + 27, + 44, + 52 + ], + "interviewAttempts": 1, + "interviewStage": 7, + "endpoints": [ + { + "nodeId": 54, + "index": 0, + "installerIcon": 6400, + "userIcon": 6400 + } + ], + "values": [ + { + "endpoint": 0, + "commandClass": 37, + "commandClassName": "Binary Switch", + "property": "currentValue", + "propertyName": "currentValue", + "ccVersion": 2, + "metadata": { + "type": "boolean", + "readable": true, + "writeable": false, + "label": "Current value" + }, + "value": true + }, + { + "endpoint": 0, + "commandClass": 37, + "commandClassName": "Binary Switch", + "property": "targetValue", + "propertyName": "targetValue", + "ccVersion": 2, + "metadata": { + "type": "boolean", + "readable": true, + "writeable": true, + "label": "Target value" + }, + "value": true + }, + { + "endpoint": 0, + "commandClass": 37, + "commandClassName": "Binary Switch", + "property": "duration", + "propertyName": "duration", + "ccVersion": 2, + "metadata": { + "type": "duration", + "readable": true, + "writeable": true, + "label": "Transition duration" + }, + "value": { + "value": 0, + "unit": "seconds" + } + }, + { + "endpoint": 0, + "commandClass": 38, + "commandClassName": "Multilevel Switch", + "property": "targetValue", + "propertyName": "targetValue", + "ccVersion": 4, + "metadata": { + "type": "number", + "readable": true, + "writeable": true, + "min": 0, + "max": 99, + "label": "Target value" + }, + "value": 99 + }, + { + "endpoint": 0, + "commandClass": 38, + "commandClassName": "Multilevel Switch", + "property": "duration", + "propertyName": "duration", + "ccVersion": 4, + "metadata": { + "type": "duration", + "readable": true, + "writeable": true, + "label": "Transition duration" + }, + "value": { + "value": 0, + "unit": "seconds" + } + }, + { + "endpoint": 0, + "commandClass": 38, + "commandClassName": "Multilevel Switch", + "property": "currentValue", + "propertyName": "currentValue", + "ccVersion": 4, + "metadata": { + "type": "number", + "readable": true, + "writeable": false, + "min": 0, + "max": 99, + "label": "Current value" + }, + "value": 30 + }, + { + "endpoint": 0, + "commandClass": 38, + "commandClassName": "Multilevel Switch", + "property": "Up", + "propertyName": "Up", + "ccVersion": 4, + "metadata": { + "type": "boolean", + "readable": true, + "writeable": true, + "label": "Perform a level change (Up)", + "ccSpecific": { + "switchType": 2 + } + } + }, + { + "endpoint": 0, + "commandClass": 38, + "commandClassName": "Multilevel Switch", + "property": "Down", + "propertyName": "Down", + "ccVersion": 4, + "metadata": { + "type": "boolean", + "readable": true, + "writeable": true, + "label": "Perform a level change (Down)", + "ccSpecific": { + "switchType": 2 + } + } + }, + { + "endpoint": 0, + "commandClass": 114, + "commandClassName": "Manufacturer Specific", + "property": "manufacturerId", + "propertyName": "manufacturerId", + "ccVersion": 2, + "metadata": { + "type": "number", + "readable": true, + "writeable": false, + "min": 0, + "max": 65535, + "label": "Manufacturer ID" + }, + "value": 647 + }, + { + "endpoint": 0, + "commandClass": 114, + "commandClassName": "Manufacturer Specific", + "property": "productType", + "propertyName": "productType", + "ccVersion": 2, + "metadata": { + "type": "number", + "readable": true, + "writeable": false, + "min": 0, + "max": 65535, + "label": "Product type" + }, + "value": 3 + }, + { + "endpoint": 0, + "commandClass": 114, + "commandClassName": "Manufacturer Specific", + "property": "productId", + "propertyName": "productId", + "ccVersion": 2, + "metadata": { + "type": "number", + "readable": true, + "writeable": false, + "min": 0, + "max": 65535, + "label": "Product ID" + }, + "value": 13 + }, + { + "endpoint": 0, + "commandClass": 128, + "commandClassName": "Battery", + "property": "level", + "propertyName": "level", + "ccVersion": 1, + "metadata": { + "type": "number", + "readable": true, + "writeable": false, + "min": 0, + "max": 100, + "unit": "%", + "label": "Battery level" + }, + "value": 100 + }, + { + "endpoint": 0, + "commandClass": 128, + "commandClassName": "Battery", + "property": "isLow", + "propertyName": "isLow", + "ccVersion": 1, + "metadata": { + "type": "boolean", + "readable": true, + "writeable": false, + "label": "Low battery level" + }, + "value": false + }, + { + "endpoint": 0, + "commandClass": 134, + "commandClassName": "Version", + "property": "libraryType", + "propertyName": "libraryType", + "ccVersion": 2, + "metadata": { + "type": "any", + "readable": true, + "writeable": false, + "label": "Library type" + }, + "value": 3 + }, + { + "endpoint": 0, + "commandClass": 134, + "commandClassName": "Version", + "property": "protocolVersion", + "propertyName": "protocolVersion", + "ccVersion": 2, + "metadata": { + "type": "any", + "readable": true, + "writeable": false, + "label": "Z-Wave protocol version" + }, + "value": "4.33" + }, + { + "endpoint": 0, + "commandClass": 134, + "commandClassName": "Version", + "property": "firmwareVersions", + "propertyName": "firmwareVersions", + "ccVersion": 2, + "metadata": { + "type": "any", + "readable": true, + "writeable": false, + "label": "Z-Wave chip firmware versions" + }, + "value": [ + "1.65" + ] + }, + { + "endpoint": 0, + "commandClass": 134, + "commandClassName": "Version", + "property": "hardwareVersion", + "propertyName": "hardwareVersion", + "ccVersion": 2, + "metadata": { + "type": "any", + "readable": true, + "writeable": false, + "label": "Z-Wave chip hardware version" + } + } + ] +}