mirror of
https://github.com/home-assistant/core.git
synced 2025-07-23 05:07:41 +00:00
Add device_info to onewire sensors (#42309)
* Add device info * Cleanup log
This commit is contained in:
parent
9a970cfe3d
commit
c157a582b8
@ -186,10 +186,12 @@ def get_entities(config):
|
||||
for device in devices:
|
||||
_LOGGER.debug("Found device: %s", device)
|
||||
family = owproxy.read(f"{device}family").decode()
|
||||
device_type = owproxy.read(f"{device}type").decode()
|
||||
sensor_id = os.path.split(os.path.split(device)[0])[1]
|
||||
dev_type = "std"
|
||||
if "EF" in family:
|
||||
dev_type = "HobbyBoard"
|
||||
family = owproxy.read(f"{device}type").decode()
|
||||
family = device_type
|
||||
|
||||
if family not in hb_info_from_type(dev_type):
|
||||
_LOGGER.warning(
|
||||
@ -198,6 +200,12 @@ def get_entities(config):
|
||||
device,
|
||||
)
|
||||
continue
|
||||
device_info = {
|
||||
"identifiers": {(DOMAIN, sensor_id)},
|
||||
"manufacturer": "Maxim Integrated",
|
||||
"model": device_type,
|
||||
"name": sensor_id,
|
||||
}
|
||||
for sensor_key, sensor_value in hb_info_from_type(dev_type)[family].items():
|
||||
if "moisture" in sensor_key:
|
||||
s_id = sensor_key.split("_")[1]
|
||||
@ -206,13 +214,13 @@ def get_entities(config):
|
||||
)
|
||||
if is_leaf:
|
||||
sensor_key = f"wetness_{s_id}"
|
||||
sensor_id = os.path.split(os.path.split(device)[0])[1]
|
||||
device_file = os.path.join(os.path.split(device)[0], sensor_value)
|
||||
entities.append(
|
||||
OneWireProxy(
|
||||
device_names.get(sensor_id, sensor_id),
|
||||
device_file,
|
||||
sensor_key,
|
||||
device_info,
|
||||
owproxy,
|
||||
)
|
||||
)
|
||||
@ -232,12 +240,19 @@ def get_entities(config):
|
||||
)
|
||||
continue
|
||||
|
||||
device_info = {
|
||||
"identifiers": {(DOMAIN, sensor_id)},
|
||||
"manufacturer": "Maxim Integrated",
|
||||
"model": family,
|
||||
"name": sensor_id,
|
||||
}
|
||||
device_file = f"/sys/bus/w1/devices/{sensor_id}/w1_slave"
|
||||
entities.append(
|
||||
OneWireDirect(
|
||||
device_names.get(sensor_id, sensor_id),
|
||||
device_file,
|
||||
"temperature",
|
||||
device_info,
|
||||
p1sensor,
|
||||
)
|
||||
)
|
||||
@ -286,12 +301,13 @@ def get_entities(config):
|
||||
class OneWire(Entity):
|
||||
"""Implementation of a 1-Wire sensor."""
|
||||
|
||||
def __init__(self, name, device_file, sensor_type):
|
||||
def __init__(self, name, device_file, sensor_type, device_info=None):
|
||||
"""Initialize the sensor."""
|
||||
self._name = f"{name} {sensor_type.capitalize()}"
|
||||
self._device_file = device_file
|
||||
self._device_class = SENSOR_TYPES[sensor_type][2]
|
||||
self._unit_of_measurement = SENSOR_TYPES[sensor_type][1]
|
||||
self._device_info = device_info
|
||||
self._state = None
|
||||
self._value_raw = None
|
||||
|
||||
@ -327,13 +343,18 @@ class OneWire(Entity):
|
||||
"""Return a unique ID."""
|
||||
return self._device_file
|
||||
|
||||
@property
|
||||
def device_info(self) -> Optional[Dict[str, Any]]:
|
||||
"""Return device specific attributes."""
|
||||
return self._device_info
|
||||
|
||||
|
||||
class OneWireProxy(OneWire):
|
||||
"""Implementation of a 1-Wire sensor through owserver."""
|
||||
|
||||
def __init__(self, name, device_file, sensor_type, owproxy):
|
||||
def __init__(self, name, device_file, sensor_type, device_info, owproxy):
|
||||
"""Initialize the sensor."""
|
||||
super().__init__(name, device_file, sensor_type)
|
||||
super().__init__(name, device_file, sensor_type, device_info)
|
||||
self._owproxy = owproxy
|
||||
|
||||
def _read_value_ownet(self):
|
||||
@ -358,9 +379,9 @@ class OneWireProxy(OneWire):
|
||||
class OneWireDirect(OneWire):
|
||||
"""Implementation of a 1-Wire sensor directly connected to RPI GPIO."""
|
||||
|
||||
def __init__(self, name, device_file, sensor_type, owsensor):
|
||||
def __init__(self, name, device_file, sensor_type, device_info, owsensor):
|
||||
"""Initialize the sensor."""
|
||||
super().__init__(name, device_file, sensor_type)
|
||||
super().__init__(name, device_file, sensor_type, device_info)
|
||||
self._owsensor = owsensor
|
||||
|
||||
def update(self):
|
||||
|
@ -25,7 +25,7 @@ from homeassistant.const import (
|
||||
from homeassistant.setup import async_setup_component
|
||||
|
||||
from tests.async_mock import patch
|
||||
from tests.common import mock_registry
|
||||
from tests.common import mock_device_registry, mock_registry
|
||||
|
||||
MOCK_CONFIG = {
|
||||
SENSOR_DOMAIN: {
|
||||
@ -39,8 +39,22 @@ MOCK_CONFIG = {
|
||||
}
|
||||
|
||||
MOCK_DEVICE_SENSORS = {
|
||||
"00.111111111111": {"sensors": []},
|
||||
"00.111111111111": {
|
||||
"inject_reads": [
|
||||
b"", # read device type
|
||||
],
|
||||
"sensors": [],
|
||||
},
|
||||
"10.111111111111": {
|
||||
"inject_reads": [
|
||||
b"DS18S20", # read device type
|
||||
],
|
||||
"device_info": {
|
||||
"identifiers": {(DOMAIN, "10.111111111111")},
|
||||
"manufacturer": "Maxim Integrated",
|
||||
"model": "DS18S20",
|
||||
"name": "10.111111111111",
|
||||
},
|
||||
"sensors": [
|
||||
{
|
||||
"entity_id": "sensor.my_ds18b20_temperature",
|
||||
@ -50,9 +64,18 @@ MOCK_DEVICE_SENSORS = {
|
||||
"unit": TEMP_CELSIUS,
|
||||
"class": DEVICE_CLASS_TEMPERATURE,
|
||||
},
|
||||
]
|
||||
],
|
||||
},
|
||||
"12.111111111111": {
|
||||
"inject_reads": [
|
||||
b"DS2406", # read device type
|
||||
],
|
||||
"device_info": {
|
||||
"identifiers": {(DOMAIN, "12.111111111111")},
|
||||
"manufacturer": "Maxim Integrated",
|
||||
"model": "DS2406",
|
||||
"name": "12.111111111111",
|
||||
},
|
||||
"sensors": [
|
||||
{
|
||||
"entity_id": "sensor.12_111111111111_temperature",
|
||||
@ -70,9 +93,18 @@ MOCK_DEVICE_SENSORS = {
|
||||
"unit": PRESSURE_MBAR,
|
||||
"class": DEVICE_CLASS_PRESSURE,
|
||||
},
|
||||
]
|
||||
],
|
||||
},
|
||||
"1D.111111111111": {
|
||||
"inject_reads": [
|
||||
b"DS2423", # read device type
|
||||
],
|
||||
"device_info": {
|
||||
"identifiers": {(DOMAIN, "1D.111111111111")},
|
||||
"manufacturer": "Maxim Integrated",
|
||||
"model": "DS2423",
|
||||
"name": "1D.111111111111",
|
||||
},
|
||||
"sensors": [
|
||||
{
|
||||
"entity_id": "sensor.1d_111111111111_counter_a",
|
||||
@ -90,9 +122,18 @@ MOCK_DEVICE_SENSORS = {
|
||||
"unit": "count",
|
||||
"class": None,
|
||||
},
|
||||
]
|
||||
],
|
||||
},
|
||||
"22.111111111111": {
|
||||
"inject_reads": [
|
||||
b"DS1822", # read device type
|
||||
],
|
||||
"device_info": {
|
||||
"identifiers": {(DOMAIN, "22.111111111111")},
|
||||
"manufacturer": "Maxim Integrated",
|
||||
"model": "DS1822",
|
||||
"name": "22.111111111111",
|
||||
},
|
||||
"sensors": [
|
||||
{
|
||||
"entity_id": "sensor.22_111111111111_temperature",
|
||||
@ -102,9 +143,18 @@ MOCK_DEVICE_SENSORS = {
|
||||
"unit": TEMP_CELSIUS,
|
||||
"class": DEVICE_CLASS_TEMPERATURE,
|
||||
},
|
||||
]
|
||||
],
|
||||
},
|
||||
"26.111111111111": {
|
||||
"inject_reads": [
|
||||
b"DS2438", # read device type
|
||||
],
|
||||
"device_info": {
|
||||
"identifiers": {(DOMAIN, "26.111111111111")},
|
||||
"manufacturer": "Maxim Integrated",
|
||||
"model": "DS2438",
|
||||
"name": "26.111111111111",
|
||||
},
|
||||
"sensors": [
|
||||
{
|
||||
"entity_id": "sensor.26_111111111111_temperature",
|
||||
@ -194,9 +244,18 @@ MOCK_DEVICE_SENSORS = {
|
||||
"unit": ELECTRICAL_CURRENT_AMPERE,
|
||||
"class": DEVICE_CLASS_CURRENT,
|
||||
},
|
||||
]
|
||||
],
|
||||
},
|
||||
"28.111111111111": {
|
||||
"inject_reads": [
|
||||
b"DS18B20", # read device type
|
||||
],
|
||||
"device_info": {
|
||||
"identifiers": {(DOMAIN, "28.111111111111")},
|
||||
"manufacturer": "Maxim Integrated",
|
||||
"model": "DS18B20",
|
||||
"name": "28.111111111111",
|
||||
},
|
||||
"sensors": [
|
||||
{
|
||||
"entity_id": "sensor.28_111111111111_temperature",
|
||||
@ -206,9 +265,18 @@ MOCK_DEVICE_SENSORS = {
|
||||
"unit": TEMP_CELSIUS,
|
||||
"class": DEVICE_CLASS_TEMPERATURE,
|
||||
},
|
||||
]
|
||||
],
|
||||
},
|
||||
"3B.111111111111": {
|
||||
"inject_reads": [
|
||||
b"DS1825", # read device type
|
||||
],
|
||||
"device_info": {
|
||||
"identifiers": {(DOMAIN, "3B.111111111111")},
|
||||
"manufacturer": "Maxim Integrated",
|
||||
"model": "DS1825",
|
||||
"name": "3B.111111111111",
|
||||
},
|
||||
"sensors": [
|
||||
{
|
||||
"entity_id": "sensor.3b_111111111111_temperature",
|
||||
@ -218,9 +286,18 @@ MOCK_DEVICE_SENSORS = {
|
||||
"unit": TEMP_CELSIUS,
|
||||
"class": DEVICE_CLASS_TEMPERATURE,
|
||||
},
|
||||
]
|
||||
],
|
||||
},
|
||||
"42.111111111111": {
|
||||
"inject_reads": [
|
||||
b"DS28EA00", # read device type
|
||||
],
|
||||
"device_info": {
|
||||
"identifiers": {(DOMAIN, "42.111111111111")},
|
||||
"manufacturer": "Maxim Integrated",
|
||||
"model": "DS28EA00",
|
||||
"name": "42.111111111111",
|
||||
},
|
||||
"sensors": [
|
||||
{
|
||||
"entity_id": "sensor.42_111111111111_temperature",
|
||||
@ -230,12 +307,18 @@ MOCK_DEVICE_SENSORS = {
|
||||
"unit": TEMP_CELSIUS,
|
||||
"class": DEVICE_CLASS_TEMPERATURE,
|
||||
},
|
||||
]
|
||||
],
|
||||
},
|
||||
"EF.111111111111": {
|
||||
"inject_reads": [
|
||||
b"HobbyBoards_EF", # read type
|
||||
],
|
||||
"device_info": {
|
||||
"identifiers": {(DOMAIN, "EF.111111111111")},
|
||||
"manufacturer": "Maxim Integrated",
|
||||
"model": "HobbyBoards_EF",
|
||||
"name": "EF.111111111111",
|
||||
},
|
||||
"sensors": [
|
||||
{
|
||||
"entity_id": "sensor.ef_111111111111_humidity",
|
||||
@ -271,6 +354,12 @@ MOCK_DEVICE_SENSORS = {
|
||||
b" 0", # read is_leaf_2
|
||||
b" 0", # read is_leaf_3
|
||||
],
|
||||
"device_info": {
|
||||
"identifiers": {(DOMAIN, "EF.111111111112")},
|
||||
"manufacturer": "Maxim Integrated",
|
||||
"model": "HB_MOISTURE_METER",
|
||||
"name": "EF.111111111112",
|
||||
},
|
||||
"sensors": [
|
||||
{
|
||||
"entity_id": "sensor.ef_111111111112_wetness_0",
|
||||
@ -313,13 +402,16 @@ MOCK_DEVICE_SENSORS = {
|
||||
async def test_owserver_setup_valid_device(hass, device_id):
|
||||
"""Test for 1-Wire device."""
|
||||
entity_registry = mock_registry(hass)
|
||||
device_registry = mock_device_registry(hass)
|
||||
|
||||
mock_device_sensor = MOCK_DEVICE_SENSORS[device_id]
|
||||
|
||||
dir_return_value = [f"/{device_id}/"]
|
||||
read_side_effect = [device_id[0:2].encode()]
|
||||
if "inject_reads" in MOCK_DEVICE_SENSORS[device_id]:
|
||||
read_side_effect += MOCK_DEVICE_SENSORS[device_id]["inject_reads"]
|
||||
if "inject_reads" in mock_device_sensor:
|
||||
read_side_effect += mock_device_sensor["inject_reads"]
|
||||
|
||||
expected_sensors = MOCK_DEVICE_SENSORS[device_id]["sensors"]
|
||||
expected_sensors = mock_device_sensor["sensors"]
|
||||
for expected_sensor in expected_sensors:
|
||||
read_side_effect.append(expected_sensor["injected_value"])
|
||||
|
||||
@ -335,6 +427,16 @@ async def test_owserver_setup_valid_device(hass, device_id):
|
||||
|
||||
assert len(entity_registry.entities) == len(expected_sensors)
|
||||
|
||||
if len(expected_sensors) > 0:
|
||||
device_info = mock_device_sensor["device_info"]
|
||||
assert len(device_registry.devices) == 1
|
||||
registry_entry = device_registry.async_get_device({(DOMAIN, device_id)}, set())
|
||||
assert registry_entry is not None
|
||||
assert registry_entry.identifiers == {(DOMAIN, device_id)}
|
||||
assert registry_entry.manufacturer == device_info["manufacturer"]
|
||||
assert registry_entry.name == device_info["name"]
|
||||
assert registry_entry.model == device_info["model"]
|
||||
|
||||
for expected_sensor in expected_sensors:
|
||||
entity_id = expected_sensor["entity_id"]
|
||||
registry_entry = entity_registry.entities.get(entity_id)
|
||||
|
@ -8,7 +8,7 @@ from homeassistant.const import DEVICE_CLASS_TEMPERATURE, TEMP_CELSIUS
|
||||
from homeassistant.setup import async_setup_component
|
||||
|
||||
from tests.async_mock import patch
|
||||
from tests.common import mock_registry
|
||||
from tests.common import mock_device_registry, mock_registry
|
||||
|
||||
MOCK_CONFIG = {
|
||||
SENSOR_DOMAIN: {
|
||||
@ -23,6 +23,12 @@ MOCK_CONFIG = {
|
||||
MOCK_DEVICE_SENSORS = {
|
||||
"00-111111111111": {"sensors": []},
|
||||
"10-111111111111": {
|
||||
"device_info": {
|
||||
"identifiers": {(DOMAIN, "10-111111111111")},
|
||||
"manufacturer": "Maxim Integrated",
|
||||
"model": "10",
|
||||
"name": "10-111111111111",
|
||||
},
|
||||
"sensors": [
|
||||
{
|
||||
"entity_id": "sensor.my_ds18b20_temperature",
|
||||
@ -32,11 +38,17 @@ MOCK_DEVICE_SENSORS = {
|
||||
"unit": TEMP_CELSIUS,
|
||||
"class": DEVICE_CLASS_TEMPERATURE,
|
||||
},
|
||||
]
|
||||
],
|
||||
},
|
||||
"12-111111111111": {"sensors": []},
|
||||
"1D-111111111111": {"sensors": []},
|
||||
"22-111111111111": {
|
||||
"device_info": {
|
||||
"identifiers": {(DOMAIN, "22-111111111111")},
|
||||
"manufacturer": "Maxim Integrated",
|
||||
"model": "22",
|
||||
"name": "22-111111111111",
|
||||
},
|
||||
"sensors": [
|
||||
{
|
||||
"entity_id": "sensor.22_111111111111_temperature",
|
||||
@ -46,10 +58,16 @@ MOCK_DEVICE_SENSORS = {
|
||||
"unit": TEMP_CELSIUS,
|
||||
"class": DEVICE_CLASS_TEMPERATURE,
|
||||
},
|
||||
]
|
||||
],
|
||||
},
|
||||
"26-111111111111": {"sensors": []},
|
||||
"28-111111111111": {
|
||||
"device_info": {
|
||||
"identifiers": {(DOMAIN, "28-111111111111")},
|
||||
"manufacturer": "Maxim Integrated",
|
||||
"model": "28",
|
||||
"name": "28-111111111111",
|
||||
},
|
||||
"sensors": [
|
||||
{
|
||||
"entity_id": "sensor.28_111111111111_temperature",
|
||||
@ -59,9 +77,15 @@ MOCK_DEVICE_SENSORS = {
|
||||
"unit": TEMP_CELSIUS,
|
||||
"class": DEVICE_CLASS_TEMPERATURE,
|
||||
},
|
||||
]
|
||||
],
|
||||
},
|
||||
"3B-111111111111": {
|
||||
"device_info": {
|
||||
"identifiers": {(DOMAIN, "3B-111111111111")},
|
||||
"manufacturer": "Maxim Integrated",
|
||||
"model": "3B",
|
||||
"name": "3B-111111111111",
|
||||
},
|
||||
"sensors": [
|
||||
{
|
||||
"entity_id": "sensor.3b_111111111111_temperature",
|
||||
@ -71,9 +95,15 @@ MOCK_DEVICE_SENSORS = {
|
||||
"unit": TEMP_CELSIUS,
|
||||
"class": DEVICE_CLASS_TEMPERATURE,
|
||||
},
|
||||
]
|
||||
],
|
||||
},
|
||||
"42-111111111111": {
|
||||
"device_info": {
|
||||
"identifiers": {(DOMAIN, "42-111111111111")},
|
||||
"manufacturer": "Maxim Integrated",
|
||||
"model": "42",
|
||||
"name": "42-111111111111",
|
||||
},
|
||||
"sensors": [
|
||||
{
|
||||
"entity_id": "sensor.42_111111111111_temperature",
|
||||
@ -83,7 +113,7 @@ MOCK_DEVICE_SENSORS = {
|
||||
"unit": TEMP_CELSIUS,
|
||||
"class": DEVICE_CLASS_TEMPERATURE,
|
||||
},
|
||||
]
|
||||
],
|
||||
},
|
||||
"EF-111111111111": {
|
||||
"sensors": [],
|
||||
@ -98,10 +128,13 @@ MOCK_DEVICE_SENSORS = {
|
||||
async def test_onewiredirect_setup_valid_device(hass, device_id):
|
||||
"""Test that sysbus config entry works correctly."""
|
||||
entity_registry = mock_registry(hass)
|
||||
device_registry = mock_device_registry(hass)
|
||||
|
||||
mock_device_sensor = MOCK_DEVICE_SENSORS[device_id]
|
||||
|
||||
glob_result = [f"/{DEFAULT_SYSBUS_MOUNT_DIR}/{device_id}"]
|
||||
read_side_effect = []
|
||||
expected_sensors = MOCK_DEVICE_SENSORS[device_id]["sensors"]
|
||||
expected_sensors = mock_device_sensor["sensors"]
|
||||
for expected_sensor in expected_sensors:
|
||||
read_side_effect.append(expected_sensor["injected_value"])
|
||||
|
||||
@ -119,6 +152,16 @@ async def test_onewiredirect_setup_valid_device(hass, device_id):
|
||||
|
||||
assert len(entity_registry.entities) == len(expected_sensors)
|
||||
|
||||
if len(expected_sensors) > 0:
|
||||
device_info = mock_device_sensor["device_info"]
|
||||
assert len(device_registry.devices) == 1
|
||||
registry_entry = device_registry.async_get_device({(DOMAIN, device_id)}, set())
|
||||
assert registry_entry is not None
|
||||
assert registry_entry.identifiers == {(DOMAIN, device_id)}
|
||||
assert registry_entry.manufacturer == device_info["manufacturer"]
|
||||
assert registry_entry.name == device_info["name"]
|
||||
assert registry_entry.model == device_info["model"]
|
||||
|
||||
for expected_sensor in expected_sensors:
|
||||
entity_id = expected_sensor["entity_id"]
|
||||
registry_entry = entity_registry.entities.get(entity_id)
|
||||
|
Loading…
x
Reference in New Issue
Block a user