Skip to content

Commit

Permalink
Service split (#2283)
Browse files Browse the repository at this point in the history
* Split the service into a separate file from init

* Update device: H5126 by Govee (#2282)

* Apply automatic changes

* Fix last_replaced dates #2280

---------

Co-authored-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com>
Co-authored-by: andrew-codechimp <[email protected]>
  • Loading branch information
3 people authored Nov 2, 2024
1 parent cac9e18 commit bb1530e
Show file tree
Hide file tree
Showing 2 changed files with 255 additions and 234 deletions.
237 changes: 3 additions & 234 deletions custom_components/battery_notes/__init__.py
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
"""Custom integration to integrate BatteryNotes with Home Assistant.
"""Battery Notes integration for Home Assistant.
For more details about this integration, please refer to
https://github.com/andrew-codechimp/ha-battery-notes
Expand All @@ -9,35 +9,20 @@
import logging
import re
from dataclasses import dataclass, field
from datetime import datetime

import voluptuous as vol
from awesomeversion.awesomeversion import AwesomeVersion
from homeassistant.config_entries import ConfigEntry
from homeassistant.const import __version__ as HA_VERSION # noqa: N812
from homeassistant.core import HomeAssistant, callback
from homeassistant.helpers import config_validation as cv
from homeassistant.helpers import device_registry as dr
from homeassistant.helpers import entity_registry as er
from homeassistant.helpers.typing import ConfigType
from homeassistant.util import dt as dt_util

from .config_flow import CONFIG_VERSION
from .const import (
ATTR_BATTERY_LAST_REPORTED,
ATTR_BATTERY_LAST_REPORTED_DAYS,
ATTR_BATTERY_LAST_REPORTED_LEVEL,
ATTR_BATTERY_LEVEL,
ATTR_BATTERY_LOW,
ATTR_BATTERY_QUANTITY,
ATTR_BATTERY_THRESHOLD_REMINDER,
ATTR_BATTERY_TYPE,
ATTR_BATTERY_TYPE_AND_QUANTITY,
ATTR_DEVICE_ID,
ATTR_DEVICE_NAME,
ATTR_PREVIOUS_BATTERY_LEVEL,
ATTR_REMOVE,
ATTR_SOURCE_ENTITY_ID,
CONF_BATTERY_INCREASE_THRESHOLD,
CONF_BATTERY_QUANTITY,
CONF_BATTERY_TYPE,
Expand All @@ -55,24 +40,15 @@
DEFAULT_BATTERY_LOW_THRESHOLD,
DOMAIN,
DOMAIN_CONFIG,
EVENT_BATTERY_NOT_REPORTED,
EVENT_BATTERY_REPLACED,
EVENT_BATTERY_THRESHOLD,
MIN_HA_VERSION,
PLATFORMS,
SERVICE_BATTERY_REPLACED,
SERVICE_BATTERY_REPLACED_SCHEMA,
SERVICE_CHECK_BATTERY_LAST_REPORTED,
SERVICE_CHECK_BATTERY_LAST_REPORTED_SCHEMA,
SERVICE_CHECK_BATTERY_LOW,
SERVICE_DATA_DATE_TIME_REPLACED,
SERVICE_DATA_DAYS_LAST_REPORTED,
)
from .device import BatteryNotesDevice
from .discovery import DiscoveryManager
from .library_updater import (
LibraryUpdater,
)
from .services import setup_services
from .store import (
async_get_registry,
)
Expand Down Expand Up @@ -158,7 +134,7 @@ async def async_setup(hass: HomeAssistant, config: ConfigType) -> bool:
_LOGGER.debug("Auto discovery disabled")

# Register custom services
register_services(hass)
setup_services(hass)

return True

Expand Down Expand Up @@ -267,210 +243,3 @@ async def async_migrate_entry(hass: HomeAssistant, config_entry: ConfigEntry):
async def async_update_options(hass: HomeAssistant, entry: ConfigEntry) -> None:
"""Update options."""
await hass.config_entries.async_reload(entry.entry_id)


@callback
def register_services(hass: HomeAssistant):
"""Register services used by battery notes component."""

async def handle_battery_replaced(call):
"""Handle the service call."""
device_id = call.data.get(ATTR_DEVICE_ID, "")
source_entity_id = call.data.get(ATTR_SOURCE_ENTITY_ID, "")
datetime_replaced_entry = call.data.get(SERVICE_DATA_DATE_TIME_REPLACED)

if datetime_replaced_entry:
datetime_replaced = dt_util.as_utc(datetime_replaced_entry).replace(
tzinfo=None
)
else:
datetime_replaced = datetime.utcnow()

entity_registry = er.async_get(hass)
device_registry = dr.async_get(hass)

if source_entity_id:
source_entity_entry = entity_registry.async_get(source_entity_id)
if not source_entity_entry:
_LOGGER.error(
"Entity %s not found",
source_entity_id,
)
return

# entity_id is the associated entity, now need to find the config entry for battery notes
for config_entry in hass.config_entries.async_entries(DOMAIN):
if config_entry.data.get("source_entity_id") == source_entity_id:
config_entry_id = config_entry.entry_id

coordinator = (
hass.data[DOMAIN][DATA].devices[config_entry_id].coordinator
)

coordinator.last_replaced =datetime_replaced
await coordinator.async_request_refresh()

_LOGGER.debug(
"Entity %s battery replaced on %s",
source_entity_id,
str(datetime_replaced),
)

hass.bus.async_fire(
EVENT_BATTERY_REPLACED,
{
ATTR_DEVICE_ID: coordinator.device_id or "",
ATTR_SOURCE_ENTITY_ID: coordinator.source_entity_id
or "",
ATTR_DEVICE_NAME: coordinator.device_name,
ATTR_BATTERY_TYPE_AND_QUANTITY: coordinator.battery_type_and_quantity,
ATTR_BATTERY_TYPE: coordinator.battery_type,
ATTR_BATTERY_QUANTITY: coordinator.battery_quantity,
},
)

_LOGGER.debug(
"Raised event battery replaced %s",
coordinator.device_id,
)

return

_LOGGER.error("Entity %s not configured in Battery Notes", source_entity_id)

else:
device_entry = device_registry.async_get(device_id)
if not device_entry:
_LOGGER.error(
"Device %s not found",
device_id,
)
return

for entry_id in device_entry.config_entries:
if (
entry := hass.config_entries.async_get_entry(entry_id)
) and entry.domain == DOMAIN:
coordinator = (
hass.data[DOMAIN][DATA].devices[entry.entry_id].coordinator
)

coordinator.last_replaced =datetime_replaced

await coordinator.async_request_refresh()

_LOGGER.debug(
"Device %s battery replaced on %s",
device_id,
str(datetime_replaced),
)

hass.bus.async_fire(
EVENT_BATTERY_REPLACED,
{
ATTR_DEVICE_ID: coordinator.device_id or "",
ATTR_SOURCE_ENTITY_ID: coordinator.source_entity_id
or "",
ATTR_DEVICE_NAME: coordinator.device_name,
ATTR_BATTERY_TYPE_AND_QUANTITY: coordinator.battery_type_and_quantity,
ATTR_BATTERY_TYPE: coordinator.battery_type,
ATTR_BATTERY_QUANTITY: coordinator.battery_quantity,
},
)

_LOGGER.debug(
"Raised event battery replaced %s",
coordinator.device_id,
)

# Found and dealt with, exit
return

_LOGGER.error(
"Device %s not configured in Battery Notes",
device_id,
)


async def handle_battery_last_reported(call):
"""Handle the service call."""
days_last_reported = call.data.get(SERVICE_DATA_DAYS_LAST_REPORTED)

device: BatteryNotesDevice
for device in hass.data[DOMAIN][DATA].devices.values():
if device.coordinator.wrapped_battery and device.coordinator.last_reported:
time_since_lastreported = (
datetime.fromisoformat(str(datetime.utcnow()) + "+00:00")
- device.coordinator.last_reported
)

if time_since_lastreported.days > days_last_reported:
hass.bus.async_fire(
EVENT_BATTERY_NOT_REPORTED,
{
ATTR_DEVICE_ID: device.coordinator.device_id or "",
ATTR_SOURCE_ENTITY_ID: device.coordinator.source_entity_id
or "",
ATTR_DEVICE_NAME: device.coordinator.device_name,
ATTR_BATTERY_TYPE_AND_QUANTITY: device.coordinator.battery_type_and_quantity,
ATTR_BATTERY_TYPE: device.coordinator.battery_type,
ATTR_BATTERY_QUANTITY: device.coordinator.battery_quantity,
ATTR_BATTERY_LAST_REPORTED: device.coordinator.last_reported,
ATTR_BATTERY_LAST_REPORTED_DAYS: time_since_lastreported.days,
ATTR_BATTERY_LAST_REPORTED_LEVEL: device.coordinator.last_reported_level,
},
)

_LOGGER.debug(
"Raised event device %s not reported since %s",
device.coordinator.device_id,
str(device.coordinator.last_reported),
)

async def handle_battery_low(call):
"""Handle the service call."""

device: BatteryNotesDevice
for device in hass.data[DOMAIN][DATA].devices.values():
if device.coordinator.battery_low is True:
hass.bus.async_fire(
EVENT_BATTERY_THRESHOLD,
{
ATTR_DEVICE_ID: device.coordinator.device_id or "",
ATTR_DEVICE_NAME: device.coordinator.device_name,
ATTR_SOURCE_ENTITY_ID: device.coordinator.source_entity_id
or "",
ATTR_BATTERY_LOW: device.coordinator.battery_low,
ATTR_BATTERY_TYPE_AND_QUANTITY: device.coordinator.battery_type_and_quantity,
ATTR_BATTERY_TYPE: device.coordinator.battery_type,
ATTR_BATTERY_QUANTITY: device.coordinator.battery_quantity,
ATTR_BATTERY_LEVEL: device.coordinator.rounded_battery_level,
ATTR_PREVIOUS_BATTERY_LEVEL: device.coordinator.rounded_previous_battery_level,
ATTR_BATTERY_THRESHOLD_REMINDER: True,
},
)

_LOGGER.debug(
"Raised event device %s battery low",
device.coordinator.device_id,
)

hass.services.async_register(
DOMAIN,
SERVICE_BATTERY_REPLACED,
handle_battery_replaced,
schema=SERVICE_BATTERY_REPLACED_SCHEMA,
)

hass.services.async_register(
DOMAIN,
SERVICE_CHECK_BATTERY_LAST_REPORTED,
handle_battery_last_reported,
schema=SERVICE_CHECK_BATTERY_LAST_REPORTED_SCHEMA,
)

hass.services.async_register(
DOMAIN,
SERVICE_CHECK_BATTERY_LOW,
handle_battery_low,
)
Loading

0 comments on commit bb1530e

Please sign in to comment.