Skip to content

Commit

Permalink
Hw version (#1286)
Browse files Browse the repository at this point in the history
* Update schema with hw_version

Allow for other fields in future if every the component code validates

* Load hw_version into device library

* Start of lookup with hw_version

* WIP

* Search with optional hw_version

* Apply automatic changes

* Update docs

---------

Co-authored-by: andrew-codechimp <andrew-codechimp@users.noreply.github.com>
  • Loading branch information
andrew-codechimp and andrew-codechimp authored Mar 12, 2024
1 parent 2bddaed commit e3da6b6
Show file tree
Hide file tree
Showing 5 changed files with 73 additions and 23 deletions.
10 changes: 6 additions & 4 deletions custom_components/battery_notes/config_flow.py
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,7 @@
CONF_DEVICE_ID,
)

from .library import Library
from .library import Library, ModelInfo
from .library_updater import LibraryUpdater

from .const import (
Expand Down Expand Up @@ -134,21 +134,23 @@ async def async_step_user(
device_entry = device_registry.async_get(device_id)

_LOGGER.debug(
"Looking up device %s %s", device_entry.manufacturer, device_entry.model
"Looking up device %s %s %s", device_entry.manufacturer, device_entry.model, device_entry.hw_version
)

model_info = ModelInfo(device_entry.manufacturer, device_entry.model, device_entry.hw_version)

library = Library.factory(self.hass)

# Set defaults if not found in library
self.data[CONF_BATTERY_QUANTITY] = 1

device_battery_details = await library.get_device_battery_details(
device_entry.manufacturer, device_entry.model
model_info
)

if device_battery_details and not device_battery_details.is_manual:
_LOGGER.debug(
"Found device %s %s", device_entry.manufacturer, device_entry.model
"Found device %s %s %s", device_entry.manufacturer, device_entry.model, device_entry.hw_version
)
self.data[CONF_BATTERY_TYPE] = device_battery_details.battery_type

Expand Down
5 changes: 3 additions & 2 deletions custom_components/battery_notes/discovery.py
Original file line number Diff line number Diff line change
Expand Up @@ -55,11 +55,12 @@ async def get_model_information(

manufacturer = device_entry.manufacturer
model = device_entry.model
hw_version = device_entry.hw_version

if not manufacturer or not model:
return None

return ModelInfo(manufacturer, model)
return ModelInfo(manufacturer, model, hw_version)


class DiscoveryManager:
Expand Down Expand Up @@ -98,7 +99,7 @@ async def start_discovery(self) -> None:
continue

device_battery_details = await library.get_device_battery_details(
model_info.manufacturer, model_info.model
model_info
)

if not device_battery_details:
Expand Down
76 changes: 60 additions & 16 deletions custom_components/battery_notes/library.py
Original file line number Diff line number Diff line change
Expand Up @@ -88,26 +88,68 @@ def factory(hass: HomeAssistant) -> Library:

async def get_device_battery_details(
self,
manufacturer: str,
model: str,
model_info: ModelInfo,
) -> DeviceBatteryDetails | None:
"""Create a battery details object from the JSON devices data."""

if self._devices is not None:
for device in self._devices:
if (
str(device["manufacturer"] or "").casefold()
== str(manufacturer or "").casefold()
and str(device["model"] or "").casefold()
== str(model or "").casefold()
):
device_battery_details = DeviceBatteryDetails(
manufacturer=device["manufacturer"],
model=device["model"],
battery_type=device["battery_type"],
battery_quantity=device.get("battery_quantity", 1),
)
return device_battery_details

# If a hw_version is present try find that first
if model_info.hw_version:
matching_devices = []

# Find all devices that match the manufacturer and model
for device in self._devices:
if (
str(device["manufacturer"] or "").casefold()
== str(model_info.manufacturer or "").casefold()
and str(device["model"] or "").casefold()
== str(model_info.model or "").casefold()
):
matching_devices.append(device)

# Check if any matching devices have specified hw_version
for device in matching_devices:
if device.get("hw_version", "").casefold() == str(model_info.hw_version or "").casefold():
matched_device = device
device_battery_details = DeviceBatteryDetails(
manufacturer=matched_device["manufacturer"],
model=matched_device["model"],
hw_version=matched_device["hw_version"],
battery_type=matched_device["battery_type"],
battery_quantity=matched_device.get("battery_quantity", 1),
)
break
else:
# Return first item in list, the non hw_version one
matched_device = matching_devices[0]

device_battery_details = DeviceBatteryDetails(
manufacturer=matched_device["manufacturer"],
model=matched_device["model"],
hw_version=matched_device.get("hw_version", None),
battery_type=matched_device["battery_type"],
battery_quantity=matched_device.get("battery_quantity", 1),
)
return device_battery_details

else:
# For devices that don't have hw_version
for device in self._devices:
if (
str(device["manufacturer"] or "").casefold()
== str(model_info.manufacturer or "").casefold()
and str(device["model"] or "").casefold()
== str(model_info.model or "").casefold()
):
device_battery_details = DeviceBatteryDetails(
manufacturer=device["manufacturer"],
model=device["model"],
hw_version=device.get("hw_version", None),
battery_type=device["battery_type"],
battery_quantity=device.get("battery_quantity", 1),
)
return device_battery_details

return None

Expand All @@ -121,6 +163,7 @@ class DeviceBatteryDetails(NamedTuple):

manufacturer: str
model: str
hw_version: str
battery_type: str
battery_quantity: int

Expand Down Expand Up @@ -152,3 +195,4 @@ class ModelInfo(NamedTuple):

manufacturer: str
model: str
hw_version: str
3 changes: 2 additions & 1 deletion docs/library.md
Original file line number Diff line number Diff line change
Expand Up @@ -31,8 +31,9 @@ For the example image below, your JSON entry will look like this:
{
"manufacturer": "Philips",
"model": "Hue motion sensor (9290012607)",
"hw_version": "Some specific hardware detail", < Optional, only use if two devices have the same model and the hw_version are different.
"battery_type": "AAA",
"battery_quantity": 2
"battery_quantity": 2 < Only use if more than 1 battery
},
```

Expand Down
2 changes: 2 additions & 0 deletions library.md
Original file line number Diff line number Diff line change
Expand Up @@ -604,6 +604,8 @@ Request new devices to be added to the library [here](https://github.com/andrew-
|Somfy |Somfy Smoke Detector |2× AA |
|SOMFY |Sonesse 28 WF Li-Ion Roller |Rechargeable |
|SOMFY |Sonesse 28 WF Li-Ion Roller |MANUAL |
|SOMFY |Sonesse 28 WF Li-Ion Roller |Rechargeable |
|SOMFY |Sonesse 28 WF Li-Ion Roller |MANUAL |
|Sonoff |Contact sensor (SNZB-04) |CR2032 |
|SONOFF |DW2-Wi-Fi |2× AAA |
|SONOFF |DW2-WI-FI-L |2× AAA |
Expand Down

0 comments on commit e3da6b6

Please sign in to comment.