mirror of
https://github.com/home-assistant/core.git
synced 2025-07-23 13:17:32 +00:00
Discover onewire devices at startup (#42410)
This commit is contained in:
parent
5f3384fc8a
commit
f3a15eab6e
@ -1,6 +1,7 @@
|
||||
"""Hub for communication with 1-Wire server or mount_dir."""
|
||||
import os
|
||||
|
||||
from pi1wire import Pi1Wire
|
||||
from pyownet import protocol
|
||||
|
||||
from homeassistant.config_entries import ConfigEntry
|
||||
@ -17,7 +18,10 @@ class OneWireHub:
|
||||
def __init__(self, hass: HomeAssistantType):
|
||||
"""Initialize."""
|
||||
self.hass = hass
|
||||
self.type: str = None
|
||||
self.pi1proxy: Pi1Wire = None
|
||||
self.owproxy: protocol._Proxy = None
|
||||
self.devices = None
|
||||
|
||||
async def connect(self, host: str, port: int) -> None:
|
||||
"""Connect to the owserver host."""
|
||||
@ -32,15 +36,44 @@ class OneWireHub:
|
||||
"""Test that the mount_dir is a valid path."""
|
||||
if not await self.hass.async_add_executor_job(os.path.isdir, mount_dir):
|
||||
raise InvalidPath
|
||||
self.pi1proxy = Pi1Wire(mount_dir)
|
||||
|
||||
async def initialize(self, config_entry: ConfigEntry) -> None:
|
||||
"""Initialize a config entry."""
|
||||
if config_entry.data[CONF_TYPE] == CONF_TYPE_SYSBUS:
|
||||
self.type = config_entry.data[CONF_TYPE]
|
||||
if self.type == CONF_TYPE_SYSBUS:
|
||||
await self.check_mount_dir(config_entry.data[CONF_MOUNT_DIR])
|
||||
elif config_entry.data[CONF_TYPE] == CONF_TYPE_OWSERVER:
|
||||
elif self.type == CONF_TYPE_OWSERVER:
|
||||
host = config_entry.data[CONF_HOST]
|
||||
port = config_entry.data[CONF_PORT]
|
||||
await self.connect(host, port)
|
||||
await self.discover_devices()
|
||||
|
||||
async def discover_devices(self):
|
||||
"""Discover all devices."""
|
||||
if self.devices is None:
|
||||
if self.type == CONF_TYPE_SYSBUS:
|
||||
self.devices = await self.hass.async_add_executor_job(
|
||||
self.pi1proxy.find_all_sensors
|
||||
)
|
||||
if self.type == CONF_TYPE_OWSERVER:
|
||||
self.devices = await self.hass.async_add_executor_job(
|
||||
self._discover_devices_owserver
|
||||
)
|
||||
return self.devices
|
||||
|
||||
def _discover_devices_owserver(self):
|
||||
"""Discover all owserver devices."""
|
||||
devices = []
|
||||
for device_path in self.owproxy.dir():
|
||||
devices.append(
|
||||
{
|
||||
"path": device_path,
|
||||
"family": self.owproxy.read(f"{device_path}family").decode(),
|
||||
"type": self.owproxy.read(f"{device_path}type").decode(),
|
||||
}
|
||||
)
|
||||
return devices
|
||||
|
||||
|
||||
class CannotConnect(HomeAssistantError):
|
||||
|
@ -4,7 +4,7 @@ import logging
|
||||
import os
|
||||
from typing import Any, Dict, Optional
|
||||
|
||||
from pi1wire import InvalidCRCException, Pi1Wire, UnsupportResponseException
|
||||
from pi1wire import InvalidCRCException, UnsupportResponseException
|
||||
from pyownet import protocol
|
||||
import voluptuous as vol
|
||||
|
||||
@ -175,21 +175,10 @@ def get_entities(onewirehub: OneWireHub, config):
|
||||
conf_type = config[CONF_TYPE]
|
||||
# We have an owserver on a remote(or local) host/port
|
||||
if conf_type == CONF_TYPE_OWSERVER:
|
||||
owhost = config[CONF_HOST]
|
||||
owport = config[CONF_PORT]
|
||||
|
||||
try:
|
||||
devices = onewirehub.owproxy.dir()
|
||||
except protocol.OwnetError as exc:
|
||||
_LOGGER.error(
|
||||
"Failed to list devices on %s:%d, got: %s", owhost, owport, exc
|
||||
)
|
||||
return entities
|
||||
for device in devices:
|
||||
_LOGGER.debug("Found device: %s", device)
|
||||
family = onewirehub.owproxy.read(f"{device}family").decode()
|
||||
device_type = onewirehub.owproxy.read(f"{device}type").decode()
|
||||
sensor_id = os.path.split(os.path.split(device)[0])[1]
|
||||
for device in onewirehub.devices:
|
||||
family = device["family"]
|
||||
device_type = device["type"]
|
||||
sensor_id = os.path.split(os.path.split(device["path"])[0])[1]
|
||||
dev_type = "std"
|
||||
if "EF" in family:
|
||||
dev_type = "HobbyBoard"
|
||||
@ -199,7 +188,7 @@ def get_entities(onewirehub: OneWireHub, config):
|
||||
_LOGGER.warning(
|
||||
"Ignoring unknown family (%s) of sensor found for device: %s",
|
||||
family,
|
||||
device,
|
||||
sensor_id,
|
||||
)
|
||||
continue
|
||||
device_info = {
|
||||
@ -213,12 +202,14 @@ def get_entities(onewirehub: OneWireHub, config):
|
||||
s_id = sensor_key.split("_")[1]
|
||||
is_leaf = int(
|
||||
onewirehub.owproxy.read(
|
||||
f"{device}moisture/is_leaf.{s_id}"
|
||||
f"{device['path']}moisture/is_leaf.{s_id}"
|
||||
).decode()
|
||||
)
|
||||
if is_leaf:
|
||||
sensor_key = f"wetness_{s_id}"
|
||||
device_file = os.path.join(os.path.split(device)[0], sensor_value)
|
||||
device_file = os.path.join(
|
||||
os.path.split(device["path"])[0], sensor_value
|
||||
)
|
||||
entities.append(
|
||||
OneWireProxy(
|
||||
device_names.get(sensor_id, sensor_id),
|
||||
@ -233,7 +224,7 @@ def get_entities(onewirehub: OneWireHub, config):
|
||||
elif conf_type == CONF_TYPE_SYSBUS:
|
||||
base_dir = config[CONF_MOUNT_DIR]
|
||||
_LOGGER.debug("Initializing using SysBus %s", base_dir)
|
||||
for p1sensor in Pi1Wire(base_dir).find_all_sensors():
|
||||
for p1sensor in onewirehub.devices:
|
||||
family = p1sensor.mac_address[:2]
|
||||
sensor_id = f"{family}-{p1sensor.mac_address[2:]}"
|
||||
if family not in DEVICE_SUPPORT_SYSBUS:
|
||||
|
@ -418,7 +418,7 @@ async def test_owserver_setup_valid_device(hass, device_id):
|
||||
# Ensure enough read side effect
|
||||
read_side_effect.extend([ProtocolError("Missing injected value")] * 10)
|
||||
|
||||
with patch("homeassistant.components.onewire.sensor.protocol.proxy") as owproxy:
|
||||
with patch("homeassistant.components.onewire.onewirehub.protocol.proxy") as owproxy:
|
||||
owproxy.return_value.dir.return_value = dir_return_value
|
||||
owproxy.return_value.read.side_effect = read_side_effect
|
||||
|
||||
|
@ -142,7 +142,7 @@ async def test_onewiredirect_setup_valid_device(hass, device_id):
|
||||
read_side_effect.extend([FileNotFoundError("Missing injected value")] * 20)
|
||||
|
||||
with patch(
|
||||
"homeassistant.components.onewire.sensor.os.path.isdir", return_value=True
|
||||
"homeassistant.components.onewire.onewirehub.os.path.isdir", return_value=True
|
||||
), patch("pi1wire._finder.glob.glob", return_value=glob_result,), patch(
|
||||
"pi1wire.OneWire.get_temperature",
|
||||
side_effect=read_side_effect,
|
||||
|
@ -16,8 +16,8 @@ from . import setup_onewire_owserver_integration, setup_onewire_sysbus_integrati
|
||||
from tests.common import MockConfigEntry
|
||||
|
||||
|
||||
async def test_owserver_platform_not_ready(hass):
|
||||
"""Create the 1-Wire integration."""
|
||||
async def test_owserver_connect_failure(hass):
|
||||
"""Test connection failure raises ConfigEntryNotReady."""
|
||||
config_entry_owserver = MockConfigEntry(
|
||||
domain=DOMAIN,
|
||||
source="user",
|
||||
|
Loading…
x
Reference in New Issue
Block a user