Skip to content

Commit ce880f9

Browse files
authored
Update for HA 2024.11.0 (#922)
1 parent c5d4caa commit ce880f9

File tree

12 files changed

+2489
-996
lines changed

12 files changed

+2489
-996
lines changed

custom_components/google_home/__init__.py

Lines changed: 13 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -7,9 +7,9 @@
77

88
from datetime import timedelta
99
import logging
10+
from typing import cast
1011

1112
from homeassistant.components import zeroconf
12-
from homeassistant.config_entries import ConfigEntry
1313
from homeassistant.const import CONF_PASSWORD, CONF_USERNAME
1414
from homeassistant.core import HomeAssistant
1515
from homeassistant.helpers.aiohttp_client import async_get_clientsession
@@ -29,21 +29,24 @@
2929
UPDATE_INTERVAL,
3030
)
3131
from .models import GoogleHomeDevice
32+
from .types import GoogleHomeConfigEntry
3233

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

3536

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

42-
username: str = entry.data.get(CONF_USERNAME)
43-
password: str = entry.data.get(CONF_PASSWORD)
44-
android_id: str = entry.data.get(CONF_ANDROID_ID)
45-
master_token: str = entry.data.get(CONF_MASTER_TOKEN)
46-
update_interval: int = entry.options.get(CONF_UPDATE_INTERVAL, UPDATE_INTERVAL)
43+
username = cast(str, entry.data.get(CONF_USERNAME))
44+
password = cast(str, entry.data.get(CONF_PASSWORD))
45+
android_id = cast(str, entry.data.get(CONF_ANDROID_ID))
46+
master_token = cast(str, entry.data.get(CONF_MASTER_TOKEN))
47+
update_interval = cast(
48+
int, entry.options.get(CONF_UPDATE_INTERVAL, UPDATE_INTERVAL)
49+
)
4750

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

8588

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

9497

95-
async def async_update_entry(hass: HomeAssistant, entry: ConfigEntry) -> None:
98+
async def async_update_entry(hass: HomeAssistant, entry: GoogleHomeConfigEntry) -> None:
9699
"""Update config entry."""
97100
_LOGGER.debug("Updating entry...")
98101
update_interval: int = entry.options.get(CONF_UPDATE_INTERVAL, UPDATE_INTERVAL)
99102
coordinator: DataUpdateCoordinator[list[GoogleHomeDevice]] = hass.data[DOMAIN][
100103
entry.entry_id
101104
][DATA_COORDINATOR]
102-
coordinator.update_interval = timedelta(seconds=update_interval)
105+
coordinator.update_interval = timedelta(seconds=update_interval) # type: ignore[misc]
103106
_LOGGER.debug(
104107
"Coordinator update interval is: %s", timedelta(seconds=update_interval)
105108
)

custom_components/google_home/api.py

Lines changed: 7 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@
88
import logging
99
from typing import Literal, cast
1010

11-
from aiohttp import ClientError, ClientSession
11+
from aiohttp import ClientError, ClientSession, ClientTimeout
1212
from aiohttp.client_exceptions import ClientConnectorError, ContentTypeError
1313
from glocaltokens.client import Device, GLocalAuthenticationTokens
1414
from glocaltokens.utils.token import is_aas_et
@@ -74,7 +74,7 @@ async def async_get_master_token(self) -> str:
7474
def _get_master_token() -> str | None:
7575
return self._client.get_master_token()
7676

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

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

105-
google_devices = await self.hass.async_add_executor_job(_get_google_devices)
105+
google_devices = await self.hass.async_add_executor_job(_get_google_devices) # type: ignore[arg-type]
106106
self.google_devices = [
107107
GoogleHomeDevice(
108108
device_id=device.device_id,
@@ -121,7 +121,7 @@ async def get_android_id(self) -> str:
121121
def _get_android_id() -> str:
122122
return self._client.get_android_id()
123123

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

126126
@staticmethod
127127
def create_url(ip_address: str, port: int, api_endpoint: str) -> str:
@@ -421,8 +421,9 @@ async def request(
421421
resp = None
422422

423423
try:
424+
timeout = ClientTimeout(total=TIMEOUT)
424425
async with self._session.request(
425-
method, url, json=data, headers=headers, timeout=TIMEOUT
426+
method, url, json=data, headers=headers, timeout=timeout
426427
) as response:
427428
if response.status == HTTPStatus.OK:
428429
try:

custom_components/google_home/config_flow.py

Lines changed: 16 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -4,14 +4,13 @@
44

55
from datetime import timedelta
66
import logging
7+
from typing import Self
78

89
from requests.exceptions import RequestException
910
import voluptuous as vol
1011

11-
from homeassistant import config_entries
12-
from homeassistant.config_entries import ConfigEntry
12+
from homeassistant.config_entries import ConfigFlow, ConfigFlowResult, OptionsFlow
1313
from homeassistant.core import callback
14-
from homeassistant.data_entry_flow import FlowResult
1514
from homeassistant.helpers.aiohttp_client import async_create_clientsession
1615

1716
from .api import GlocaltokensApiClient
@@ -28,23 +27,28 @@
2827
UPDATE_INTERVAL,
2928
)
3029
from .exceptions import InvalidMasterToken
31-
from .types import ConfigFlowDict, OptionsFlowDict
30+
from .types import ConfigFlowDict, GoogleHomeConfigEntry, OptionsFlowDict
3231

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

3534

36-
class GoogleHomeFlowHandler(config_entries.ConfigFlow, domain=DOMAIN):
35+
class GoogleHomeFlowHandler(ConfigFlow, domain=DOMAIN):
3736
"""Config flow for GoogleHome."""
3837

3938
VERSION = 1
4039

4140
def __init__(self) -> None:
4241
"""Initialize."""
42+
self.username: str | None = None
4343
self._errors: dict[str, str] = {}
4444

45+
def is_matching(self, other_flow: Self) -> bool:
46+
"""Return True if other_flow is matching this flow."""
47+
return other_flow.username == self.username
48+
4549
async def async_step_user(
4650
self, user_input: ConfigFlowDict | None = None # type: ignore[override]
47-
) -> FlowResult:
51+
) -> ConfigFlowResult:
4852
"""Handle a flow initialized by the user."""
4953
self._errors = {}
5054

@@ -55,6 +59,7 @@ async def async_step_user(
5559
if user_input is not None:
5660
session = async_create_clientsession(self.hass)
5761
username = user_input.get(CONF_USERNAME, "")
62+
self.username = username
5863
password = user_input.get(CONF_PASSWORD, "")
5964
master_token = user_input.get(CONF_MASTER_TOKEN, "")
6065

@@ -104,11 +109,11 @@ async def async_step_user(
104109
@staticmethod
105110
@callback
106111
def async_get_options_flow(
107-
config_entry: ConfigEntry,
112+
config_entry: GoogleHomeConfigEntry,
108113
) -> GoogleHomeOptionsFlowHandler:
109114
return GoogleHomeOptionsFlowHandler(config_entry)
110115

111-
async def _show_config_form(self) -> FlowResult:
116+
async def _show_config_form(self) -> ConfigFlowResult:
112117
"""Show the configuration form to edit login information."""
113118
return self.async_show_form(
114119
step_id="user",
@@ -143,18 +148,18 @@ async def _get_access_token(client: GlocaltokensApiClient) -> str:
143148
return access_token
144149

145150

146-
class GoogleHomeOptionsFlowHandler(config_entries.OptionsFlow):
151+
class GoogleHomeOptionsFlowHandler(OptionsFlow):
147152
"""Config flow options handler for GoogleHome."""
148153

149-
def __init__(self, config_entry: ConfigEntry):
154+
def __init__(self, config_entry: GoogleHomeConfigEntry):
150155
"""Initialize options flow."""
151156
self.config_entry = config_entry
152157
# Cast from MappingProxy to dict to allow update.
153158
self.options = dict(config_entry.options)
154159

155160
async def async_step_init(
156161
self, user_input: OptionsFlowDict | None = None
157-
) -> FlowResult:
162+
) -> ConfigFlowResult:
158163
"""Manage the options."""
159164
if user_input is not None:
160165
self.options.update(user_input)

custom_components/google_home/entity.py

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -40,17 +40,17 @@ def label(self) -> str:
4040
"""Label to use for name and unique id."""
4141

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

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

5252
@property
53-
def device_info(self) -> DeviceInfo | None:
53+
def device_info(self) -> DeviceInfo | None: # type: ignore[override]
5454
return {
5555
"identifiers": {(DOMAIN, self.device_id)},
5656
"name": f"{DEFAULT_NAME} {self.device_name}",

custom_components/google_home/manifest.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -18,7 +18,7 @@
1818
"iot_class": "cloud_polling",
1919
"issue_tracker": "https://github.com/leikoilja/ha-google-home/issues",
2020
"requirements": [
21-
"glocaltokens==0.7.1"
21+
"glocaltokens==0.7.3"
2222
],
2323
"version": "1.11.1",
2424
"zeroconf": [

custom_components/google_home/number.py

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,6 @@
55
import logging
66

77
from homeassistant.components.number import NumberEntity
8-
from homeassistant.config_entries import ConfigEntry
98
from homeassistant.const import PERCENTAGE
109
from homeassistant.core import HomeAssistant
1110
from homeassistant.helpers.entity import EntityCategory
@@ -26,13 +25,14 @@
2625
)
2726
from .entity import GoogleHomeBaseEntity
2827
from .models import GoogleHomeDevice
28+
from .types import GoogleHomeConfigEntry
2929

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

3232

3333
async def async_setup_entry(
3434
hass: HomeAssistant,
35-
entry: ConfigEntry,
35+
entry: GoogleHomeConfigEntry,
3636
async_add_devices: AddEntitiesCallback,
3737
) -> bool:
3838
"""Setup switch platform."""
@@ -71,7 +71,7 @@ def label(self) -> str:
7171
return LABEL_ALARM_VOLUME
7272

7373
@property
74-
def icon(self) -> str:
74+
def icon(self) -> str: # type: ignore[override]
7575
"""Return the icon of the sensor."""
7676
device = self.get_device()
7777
if device is None:
@@ -86,7 +86,7 @@ def icon(self) -> str:
8686
return ICON_ALARM_VOLUME_HIGH
8787

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

custom_components/google_home/sensor.py

Lines changed: 12 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,6 @@
77
import voluptuous as vol
88

99
from homeassistant.components.sensor import SensorDeviceClass
10-
from homeassistant.config_entries import ConfigEntry
1110
from homeassistant.const import STATE_UNAVAILABLE
1211
from homeassistant.core import HomeAssistant, ServiceCall
1312
from homeassistant.helpers import config_validation as cv, entity_platform
@@ -40,6 +39,7 @@
4039
AlarmsAttributes,
4140
DeviceAttributes,
4241
GoogleHomeAlarmDict,
42+
GoogleHomeConfigEntry,
4343
GoogleHomeTimerDict,
4444
TimersAttributes,
4545
)
@@ -49,7 +49,7 @@
4949

5050
async def async_setup_entry(
5151
hass: HomeAssistant,
52-
entry: ConfigEntry,
52+
entry: GoogleHomeConfigEntry,
5353
async_add_devices: AddEntitiesCallback,
5454
) -> bool:
5555
"""Setup sensor platform."""
@@ -91,21 +91,17 @@ async def async_setup_entry(
9191
platform.async_register_entity_service(
9292
SERVICE_DELETE_ALARM,
9393
{
94-
vol.Required(SERVICE_ATTR_ALARM_ID): cv.string, # type: ignore[dict-item]
95-
vol.Optional(
96-
SERVICE_ATTR_SKIP_REFRESH
97-
): cv.boolean, # type: ignore[dict-item]
94+
vol.Required(SERVICE_ATTR_ALARM_ID): cv.string,
95+
vol.Optional(SERVICE_ATTR_SKIP_REFRESH): cv.boolean,
9896
},
9997
GoogleHomeAlarmsSensor.async_delete_alarm,
10098
)
10199

102100
platform.async_register_entity_service(
103101
SERVICE_DELETE_TIMER,
104102
{
105-
vol.Required(SERVICE_ATTR_TIMER_ID): cv.string, # type: ignore[dict-item]
106-
vol.Optional(
107-
SERVICE_ATTR_SKIP_REFRESH
108-
): cv.boolean, # type: ignore[dict-item]
103+
vol.Required(SERVICE_ATTR_TIMER_ID): cv.string,
104+
vol.Optional(SERVICE_ATTR_SKIP_REFRESH): cv.boolean,
109105
},
110106
GoogleHomeTimersSensor.async_delete_timer,
111107
)
@@ -137,12 +133,12 @@ def label(self) -> str:
137133
return LABEL_DEVICE
138134

139135
@property
140-
def state(self) -> str | None:
136+
def state(self) -> str | None: # type: ignore[override]
141137
device = self.get_device()
142138
return device.ip_address if device else None
143139

144140
@property
145-
def extra_state_attributes(self) -> DeviceAttributes:
141+
def extra_state_attributes(self) -> DeviceAttributes: # type: ignore[override]
146142
"""Return the state attributes."""
147143
device = self.get_device()
148144
attributes: DeviceAttributes = {
@@ -192,7 +188,7 @@ def label(self) -> str:
192188
return LABEL_ALARMS
193189

194190
@property
195-
def state(self) -> str | None:
191+
def state(self) -> str | None: # type: ignore[override]
196192
device = self.get_device()
197193
if not device:
198194
return None
@@ -206,7 +202,7 @@ def state(self) -> str | None:
206202
)
207203

208204
@property
209-
def extra_state_attributes(self) -> AlarmsAttributes:
205+
def extra_state_attributes(self) -> AlarmsAttributes: # type: ignore[override]
210206
"""Return the state attributes."""
211207
return {
212208
"next_alarm_status": self._get_next_alarm_status(),
@@ -277,7 +273,7 @@ def label(self) -> str:
277273
return LABEL_TIMERS
278274

279275
@property
280-
def state(self) -> str | None:
276+
def state(self) -> str | None: # type: ignore[override]
281277
device = self.get_device()
282278
if not device:
283279
return None
@@ -289,7 +285,7 @@ def state(self) -> str | None:
289285
)
290286

291287
@property
292-
def extra_state_attributes(self) -> TimersAttributes:
288+
def extra_state_attributes(self) -> TimersAttributes: # type: ignore[override]
293289
"""Return the state attributes."""
294290
return {
295291
"next_timer_status": self._get_next_timer_status(),

0 commit comments

Comments
 (0)