Skip to content

Commit 52034a3

Browse files
Round battery (#745)
* Round the battery config option * Round the event battery levels * Delete unused schema now migrated * Change device class of battery_low to show nice coloured icon * Update readme * Update readme * Fix icons.json
1 parent 024e711 commit 52034a3

File tree

8 files changed

+39
-66
lines changed

8 files changed

+39
-66
lines changed

README.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@
88

99
Integration to add battery notes to a device, with automatic discovery via a growing [battery library](library.md) for devices.
1010
Track the battery type, when the battery was replaced and also when a battery is low based on device or global thresholds.
11+
A battery+ sensor provides useful attributes for easy use in dashboards, the standard battery can optionally be hidden.
1112

1213
*Please :star: this repo if you find it useful*
1314
*If you want to show your support please*

custom_components/battery_notes/__init__.py

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -46,6 +46,7 @@
4646
CONF_DEFAULT_BATTERY_LOW_THRESHOLD,
4747
CONF_BATTERY_INCREASE_THRESHOLD,
4848
CONF_HIDE_BATTERY,
49+
CONF_ROUND_BATTERY,
4950
DEFAULT_BATTERY_LOW_THRESHOLD,
5051
DEFAULT_BATTERY_INCREASE_THRESHOLD,
5152
SERVICE_BATTERY_REPLACED,
@@ -72,6 +73,7 @@
7273
vol.Optional(CONF_SHOW_ALL_DEVICES, default=False): cv.boolean,
7374
vol.Optional(CONF_ENABLE_REPLACED, default=True): cv.boolean,
7475
vol.Optional(CONF_HIDE_BATTERY, default=False): cv.boolean,
76+
vol.Optional(CONF_ROUND_BATTERY, default=False): cv.boolean,
7577
vol.Optional(
7678
CONF_DEFAULT_BATTERY_LOW_THRESHOLD,
7779
default=DEFAULT_BATTERY_LOW_THRESHOLD,
@@ -113,6 +115,7 @@ async def async_setup(hass: HomeAssistant, config: ConfigType) -> bool:
113115
CONF_SHOW_ALL_DEVICES: False,
114116
CONF_ENABLE_REPLACED: True,
115117
CONF_HIDE_BATTERY: False,
118+
CONF_ROUND_BATTERY: False,
116119
CONF_DEFAULT_BATTERY_LOW_THRESHOLD: DEFAULT_BATTERY_LOW_THRESHOLD,
117120
CONF_BATTERY_INCREASE_THRESHOLD: DEFAULT_BATTERY_INCREASE_THRESHOLD,
118121
}

custom_components/battery_notes/binary_sensor.py

Lines changed: 20 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,7 @@
1919
PLATFORM_SCHEMA,
2020
BinarySensorEntity,
2121
BinarySensorEntityDescription,
22+
BinarySensorDeviceClass,
2223
)
2324

2425
from homeassistant.helpers.entity import DeviceInfo, EntityCategory
@@ -44,6 +45,7 @@
4445
DOMAIN_CONFIG,
4546
DATA,
4647
CONF_ENABLE_REPLACED,
48+
CONF_ROUND_BATTERY,
4749
CONF_BATTERY_INCREASE_THRESHOLD,
4850
EVENT_BATTERY_THRESHOLD,
4951
EVENT_BATTERY_INCREASED,
@@ -146,9 +148,12 @@ async def async_registry_updated(event: Event) -> None:
146148
device_id = async_add_to_device(hass, config_entry)
147149

148150
enable_replaced = True
151+
round_battery = False
152+
149153
if DOMAIN_CONFIG in hass.data[DOMAIN]:
150154
domain_config: dict = hass.data[DOMAIN][DOMAIN_CONFIG]
151155
enable_replaced = domain_config.get(CONF_ENABLE_REPLACED, True)
156+
round_battery = domain_config.get(CONF_ROUND_BATTERY, False)
152157

153158
description = BatteryNotesBinarySensorEntityDescription(
154159
unique_id_suffix="_battery_low",
@@ -157,6 +162,7 @@ async def async_registry_updated(event: Event) -> None:
157162
icon="mdi:battery-alert",
158163
entity_category=EntityCategory.DIAGNOSTIC,
159164
entity_registry_enabled_default=enable_replaced,
165+
device_class=BinarySensorDeviceClass.BATTERY,
160166
)
161167

162168
device = hass.data[DOMAIN][DATA].devices[config_entry.entry_id]
@@ -170,6 +176,7 @@ async def async_registry_updated(event: Event) -> None:
170176
description,
171177
f"{config_entry.entry_id}{description.unique_id_suffix}",
172178
device,
179+
round_battery,
173180
)
174181
]
175182
)
@@ -202,6 +209,7 @@ def __init__(
202209
description: BatteryNotesBinarySensorEntityDescription,
203210
unique_id: str,
204211
device: BatteryNotesDevice,
212+
round_battery: bool,
205213
) -> None:
206214
"""Create a low battery binary sensor."""
207215
device_registry = dr.async_get(hass)
@@ -210,6 +218,7 @@ def __init__(
210218
self.entity_description = description
211219
self._attr_unique_id = unique_id
212220
self._attr_has_entity_name = True
221+
self.round_battery = round_battery
213222

214223
if coordinator.device_id and (
215224
device_entry := device_registry.async_get(coordinator.device_id)
@@ -261,6 +270,14 @@ async def async_state_changed_listener(
261270

262271
await self.coordinator.async_request_refresh()
263272

273+
if isfloat(wrapped_battery_state.state):
274+
if self.round_battery:
275+
battery_level = int(wrapped_battery_state.state)
276+
else:
277+
battery_level = round(float(wrapped_battery_state.state), 1)
278+
else:
279+
battery_level = wrapped_battery_state.state
280+
264281
if self._previous_state_last_changed:
265282
# Battery low event
266283
if battery_low != self._previous_battery_low:
@@ -273,9 +290,7 @@ async def async_state_changed_listener(
273290
ATTR_BATTERY_TYPE_AND_QUANTITY: self.coordinator.battery_type_and_quantity,
274291
ATTR_BATTERY_TYPE: self.coordinator.battery_type,
275292
ATTR_BATTERY_QUANTITY: self.coordinator.battery_quantity,
276-
ATTR_BATTERY_LEVEL: round(float(wrapped_battery_state.state), 1)
277-
if isfloat(wrapped_battery_state.state)
278-
else wrapped_battery_state.state,
293+
ATTR_BATTERY_LEVEL: battery_level,
279294
ATTR_PREVIOUS_BATTERY_LEVEL: self._previous_battery_level,
280295
},
281296
)
@@ -306,18 +321,14 @@ async def async_state_changed_listener(
306321
ATTR_BATTERY_TYPE_AND_QUANTITY: self.coordinator.battery_type_and_quantity,
307322
ATTR_BATTERY_TYPE: self.coordinator.battery_type,
308323
ATTR_BATTERY_QUANTITY: self.coordinator.battery_quantity,
309-
ATTR_BATTERY_LEVEL: round(
310-
float(wrapped_battery_state.state), 1
311-
)
312-
if isfloat(wrapped_battery_state.state)
313-
else wrapped_battery_state.state,
324+
ATTR_BATTERY_LEVEL: battery_level,
314325
ATTR_PREVIOUS_BATTERY_LEVEL: self._previous_battery_level,
315326
},
316327
)
317328

318329
_LOGGER.debug("battery_increased event fired")
319330

320-
self._previous_battery_level = float(wrapped_battery_state.state)
331+
self._previous_battery_level = battery_level
321332
self._previous_state_last_changed = wrapped_battery_state.last_changed
322333
self._previous_battery_low = battery_low
323334

custom_components/battery_notes/const.py

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -42,6 +42,7 @@
4242
CONF_DEFAULT_BATTERY_LOW_THRESHOLD = "default_battery_low_threshold"
4343
CONF_BATTERY_INCREASE_THRESHOLD = "battery_increase_threshold"
4444
CONF_HIDE_BATTERY = "hide_battery"
45+
CONF_ROUND_BATTERY = "round_battery"
4546

4647
DATA_CONFIGURED_ENTITIES = "configured_entities"
4748
DATA_DISCOVERED_ENTITIES = "discovered_entities"
Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
{
2-
"service": {
2+
"services": {
33
"set_battery_replaced": "mdi:battery-sync"
44
}
55
}

custom_components/battery_notes/sensor.py

Lines changed: 12 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -55,6 +55,7 @@
5555
DOMAIN_CONFIG,
5656
CONF_ENABLE_REPLACED,
5757
CONF_HIDE_BATTERY,
58+
CONF_ROUND_BATTERY,
5859
ATTR_BATTERY_QUANTITY,
5960
ATTR_BATTERY_TYPE,
6061
ATTR_BATTERY_TYPE_AND_QUANTITY,
@@ -157,16 +158,19 @@ async def async_registry_updated(event: Event) -> None:
157158
await coordinator.async_refresh()
158159

159160
enable_replaced = True
161+
round_battery = False
162+
160163
if DOMAIN_CONFIG in hass.data[DOMAIN]:
161164
domain_config: dict = hass.data[DOMAIN][DOMAIN_CONFIG]
162165
enable_replaced = domain_config.get(CONF_ENABLE_REPLACED, True)
166+
round_battery = domain_config.get(CONF_ROUND_BATTERY, False)
163167

164168
battery_plus_sensor_entity_description = BatteryNotesSensorEntityDescription(
165169
unique_id_suffix="_battery_plus",
166170
key="battery_plus",
167171
translation_key="battery_plus",
168172
device_class=SensorDeviceClass.BATTERY,
169-
suggested_display_precision=1,
173+
suggested_display_precision=0 if round_battery else 1,
170174
)
171175

172176
type_sensor_entity_description = BatteryNotesSensorEntityDescription(
@@ -214,6 +218,7 @@ async def async_registry_updated(event: Event) -> None:
214218
f"{config_entry.entry_id}{battery_plus_sensor_entity_description.unique_id_suffix}",
215219
device,
216220
enable_replaced,
221+
round_battery,
217222
)
218223
)
219224

@@ -247,6 +252,7 @@ def __init__(
247252
unique_id: str,
248253
device: BatteryNotesDevice,
249254
enable_replaced: bool,
255+
round_battery: bool,
250256
) -> None:
251257
"""Initialize the sensor."""
252258
super().__init__(coordinator)
@@ -260,6 +266,7 @@ def __init__(
260266
self._attr_unique_id = unique_id
261267
self.device = device
262268
self.enable_replaced = enable_replaced
269+
self.round_battery = round_battery
263270

264271
self._device_id = coordinator.device_id
265272
if coordinator.device_id and (
@@ -313,7 +320,10 @@ def async_state_changed_listener(
313320

314321
self._attr_available = True
315322

316-
self._attr_native_value = round(float(wrapped_battery_state.state), 1)
323+
if self.round_battery:
324+
self._attr_native_value = int(wrapped_battery_state.state)
325+
else:
326+
self._attr_native_value = round(float(wrapped_battery_state.state), 1)
317327

318328
self._wrapped_attributes = wrapped_battery_state.attributes
319329

docs/configuration.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,7 @@ enable_replaced | Boolean | Optional | True | If set to false new devices added
2222
default_battery_low_threshold | Int | Optional | 10 | The default threshold where a devices battery_low entity is set to true and the battery_notes_battery_threshold event is fired, can be overriden per device in device configuration. |
2323
battery_increase_threshold | Int | Optional | 25 | The threshold where the battery_notes_battery_increased event is fired, use this event for battery replaced automations. The threshold is the difference in increase between previous and current battery level. |
2424
hide_battery | Boolean | Optional | False | Hide the standard battery when adding Battery+. This will not effect existing dashboards, automations etc.|
25+
round_battery | Boolean | Optional | False | Round battery+ to whole percentages.|
2526
user_library | String | Optional | | If specified then a user library file will be searched prior to the main library, the user library must be in the same format as the library and placed in the same folder. Only really used for dev purposes. |
2627

2728
# Debug Logging

schema.json

Lines changed: 0 additions & 54 deletions
This file was deleted.

0 commit comments

Comments
 (0)