-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Add a service to get hourly usage history
- Loading branch information
Showing
9 changed files
with
1,758 additions
and
12 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,140 @@ | ||
"""Support for the WaterSmart integration.""" | ||
|
||
from datetime import date, datetime | ||
from functools import partial | ||
from typing import Final | ||
|
||
import voluptuous as vol | ||
|
||
from homeassistant.config_entries import ConfigEntry, ConfigEntryState | ||
from homeassistant.core import ( | ||
HomeAssistant, | ||
ServiceCall, | ||
ServiceResponse, | ||
SupportsResponse, | ||
callback, | ||
) | ||
from homeassistant.exceptions import ServiceValidationError | ||
from homeassistant.helpers import selector | ||
from homeassistant.util import dt | ||
|
||
from .const import DOMAIN | ||
from .coordinator import ( | ||
WaterSmartUpdateCoordinator, | ||
_from_timestamp, | ||
_serialize_records, | ||
) | ||
from .types import WaterSmartData | ||
|
||
ATTR_CONFIG_ENTRY: Final = "config_entry" | ||
ATTR_FROM_CACHE: Final = "cached" | ||
ATTR_START: Final = "start" | ||
ATTR_END: Final = "end" | ||
HOURLY_HISTORY_SERVICE_NAME: Final = "get_water_usage_hourly_history" | ||
|
||
SERVICE_SCHEMA: Final = vol.Schema( | ||
{ | ||
vol.Required(ATTR_CONFIG_ENTRY): selector.ConfigEntrySelector( | ||
{ | ||
"integration": DOMAIN, | ||
} | ||
), | ||
vol.Optional(ATTR_FROM_CACHE): bool, | ||
vol.Optional(ATTR_START): vol.Any(str, int), | ||
vol.Optional(ATTR_END): vol.Any(str, int), | ||
} | ||
) | ||
|
||
|
||
def __get_date(date_input: str | int | None) -> date | datetime | None: | ||
"""Get date.""" | ||
|
||
if not date_input: | ||
return None | ||
|
||
if isinstance(date_input, int) and (value := dt.utc_from_timestamp(date_input)): | ||
return value | ||
|
||
if isinstance(date_input, str) and (value := dt.parse_datetime(date_input)): | ||
return value | ||
|
||
raise ServiceValidationError( | ||
translation_domain=DOMAIN, | ||
translation_key="invalid_date", | ||
translation_placeholders={ | ||
"date": date_input, | ||
}, | ||
) | ||
|
||
|
||
def __get_coordinator( | ||
hass: HomeAssistant, call: ServiceCall | ||
) -> WaterSmartUpdateCoordinator: | ||
"""Get the coordinator from the entry.""" | ||
|
||
entry_id: str = call.data[ATTR_CONFIG_ENTRY] | ||
entry: ConfigEntry | None = hass.config_entries.async_get_entry(entry_id) | ||
|
||
if not entry: | ||
raise ServiceValidationError( | ||
translation_domain=DOMAIN, | ||
translation_key="invalid_config_entry", | ||
translation_placeholders={ | ||
"config_entry": entry_id, | ||
}, | ||
) | ||
|
||
if entry.state != ConfigEntryState.LOADED: | ||
raise ServiceValidationError( | ||
translation_domain=DOMAIN, | ||
translation_key="unloaded_config_entry", | ||
translation_placeholders={ | ||
"config_entry": entry.title, | ||
}, | ||
) | ||
|
||
runtime_data: WaterSmartData = hass.data[DOMAIN][entry_id] | ||
|
||
return runtime_data.coordinator | ||
|
||
|
||
async def __get_hourly_history( | ||
call: ServiceCall, | ||
*, | ||
hass: HomeAssistant, | ||
) -> ServiceResponse: | ||
coordinator = __get_coordinator(hass, call) | ||
|
||
start = __get_date(call.data.get(ATTR_START)) | ||
end = __get_date(call.data.get(ATTR_END)) | ||
|
||
if call.data.get(ATTR_FROM_CACHE) is False: | ||
await coordinator.async_refresh() | ||
|
||
records = [] | ||
|
||
for record in coordinator.data["hourly"]: | ||
record_date = _from_timestamp(record["read_datetime"]) | ||
|
||
if start and dt.as_local(record_date) < dt.as_local(start): | ||
continue | ||
|
||
if end and dt.as_local(record_date) > dt.as_local(end): | ||
continue | ||
|
||
records.append(record) | ||
|
||
return {"history": _serialize_records(records)} | ||
|
||
|
||
@callback | ||
def async_setup_services(hass: HomeAssistant) -> None: | ||
"""Set up WaterSmart services.""" | ||
|
||
hass.services.async_register( | ||
DOMAIN, | ||
HOURLY_HISTORY_SERVICE_NAME, | ||
partial(__get_hourly_history, hass=hass), | ||
schema=SERVICE_SCHEMA, | ||
supports_response=SupportsResponse.ONLY, | ||
) |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,22 @@ | ||
get_water_usage_hourly_history: | ||
fields: | ||
config_entry: | ||
required: true | ||
selector: | ||
config_entry: | ||
integration: watersmart | ||
cached: | ||
required: false | ||
default: false | ||
selector: | ||
boolean: | ||
start: | ||
required: false | ||
example: "2024-01-01 00:00:00" | ||
selector: | ||
datetime: | ||
end: | ||
required: false | ||
example: "2024-01-01 00:00:00" | ||
selector: | ||
datetime: |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,17 @@ | ||
"""WaterSmart dataclasses and typing.""" | ||
|
||
from __future__ import annotations | ||
|
||
from dataclasses import dataclass | ||
from homeassistant.config_entries import ConfigEntry | ||
|
||
from .coordinator import WaterSmartUpdateCoordinator | ||
|
||
type WaterSmartConfigEntry = ConfigEntry[WaterSmartData] | ||
|
||
|
||
@dataclass | ||
class WaterSmartData: | ||
"""Runtime data definition.""" | ||
|
||
coordinator: WaterSmartUpdateCoordinator |
Oops, something went wrong.