diff --git a/homeassistant/components/zwave_js/cover.py b/homeassistant/components/zwave_js/cover.py index e9759dbb1717017fcc7b8df1e580639e1e4279e8..1dee8b0bad325a20b13cda97ce79b4b9da12f23a 100644 --- a/homeassistant/components/zwave_js/cover.py +++ b/homeassistant/components/zwave_js/cover.py @@ -1,8 +1,9 @@ """Support for Z-Wave cover devices.""" from __future__ import annotations +import asyncio import logging -from typing import Any +from typing import Any, cast from zwave_js_server.client import Client as ZwaveClient from zwave_js_server.const import TARGET_STATE_PROPERTY, TARGET_VALUE_PROPERTY @@ -19,13 +20,19 @@ from zwave_js_server.model.value import Value as ZwaveValue from homeassistant.components.cover import ( ATTR_POSITION, + ATTR_TILT_POSITION, DEVICE_CLASS_BLIND, DEVICE_CLASS_GARAGE, DEVICE_CLASS_SHUTTER, DEVICE_CLASS_WINDOW, DOMAIN as COVER_DOMAIN, SUPPORT_CLOSE, + SUPPORT_CLOSE_TILT, SUPPORT_OPEN, + SUPPORT_OPEN_TILT, + SUPPORT_SET_POSITION, + SUPPORT_SET_TILT_POSITION, + SUPPORT_STOP, CoverEntity, ) from homeassistant.config_entries import ConfigEntry @@ -35,6 +42,7 @@ from homeassistant.helpers.entity_platform import AddEntitiesCallback from .const import DATA_CLIENT, DOMAIN from .discovery import ZwaveDiscoveryInfo +from .discovery_data_template import CoverTiltDataTemplate from .entity import ZWaveBaseEntity LOGGER = logging.getLogger(__name__) @@ -54,6 +62,8 @@ async def async_setup_entry( entities: list[ZWaveBaseEntity] = [] if info.platform_hint == "motorized_barrier": entities.append(ZwaveMotorizedBarrier(config_entry, client, info)) + elif info.platform_hint == "window_shutter_tilt": + entities.append(ZWaveTiltCover(config_entry, client, info)) else: entities.append(ZWaveCover(config_entry, client, info)) async_add_entities(entities) @@ -77,6 +87,26 @@ def percent_to_zwave_position(value: int) -> int: return 0 +def percent_to_zwave_tilt(value: int) -> int: + """Convert position in 0-100 scale to 0-99 scale. + + `value` -- (int) Position byte value from 0-100. + """ + if value > 0: + return round((value / 100) * 99) + return 0 + + +def zwave_tilt_to_percent(value: int) -> int: + """Convert 0-99 scale to position in 0-100 scale. + + `value` -- (int) Position byte value from 0-99. + """ + if value > 0: + return round((value / 99) * 100) + return 0 + + class ZWaveCover(ZWaveBaseEntity, CoverEntity): """Representation of a Z-Wave Cover device.""" @@ -91,7 +121,7 @@ class ZWaveCover(ZWaveBaseEntity, CoverEntity): # Entity class attributes self._attr_device_class = DEVICE_CLASS_WINDOW - if self.info.platform_hint == "window_shutter": + if self.info.platform_hint in ("window_shutter", "window_shutter_tilt"): self._attr_device_class = DEVICE_CLASS_SHUTTER if self.info.platform_hint == "window_blind": self._attr_device_class = DEVICE_CLASS_BLIND @@ -150,6 +180,64 @@ class ZWaveCover(ZWaveBaseEntity, CoverEntity): await self.info.node.async_set_value(close_value, False) +class ZWaveTiltCover(ZWaveCover): + """Representation of a Fibaro Z-Wave cover device.""" + + _attr_supported_features = ( + SUPPORT_OPEN + | SUPPORT_CLOSE + | SUPPORT_STOP + | SUPPORT_SET_POSITION + | SUPPORT_OPEN_TILT + | SUPPORT_CLOSE_TILT + | SUPPORT_SET_TILT_POSITION + ) + + def __init__( + self, + config_entry: ConfigEntry, + client: ZwaveClient, + info: ZwaveDiscoveryInfo, + ) -> None: + """Initialize a ZWaveCover entity.""" + super().__init__(config_entry, client, info) + self.data_template = cast( + CoverTiltDataTemplate, self.info.platform_data_template + ) + + @property + def current_cover_tilt_position(self) -> int | None: + """Return current position of cover tilt. + + None is unknown, 0 is closed, 100 is fully open. + """ + value = self.data_template.current_tilt_value(self.info.platform_data) + return zwave_tilt_to_percent(value.value) if value else None + + async def async_set_cover_tilt_position(self, **kwargs: Any) -> None: + """Move the cover tilt to a specific position.""" + tilt_value = self.data_template.current_tilt_value(self.info.platform_data) + if tilt_value: + await self.info.node.async_set_value( + tilt_value, + percent_to_zwave_tilt(kwargs[ATTR_TILT_POSITION]), + ) + # The following 2 lines are a workaround for this issue: + # https://github.com/zwave-js/node-zwave-js/issues/3611 + # As soon as the issue is fixed, and minimum server schema is bumped + # the 2 lines should be removed. + await asyncio.sleep(2.5) + await self.info.node.async_refresh_cc_values(tilt_value.command_class) + + async def async_open_cover_tilt(self, **kwargs: Any) -> None: + """Open the cover tilt.""" + await self.async_set_cover_tilt_position(tilt_position=100) + + async def async_close_cover_tilt(self, **kwargs: Any) -> None: + """Close the cover tilt.""" + await self.async_set_cover_tilt_position(tilt_position=0) + + class ZwaveMotorizedBarrier(ZWaveBaseEntity, CoverEntity): """Representation of a Z-Wave motorized barrier device.""" diff --git a/homeassistant/components/zwave_js/discovery.py b/homeassistant/components/zwave_js/discovery.py index 23053804aae073c69dc8457851e644209c47b165..80cd6f023fb8b42906d4ced9aef063753bee40b0 100644 --- a/homeassistant/components/zwave_js/discovery.py +++ b/homeassistant/components/zwave_js/discovery.py @@ -44,6 +44,7 @@ from homeassistant.helpers.device_registry import DeviceEntry from .const import LOGGER from .discovery_data_template import ( BaseDiscoverySchemaDataTemplate, + CoverTiltDataTemplate, DynamicCurrentTempClimateDataTemplate, NumericSensorDataTemplate, ZwaveValueID, @@ -258,14 +259,29 @@ DISCOVERY_SCHEMAS = [ type={"number"}, ), ), - # Fibaro Shutter Fibaro FGS222 + # Fibaro Shutter Fibaro FGR222 ZWaveDiscoverySchema( platform="cover", - hint="window_shutter", + hint="window_shutter_tilt", manufacturer_id={0x010F}, - product_id={0x1000}, - product_type={0x0302}, + product_id={0x1000, 0x1001}, + product_type={0x0301, 0x0302}, primary_value=SWITCH_MULTILEVEL_CURRENT_VALUE_SCHEMA, + data_template=CoverTiltDataTemplate( + tilt_value_id=ZwaveValueID( + "fibaro", + CommandClass.MANUFACTURER_PROPRIETARY, + endpoint=0, + property_key="venetianBlindsTilt", + ) + ), + required_values=[ + ZWaveValueDiscoverySchema( + command_class={CommandClass.MANUFACTURER_PROPRIETARY}, + property={"fibaro"}, + property_key={"venetianBlindsTilt"}, + ) + ], ), # Qubino flush shutter ZWaveDiscoverySchema( diff --git a/homeassistant/components/zwave_js/discovery_data_template.py b/homeassistant/components/zwave_js/discovery_data_template.py index 7b76465d60ebafdf47a4b3c80782f00a14547663..a550c683ea280db699735956583204df808229c6 100644 --- a/homeassistant/components/zwave_js/discovery_data_template.py +++ b/homeassistant/components/zwave_js/discovery_data_template.py @@ -226,3 +226,28 @@ class NumericSensorDataTemplate(BaseDiscoverySchemaDataTemplate): return key return None + + +@dataclass +class TiltValueMix: + """Mixin data class for the tilt_value.""" + + tilt_value_id: ZwaveValueID + + +@dataclass +class CoverTiltDataTemplate(BaseDiscoverySchemaDataTemplate, TiltValueMix): + """Tilt data template class for Z-Wave Cover entities.""" + + def resolve_data(self, value: ZwaveValue) -> dict[str, Any]: + """Resolve helper class data for a discovered value.""" + return {"tilt_value": self._get_value_from_id(value.node, self.tilt_value_id)} + + def values_to_watch(self, resolved_data: dict[str, Any]) -> Iterable[ZwaveValue]: + """Return list of all ZwaveValues resolved by helper that should be watched.""" + return [resolved_data["tilt_value"]] + + @staticmethod + def current_tilt_value(resolved_data: dict[str, Any]) -> ZwaveValue | None: + """Get current tilt ZwaveValue from resolved data.""" + return resolved_data["tilt_value"] diff --git a/tests/components/zwave_js/conftest.py b/tests/components/zwave_js/conftest.py index 422f4b55c16d2c627644ec785994d688a852ab67..be9dec3b6bc352128ba283de4a8da2423c6427d9 100644 --- a/tests/components/zwave_js/conftest.py +++ b/tests/components/zwave_js/conftest.py @@ -356,6 +356,12 @@ def aeotec_nano_shutter_state_fixture(): return json.loads(load_fixture("zwave_js/cover_aeotec_nano_shutter_state.json")) +@pytest.fixture(name="fibaro_fgr222_shutter_state", scope="session") +def fibaro_fgr222_shutter_state_fixture(): + """Load the Fibaro FGR222 node state fixture data.""" + return json.loads(load_fixture("zwave_js/cover_fibaro_fgr222_state.json")) + + @pytest.fixture(name="aeon_smart_switch_6_state", scope="session") def aeon_smart_switch_6_state_fixture(): """Load the AEON Labs (ZW096) Smart Switch 6 node state fixture data.""" @@ -743,6 +749,14 @@ def aeotec_nano_shutter_cover_fixture(client, aeotec_nano_shutter_state): return node +@pytest.fixture(name="fibaro_fgr222_shutter") +def fibaro_fgr222_shutter_cover_fixture(client, fibaro_fgr222_shutter_state): + """Mock a Fibaro FGR222 Shutter node.""" + node = Node(client, copy.deepcopy(fibaro_fgr222_shutter_state)) + client.driver.controller.nodes[node.node_id] = node + return node + + @pytest.fixture(name="aeon_smart_switch_6") def aeon_smart_switch_6_fixture(client, aeon_smart_switch_6_state): """Mock an AEON Labs (ZW096) Smart Switch 6 node.""" diff --git a/tests/components/zwave_js/test_cover.py b/tests/components/zwave_js/test_cover.py index 1afe7a114da65f205323e206ad99704913a4eaae..d6d3376d0e603bbc385ea578de6410a34b23c3ea 100644 --- a/tests/components/zwave_js/test_cover.py +++ b/tests/components/zwave_js/test_cover.py @@ -3,6 +3,7 @@ from zwave_js_server.event import Event from homeassistant.components.cover import ( ATTR_CURRENT_POSITION, + ATTR_CURRENT_TILT_POSITION, DEVICE_CLASS_BLIND, DEVICE_CLASS_GARAGE, DEVICE_CLASS_SHUTTER, @@ -25,6 +26,7 @@ GDC_COVER_ENTITY = "cover.aeon_labs_garage_door_controller_gen5" BLIND_COVER_ENTITY = "cover.window_blind_controller" SHUTTER_COVER_ENTITY = "cover.flush_shutter" AEOTEC_SHUTTER_COVER_ENTITY = "cover.nano_shutter_v_3" +FIBARO_SHUTTER_COVER_ENTITY = "cover.fgr_222_test_cover" async def test_window_cover(hass, client, chain_actuator_zws12, integration): @@ -307,6 +309,85 @@ async def test_window_cover(hass, client, chain_actuator_zws12, integration): assert state.state == "closed" +async def test_fibaro_FGR222_shutter_cover( + hass, client, fibaro_fgr222_shutter, integration +): + """Test tilt function of the Fibaro Shutter devices.""" + state = hass.states.get(FIBARO_SHUTTER_COVER_ENTITY) + assert state + assert state.attributes[ATTR_DEVICE_CLASS] == DEVICE_CLASS_SHUTTER + + assert state.state == "open" + assert state.attributes[ATTR_CURRENT_TILT_POSITION] == 0 + + # Test opening tilts + await hass.services.async_call( + "cover", + "open_cover_tilt", + {"entity_id": FIBARO_SHUTTER_COVER_ENTITY}, + blocking=True, + ) + + assert len(client.async_send_command.call_args_list) == 1 + args = client.async_send_command.call_args[0][0] + assert args["command"] == "node.set_value" + assert args["nodeId"] == 42 + assert args["valueId"] == { + "endpoint": 0, + "commandClass": 145, + "commandClassName": "Manufacturer Proprietary", + "property": "fibaro", + "propertyKey": "venetianBlindsTilt", + "propertyName": "fibaro", + "propertyKeyName": "venetianBlindsTilt", + "ccVersion": 0, + "metadata": { + "type": "number", + "readable": True, + "writeable": True, + "label": "Venetian blinds tilt", + "min": 0, + "max": 99, + }, + "value": 0, + } + assert args["value"] == 99 + + client.async_send_command.reset_mock() + # Test closing tilts + await hass.services.async_call( + "cover", + "close_cover_tilt", + {"entity_id": FIBARO_SHUTTER_COVER_ENTITY}, + blocking=True, + ) + + assert len(client.async_send_command.call_args_list) == 1 + args = client.async_send_command.call_args[0][0] + assert args["command"] == "node.set_value" + assert args["nodeId"] == 42 + assert args["valueId"] == { + "endpoint": 0, + "commandClass": 145, + "commandClassName": "Manufacturer Proprietary", + "property": "fibaro", + "propertyKey": "venetianBlindsTilt", + "propertyName": "fibaro", + "propertyKeyName": "venetianBlindsTilt", + "ccVersion": 0, + "metadata": { + "type": "number", + "readable": True, + "writeable": True, + "label": "Venetian blinds tilt", + "min": 0, + "max": 99, + }, + "value": 0, + } + assert args["value"] == 0 + + async def test_aeotec_nano_shutter_cover( hass, client, aeotec_nano_shutter, integration ): diff --git a/tests/fixtures/zwave_js/cover_fibaro_fgr222_state.json b/tests/fixtures/zwave_js/cover_fibaro_fgr222_state.json new file mode 100644 index 0000000000000000000000000000000000000000..59dff9458464ee31bc4523ec3588c324c3013f86 --- /dev/null +++ b/tests/fixtures/zwave_js/cover_fibaro_fgr222_state.json @@ -0,0 +1,1133 @@ +{ + "nodeId": 42, + "index": 0, + "status": 4, + "ready": true, + "isListening": true, + "isRouting": true, + "isSecure": "unknown", + "manufacturerId": 271, + "productId": 4096, + "productType": 770, + "firmwareVersion": "25.25", + "name": "fgr 222 test cover", + "location": "test location", + "deviceConfig": { + "filename": "/usr/src/app/store/.config-db/devices/0x010f/fgr222_24.24.json", + "isEmbedded": true, + "manufacturer": "Fibargroup", + "manufacturerId": 271, + "label": "FGR222", + "description": "Roller Shutter 2", + "devices": [ + { + "productType": 769, + "productId": 4097 + }, + { + "productType": 770, + "productId": 4096 + }, + { + "productType": 770, + "productId": 12288 + }, + { + "productType": 770, + "productId": 16384 + }, + { + "productType": 768, + "productId": 258 + } + ], + "firmwareVersion": { + "min": "24.24", + "max": "255.255" + }, + "associations": {}, + "paramInformation": { + "_map": {} + }, + "proprietary": { + "fibaroCCs": [ + 38 + ] + } + }, + "label": "FGR222", + "interviewAttempts": 0, + "endpoints": [ + { + "nodeId": 42, + "index": 0, + "deviceClass": { + "basic": { + "key": 4, + "label": "Routing Slave" + }, + "generic": { + "key": 17, + "label": "Multilevel Switch" + }, + "specific": { + "key": 6, + "label": "Motor Control Class B" + }, + "mandatorySupportedCCs": [ + 32, + 38, + 37, + 114, + 134 + ], + "mandatoryControlledCCs": [] + } + } + ], + "values": [ + { + "endpoint": 0, + "commandClass": 37, + "commandClassName": "Binary Switch", + "property": "currentValue", + "propertyName": "currentValue", + "ccVersion": 1, + "metadata": { + "type": "boolean", + "readable": true, + "writeable": false, + "label": "Current value" + }, + "value": true + }, + { + "endpoint": 0, + "commandClass": 37, + "commandClassName": "Binary Switch", + "property": "targetValue", + "propertyName": "targetValue", + "ccVersion": 1, + "metadata": { + "type": "boolean", + "readable": true, + "writeable": true, + "label": "Target value", + "valueChangeOptions": [ + "transitionDuration" + ] + } + }, + { + "endpoint": 0, + "commandClass": 38, + "commandClassName": "Multilevel Switch", + "property": "targetValue", + "propertyName": "targetValue", + "ccVersion": 3, + "metadata": { + "type": "number", + "readable": true, + "writeable": true, + "label": "Target value", + "valueChangeOptions": [ + "transitionDuration" + ], + "min": 0, + "max": 99 + }, + "value": 99 + }, + { + "endpoint": 0, + "commandClass": 38, + "commandClassName": "Multilevel Switch", + "property": "duration", + "propertyName": "duration", + "ccVersion": 3, + "metadata": { + "type": "duration", + "readable": true, + "writeable": true, + "label": "Transition duration" + } + }, + { + "endpoint": 0, + "commandClass": 38, + "commandClassName": "Multilevel Switch", + "property": "currentValue", + "propertyName": "currentValue", + "ccVersion": 3, + "metadata": { + "type": "number", + "readable": true, + "writeable": false, + "label": "Current value", + "min": 0, + "max": 99 + }, + "value": 96 + }, + { + "endpoint": 0, + "commandClass": 38, + "commandClassName": "Multilevel Switch", + "property": "Open", + "propertyName": "Open", + "ccVersion": 3, + "metadata": { + "type": "boolean", + "readable": true, + "writeable": true, + "label": "Perform a level change (Open)", + "ccSpecific": { + "switchType": 3 + } + }, + "value": false + }, + { + "endpoint": 0, + "commandClass": 38, + "commandClassName": "Multilevel Switch", + "property": "Close", + "propertyName": "Close", + "ccVersion": 3, + "metadata": { + "type": "boolean", + "readable": true, + "writeable": true, + "label": "Perform a level change (Close)", + "ccSpecific": { + "switchType": 3 + } + }, + "value": false + }, + { + "endpoint": 0, + "commandClass": 43, + "commandClassName": "Scene Activation", + "property": "sceneId", + "propertyName": "sceneId", + "ccVersion": 0, + "metadata": { + "type": "number", + "readable": true, + "writeable": true, + "label": "Scene ID", + "valueChangeOptions": [ + "transitionDuration" + ], + "min": 1, + "max": 255 + } + }, + { + "endpoint": 0, + "commandClass": 43, + "commandClassName": "Scene Activation", + "property": "dimmingDuration", + "propertyName": "dimmingDuration", + "ccVersion": 0, + "metadata": { + "type": "any", + "readable": true, + "writeable": true, + "label": "Dimming duration" + } + }, + { + "endpoint": 0, + "commandClass": 49, + "commandClassName": "Multilevel Sensor", + "property": "Power", + "propertyName": "Power", + "ccVersion": 2, + "metadata": { + "type": "number", + "readable": true, + "writeable": false, + "label": "Power", + "ccSpecific": { + "sensorType": 4, + "scale": 0 + }, + "unit": "W" + }, + "value": 0 + }, + { + "endpoint": 0, + "commandClass": 50, + "commandClassName": "Meter", + "property": "value", + "propertyKey": 65537, + "propertyName": "value", + "propertyKeyName": "Electric_kWh_Consumed", + "ccVersion": 2, + "metadata": { + "type": "number", + "readable": true, + "writeable": false, + "label": "Electric Consumed [kWh]", + "ccSpecific": { + "meterType": 1, + "rateType": 1, + "scale": 0 + }, + "unit": "kWh" + }, + "value": 0.48 + }, + { + "endpoint": 0, + "commandClass": 50, + "commandClassName": "Meter", + "property": "value", + "propertyKey": 66049, + "propertyName": "value", + "propertyKeyName": "Electric_W_Consumed", + "ccVersion": 2, + "metadata": { + "type": "number", + "readable": true, + "writeable": false, + "label": "Electric Consumed [W]", + "ccSpecific": { + "meterType": 1, + "rateType": 1, + "scale": 2 + }, + "unit": "W" + }, + "value": 0 + }, + { + "endpoint": 0, + "commandClass": 50, + "commandClassName": "Meter", + "property": "reset", + "propertyName": "reset", + "ccVersion": 2, + "metadata": { + "type": "boolean", + "readable": false, + "writeable": true, + "label": "Reset accumulated values" + } + }, + { + "endpoint": 0, + "commandClass": 112, + "commandClassName": "Configuration", + "property": 3, + "propertyName": "Reports type", + "ccVersion": 1, + "metadata": { + "type": "number", + "readable": true, + "writeable": true, + "description": "value should be set to 1 if the module operates in Venetian Blind mode.", + "label": "Reports type", + "default": 0, + "min": 0, + "max": 1, + "states": { + "0": "Blind position using Z-Wave Command", + "1": "Blind position via Fibar Command" + }, + "valueSize": 1, + "format": 0, + "allowManualEntry": false, + "isFromConfig": true + }, + "value": 0 + }, + { + "endpoint": 0, + "commandClass": 112, + "commandClassName": "Configuration", + "property": 10, + "propertyName": "Roller Shutter operating modes", + "ccVersion": 1, + "metadata": { + "type": "number", + "readable": true, + "writeable": true, + "label": "Roller Shutter operating modes", + "default": 1, + "min": 0, + "max": 4, + "states": { + "0": "Roller Blind Mode, without positioning", + "1": "Roller Blind Mode, with positioning", + "2": "Venetian Blind Mode, with positioning", + "3": "Gate Mode, without positioning", + "4": "Gate Mode, with positioning" + }, + "valueSize": 1, + "format": 0, + "allowManualEntry": false, + "isFromConfig": true + }, + "value": 2 + }, + { + "endpoint": 0, + "commandClass": 112, + "commandClassName": "Configuration", + "property": 12, + "propertyName": "Turning time/ delay time", + "ccVersion": 1, + "metadata": { + "type": "number", + "readable": true, + "writeable": true, + "description": "depending on mode, turning time or delay time", + "label": "Turning time/ delay time", + "default": 150, + "min": 0, + "max": 65535, + "valueSize": 2, + "format": 1, + "allowManualEntry": true, + "isFromConfig": true + }, + "value": 83 + }, + { + "endpoint": 0, + "commandClass": 112, + "commandClassName": "Configuration", + "property": 13, + "propertyName": "Lamellas positioning mode", + "ccVersion": 1, + "metadata": { + "type": "number", + "readable": true, + "writeable": true, + "description": "Parameter influences the lamellas positioning in venetian blind mode", + "label": "Lamellas positioning mode", + "default": 2, + "min": 0, + "max": 2, + "states": { + "0": "only in case of the main controller operation", + "1": "default - controller+switchlimit", + "2": "like 1 + STOP control frame" + }, + "valueSize": 1, + "format": 0, + "allowManualEntry": false, + "isFromConfig": true + }, + "value": 1 + }, + { + "endpoint": 0, + "commandClass": 112, + "commandClassName": "Configuration", + "property": 17, + "propertyName": "Delay time after S2", + "ccVersion": 1, + "metadata": { + "type": "number", + "readable": true, + "writeable": true, + "description": "delay till auto turned off or auto gate close", + "label": "Delay time after S2", + "default": 10, + "min": 0, + "max": 255, + "valueSize": 1, + "format": 1, + "allowManualEntry": true, + "isFromConfig": true + }, + "value": 10 + }, + { + "endpoint": 0, + "commandClass": 112, + "commandClassName": "Configuration", + "property": 18, + "propertyName": "Motor operation detection", + "ccVersion": 1, + "metadata": { + "type": "number", + "readable": true, + "writeable": true, + "description": "Power threshold to be interpreted as reaching a limit switch.", + "label": "Motor operation detection", + "default": 10, + "min": 0, + "max": 255, + "valueSize": 1, + "format": 1, + "allowManualEntry": true, + "isFromConfig": true + }, + "value": 10 + }, + { + "endpoint": 0, + "commandClass": 112, + "commandClassName": "Configuration", + "property": 22, + "propertyName": "Motor operation time", + "ccVersion": 1, + "metadata": { + "type": "number", + "readable": true, + "writeable": true, + "description": "Time period for the motor to continue operation.", + "label": "Motor operation time", + "default": 10, + "min": 0, + "max": 65535, + "valueSize": 2, + "format": 1, + "allowManualEntry": true, + "isFromConfig": true + }, + "value": 240 + }, + { + "endpoint": 0, + "commandClass": 112, + "commandClassName": "Configuration", + "property": 29, + "propertyName": "Forced Roller Shutter calibration", + "ccVersion": 1, + "metadata": { + "type": "number", + "readable": true, + "writeable": true, + "description": "set to 1 will enter calibration mode", + "label": "Forced Roller Shutter calibration", + "default": 0, + "min": 0, + "max": 1, + "states": { + "0": "Deactivated", + "1": "Start calibration process" + }, + "valueSize": 1, + "format": 0, + "allowManualEntry": false, + "isFromConfig": true + }, + "value": 0 + }, + { + "endpoint": 0, + "commandClass": 112, + "commandClassName": "Configuration", + "property": 30, + "propertyName": "Response to General Alarm", + "ccVersion": 1, + "metadata": { + "type": "number", + "readable": true, + "writeable": true, + "label": "Response to General Alarm", + "default": 2, + "min": 0, + "max": 2, + "states": { + "0": "No response to alarm frames", + "1": "Open Blind", + "2": "Close Blind" + }, + "valueSize": 1, + "format": 0, + "allowManualEntry": false, + "isFromConfig": true + }, + "value": 2 + }, + { + "endpoint": 0, + "commandClass": 112, + "commandClassName": "Configuration", + "property": 31, + "propertyName": "Response to Water Flood Alarm", + "ccVersion": 1, + "metadata": { + "type": "number", + "readable": true, + "writeable": true, + "label": "Response to Water Flood Alarm", + "default": 0, + "min": 0, + "max": 2, + "states": { + "0": "No response to alarm frames", + "1": "Open Blind", + "2": "Close Blind" + }, + "valueSize": 1, + "format": 0, + "allowManualEntry": false, + "isFromConfig": true + }, + "value": 0 + }, + { + "endpoint": 0, + "commandClass": 112, + "commandClassName": "Configuration", + "property": 32, + "propertyName": "Response to Smoke, CO, CO2 Alarm", + "ccVersion": 1, + "metadata": { + "type": "number", + "readable": true, + "writeable": true, + "label": "Response to Smoke, CO, CO2 Alarm", + "default": 1, + "min": 0, + "max": 2, + "states": { + "0": "No response to alarm frames", + "1": "Open Blind", + "2": "Close Blind" + }, + "valueSize": 1, + "format": 0, + "allowManualEntry": false, + "isFromConfig": true + }, + "value": 1 + }, + { + "endpoint": 0, + "commandClass": 112, + "commandClassName": "Configuration", + "property": 33, + "propertyName": "Response to Temperature Alarm", + "ccVersion": 1, + "metadata": { + "type": "number", + "readable": true, + "writeable": true, + "label": "Response to Temperature Alarm", + "default": 1, + "min": 0, + "max": 2, + "states": { + "0": "No response to alarm frames", + "1": "Open Blind", + "2": "Close Blind" + }, + "valueSize": 1, + "format": 0, + "allowManualEntry": false, + "isFromConfig": true + }, + "value": 1 + }, + { + "endpoint": 0, + "commandClass": 112, + "commandClassName": "Configuration", + "property": 35, + "propertyName": "Managing lamellas in response to alarm", + "ccVersion": 1, + "metadata": { + "type": "number", + "readable": true, + "writeable": true, + "description": "0 no change, 1 extreme position", + "label": "Managing lamellas in response to alarm", + "default": 1, + "min": 0, + "max": 255, + "states": { + "0": "Do not change lamellas position", + "1": "Set lamellas to their extreme position" + }, + "valueSize": 1, + "format": 1, + "allowManualEntry": false, + "isFromConfig": true + }, + "value": 1 + }, + { + "endpoint": 0, + "commandClass": 112, + "commandClassName": "Configuration", + "property": 40, + "propertyName": "Power reports", + "ccVersion": 1, + "metadata": { + "type": "number", + "readable": true, + "writeable": true, + "description": "change that needs to occur to trigger the power report", + "label": "Power reports", + "default": 10, + "min": 0, + "max": 100, + "valueSize": 1, + "format": 0, + "allowManualEntry": true, + "isFromConfig": true + }, + "value": 10 + }, + { + "endpoint": 0, + "commandClass": 112, + "commandClassName": "Configuration", + "property": 42, + "propertyName": "Periodic power or energy reports", + "ccVersion": 1, + "metadata": { + "type": "number", + "readable": true, + "writeable": true, + "description": "Time to the next report. Value of 0 means the reports are turned off.", + "label": "Periodic power or energy reports", + "default": 3600, + "min": 0, + "max": 65534, + "valueSize": 2, + "format": 1, + "allowManualEntry": true, + "isFromConfig": true + }, + "value": 3600 + }, + { + "endpoint": 0, + "commandClass": 112, + "commandClassName": "Configuration", + "property": 43, + "propertyName": "Energy reports", + "ccVersion": 1, + "metadata": { + "type": "number", + "readable": true, + "writeable": true, + "description": "Energy threshold to trigger report", + "label": "Energy reports", + "default": 10, + "min": 0, + "max": 254, + "valueSize": 1, + "format": 1, + "allowManualEntry": true, + "isFromConfig": true + }, + "value": 10 + }, + { + "endpoint": 0, + "commandClass": 112, + "commandClassName": "Configuration", + "property": 44, + "propertyName": "Self-measurement", + "ccVersion": 1, + "metadata": { + "type": "number", + "readable": true, + "writeable": true, + "description": "if power and energy reports are to sent to the main controller", + "label": "Self-measurement", + "default": 0, + "min": 0, + "max": 1, + "states": { + "0": "Disabled", + "1": "Activated" + }, + "valueSize": 1, + "format": 0, + "allowManualEntry": false, + "isFromConfig": true + }, + "value": 0 + }, + { + "endpoint": 0, + "commandClass": 112, + "commandClassName": "Configuration", + "property": 50, + "propertyName": "Scenes/ Associations activation", + "ccVersion": 1, + "metadata": { + "type": "number", + "readable": true, + "writeable": true, + "description": "whether scenes or associations are activated by the switch keys", + "label": "Scenes/ Associations activation", + "default": 0, + "min": 0, + "max": 1, + "states": { + "0": "Associations Active", + "1": "Scenes Active" + }, + "valueSize": 1, + "format": 0, + "allowManualEntry": false, + "isFromConfig": true + }, + "value": 0 + }, + { + "endpoint": 0, + "commandClass": 112, + "commandClassName": "Configuration", + "property": 14, + "propertyName": "Switch type", + "ccVersion": 1, + "metadata": { + "type": "number", + "readable": true, + "writeable": true, + "description": "either Toggle switches or a single, momentary switch.", + "label": "Switch type", + "default": 0, + "min": 0, + "max": 2, + "states": { + "0": "Momentary switches", + "1": "Toggle switches", + "2": "Single, momentary switch." + }, + "valueSize": 1, + "format": 0, + "allowManualEntry": false, + "isFromConfig": true + }, + "value": 0 + }, + { + "endpoint": 0, + "commandClass": 114, + "commandClassName": "Manufacturer Specific", + "property": "manufacturerId", + "propertyName": "manufacturerId", + "ccVersion": 1, + "metadata": { + "type": "number", + "readable": true, + "writeable": false, + "label": "Manufacturer ID", + "min": 0, + "max": 65535 + }, + "value": 271 + }, + { + "endpoint": 0, + "commandClass": 114, + "commandClassName": "Manufacturer Specific", + "property": "productType", + "propertyName": "productType", + "ccVersion": 1, + "metadata": { + "type": "number", + "readable": true, + "writeable": false, + "label": "Product type", + "min": 0, + "max": 65535 + }, + "value": 770 + }, + { + "endpoint": 0, + "commandClass": 114, + "commandClassName": "Manufacturer Specific", + "property": "productId", + "propertyName": "productId", + "ccVersion": 1, + "metadata": { + "type": "number", + "readable": true, + "writeable": false, + "label": "Product ID", + "min": 0, + "max": 65535 + }, + "value": 4096 + }, + { + "endpoint": 0, + "commandClass": 117, + "commandClassName": "Protection", + "property": "local", + "propertyName": "local", + "ccVersion": 2, + "metadata": { + "type": "number", + "readable": true, + "writeable": true, + "label": "Local protection state", + "states": { + "0": "Unprotected", + "2": "NoOperationPossible" + } + }, + "value": 0 + }, + { + "endpoint": 0, + "commandClass": 117, + "commandClassName": "Protection", + "property": "rf", + "propertyName": "rf", + "ccVersion": 2, + "metadata": { + "type": "number", + "readable": true, + "writeable": true, + "label": "RF protection state", + "states": { + "0": "Unprotected", + "1": "NoControl" + } + }, + "value": 0 + }, + { + "endpoint": 0, + "commandClass": 117, + "commandClassName": "Protection", + "property": "exclusiveControlNodeId", + "propertyName": "exclusiveControlNodeId", + "ccVersion": 2, + "metadata": { + "type": "any", + "readable": true, + "writeable": true + } + }, + { + "endpoint": 0, + "commandClass": 117, + "commandClassName": "Protection", + "property": "timeout", + "propertyName": "timeout", + "ccVersion": 2, + "metadata": { + "type": "any", + "readable": true, + "writeable": true + } + }, + { + "endpoint": 0, + "commandClass": 134, + "commandClassName": "Version", + "property": "libraryType", + "propertyName": "libraryType", + "ccVersion": 1, + "metadata": { + "type": "number", + "readable": true, + "writeable": false, + "label": "Library type", + "states": { + "0": "Unknown", + "1": "Static Controller", + "2": "Controller", + "3": "Enhanced Slave", + "4": "Slave", + "5": "Installer", + "6": "Routing Slave", + "7": "Bridge Controller", + "8": "Device under Test", + "9": "N/A", + "10": "AV Remote", + "11": "AV Device" + } + }, + "value": 3 + }, + { + "endpoint": 0, + "commandClass": 134, + "commandClassName": "Version", + "property": "protocolVersion", + "propertyName": "protocolVersion", + "ccVersion": 1, + "metadata": { + "type": "string", + "readable": true, + "writeable": false, + "label": "Z-Wave protocol version" + }, + "value": "3.52" + }, + { + "endpoint": 0, + "commandClass": 134, + "commandClassName": "Version", + "property": "firmwareVersions", + "propertyName": "firmwareVersions", + "ccVersion": 1, + "metadata": { + "type": "string[]", + "readable": true, + "writeable": false, + "label": "Z-Wave chip firmware versions" + }, + "value": [ + "25.25" + ] + }, + { + "endpoint": 0, + "commandClass": 145, + "commandClassName": "Manufacturer Proprietary", + "property": "fibaro", + "propertyKey": "venetianBlindsPosition", + "propertyName": "fibaro", + "propertyKeyName": "venetianBlindsPosition", + "ccVersion": 0, + "metadata": { + "type": "number", + "readable": true, + "writeable": true, + "label": "Venetian blinds position", + "min": 0, + "max": 99 + }, + "value": 50 + }, + { + "endpoint": 0, + "commandClass": 145, + "commandClassName": "Manufacturer Proprietary", + "property": "fibaro", + "propertyKey": "venetianBlindsTilt", + "propertyName": "fibaro", + "propertyKeyName": "venetianBlindsTilt", + "ccVersion": 0, + "metadata": { + "type": "number", + "readable": true, + "writeable": true, + "label": "Venetian blinds tilt", + "min": 0, + "max": 99 + }, + "value": 0 + } + ], + "isFrequentListening": false, + "maxDataRate": 40000, + "supportedDataRates": [ + 40000 + ], + "protocolVersion": 3, + "supportsBeaming": true, + "supportsSecurity": false, + "nodeType": 1, + "deviceClass": { + "basic": { + "key": 4, + "label": "Routing Slave" + }, + "generic": { + "key": 17, + "label": "Multilevel Switch" + }, + "specific": { + "key": 6, + "label": "Motor Control Class B" + }, + "mandatorySupportedCCs": [ + 32, + 38, + 37, + 114, + 134 + ], + "mandatoryControlledCCs": [] + }, + "commandClasses": [ + { + "id": 37, + "name": "Binary Switch", + "version": 1, + "isSecure": false + }, + { + "id": 38, + "name": "Multilevel Switch", + "version": 3, + "isSecure": false + }, + { + "id": 49, + "name": "Multilevel Sensor", + "version": 2, + "isSecure": false + }, + { + "id": 50, + "name": "Meter", + "version": 2, + "isSecure": false + }, + { + "id": 112, + "name": "Configuration", + "version": 1, + "isSecure": false + }, + { + "id": 114, + "name": "Manufacturer Specific", + "version": 1, + "isSecure": false + }, + { + "id": 117, + "name": "Protection", + "version": 2, + "isSecure": false + }, + { + "id": 133, + "name": "Association", + "version": 2, + "isSecure": false + }, + { + "id": 134, + "name": "Version", + "version": 1, + "isSecure": false + }, + { + "id": 142, + "name": "Multi Channel Association", + "version": 2, + "isSecure": false + }, + { + "id": 145, + "name": "Manufacturer Proprietary", + "version": 1, + "isSecure": false + } + ], + "interviewStage": "Complete", + "deviceDatabaseUrl": "https://devices.zwave-js.io/?jumpTo=0x010f:0x0302:0x1000:25.25", + "statistics": { + "commandsTX": 24, + "commandsRX": 350, + "commandsDroppedRX": 1, + "commandsDroppedTX": 0, + "timeoutResponse": 0 + } +} \ No newline at end of file