Skip to content

Commit 88e17f8

Browse files
Refactor (#223)
* Typing * WIP * Combine and short circuit multiple if's * Remove unused code in sensor * Move to minimum HA 2023.8.0 * Lint issues & warnings * Tidy up file operations * Fix config flow after change to library updater * Use extend method rather than loop * Update readme * Tidy up sensors * Fix entity id's getting translated where system language not english * Versino bump
1 parent 8f73a1c commit 88e17f8

File tree

12 files changed

+207
-259
lines changed

12 files changed

+207
-259
lines changed

README.md

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -118,11 +118,12 @@ To add a device definition to the battery library so that it will be automatical
118118

119119
### Submit Definition via GitHub Issues Form
120120

121-
To add a new device via GitHub Issues, fill out [this form (BETA)](https://github.com/andrew-codechimp/HA-Battery-Notes/issues/new?template=new_device_request.yml&title=[Device]%3A+).
121+
To add a new device via GitHub Issues, fill out [this form](https://github.com/andrew-codechimp/HA-Battery-Notes/issues/new?template=new_device_request.yml&title=[Device]%3A+).
122122
Upon submission of the issue, GitHub will attempt to make the required code changes automatically.
123123

124124
### Submit Definition via Pull Request
125-
125+
<details>
126+
<summary>More Details</summary>
126127
If you have issues with the form, or if you feel more comfortable editing JSON data, you can directly add definitions to [the library.json file](custom_components/battery_notes/data/library.json).
127128
Fork the repository, add your device details to the JSON document `custom_components/battery_notes/data/library.json`, and then submit a pull request.
128129
Do not enable GitHub Actions (disabled by default) on your fork as this will mess with the pull request and they are unnecessary for a library submission.
@@ -148,6 +149,7 @@ For the example image below, your JSON entry will look like this:
148149

149150
![Device Details](https://github.com/andrew-codechimp/HA-Battery-Notes/blob/main/images/screenshot-device-info.png "Device Details")
150151
<!---->
152+
</details>
151153

152154
## Contributions are welcome!
153155

custom_components/battery_notes/__init__.py

Lines changed: 9 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -15,14 +15,13 @@
1515
from homeassistant.config_entries import ConfigEntry
1616
from homeassistant.core import HomeAssistant, callback
1717
from homeassistant.const import __version__ as HA_VERSION # noqa: N812
18-
from homeassistant.helpers.aiohttp_client import async_get_clientsession
1918
from homeassistant.helpers.typing import ConfigType
2019
from homeassistant.helpers import device_registry as dr
20+
from homeassistant.util import dt as dt_util
2121

2222
from .discovery import DiscoveryManager
23-
from .library_coordinator import BatteryNotesLibraryUpdateCoordinator
2423
from .library_updater import (
25-
LibraryUpdaterClient,
24+
LibraryUpdater,
2625
)
2726
from .coordinator import BatteryNotesCoordinator
2827
from .store import (
@@ -35,7 +34,7 @@
3534
PLATFORMS,
3635
CONF_ENABLE_AUTODISCOVERY,
3736
CONF_USER_LIBRARY,
38-
DATA_UPDATE_COORDINATOR,
37+
DATA_LIBRARY_UPDATER,
3938
CONF_SHOW_ALL_DEVICES,
4039
CONF_ENABLE_REPLACED,
4140
SERVICE_BATTERY_REPLACED,
@@ -93,12 +92,11 @@ async def async_setup(hass: HomeAssistant, config: ConfigType) -> bool:
9392
coordinator = BatteryNotesCoordinator(hass, store)
9493
hass.data[DOMAIN][DATA_COORDINATOR] = coordinator
9594

96-
library_coordinator = BatteryNotesLibraryUpdateCoordinator(
97-
hass=hass,
98-
client=LibraryUpdaterClient(session=async_get_clientsession(hass)),
99-
)
95+
library_updater = LibraryUpdater(hass)
96+
97+
await library_updater.get_library_updates(dt_util.utcnow())
10098

101-
hass.data[DOMAIN][DATA_UPDATE_COORDINATOR] = library_coordinator
99+
hass.data[DOMAIN][DATA_LIBRARY_UPDATER] = library_updater
102100

103101
await coordinator.async_refresh()
104102

@@ -110,7 +108,6 @@ async def async_setup(hass: HomeAssistant, config: ConfigType) -> bool:
110108

111109
return True
112110

113-
114111
async def async_setup_entry(hass: HomeAssistant, entry: ConfigEntry) -> bool:
115112
"""Set up a config entry."""
116113

@@ -132,7 +129,7 @@ async def async_remove_entry(hass: HomeAssistant, config_entry: ConfigEntry) ->
132129

133130
device_id = config_entry.data["device_id"]
134131

135-
coordinator = hass.data[DOMAIN][DATA_COORDINATOR]
132+
coordinator: BatteryNotesCoordinator = hass.data[DOMAIN][DATA_COORDINATOR]
136133
data = {ATTR_REMOVE: True}
137134

138135
coordinator.async_update_device_config(device_id=device_id, data=data)
@@ -171,14 +168,13 @@ async def handle_battery_replaced(call):
171168
) and entry.domain == DOMAIN:
172169
date_replaced = datetime.utcnow()
173170

174-
coordinator = hass.data[DOMAIN][DATA_COORDINATOR]
171+
coordinator: BatteryNotesCoordinator = hass.data[DOMAIN][DATA_COORDINATOR]
175172
device_entry = {"battery_last_replaced": date_replaced}
176173

177174
coordinator.async_update_device_config(
178175
device_id=device_id, data=device_entry
179176
)
180177

181-
await coordinator._async_update_data()
182178
await coordinator.async_request_refresh()
183179

184180
_LOGGER.debug(

custom_components/battery_notes/button.py

Lines changed: 13 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -41,6 +41,8 @@
4141
CONF_ENABLE_REPLACED,
4242
)
4343

44+
from .coordinator import BatteryNotesCoordinator
45+
4446
from .entity import (
4547
BatteryNotesEntityDescription,
4648
)
@@ -56,17 +58,6 @@ class BatteryNotesButtonEntityDescription(
5658
unique_id_suffix: str
5759

5860

59-
ENTITY_DESCRIPTIONS: tuple[BatteryNotesButtonEntityDescription, ...] = (
60-
BatteryNotesButtonEntityDescription(
61-
unique_id_suffix="_battery_replaced_button",
62-
key="battery_replaced",
63-
translation_key="battery_replaced",
64-
icon="mdi:battery-sync",
65-
entity_category=EntityCategory.DIAGNOSTIC,
66-
entity_registry_enabled_default = False,
67-
),
68-
)
69-
7061
PLATFORM_SCHEMA = PLATFORM_SCHEMA.extend(
7162
{vol.Optional(CONF_NAME): cv.string, vol.Required(CONF_DEVICE_ID): cv.string}
7263
)
@@ -132,7 +123,7 @@ async def async_registry_updated(event: Event) -> None:
132123

133124
enable_replaced = True
134125
if DOMAIN_CONFIG in hass.data[DOMAIN]:
135-
domain_config = hass.data[DOMAIN][DOMAIN_CONFIG]
126+
domain_config: dict = hass.data[DOMAIN][DOMAIN_CONFIG]
136127
enable_replaced = domain_config.get(CONF_ENABLE_REPLACED, True)
137128

138129
description = BatteryNotesButtonEntityDescription(
@@ -141,27 +132,29 @@ async def async_registry_updated(event: Event) -> None:
141132
translation_key="battery_replaced",
142133
icon="mdi:battery-sync",
143134
entity_category=EntityCategory.DIAGNOSTIC,
144-
entity_registry_enabled_default = enable_replaced,
135+
entity_registry_enabled_default=enable_replaced,
145136
)
146137

147138
async_add_entities(
148139
[
149140
BatteryNotesButton(
150-
hass,
151-
description,
152-
f"{config_entry.entry_id}{description.unique_id_suffix}",
153-
device_id,
141+
hass,
142+
description,
143+
f"{config_entry.entry_id}{description.unique_id_suffix}",
144+
device_id,
154145
)
155146
]
156147
)
157148

149+
158150
async def async_setup_platform(
159151
hass: HomeAssistant,
160152
) -> None:
161153
"""Set up the battery note sensor."""
162154

163155
await async_setup_reload_service(hass, DOMAIN, PLATFORMS)
164156

157+
165158
class BatteryNotesButton(ButtonEntity):
166159
"""Represents a battery replaced button."""
167160

@@ -190,11 +183,12 @@ def __init__(
190183
identifiers=device.identifiers,
191184
)
192185

186+
self.entity_id = f"button.{device.name}_{description.key}"
187+
193188
async def async_added_to_hass(self) -> None:
194189
"""Handle added to Hass."""
195190
registry = er.async_get(self.hass)
196191
if registry.async_get(self.entity_id) is not None:
197-
198192
registry.async_update_entity_options(
199193
self.entity_id,
200194
DOMAIN,
@@ -207,8 +201,6 @@ async def async_press(self) -> None:
207201

208202
device_entry = {"battery_last_replaced": datetime.utcnow()}
209203

210-
coordinator = self.hass.data[DOMAIN][DATA_COORDINATOR]
204+
coordinator: BatteryNotesCoordinator = self.hass.data[DOMAIN][DATA_COORDINATOR]
211205
coordinator.async_update_device_config(device_id=device_id, data=device_entry)
212-
await coordinator._async_update_data()
213206
await coordinator.async_request_refresh()
214-

custom_components/battery_notes/config_flow.py

Lines changed: 27 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -16,21 +16,23 @@
1616
from homeassistant.const import Platform
1717
from homeassistant.components.sensor import SensorDeviceClass
1818
import homeassistant.helpers.device_registry as dr
19+
from homeassistant.util import dt as dt_util
1920

2021
from homeassistant.const import (
2122
CONF_NAME,
2223
CONF_DEVICE_ID,
2324
)
2425

2526
from .library import Library
27+
from .library_updater import LibraryUpdater
2628

2729
from .const import (
2830
DOMAIN,
2931
CONF_BATTERY_TYPE,
3032
CONF_DEVICE_NAME,
3133
CONF_MANUFACTURER,
3234
CONF_MODEL,
33-
DATA_UPDATE_COORDINATOR,
35+
DATA_LIBRARY_UPDATER,
3436
DOMAIN_CONFIG,
3537
CONF_SHOW_ALL_DEVICES,
3638
)
@@ -114,10 +116,13 @@ async def async_step_user(
114116

115117
device_id = user_input[CONF_DEVICE_ID]
116118

117-
if DOMAIN in self.hass.data:
118-
if DATA_UPDATE_COORDINATOR in self.hass.data[DOMAIN]:
119-
coordinator = self.hass.data[DOMAIN][DATA_UPDATE_COORDINATOR]
120-
await coordinator.async_refresh()
119+
if (
120+
DOMAIN in self.hass.data
121+
and DATA_LIBRARY_UPDATER in self.hass.data[DOMAIN]
122+
):
123+
library_updater: LibraryUpdater = self.hass.data[DOMAIN][DATA_LIBRARY_UPDATER]
124+
await library_updater.get_library_updates(dt_util.utcnow())
125+
121126

122127
device_registry = dr.async_get(self.hass)
123128
device_entry = device_registry.async_get(device_id)
@@ -132,24 +137,28 @@ async def async_step_user(
132137
device_entry.manufacturer, device_entry.model
133138
)
134139

135-
if device_battery_details:
136-
if not device_battery_details.is_manual:
137-
_LOGGER.debug(
138-
"Found device %s %s", device_entry.manufacturer, device_entry.model
139-
)
140-
self.data[
141-
CONF_BATTERY_TYPE
142-
] = device_battery_details.battery_type_and_quantity
140+
if (
141+
device_battery_details
142+
and not device_battery_details.is_manual
143+
):
144+
_LOGGER.debug(
145+
"Found device %s %s", device_entry.manufacturer, device_entry.model
146+
)
147+
self.data[
148+
CONF_BATTERY_TYPE
149+
] = device_battery_details.battery_type_and_quantity
143150

144151
return await self.async_step_battery()
145152

146153
schema = DEVICE_SCHEMA
147154
# If show_all_devices = is specified and true, don't filter
148-
if DOMAIN in self.hass.data:
149-
if DOMAIN_CONFIG in self.hass.data[DOMAIN]:
150-
domain_config = self.hass.data[DOMAIN][DOMAIN_CONFIG]
151-
if domain_config.get(CONF_SHOW_ALL_DEVICES, False):
152-
schema = DEVICE_SCHEMA_ALL
155+
if (
156+
DOMAIN in self.hass.data
157+
and DOMAIN_CONFIG in self.hass.data[DOMAIN]
158+
):
159+
domain_config: dict = self.hass.data[DOMAIN][DOMAIN_CONFIG]
160+
if domain_config.get(CONF_SHOW_ALL_DEVICES, False):
161+
schema = DEVICE_SCHEMA_ALL
153162

154163
return self.async_show_form(
155164
step_id="user",

custom_components/battery_notes/const.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -39,7 +39,7 @@
3939
DATA_DISCOVERED_ENTITIES = "discovered_entities"
4040
DATA_DOMAIN_ENTITIES = "domain_entities"
4141
DATA_LIBRARY = "library"
42-
DATA_UPDATE_COORDINATOR = "update_coordinator"
42+
DATA_LIBRARY_UPDATER = "library_updater"
4343
DATA_LIBRARY_LAST_UPDATE = "library_last_update"
4444
DATA_COORDINATOR = "coordinator"
4545
DATA_STORE = "store"

custom_components/battery_notes/library.py

Lines changed: 23 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -29,27 +29,29 @@ def __init__(self, hass: HomeAssistant) -> None:
2929
"""Init."""
3030

3131
# User Library
32-
if DOMAIN_CONFIG in hass.data[DOMAIN]:
33-
if CONF_USER_LIBRARY in hass.data[DOMAIN][DOMAIN_CONFIG]:
34-
user_library_filename = hass.data[DOMAIN][DOMAIN_CONFIG].get(CONF_USER_LIBRARY)
35-
if user_library_filename != "":
36-
json_user_path = os.path.join(
37-
BUILT_IN_DATA_DIRECTORY,
38-
user_library_filename,
32+
if (
33+
DOMAIN_CONFIG in hass.data[DOMAIN]
34+
and CONF_USER_LIBRARY in hass.data[DOMAIN][DOMAIN_CONFIG]
35+
):
36+
user_library_filename = hass.data[DOMAIN][DOMAIN_CONFIG].get(CONF_USER_LIBRARY)
37+
if user_library_filename != "":
38+
json_user_path = os.path.join(
39+
BUILT_IN_DATA_DIRECTORY,
40+
user_library_filename,
41+
)
42+
_LOGGER.debug("Using user library file at %s", json_user_path)
43+
44+
try:
45+
with open(json_user_path, encoding="utf-8") as user_file:
46+
user_json_data = json.load(user_file)
47+
self._devices = user_json_data["devices"]
48+
user_file.close()
49+
50+
except FileNotFoundError:
51+
_LOGGER.error(
52+
"User library file not found at %s",
53+
json_user_path,
3954
)
40-
_LOGGER.debug("Using user library file at %s", json_user_path)
41-
42-
try:
43-
with open(json_user_path, encoding="utf-8") as user_file:
44-
user_json_data = json.load(user_file)
45-
self._devices = user_json_data["devices"]
46-
user_file.close()
47-
48-
except FileNotFoundError:
49-
_LOGGER.error(
50-
"User library file not found at %s",
51-
json_user_path,
52-
)
5355

5456
# Default Library
5557
json_default_path = os.path.join(
@@ -61,8 +63,7 @@ def __init__(self, hass: HomeAssistant) -> None:
6163
try:
6264
with open(json_default_path, encoding="utf-8") as default_file:
6365
default_json_data = json.load(default_file)
64-
for i in default_json_data["devices"]:
65-
self._devices.append(i)
66+
self._devices.extend(default_json_data["devices"])
6667
default_file.close()
6768

6869
except FileNotFoundError:

0 commit comments

Comments
 (0)