Skip to content

Commit

Permalink
Adjust HomeWizard to use updated python-homewizard-energy library (ho…
Browse files Browse the repository at this point in the history
  • Loading branch information
DCSBL authored Jan 10, 2025
1 parent 1f0eda8 commit f31f6d7
Show file tree
Hide file tree
Showing 20 changed files with 722 additions and 786 deletions.
2 changes: 1 addition & 1 deletion homeassistant/components/homewizard/button.py
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@ async def async_setup_entry(
async_add_entities: AddEntitiesCallback,
) -> None:
"""Set up the Identify button."""
if entry.runtime_data.supports_identify():
if entry.runtime_data.data.device.supports_identify():
async_add_entities([HomeWizardIdentifyButton(entry.runtime_data)])


Expand Down
3 changes: 2 additions & 1 deletion homeassistant/components/homewizard/config_flow.py
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@

from homewizard_energy import HomeWizardEnergyV1
from homewizard_energy.errors import DisabledError, RequestError, UnsupportedError
from homewizard_energy.v1.models import Device
from homewizard_energy.models import Device
import voluptuous as vol

from homeassistant.components import onboarding, zeroconf
Expand Down Expand Up @@ -206,6 +206,7 @@ async def async_step_reconfigure(
if user_input:
try:
device_info = await self._async_try_connect(user_input[CONF_IP_ADDRESS])

except RecoverableError as ex:
_LOGGER.error(ex)
errors = {"base": ex.error_code}
Expand Down
13 changes: 0 additions & 13 deletions homeassistant/components/homewizard/const.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,12 +2,9 @@

from __future__ import annotations

from dataclasses import dataclass
from datetime import timedelta
import logging

from homewizard_energy.v1.models import Data, Device, State, System

from homeassistant.const import Platform

DOMAIN = "homewizard"
Expand All @@ -23,13 +20,3 @@
CONF_SERIAL = "serial"

UPDATE_INTERVAL = timedelta(seconds=5)


@dataclass
class DeviceResponseEntry:
"""Dict describing a single response entry."""

device: Device
data: Data
state: State | None = None
system: System | None = None
49 changes: 6 additions & 43 deletions homeassistant/components/homewizard/coordinator.py
Original file line number Diff line number Diff line change
Expand Up @@ -4,30 +4,27 @@

import logging

from homewizard_energy import HomeWizardEnergyV1
from homewizard_energy.errors import DisabledError, RequestError, UnsupportedError
from homewizard_energy.v1.const import SUPPORTS_IDENTIFY, SUPPORTS_STATE
from homewizard_energy.v1.models import Device
from homewizard_energy import HomeWizardEnergy, HomeWizardEnergyV1
from homewizard_energy.errors import DisabledError, RequestError
from homewizard_energy.models import CombinedModels as DeviceResponseEntry

from homeassistant.config_entries import ConfigEntry
from homeassistant.const import CONF_IP_ADDRESS
from homeassistant.core import HomeAssistant
from homeassistant.helpers.aiohttp_client import async_get_clientsession
from homeassistant.helpers.update_coordinator import DataUpdateCoordinator, UpdateFailed

from .const import DOMAIN, UPDATE_INTERVAL, DeviceResponseEntry
from .const import DOMAIN, UPDATE_INTERVAL

_LOGGER = logging.getLogger(__name__)


class HWEnergyDeviceUpdateCoordinator(DataUpdateCoordinator[DeviceResponseEntry]):
"""Gather data for the energy device."""

api: HomeWizardEnergyV1
api: HomeWizardEnergy
api_disabled: bool = False

_unsupported_error: bool = False

config_entry: ConfigEntry

def __init__(
Expand All @@ -44,26 +41,7 @@ def __init__(
async def _async_update_data(self) -> DeviceResponseEntry:
"""Fetch all device and sensor data from api."""
try:
data = DeviceResponseEntry(
device=await self.api.device(),
data=await self.api.data(),
)

try:
if self.supports_state(data.device):
data.state = await self.api.state()

data.system = await self.api.system()

except UnsupportedError as ex:
# Old firmware, ignore
if not self._unsupported_error:
self._unsupported_error = True
_LOGGER.warning(
"%s is running an outdated firmware version (%s). Contact HomeWizard support to update your device",
self.config_entry.title,
ex,
)
data = await self.api.combined()

except RequestError as ex:
raise UpdateFailed(
Expand All @@ -89,18 +67,3 @@ async def _async_update_data(self) -> DeviceResponseEntry:

self.data = data
return data

def supports_state(self, device: Device | None = None) -> bool:
"""Return True if the device supports state."""

if device is None:
device = self.data.device

return device.product_type in SUPPORTS_STATE

def supports_identify(self, device: Device | None = None) -> bool:
"""Return True if the device supports identify."""
if device is None:
device = self.data.device

return device.product_type in SUPPORTS_IDENTIFY
22 changes: 5 additions & 17 deletions homeassistant/components/homewizard/diagnostics.py
Original file line number Diff line number Diff line change
Expand Up @@ -13,11 +13,12 @@

TO_REDACT = {
CONF_IP_ADDRESS,
"gas_unique_id",
"id",
"serial",
"wifi_ssid",
"unique_meter_id",
"unique_id",
"gas_unique_id",
"unique_meter_id",
"wifi_ssid",
}


Expand All @@ -27,23 +28,10 @@ async def async_get_config_entry_diagnostics(
"""Return diagnostics for a config entry."""
data = entry.runtime_data.data

state: dict[str, Any] | None = None
if data.state:
state = asdict(data.state)

system: dict[str, Any] | None = None
if data.system:
system = asdict(data.system)

return async_redact_data(
{
"entry": async_redact_data(entry.data, TO_REDACT),
"data": {
"device": asdict(data.device),
"data": asdict(data.data),
"state": state,
"system": system,
},
"data": asdict(data),
},
TO_REDACT,
)
4 changes: 1 addition & 3 deletions homeassistant/components/homewizard/entity.py
Original file line number Diff line number Diff line change
Expand Up @@ -22,9 +22,7 @@ def __init__(self, coordinator: HWEnergyDeviceUpdateCoordinator) -> None:
manufacturer="HomeWizard",
sw_version=coordinator.data.device.firmware_version,
model_id=coordinator.data.device.product_type,
model=coordinator.data.device.product.name
if coordinator.data.device.product
else None,
model=coordinator.data.device.model_name,
)

if (serial_number := coordinator.data.device.serial) is not None:
Expand Down
2 changes: 1 addition & 1 deletion homeassistant/components/homewizard/manifest.json
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,6 @@
"iot_class": "local_polling",
"loggers": ["homewizard_energy"],
"quality_scale": "platinum",
"requirements": ["python-homewizard-energy==v7.0.1"],
"requirements": ["python-homewizard-energy==v8.0.0"],
"zeroconf": ["_hwenergy._tcp.local."]
}
16 changes: 7 additions & 9 deletions homeassistant/components/homewizard/number.py
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,6 @@
from homeassistant.const import PERCENTAGE, EntityCategory
from homeassistant.core import HomeAssistant
from homeassistant.helpers.entity_platform import AddEntitiesCallback
from homeassistant.util.color import brightness_to_value, value_to_brightness

from . import HomeWizardConfigEntry
from .coordinator import HWEnergyDeviceUpdateCoordinator
Expand All @@ -22,7 +21,7 @@ async def async_setup_entry(
async_add_entities: AddEntitiesCallback,
) -> None:
"""Set up numbers for device."""
if entry.runtime_data.supports_state():
if entry.runtime_data.data.device.supports_state():
async_add_entities([HWEnergyNumberEntity(entry.runtime_data)])


Expand All @@ -46,22 +45,21 @@ def __init__(
@homewizard_exception_handler
async def async_set_native_value(self, value: float) -> None:
"""Set a new value."""
await self.coordinator.api.state_set(
brightness=value_to_brightness((0, 100), value)
)
await self.coordinator.api.system(status_led_brightness_pct=int(value))
await self.coordinator.async_refresh()

@property
def available(self) -> bool:
"""Return if entity is available."""
return super().available and self.coordinator.data.state is not None
return super().available and self.coordinator.data.system is not None

@property
def native_value(self) -> float | None:
"""Return the current value."""
if (
not self.coordinator.data.state
or (brightness := self.coordinator.data.state.brightness) is None
not self.coordinator.data.system
or (brightness := self.coordinator.data.system.status_led_brightness_pct)
is None
):
return None
return round(brightness_to_value((0, 100), brightness))
return round(brightness)
Loading

0 comments on commit f31f6d7

Please sign in to comment.