Skip to content

Commit 69f3bc5

Browse files
andrew-codechimpgithub-actions[bot]crowdin-botjzucker2uvjim
authored
Mypy & R2 (#2439)
* Entity * Description class inheritance * Duplicate definition * Attributes * Missing service return * Service param typing * Entity registry updated * Template sensor * Config flow title * Store * init * Repairs * Typing * Typing * Typing * Check wrapped_battery * Typing * Add dev version suffix to non github packaged versions * Bump HA min version to 2024.10 * Update device: Smart door and window sensor (ZSS-JM-GWM-C-MS) by Moes (#2418) * Apply automatic changes * Update events documentation * Fix doc links * Fix docs links * New Crowdin translations by GitHub Action (#2420) Co-authored-by: Crowdin Bot <[email protected]> * Update device: MCCGQ02HL by Xiaomi (#2422) * Apply automatic changes * New Crowdin translations by GitHub Action (#2424) * New Crowdin translations by GitHub Action (#2425) Co-authored-by: Crowdin Bot <[email protected]> * Adjusting the battery type for the QingPing CGG1 temp sensor (#2427) * New Crowdin translations by GitHub Action (#2429) Co-authored-by: Crowdin Bot <[email protected]> * Update device: Model A by Waveshare (#2431) Co-authored-by: uvjim <[email protected]> * Apply automatic changes * Update device: Meter by SwitchBot (#2433) * Apply automatic changes * New Crowdin translations by GitHub Action (#2436) * Device: Ecowitt - GW2001 (#2435) * Update device: GW2001 by Ecowitt * Update library.json * Apply automatic changes --------- Co-authored-by: mehuman <[email protected]> Co-authored-by: Andrew Jackson <[email protected]> Co-authored-by: andrew-codechimp <[email protected]> * Update device: Duette by Hunter Douglas by Hunter Douglas (#2438) Co-authored-by: marinus61 <[email protected]> * Apply automatic changes * Typing # Conflicts: # custom_components/battery_notes/library_updater.py # Conflicts: # custom_components/battery_notes/library.py * Fix library url * Change to R2 URL --------- Co-authored-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com> Co-authored-by: andrew-codechimp <[email protected]> Co-authored-by: Crowdin Bot <[email protected]> Co-authored-by: Jordan Zucker <[email protected]> Co-authored-by: uvjim <[email protected]> Co-authored-by: mehuman <[email protected]> Co-authored-by: marinus61 <[email protected]>
1 parent fd82401 commit 69f3bc5

20 files changed

+99
-93
lines changed

custom_components/battery_notes/__init__.py

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -136,7 +136,7 @@ async def async_setup(hass: HomeAssistant, config: ConfigType) -> bool:
136136
hass.data[DOMAIN][DATA_LIBRARY_UPDATER] = library_updater
137137

138138
if domain_config.get(CONF_ENABLE_AUTODISCOVERY):
139-
discovery_manager = DiscoveryManager(hass, config)
139+
discovery_manager = DiscoveryManager(hass, domain_config)
140140
await discovery_manager.start_discovery()
141141
else:
142142
_LOGGER.debug("Auto discovery disabled")
@@ -181,7 +181,7 @@ async def async_remove_entry(hass: HomeAssistant, config_entry: ConfigEntry) ->
181181
return
182182

183183
device: BatteryNotesDevice = hass.data[DOMAIN][DATA].devices[config_entry.entry_id]
184-
if not device:
184+
if not device or not device.coordinator.device_id:
185185
return
186186

187187
data = {ATTR_REMOVE: True}
@@ -221,7 +221,7 @@ async def async_migrate_entry(hass: HomeAssistant, config_entry: ConfigEntry):
221221
# Version 1 had a single config for qty & type, split them
222222
_LOGGER.debug("Migrating config entry from version %s", config_entry.version)
223223

224-
matches: re.Match = re.search(
224+
matches = re.search(
225225
r"^(\d+)(?=x)(?:x\s)(\w+$)|([\s\S]+)", config_entry.data[CONF_BATTERY_TYPE]
226226
)
227227
if matches:

custom_components/battery_notes/binary_sensor.py

Lines changed: 6 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -77,7 +77,7 @@
7777
_LOGGER = logging.getLogger(__name__)
7878

7979

80-
@dataclass
80+
@dataclass(frozen=True, kw_only=True)
8181
class BatteryNotesBinarySensorEntityDescription(
8282
BatteryNotesEntityDescription,
8383
BinarySensorEntityDescription,
@@ -123,7 +123,7 @@ async def async_setup_entry(
123123

124124
device_id = config_entry.data.get(CONF_DEVICE_ID)
125125

126-
async def async_registry_updated(event: Event) -> None:
126+
async def async_registry_updated(event: Event[er.EventEntityRegistryUpdatedData]) -> None:
127127
"""Handle entity registry update."""
128128
data = event.data
129129
if data["action"] == "remove":
@@ -177,8 +177,6 @@ async def async_registry_updated(event: Event) -> None:
177177
device_class=BinarySensorDeviceClass.BATTERY,
178178
)
179179

180-
device: BatteryNotesDevice = hass.data[DOMAIN][DATA].devices[config_entry.entry_id]
181-
182180
if coordinator.battery_low_template is not None:
183181
async_add_entities(
184182
[
@@ -314,6 +312,7 @@ class BatteryNotesBatteryLowTemplateSensor(
314312
"""Represents a low battery threshold binary sensor."""
315313

316314
_attr_should_poll = False
315+
_self_ref_update_count = 0
317316

318317
def __init__(
319318
self,
@@ -587,6 +586,8 @@ def _handle_coordinator_update(self) -> None:
587586
"""Handle updated data from the coordinator."""
588587

589588
if (
589+
not self.coordinator.wrapped_battery
590+
or
590591
(
591592
wrapped_battery_state := self.hass.states.get(
592593
self.coordinator.wrapped_battery.entity_id
@@ -616,7 +617,7 @@ def _handle_coordinator_update(self) -> None:
616617
)
617618

618619
@property
619-
def extra_state_attributes(self) -> dict[str, str] | None:
620+
def extra_state_attributes(self) -> dict[str, Any] | None:
620621
"""Return the state attributes of battery low."""
621622

622623
attrs = {

custom_components/battery_notes/button.py

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -58,7 +58,7 @@
5858
_LOGGER = logging.getLogger(__name__)
5959

6060

61-
@dataclass
61+
@dataclass(frozen=True, kw_only=True)
6262
class BatteryNotesButtonEntityDescription(
6363
BatteryNotesEntityDescription,
6464
ButtonEntityDescription,
@@ -104,7 +104,7 @@ async def async_setup_entry(
104104

105105
device_id = config_entry.data.get(CONF_DEVICE_ID, None)
106106

107-
async def async_registry_updated(event: Event) -> None:
107+
async def async_registry_updated(event: Event[er.EventEntityRegistryUpdatedData]) -> None:
108108
"""Handle entity registry update."""
109109
data = event.data
110110
if data["action"] == "remove":

custom_components/battery_notes/config_flow.py

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -515,11 +515,12 @@ async def save_options(
515515
errors["base"] = "orphaned_battery_note"
516516
return errors
517517

518+
title: Any = ""
518519
if CONF_NAME in user_input:
519520
title = user_input.get(CONF_NAME)
520-
elif source_entity_id:
521+
elif source_entity_id and entity_entry:
521522
title = entity_entry.name or entity_entry.original_name
522-
else:
523+
elif device_entry:
523524
title = device_entry.name_by_user or device_entry.name
524525

525526
self._process_user_input(user_input, schema)

custom_components/battery_notes/const.py

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,7 @@
1111

1212
LOGGER: Logger = getLogger(__package__)
1313

14-
MIN_HA_VERSION = "2024.9"
14+
MIN_HA_VERSION = "2024.10"
1515

1616
manifestfile = Path(__file__).parent / "manifest.json"
1717
with open(file=manifestfile, encoding="UTF-8") as json_file:
@@ -30,7 +30,7 @@
3030

3131
DEFAULT_BATTERY_LOW_THRESHOLD = 10
3232
DEFAULT_BATTERY_INCREASE_THRESHOLD = 25
33-
DEFAULT_LIBRARY_URL = "https://raw.githubusercontent.com/andrew-codechimp/HA-Battery-Notes/main/custom_components/battery_notes/data/library.json" # pylint: disable=line-too-long
33+
DEFAULT_LIBRARY_URL = "https://battery-notes-data.codechimp.org/library.json"
3434

3535
CONF_SOURCE_ENTITY_ID = "source_entity_id"
3636
CONF_BATTERY_TYPE = "battery_type"

custom_components/battery_notes/coordinator.py

Lines changed: 11 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -48,25 +48,25 @@
4848
class BatteryNotesCoordinator(DataUpdateCoordinator):
4949
"""Define an object to hold Battery Notes device."""
5050

51-
device_id: str = None
52-
source_entity_id: str = None
51+
device_id: str | None = None
52+
source_entity_id: str | None = None
5353
device_name: str
5454
battery_type: str
5555
battery_quantity: int
5656
battery_low_threshold: int
5757
battery_low_template: str | None
58-
wrapped_battery: RegistryEntry
59-
_current_battery_level: str = None
58+
wrapped_battery: RegistryEntry | None = None
59+
_current_battery_level: str | None = None
6060
enable_replaced: bool = True
6161
_round_battery: bool = False
62-
_previous_battery_low: bool = None
63-
_previous_battery_level: str = None
62+
_previous_battery_low: bool | None = None
63+
_previous_battery_level: str | None = None
6464
_battery_low_template_state: bool = False
65-
_previous_battery_low_template_state: bool = None
66-
_source_entity_name: str = None
65+
_previous_battery_low_template_state: bool | None = None
66+
_source_entity_name: str | None = None
6767

6868
def __init__(
69-
self, hass, store: BatteryNotesStorage, wrapped_battery: RegistryEntry
69+
self, hass, store: BatteryNotesStorage, wrapped_battery: RegistryEntry | None
7070
):
7171
"""Initialize."""
7272
self.store = store
@@ -242,13 +242,13 @@ def last_replaced(self) -> datetime | None:
242242
return None
243243

244244
@last_replaced.setter
245-
def last_replaced(self, value):
245+
def last_replaced(self, value: datetime):
246246
"""Set the last replaced datetime and store it."""
247247
entry = {LAST_REPLACED: value}
248248

249249
if self.source_entity_id:
250250
self.async_update_entity_config(entity_id=self.source_entity_id, data=entry)
251-
else:
251+
elif self.device_id:
252252
self.async_update_device_config(device_id=self.device_id, data=entry)
253253

254254
@property

custom_components/battery_notes/device.py

Lines changed: 9 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@
22

33
import logging
44
from datetime import datetime
5+
from typing import cast
56

67
from homeassistant.components.sensor import DOMAIN as SENSOR_DOMAIN
78
from homeassistant.components.sensor import (
@@ -41,11 +42,11 @@
4142
class BatteryNotesDevice:
4243
"""Manages a Battery Note device."""
4344

44-
config: ConfigEntry = None
45-
store: BatteryNotesStorage = None
46-
coordinator: BatteryNotesCoordinator = None
47-
wrapped_battery: RegistryEntry = None
48-
device_name: str = None
45+
config: ConfigEntry
46+
store: BatteryNotesStorage
47+
coordinator: BatteryNotesCoordinator
48+
wrapped_battery: RegistryEntry | None = None
49+
device_name: str | None = None
4950

5051
def __init__(self, hass: HomeAssistant, config: ConfigEntry) -> None:
5152
"""Initialize the device."""
@@ -205,9 +206,9 @@ async def async_setup(self) -> bool:
205206
self.coordinator.device_id = device_id
206207
self.coordinator.source_entity_id = source_entity_id
207208
self.coordinator.device_name = self.device_name
208-
self.coordinator.battery_type = config.data.get(CONF_BATTERY_TYPE)
209+
self.coordinator.battery_type = cast(str, config.data.get(CONF_BATTERY_TYPE))
209210
try:
210-
self.coordinator.battery_quantity = int(
211+
self.coordinator.battery_quantity = cast(int,
211212
config.data.get(CONF_BATTERY_QUANTITY)
212213
)
213214
except ValueError:
@@ -255,7 +256,7 @@ async def async_setup(self) -> bool:
255256
last_replaced,
256257
)
257258

258-
self.coordinator.last_replaced = last_replaced
259+
self.coordinator.last_replaced = datetime.fromisoformat(last_replaced) if last_replaced else None
259260

260261
# If there is not a last_reported set to now
261262
if not self.coordinator.last_reported:

custom_components/battery_notes/diagnostics.py

Lines changed: 5 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -23,15 +23,16 @@ async def async_get_config_entry_diagnostics(
2323
) -> dict[str, Any]:
2424
"""Return diagnostics for a config entry."""
2525

26-
device_id = config_entry.data.get(CONF_DEVICE_ID, None)
27-
source_entity_id = config_entry.data.get(CONF_SOURCE_ENTITY_ID, None)
28-
2926
device_registry = dr.async_get(hass)
3027
entity_registry = er.async_get(hass)
3128

29+
device_id = config_entry.data.get(CONF_DEVICE_ID, None)
30+
source_entity_id = config_entry.data.get(CONF_SOURCE_ENTITY_ID, None)
31+
3232
if source_entity_id:
3333
entity = entity_registry.async_get(source_entity_id)
34-
device_id = entity.device_id
34+
if entity:
35+
device_id = entity.device_id
3536

3637
diagnostics = {"entry": config_entry.as_dict()}
3738

custom_components/battery_notes/discovery.py

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -53,7 +53,7 @@ async def autodiscover_model(
5353

5454
async def get_model_information(
5555
device_entry: dr.DeviceEntry,
56-
) -> DeviceBatteryDetails | None:
56+
) -> ModelInfo | None:
5757
"""See if we have enough information to automatically setup the battery type."""
5858

5959
manufacturer = device_entry.manufacturer
@@ -129,7 +129,7 @@ def should_process_device(self, device_entry: dr.DeviceEntry) -> bool:
129129
def _init_entity_discovery(
130130
self,
131131
device_entry: dr.DeviceEntry,
132-
device_battery_details: DeviceBatteryDetails | None,
132+
device_battery_details: DeviceBatteryDetails,
133133
) -> None:
134134
"""Dispatch the discovery flow for a given entity."""
135135
existing_entries = [

custom_components/battery_notes/entity.py

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -7,13 +7,13 @@
77
from homeassistant.helpers.entity import EntityDescription
88

99

10-
@dataclass
10+
@dataclass(frozen=True, kw_only=True)
1111
class BatteryNotesRequiredKeysMixin:
1212
"""Mixin for required keys."""
1313

1414
unique_id_suffix: str
1515

1616

17-
@dataclass
17+
@dataclass(frozen=True, kw_only=True)
1818
class BatteryNotesEntityDescription(EntityDescription, BatteryNotesRequiredKeysMixin):
1919
"""Generic Battery Notes entity description."""

0 commit comments

Comments
 (0)