mirror of
https://github.com/home-assistant/core.git
synced 2025-04-29 19:57:52 +00:00
Add support for Aranet2 devices (#101495)
This commit is contained in:
parent
fa90b0f41e
commit
b97ec2cfce
@ -19,5 +19,5 @@
|
|||||||
"documentation": "https://www.home-assistant.io/integrations/aranet",
|
"documentation": "https://www.home-assistant.io/integrations/aranet",
|
||||||
"integration_type": "device",
|
"integration_type": "device",
|
||||||
"iot_class": "local_push",
|
"iot_class": "local_push",
|
||||||
"requirements": ["aranet4==2.1.3"]
|
"requirements": ["aranet4==2.2.2"]
|
||||||
}
|
}
|
||||||
|
@ -2,6 +2,7 @@
|
|||||||
from __future__ import annotations
|
from __future__ import annotations
|
||||||
|
|
||||||
from dataclasses import dataclass
|
from dataclasses import dataclass
|
||||||
|
from typing import Any
|
||||||
|
|
||||||
from aranet4.client import Aranet4Advertisement
|
from aranet4.client import Aranet4Advertisement
|
||||||
from bleak.backends.device import BLEDevice
|
from bleak.backends.device import BLEDevice
|
||||||
@ -32,6 +33,7 @@ from homeassistant.const import (
|
|||||||
)
|
)
|
||||||
from homeassistant.core import HomeAssistant
|
from homeassistant.core import HomeAssistant
|
||||||
from homeassistant.helpers.device_registry import DeviceInfo
|
from homeassistant.helpers.device_registry import DeviceInfo
|
||||||
|
from homeassistant.helpers.entity import EntityDescription
|
||||||
from homeassistant.helpers.entity_platform import AddEntitiesCallback
|
from homeassistant.helpers.entity_platform import AddEntitiesCallback
|
||||||
|
|
||||||
from .const import DOMAIN
|
from .const import DOMAIN
|
||||||
@ -121,22 +123,22 @@ def sensor_update_to_bluetooth_data_update(
|
|||||||
adv: Aranet4Advertisement,
|
adv: Aranet4Advertisement,
|
||||||
) -> PassiveBluetoothDataUpdate:
|
) -> PassiveBluetoothDataUpdate:
|
||||||
"""Convert a sensor update to a Bluetooth data update."""
|
"""Convert a sensor update to a Bluetooth data update."""
|
||||||
|
data: dict[PassiveBluetoothEntityKey, Any] = {}
|
||||||
|
names: dict[PassiveBluetoothEntityKey, str | None] = {}
|
||||||
|
descs: dict[PassiveBluetoothEntityKey, EntityDescription] = {}
|
||||||
|
for key, desc in SENSOR_DESCRIPTIONS.items():
|
||||||
|
tag = _device_key_to_bluetooth_entity_key(adv.device, key)
|
||||||
|
val = getattr(adv.readings, key)
|
||||||
|
if val == -1:
|
||||||
|
continue
|
||||||
|
data[tag] = val
|
||||||
|
names[tag] = desc.name
|
||||||
|
descs[tag] = desc
|
||||||
return PassiveBluetoothDataUpdate(
|
return PassiveBluetoothDataUpdate(
|
||||||
devices={adv.device.address: _sensor_device_info_to_hass(adv)},
|
devices={adv.device.address: _sensor_device_info_to_hass(adv)},
|
||||||
entity_descriptions={
|
entity_descriptions=descs,
|
||||||
_device_key_to_bluetooth_entity_key(adv.device, key): desc
|
entity_data=data,
|
||||||
for key, desc in SENSOR_DESCRIPTIONS.items()
|
entity_names=names,
|
||||||
},
|
|
||||||
entity_data={
|
|
||||||
_device_key_to_bluetooth_entity_key(adv.device, key): getattr(
|
|
||||||
adv.readings, key, None
|
|
||||||
)
|
|
||||||
for key in SENSOR_DESCRIPTIONS
|
|
||||||
},
|
|
||||||
entity_names={
|
|
||||||
_device_key_to_bluetooth_entity_key(adv.device, key): desc.name
|
|
||||||
for key, desc in SENSOR_DESCRIPTIONS.items()
|
|
||||||
},
|
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|
||||||
|
@ -435,7 +435,7 @@ aprslib==0.7.0
|
|||||||
aqualogic==2.6
|
aqualogic==2.6
|
||||||
|
|
||||||
# homeassistant.components.aranet
|
# homeassistant.components.aranet
|
||||||
aranet4==2.1.3
|
aranet4==2.2.2
|
||||||
|
|
||||||
# homeassistant.components.arcam_fmj
|
# homeassistant.components.arcam_fmj
|
||||||
arcam-fmj==1.4.0
|
arcam-fmj==1.4.0
|
||||||
|
@ -398,7 +398,7 @@ apprise==1.5.0
|
|||||||
aprslib==0.7.0
|
aprslib==0.7.0
|
||||||
|
|
||||||
# homeassistant.components.aranet
|
# homeassistant.components.aranet
|
||||||
aranet4==2.1.3
|
aranet4==2.2.2
|
||||||
|
|
||||||
# homeassistant.components.arcam_fmj
|
# homeassistant.components.arcam_fmj
|
||||||
arcam-fmj==1.4.0
|
arcam-fmj==1.4.0
|
||||||
|
@ -57,3 +57,11 @@ VALID_DATA_SERVICE_INFO = fake_service_info(
|
|||||||
1794: b'\x21\x00\x02\x01\x00\x00\x00\x01\x8a\x02\xa5\x01\xb1&"Y\x01,\x01\xe8\x00\x88'
|
1794: b'\x21\x00\x02\x01\x00\x00\x00\x01\x8a\x02\xa5\x01\xb1&"Y\x01,\x01\xe8\x00\x88'
|
||||||
},
|
},
|
||||||
)
|
)
|
||||||
|
|
||||||
|
VALID_ARANET2_DATA_SERVICE_INFO = fake_service_info(
|
||||||
|
"Aranet2 12345",
|
||||||
|
"0000fce0-0000-1000-8000-00805f9b34fb",
|
||||||
|
{
|
||||||
|
1794: b"\x01!\x04\x04\x01\x00\x00\x00\x00\x00\xf0\x01\x00\x00\x0c\x02\x00O\x00<\x00\x01\x00\x80"
|
||||||
|
},
|
||||||
|
)
|
||||||
|
@ -4,16 +4,70 @@ from homeassistant.components.sensor import ATTR_STATE_CLASS
|
|||||||
from homeassistant.const import ATTR_FRIENDLY_NAME, ATTR_UNIT_OF_MEASUREMENT
|
from homeassistant.const import ATTR_FRIENDLY_NAME, ATTR_UNIT_OF_MEASUREMENT
|
||||||
from homeassistant.core import HomeAssistant
|
from homeassistant.core import HomeAssistant
|
||||||
|
|
||||||
from . import DISABLED_INTEGRATIONS_SERVICE_INFO, VALID_DATA_SERVICE_INFO
|
from . import (
|
||||||
|
DISABLED_INTEGRATIONS_SERVICE_INFO,
|
||||||
|
VALID_ARANET2_DATA_SERVICE_INFO,
|
||||||
|
VALID_DATA_SERVICE_INFO,
|
||||||
|
)
|
||||||
|
|
||||||
from tests.common import MockConfigEntry
|
from tests.common import MockConfigEntry
|
||||||
from tests.components.bluetooth import inject_bluetooth_service_info
|
from tests.components.bluetooth import inject_bluetooth_service_info
|
||||||
|
|
||||||
|
|
||||||
async def test_sensors(
|
async def test_sensors_aranet2(
|
||||||
hass: HomeAssistant, entity_registry_enabled_by_default: None
|
hass: HomeAssistant, entity_registry_enabled_by_default: None
|
||||||
) -> None:
|
) -> None:
|
||||||
"""Test setting up creates the sensors."""
|
"""Test setting up creates the sensors for Aranet2 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_ARANET2_DATA_SERVICE_INFO)
|
||||||
|
await hass.async_block_till_done()
|
||||||
|
assert len(hass.states.async_all("sensor")) == 4
|
||||||
|
|
||||||
|
batt_sensor = hass.states.get("sensor.aranet2_12345_battery")
|
||||||
|
batt_sensor_attrs = batt_sensor.attributes
|
||||||
|
assert batt_sensor.state == "79"
|
||||||
|
assert batt_sensor_attrs[ATTR_FRIENDLY_NAME] == "Aranet2 12345 Battery"
|
||||||
|
assert batt_sensor_attrs[ATTR_UNIT_OF_MEASUREMENT] == "%"
|
||||||
|
assert batt_sensor_attrs[ATTR_STATE_CLASS] == "measurement"
|
||||||
|
|
||||||
|
humid_sensor = hass.states.get("sensor.aranet2_12345_humidity")
|
||||||
|
humid_sensor_attrs = humid_sensor.attributes
|
||||||
|
assert humid_sensor.state == "52.4"
|
||||||
|
assert humid_sensor_attrs[ATTR_FRIENDLY_NAME] == "Aranet2 12345 Humidity"
|
||||||
|
assert humid_sensor_attrs[ATTR_UNIT_OF_MEASUREMENT] == "%"
|
||||||
|
assert humid_sensor_attrs[ATTR_STATE_CLASS] == "measurement"
|
||||||
|
|
||||||
|
temp_sensor = hass.states.get("sensor.aranet2_12345_temperature")
|
||||||
|
temp_sensor_attrs = temp_sensor.attributes
|
||||||
|
assert temp_sensor.state == "24.8"
|
||||||
|
assert temp_sensor_attrs[ATTR_FRIENDLY_NAME] == "Aranet2 12345 Temperature"
|
||||||
|
assert temp_sensor_attrs[ATTR_UNIT_OF_MEASUREMENT] == "°C"
|
||||||
|
assert temp_sensor_attrs[ATTR_STATE_CLASS] == "measurement"
|
||||||
|
|
||||||
|
interval_sensor = hass.states.get("sensor.aranet2_12345_update_interval")
|
||||||
|
interval_sensor_attrs = interval_sensor.attributes
|
||||||
|
assert interval_sensor.state == "60"
|
||||||
|
assert interval_sensor_attrs[ATTR_FRIENDLY_NAME] == "Aranet2 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_aranet4(
|
||||||
|
hass: HomeAssistant, entity_registry_enabled_by_default: None
|
||||||
|
) -> None:
|
||||||
|
"""Test setting up creates the sensors for Aranet4 device."""
|
||||||
entry = MockConfigEntry(
|
entry = MockConfigEntry(
|
||||||
domain=DOMAIN,
|
domain=DOMAIN,
|
||||||
unique_id="aa:bb:cc:dd:ee:ff",
|
unique_id="aa:bb:cc:dd:ee:ff",
|
||||||
@ -90,22 +144,7 @@ async def test_smart_home_integration_disabled(
|
|||||||
assert len(hass.states.async_all("sensor")) == 0
|
assert len(hass.states.async_all("sensor")) == 0
|
||||||
inject_bluetooth_service_info(hass, DISABLED_INTEGRATIONS_SERVICE_INFO)
|
inject_bluetooth_service_info(hass, DISABLED_INTEGRATIONS_SERVICE_INFO)
|
||||||
await hass.async_block_till_done()
|
await hass.async_block_till_done()
|
||||||
assert len(hass.states.async_all("sensor")) == 6
|
assert len(hass.states.async_all("sensor")) == 0
|
||||||
|
|
||||||
batt_sensor = hass.states.get("sensor.aranet4_12345_battery")
|
|
||||||
assert batt_sensor.state == "unavailable"
|
|
||||||
|
|
||||||
co2_sensor = hass.states.get("sensor.aranet4_12345_carbon_dioxide")
|
|
||||||
assert co2_sensor.state == "unavailable"
|
|
||||||
|
|
||||||
humid_sensor = hass.states.get("sensor.aranet4_12345_humidity")
|
|
||||||
assert humid_sensor.state == "unavailable"
|
|
||||||
|
|
||||||
temp_sensor = hass.states.get("sensor.aranet4_12345_temperature")
|
|
||||||
assert temp_sensor.state == "unavailable"
|
|
||||||
|
|
||||||
press_sensor = hass.states.get("sensor.aranet4_12345_pressure")
|
|
||||||
assert press_sensor.state == "unavailable"
|
|
||||||
|
|
||||||
assert await hass.config_entries.async_unload(entry.entry_id)
|
assert await hass.config_entries.async_unload(entry.entry_id)
|
||||||
await hass.async_block_till_done()
|
await hass.async_block_till_done()
|
||||||
|
Loading…
x
Reference in New Issue
Block a user