diff --git a/CODEOWNERS b/CODEOWNERS index c8a391fd7dc7cf..45d4ad6053ee76 100644 --- a/CODEOWNERS +++ b/CODEOWNERS @@ -127,8 +127,8 @@ build.json @home-assistant/supervisor /tests/components/aprilaire/ @chamberlain2007 /homeassistant/components/aprs/ @PhilRW /tests/components/aprs/ @PhilRW -/homeassistant/components/aranet/ @aschmitz @thecode -/tests/components/aranet/ @aschmitz @thecode +/homeassistant/components/aranet/ @aschmitz @thecode @anrijs +/tests/components/aranet/ @aschmitz @thecode @anrijs /homeassistant/components/arcam_fmj/ @elupus /tests/components/arcam_fmj/ @elupus /homeassistant/components/arris_tg2492lg/ @vanbalken diff --git a/homeassistant/components/aranet/const.py b/homeassistant/components/aranet/const.py index 056c627daa87b8..e038a073fd56c4 100644 --- a/homeassistant/components/aranet/const.py +++ b/homeassistant/components/aranet/const.py @@ -1,3 +1,4 @@ """Constants for the Aranet integration.""" DOMAIN = "aranet" +ARANET_MANUFACTURER_NAME = "SAF Tehnika" diff --git a/homeassistant/components/aranet/icons.json b/homeassistant/components/aranet/icons.json new file mode 100644 index 00000000000000..6d6e9a83b039c1 --- /dev/null +++ b/homeassistant/components/aranet/icons.json @@ -0,0 +1,12 @@ +{ + "entity": { + "sensor": { + "radiation_total": { + "default": "mdi:radioactive" + }, + "radiation_rate": { + "default": "mdi:radioactive" + } + } + } +} diff --git a/homeassistant/components/aranet/manifest.json b/homeassistant/components/aranet/manifest.json index 152c56e80f3c30..a1cd80cc3c79a6 100644 --- a/homeassistant/components/aranet/manifest.json +++ b/homeassistant/components/aranet/manifest.json @@ -13,7 +13,7 @@ "connectable": false } ], - "codeowners": ["@aschmitz", "@thecode"], + "codeowners": ["@aschmitz", "@thecode", "@anrijs"], "config_flow": true, "dependencies": ["bluetooth_adapters"], "documentation": "https://www.home-assistant.io/integrations/aranet", diff --git a/homeassistant/components/aranet/sensor.py b/homeassistant/components/aranet/sensor.py index b55fe2bc5ce6aa..4509aa660278ae 100644 --- a/homeassistant/components/aranet/sensor.py +++ b/homeassistant/components/aranet/sensor.py @@ -23,6 +23,7 @@ SensorStateClass, ) from homeassistant.const import ( + ATTR_MANUFACTURER, ATTR_NAME, ATTR_SW_VERSION, CONCENTRATION_PARTS_PER_MILLION, @@ -37,7 +38,7 @@ from homeassistant.helpers.entity import EntityDescription from homeassistant.helpers.entity_platform import AddEntitiesCallback -from .const import DOMAIN +from .const import ARANET_MANUFACTURER_NAME, DOMAIN @dataclass(frozen=True) @@ -48,6 +49,7 @@ class AranetSensorEntityDescription(SensorEntityDescription): # Restrict the type to satisfy the type checker and catch attempts # to use UNDEFINED in the entity descriptions. name: str | None = None + scale: float | int = 1 SENSOR_DESCRIPTIONS = { @@ -79,6 +81,24 @@ class AranetSensorEntityDescription(SensorEntityDescription): native_unit_of_measurement=CONCENTRATION_PARTS_PER_MILLION, state_class=SensorStateClass.MEASUREMENT, ), + "radiation_rate": AranetSensorEntityDescription( + key="radiation_rate", + translation_key="radiation_rate", + name="Radiation Dose Rate", + native_unit_of_measurement="μSv/h", + state_class=SensorStateClass.MEASUREMENT, + suggested_display_precision=2, + scale=0.001, + ), + "radiation_total": AranetSensorEntityDescription( + key="radiation_total", + translation_key="radiation_total", + name="Radiation Total Dose", + native_unit_of_measurement="mSv", + state_class=SensorStateClass.MEASUREMENT, + suggested_display_precision=4, + scale=0.000001, + ), "battery": AranetSensorEntityDescription( key="battery", name="Battery", @@ -115,6 +135,7 @@ def _sensor_device_info_to_hass( hass_device_info = DeviceInfo({}) if adv.readings and adv.readings.name: hass_device_info[ATTR_NAME] = adv.readings.name + hass_device_info[ATTR_MANUFACTURER] = ARANET_MANUFACTURER_NAME if adv.manufacturer_data: hass_device_info[ATTR_SW_VERSION] = str(adv.manufacturer_data.version) return hass_device_info @@ -132,6 +153,7 @@ def sensor_update_to_bluetooth_data_update( val = getattr(adv.readings, key) if val == -1: continue + val *= desc.scale data[tag] = val names[tag] = desc.name descs[tag] = desc diff --git a/homeassistant/components/aranet/strings.json b/homeassistant/components/aranet/strings.json index ac8d1907770b1c..1cc695637d4fd7 100644 --- a/homeassistant/components/aranet/strings.json +++ b/homeassistant/components/aranet/strings.json @@ -17,7 +17,7 @@ }, "abort": { "already_configured": "[%key:common::config_flow::abort::already_configured_device%]", - "integrations_diabled": "This device doesn't have integrations enabled. Please enable smart home integrations using the app and try again.", + "integrations_disabled": "This device doesn't have integrations enabled. Please enable smart home integrations using the app and try again.", "no_devices_found": "No unconfigured Aranet devices found.", "outdated_version": "This device is using outdated firmware. Please update it to at least v1.2.0 and try again." } diff --git a/tests/components/aranet/__init__.py b/tests/components/aranet/__init__.py index 4dc9434bd65804..a6b32d56e4c11f 100644 --- a/tests/components/aranet/__init__.py +++ b/tests/components/aranet/__init__.py @@ -73,3 +73,11 @@ def fake_service_info(name, service_uuid, manufacturer_data): 1794: b"\x01!\x04\x04\x01\x00\x00\x00\x00\x00\xf0\x01\x00\x00\x0c\x02\x00O\x00<\x00\x01\x00\x80" }, ) + +VALID_ARANET_RADIATION_DATA_SERVICE_INFO = fake_service_info( + "Aranet\u2622 12345", + "0000fce0-0000-1000-8000-00805f9b34fb", + { + 1794: b"\x02!&\x04\x01\x00`-\x00\x00\x08\x98\x05\x00n\x00\x00d\x00,\x01\xfd\x00\xc7" + }, +) diff --git a/tests/components/aranet/test_sensor.py b/tests/components/aranet/test_sensor.py index 20aea65989d733..0d57f00fdf49ad 100644 --- a/tests/components/aranet/test_sensor.py +++ b/tests/components/aranet/test_sensor.py @@ -8,6 +8,7 @@ from . import ( DISABLED_INTEGRATIONS_SERVICE_INFO, VALID_ARANET2_DATA_SERVICE_INFO, + VALID_ARANET_RADIATION_DATA_SERVICE_INFO, VALID_DATA_SERVICE_INFO, ) @@ -15,6 +16,65 @@ from tests.components.bluetooth import inject_bluetooth_service_info +async def test_sensors_aranet_radiation( + hass: HomeAssistant, entity_registry_enabled_by_default: None +) -> None: + """Test setting up creates the sensors for Aranet Radiation device.""" + entry = MockConfigEntry( + domain=DOMAIN, + unique_id="aa:bb:cc:dd:ee:ff", + ) + entry.add_to_hass(hass) + + assert await hass.config_entries.async_setup(entry.entry_id) + await hass.async_block_till_done() + + assert len(hass.states.async_all("sensor")) == 0 + inject_bluetooth_service_info(hass, VALID_ARANET_RADIATION_DATA_SERVICE_INFO) + await hass.async_block_till_done() + assert len(hass.states.async_all("sensor")) == 4 + + batt_sensor = hass.states.get("sensor.aranet_12345_battery") + batt_sensor_attrs = batt_sensor.attributes + assert batt_sensor.state == "100" + assert batt_sensor_attrs[ATTR_FRIENDLY_NAME] == "Aranet\u2622 12345 Battery" + assert batt_sensor_attrs[ATTR_UNIT_OF_MEASUREMENT] == "%" + assert batt_sensor_attrs[ATTR_STATE_CLASS] == "measurement" + + humid_sensor = hass.states.get("sensor.aranet_12345_radiation_total_dose") + humid_sensor_attrs = humid_sensor.attributes + assert humid_sensor.state == "0.011616" + assert ( + humid_sensor_attrs[ATTR_FRIENDLY_NAME] + == "Aranet\u2622 12345 Radiation Total Dose" + ) + assert humid_sensor_attrs[ATTR_UNIT_OF_MEASUREMENT] == "mSv" + assert humid_sensor_attrs[ATTR_STATE_CLASS] == "measurement" + + temp_sensor = hass.states.get("sensor.aranet_12345_radiation_dose_rate") + temp_sensor_attrs = temp_sensor.attributes + assert temp_sensor.state == "0.11" + assert ( + temp_sensor_attrs[ATTR_FRIENDLY_NAME] + == "Aranet\u2622 12345 Radiation Dose Rate" + ) + assert temp_sensor_attrs[ATTR_UNIT_OF_MEASUREMENT] == "μSv/h" + assert temp_sensor_attrs[ATTR_STATE_CLASS] == "measurement" + + interval_sensor = hass.states.get("sensor.aranet_12345_update_interval") + interval_sensor_attrs = interval_sensor.attributes + assert interval_sensor.state == "300" + assert ( + interval_sensor_attrs[ATTR_FRIENDLY_NAME] + == "Aranet\u2622 12345 Update Interval" + ) + assert interval_sensor_attrs[ATTR_UNIT_OF_MEASUREMENT] == "s" + assert interval_sensor_attrs[ATTR_STATE_CLASS] == "measurement" + + assert await hass.config_entries.async_unload(entry.entry_id) + await hass.async_block_till_done() + + async def test_sensors_aranet2( hass: HomeAssistant, entity_registry_enabled_by_default: None ) -> None: