Skip to content

Commit

Permalink
Update for HA 2024.11.0 (#922)
Browse files Browse the repository at this point in the history
  • Loading branch information
KapJI authored Nov 5, 2024
1 parent c5d4caa commit ce880f9
Show file tree
Hide file tree
Showing 12 changed files with 2,489 additions and 996 deletions.
23 changes: 13 additions & 10 deletions custom_components/google_home/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -7,9 +7,9 @@

from datetime import timedelta
import logging
from typing import cast

from homeassistant.components import zeroconf
from homeassistant.config_entries import ConfigEntry
from homeassistant.const import CONF_PASSWORD, CONF_USERNAME
from homeassistant.core import HomeAssistant
from homeassistant.helpers.aiohttp_client import async_get_clientsession
Expand All @@ -29,21 +29,24 @@
UPDATE_INTERVAL,
)
from .models import GoogleHomeDevice
from .types import GoogleHomeConfigEntry

_LOGGER: logging.Logger = logging.getLogger(__package__)


async def async_setup_entry(hass: HomeAssistant, entry: ConfigEntry) -> bool:
async def async_setup_entry(hass: HomeAssistant, entry: GoogleHomeConfigEntry) -> bool:
"""Set up this integration using UI."""
if hass.data.get(DOMAIN) is None:
hass.data.setdefault(DOMAIN, {})
_LOGGER.info(STARTUP_MESSAGE)

username: str = entry.data.get(CONF_USERNAME)
password: str = entry.data.get(CONF_PASSWORD)
android_id: str = entry.data.get(CONF_ANDROID_ID)
master_token: str = entry.data.get(CONF_MASTER_TOKEN)
update_interval: int = entry.options.get(CONF_UPDATE_INTERVAL, UPDATE_INTERVAL)
username = cast(str, entry.data.get(CONF_USERNAME))
password = cast(str, entry.data.get(CONF_PASSWORD))
android_id = cast(str, entry.data.get(CONF_ANDROID_ID))
master_token = cast(str, entry.data.get(CONF_MASTER_TOKEN))
update_interval = cast(
int, entry.options.get(CONF_UPDATE_INTERVAL, UPDATE_INTERVAL)
)

_LOGGER.debug(
"Coordinator update interval is: %s", timedelta(seconds=update_interval)
Expand Down Expand Up @@ -83,7 +86,7 @@ async def async_setup_entry(hass: HomeAssistant, entry: ConfigEntry) -> bool:
return True


async def async_unload_entry(hass: HomeAssistant, entry: ConfigEntry) -> bool:
async def async_unload_entry(hass: HomeAssistant, entry: GoogleHomeConfigEntry) -> bool:
"""Handle removal of an entry."""
_LOGGER.debug("Unloading entry...")
unload_ok = await hass.config_entries.async_unload_platforms(entry, PLATFORMS)
Expand All @@ -92,14 +95,14 @@ async def async_unload_entry(hass: HomeAssistant, entry: ConfigEntry) -> bool:
return unload_ok


async def async_update_entry(hass: HomeAssistant, entry: ConfigEntry) -> None:
async def async_update_entry(hass: HomeAssistant, entry: GoogleHomeConfigEntry) -> None:
"""Update config entry."""
_LOGGER.debug("Updating entry...")
update_interval: int = entry.options.get(CONF_UPDATE_INTERVAL, UPDATE_INTERVAL)
coordinator: DataUpdateCoordinator[list[GoogleHomeDevice]] = hass.data[DOMAIN][
entry.entry_id
][DATA_COORDINATOR]
coordinator.update_interval = timedelta(seconds=update_interval)
coordinator.update_interval = timedelta(seconds=update_interval) # type: ignore[misc]
_LOGGER.debug(
"Coordinator update interval is: %s", timedelta(seconds=update_interval)
)
13 changes: 7 additions & 6 deletions custom_components/google_home/api.py
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@
import logging
from typing import Literal, cast

from aiohttp import ClientError, ClientSession
from aiohttp import ClientError, ClientSession, ClientTimeout
from aiohttp.client_exceptions import ClientConnectorError, ContentTypeError
from glocaltokens.client import Device, GLocalAuthenticationTokens
from glocaltokens.utils.token import is_aas_et
Expand Down Expand Up @@ -74,7 +74,7 @@ async def async_get_master_token(self) -> str:
def _get_master_token() -> str | None:
return self._client.get_master_token()

master_token = await self.hass.async_add_executor_job(_get_master_token)
master_token = await self.hass.async_add_executor_job(_get_master_token) # type: ignore[arg-type]
if master_token is None or is_aas_et(master_token) is False:
raise InvalidMasterToken
return master_token
Expand All @@ -85,7 +85,7 @@ async def async_get_access_token(self) -> str:
def _get_access_token() -> str | None:
return self._client.get_access_token()

access_token = await self.hass.async_add_executor_job(_get_access_token)
access_token = await self.hass.async_add_executor_job(_get_access_token) # type: ignore[arg-type]
if access_token is None:
raise InvalidMasterToken
return access_token
Expand All @@ -102,7 +102,7 @@ def _get_google_devices() -> list[Device]:
force_homegraph_reload=True,
)

google_devices = await self.hass.async_add_executor_job(_get_google_devices)
google_devices = await self.hass.async_add_executor_job(_get_google_devices) # type: ignore[arg-type]
self.google_devices = [
GoogleHomeDevice(
device_id=device.device_id,
Expand All @@ -121,7 +121,7 @@ async def get_android_id(self) -> str:
def _get_android_id() -> str:
return self._client.get_android_id()

return await self.hass.async_add_executor_job(_get_android_id)
return await self.hass.async_add_executor_job(_get_android_id) # type: ignore[arg-type]

@staticmethod
def create_url(ip_address: str, port: int, api_endpoint: str) -> str:
Expand Down Expand Up @@ -421,8 +421,9 @@ async def request(
resp = None

try:
timeout = ClientTimeout(total=TIMEOUT)
async with self._session.request(
method, url, json=data, headers=headers, timeout=TIMEOUT
method, url, json=data, headers=headers, timeout=timeout
) as response:
if response.status == HTTPStatus.OK:
try:
Expand Down
27 changes: 16 additions & 11 deletions custom_components/google_home/config_flow.py
Original file line number Diff line number Diff line change
Expand Up @@ -4,14 +4,13 @@

from datetime import timedelta
import logging
from typing import Self

from requests.exceptions import RequestException
import voluptuous as vol

from homeassistant import config_entries
from homeassistant.config_entries import ConfigEntry
from homeassistant.config_entries import ConfigFlow, ConfigFlowResult, OptionsFlow
from homeassistant.core import callback
from homeassistant.data_entry_flow import FlowResult
from homeassistant.helpers.aiohttp_client import async_create_clientsession

from .api import GlocaltokensApiClient
Expand All @@ -28,23 +27,28 @@
UPDATE_INTERVAL,
)
from .exceptions import InvalidMasterToken
from .types import ConfigFlowDict, OptionsFlowDict
from .types import ConfigFlowDict, GoogleHomeConfigEntry, OptionsFlowDict

_LOGGER: logging.Logger = logging.getLogger(__package__)


class GoogleHomeFlowHandler(config_entries.ConfigFlow, domain=DOMAIN):
class GoogleHomeFlowHandler(ConfigFlow, domain=DOMAIN):
"""Config flow for GoogleHome."""

VERSION = 1

def __init__(self) -> None:
"""Initialize."""
self.username: str | None = None
self._errors: dict[str, str] = {}

def is_matching(self, other_flow: Self) -> bool:
"""Return True if other_flow is matching this flow."""
return other_flow.username == self.username

async def async_step_user(
self, user_input: ConfigFlowDict | None = None # type: ignore[override]
) -> FlowResult:
) -> ConfigFlowResult:
"""Handle a flow initialized by the user."""
self._errors = {}

Expand All @@ -55,6 +59,7 @@ async def async_step_user(
if user_input is not None:
session = async_create_clientsession(self.hass)
username = user_input.get(CONF_USERNAME, "")
self.username = username
password = user_input.get(CONF_PASSWORD, "")
master_token = user_input.get(CONF_MASTER_TOKEN, "")

Expand Down Expand Up @@ -104,11 +109,11 @@ async def async_step_user(
@staticmethod
@callback
def async_get_options_flow(
config_entry: ConfigEntry,
config_entry: GoogleHomeConfigEntry,
) -> GoogleHomeOptionsFlowHandler:
return GoogleHomeOptionsFlowHandler(config_entry)

async def _show_config_form(self) -> FlowResult:
async def _show_config_form(self) -> ConfigFlowResult:
"""Show the configuration form to edit login information."""
return self.async_show_form(
step_id="user",
Expand Down Expand Up @@ -143,18 +148,18 @@ async def _get_access_token(client: GlocaltokensApiClient) -> str:
return access_token


class GoogleHomeOptionsFlowHandler(config_entries.OptionsFlow):
class GoogleHomeOptionsFlowHandler(OptionsFlow):
"""Config flow options handler for GoogleHome."""

def __init__(self, config_entry: ConfigEntry):
def __init__(self, config_entry: GoogleHomeConfigEntry):
"""Initialize options flow."""
self.config_entry = config_entry
# Cast from MappingProxy to dict to allow update.
self.options = dict(config_entry.options)

async def async_step_init(
self, user_input: OptionsFlowDict | None = None
) -> FlowResult:
) -> ConfigFlowResult:
"""Manage the options."""
if user_input is not None:
self.options.update(user_input)
Expand Down
6 changes: 3 additions & 3 deletions custom_components/google_home/entity.py
Original file line number Diff line number Diff line change
Expand Up @@ -40,17 +40,17 @@ def label(self) -> str:
"""Label to use for name and unique id."""

@property
def name(self) -> str:
def name(self) -> str: # type: ignore[override]
"""Return the name of the sensor."""
return f"{self.device_name} {self.label}"

@property
def unique_id(self) -> str:
def unique_id(self) -> str: # type: ignore[override]
"""Return a unique ID to use for this entity."""
return f"{self.device_id}/{self.label}"

@property
def device_info(self) -> DeviceInfo | None:
def device_info(self) -> DeviceInfo | None: # type: ignore[override]
return {
"identifiers": {(DOMAIN, self.device_id)},
"name": f"{DEFAULT_NAME} {self.device_name}",
Expand Down
2 changes: 1 addition & 1 deletion custom_components/google_home/manifest.json
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@
"iot_class": "cloud_polling",
"issue_tracker": "https://github.com/leikoilja/ha-google-home/issues",
"requirements": [
"glocaltokens==0.7.1"
"glocaltokens==0.7.3"
],
"version": "1.11.1",
"zeroconf": [
Expand Down
8 changes: 4 additions & 4 deletions custom_components/google_home/number.py
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,6 @@
import logging

from homeassistant.components.number import NumberEntity
from homeassistant.config_entries import ConfigEntry
from homeassistant.const import PERCENTAGE
from homeassistant.core import HomeAssistant
from homeassistant.helpers.entity import EntityCategory
Expand All @@ -26,13 +25,14 @@
)
from .entity import GoogleHomeBaseEntity
from .models import GoogleHomeDevice
from .types import GoogleHomeConfigEntry

_LOGGER: logging.Logger = logging.getLogger(__package__)


async def async_setup_entry(
hass: HomeAssistant,
entry: ConfigEntry,
entry: GoogleHomeConfigEntry,
async_add_devices: AddEntitiesCallback,
) -> bool:
"""Setup switch platform."""
Expand Down Expand Up @@ -71,7 +71,7 @@ def label(self) -> str:
return LABEL_ALARM_VOLUME

@property
def icon(self) -> str:
def icon(self) -> str: # type: ignore[override]
"""Return the icon of the sensor."""
device = self.get_device()
if device is None:
Expand All @@ -86,7 +86,7 @@ def icon(self) -> str:
return ICON_ALARM_VOLUME_HIGH

@property
def native_value(self) -> float:
def native_value(self) -> float: # type: ignore[override]
"""Return the current volume value."""
device = self.get_device()

Expand Down
28 changes: 12 additions & 16 deletions custom_components/google_home/sensor.py
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,6 @@
import voluptuous as vol

from homeassistant.components.sensor import SensorDeviceClass
from homeassistant.config_entries import ConfigEntry
from homeassistant.const import STATE_UNAVAILABLE
from homeassistant.core import HomeAssistant, ServiceCall
from homeassistant.helpers import config_validation as cv, entity_platform
Expand Down Expand Up @@ -40,6 +39,7 @@
AlarmsAttributes,
DeviceAttributes,
GoogleHomeAlarmDict,
GoogleHomeConfigEntry,
GoogleHomeTimerDict,
TimersAttributes,
)
Expand All @@ -49,7 +49,7 @@

async def async_setup_entry(
hass: HomeAssistant,
entry: ConfigEntry,
entry: GoogleHomeConfigEntry,
async_add_devices: AddEntitiesCallback,
) -> bool:
"""Setup sensor platform."""
Expand Down Expand Up @@ -91,21 +91,17 @@ async def async_setup_entry(
platform.async_register_entity_service(
SERVICE_DELETE_ALARM,
{
vol.Required(SERVICE_ATTR_ALARM_ID): cv.string, # type: ignore[dict-item]
vol.Optional(
SERVICE_ATTR_SKIP_REFRESH
): cv.boolean, # type: ignore[dict-item]
vol.Required(SERVICE_ATTR_ALARM_ID): cv.string,
vol.Optional(SERVICE_ATTR_SKIP_REFRESH): cv.boolean,
},
GoogleHomeAlarmsSensor.async_delete_alarm,
)

platform.async_register_entity_service(
SERVICE_DELETE_TIMER,
{
vol.Required(SERVICE_ATTR_TIMER_ID): cv.string, # type: ignore[dict-item]
vol.Optional(
SERVICE_ATTR_SKIP_REFRESH
): cv.boolean, # type: ignore[dict-item]
vol.Required(SERVICE_ATTR_TIMER_ID): cv.string,
vol.Optional(SERVICE_ATTR_SKIP_REFRESH): cv.boolean,
},
GoogleHomeTimersSensor.async_delete_timer,
)
Expand Down Expand Up @@ -137,12 +133,12 @@ def label(self) -> str:
return LABEL_DEVICE

@property
def state(self) -> str | None:
def state(self) -> str | None: # type: ignore[override]
device = self.get_device()
return device.ip_address if device else None

@property
def extra_state_attributes(self) -> DeviceAttributes:
def extra_state_attributes(self) -> DeviceAttributes: # type: ignore[override]
"""Return the state attributes."""
device = self.get_device()
attributes: DeviceAttributes = {
Expand Down Expand Up @@ -192,7 +188,7 @@ def label(self) -> str:
return LABEL_ALARMS

@property
def state(self) -> str | None:
def state(self) -> str | None: # type: ignore[override]
device = self.get_device()
if not device:
return None
Expand All @@ -206,7 +202,7 @@ def state(self) -> str | None:
)

@property
def extra_state_attributes(self) -> AlarmsAttributes:
def extra_state_attributes(self) -> AlarmsAttributes: # type: ignore[override]
"""Return the state attributes."""
return {
"next_alarm_status": self._get_next_alarm_status(),
Expand Down Expand Up @@ -277,7 +273,7 @@ def label(self) -> str:
return LABEL_TIMERS

@property
def state(self) -> str | None:
def state(self) -> str | None: # type: ignore[override]
device = self.get_device()
if not device:
return None
Expand All @@ -289,7 +285,7 @@ def state(self) -> str | None:
)

@property
def extra_state_attributes(self) -> TimersAttributes:
def extra_state_attributes(self) -> TimersAttributes: # type: ignore[override]
"""Return the state attributes."""
return {
"next_timer_status": self._get_next_timer_status(),
Expand Down
Loading

0 comments on commit ce880f9

Please sign in to comment.