diff --git a/homeassistant/components/zwave_js/discovery.py b/homeassistant/components/zwave_js/discovery.py index 39b97e5d3f4..0b66567c036 100644 --- a/homeassistant/components/zwave_js/discovery.py +++ b/homeassistant/components/zwave_js/discovery.py @@ -1106,7 +1106,7 @@ DISCOVERY_SCHEMAS = [ platform=Platform.LIGHT, primary_value=SWITCH_MULTILEVEL_CURRENT_VALUE_SCHEMA, ), - # light for Basic CC + # light for Basic CC with target ZWaveDiscoverySchema( platform=Platform.LIGHT, primary_value=ZWaveValueDiscoverySchema( @@ -1116,9 +1116,24 @@ DISCOVERY_SCHEMAS = [ ), required_values=[ ZWaveValueDiscoverySchema( - command_class={ - CommandClass.BASIC, - }, + command_class={CommandClass.BASIC}, + type={ValueType.NUMBER}, + property={TARGET_VALUE_PROPERTY}, + ) + ], + ), + # sensor for Basic CC without target + ZWaveDiscoverySchema( + platform=Platform.SENSOR, + hint="numeric_sensor", + primary_value=ZWaveValueDiscoverySchema( + command_class={CommandClass.BASIC}, + type={ValueType.NUMBER}, + property={CURRENT_VALUE_PROPERTY}, + ), + absent_values=[ + ZWaveValueDiscoverySchema( + command_class={CommandClass.BASIC}, type={ValueType.NUMBER}, property={TARGET_VALUE_PROPERTY}, ) diff --git a/homeassistant/components/zwave_js/sensor.py b/homeassistant/components/zwave_js/sensor.py index c07420615a1..e43c620ff54 100644 --- a/homeassistant/components/zwave_js/sensor.py +++ b/homeassistant/components/zwave_js/sensor.py @@ -689,6 +689,23 @@ class ZwaveSensor(ZWaveBaseEntity, SensorEntity): class ZWaveNumericSensor(ZwaveSensor): """Representation of a Z-Wave Numeric sensor.""" + def __init__( + self, + config_entry: ConfigEntry, + driver: Driver, + info: ZwaveDiscoveryInfo, + entity_description: SensorEntityDescription, + unit_of_measurement: str | None = None, + ) -> None: + """Initialize a ZWaveBasicSensor entity.""" + super().__init__( + config_entry, driver, info, entity_description, unit_of_measurement + ) + if self.info.primary_value.command_class == CommandClass.BASIC: + self._attr_name = self.generate_name( + include_value_name=True, alternate_value_name="Basic" + ) + @callback def on_value_update(self) -> None: """Handle scale changes for this value on value updated event.""" diff --git a/tests/components/zwave_js/conftest.py b/tests/components/zwave_js/conftest.py index 63a22d86b50..a2a4c217b8b 100644 --- a/tests/components/zwave_js/conftest.py +++ b/tests/components/zwave_js/conftest.py @@ -687,6 +687,12 @@ def light_device_class_is_null_state_fixture(): return json.loads(load_fixture("zwave_js/light_device_class_is_null_state.json")) +@pytest.fixture(name="basic_cc_sensor_state", scope="package") +def basic_cc_sensor_state_fixture(): + """Load node with Basic CC sensor fixture data.""" + return json.loads(load_fixture("zwave_js/basic_cc_sensor_state.json")) + + # model fixtures @@ -1355,3 +1361,11 @@ def light_device_class_is_null_fixture(client, light_device_class_is_null_state) node = Node(client, copy.deepcopy(light_device_class_is_null_state)) client.driver.controller.nodes[node.node_id] = node return node + + +@pytest.fixture(name="basic_cc_sensor") +def basic_cc_sensor_fixture(client, basic_cc_sensor_state): + """Mock a node with a Basic CC.""" + node = Node(client, copy.deepcopy(basic_cc_sensor_state)) + client.driver.controller.nodes[node.node_id] = node + return node diff --git a/tests/components/zwave_js/fixtures/basic_cc_sensor_state.json b/tests/components/zwave_js/fixtures/basic_cc_sensor_state.json new file mode 100644 index 00000000000..1d749af2021 --- /dev/null +++ b/tests/components/zwave_js/fixtures/basic_cc_sensor_state.json @@ -0,0 +1,87 @@ +{ + "nodeId": 52, + "index": 0, + "installerIcon": 3079, + "userIcon": 3079, + "status": 1, + "ready": true, + "deviceClass": { + "basic": { "key": 2, "label": "Static Controller" }, + "generic": { "key": 21, "label": "Multilevel Sensor" }, + "specific": { "key": 1, "label": "Routing Multilevel Sensor" }, + "mandatorySupportedCCs": [], + "mandatoryControlledCCs": [] + }, + "isListening": true, + "isFrequentListening": false, + "isRouting": true, + "maxBaudRate": 40000, + "isSecure": false, + "version": 4, + "isBeaming": true, + "manufacturerId": 134, + "productId": 100, + "productType": 258, + "firmwareVersion": "1.12", + "zwavePlusVersion": 1, + "nodeType": 0, + "roleType": 5, + "deviceConfig": { + "manufacturerId": 134, + "manufacturer": "Test", + "label": "test", + "description": "foo", + "devices": [ + { + "productType": "0xffff", + "productId": "0xffff" + } + ], + "firmwareVersion": { + "min": "1.10", + "max": "255.255" + }, + "paramInformation": { + "_map": {} + } + }, + "label": "test", + "neighbors": [1, 32], + "interviewAttempts": 1, + "endpoints": [ + { + "nodeId": 52, + "index": 0, + "installerIcon": 3079, + "userIcon": 3079, + "commandClasses": [ + { + "id": 32, + "name": "Basic", + "version": 8, + "isSecure": false + } + ] + } + ], + "values": [ + { + "commandClassName": "Basic", + "commandClass": 32, + "endpoint": 0, + "property": "currentValue", + "propertyName": "currentValue", + "metadata": { + "type": "number", + "readable": true, + "writeable": false, + "min": 0, + "max": 99, + "label": "Current value" + }, + "value": 255 + } + ], + "highestSecurityClass": 7, + "isControllerNode": false +} diff --git a/tests/components/zwave_js/test_sensor.py b/tests/components/zwave_js/test_sensor.py index 358c1036369..02b3df17e22 100644 --- a/tests/components/zwave_js/test_sensor.py +++ b/tests/components/zwave_js/test_sensor.py @@ -212,6 +212,15 @@ async def test_energy_sensors( assert state.attributes[ATTR_DEVICE_CLASS] == SensorDeviceClass.CURRENT +async def test_basic_cc_sensor( + hass: HomeAssistant, client, basic_cc_sensor, integration +) -> None: + """Test a Basic CC sensor gets discovered correctly.""" + state = hass.states.get("sensor.foo_basic") + assert state is not None + assert state.state == "255.0" + + async def test_disabled_notification_sensor( hass: HomeAssistant, entity_registry: er.EntityRegistry, multisensor_6, integration ) -> None: