Skip to content

Commit

Permalink
Quantity (#469)
Browse files Browse the repository at this point in the history
* Migrate to a separate type and quantity

* Streamline check

* Added attribute translations

* Update readme

* Version bump

* Update device: Temperature_and_humidity_sensor_ZG_227Z by TuYa (#427)

Co-authored-by: 4D4M-Github <[email protected]>

* Apply automatic changes

* Update device: SML004 by Signify_Netherlands_B_V (#429)

Co-authored-by: KevinBowdler <[email protected]>

* Apply automatic changes

* Update new_device_request.yml

* Update device: ROM001 by Signify_Netherlands_B_V (#431)

Co-authored-by: KevinBowdler <[email protected]>

* Apply automatic changes

* Update library.json

Remove duplicate

* Apply automatic changes

* Update device: Smart_Valve by Netatmo (#433)

Co-authored-by: hawkcapl <[email protected]>

* Apply automatic changes

* Update device: Smart_button_IH_K663 by TuYa (#435)

Co-authored-by: stijnb1234 <[email protected]>

* Apply automatic changes

* Update device: ZBT_CCTSwitch_D0001 by LDS (#438)

Co-authored-by: m4ha7m4 <[email protected]>

* Apply automatic changes

* Update device: 3450_L by CentraLite (#440)

Co-authored-by: m4ha7m4 <[email protected]>

* Apply automatic changes

* Update device: _TZ3000_qja6nq5z by TS004F (#442)

Co-authored-by: m4ha7m4 <[email protected]>

* Apply automatic changes

* Added Polish translation (#436)

* Update translation for quantity

* Update device: A001082 by LK (#446)

Co-authored-by: m4ha7m4 <[email protected]>

* Apply automatic changes

* Update device: BE468ZP by Allegion (#448)

Co-authored-by: m4ha7m4 <[email protected]>

* Apply automatic changes

* Update device: ZG8101 by Vision_Security (#450)

Co-authored-by: m4ha7m4 <[email protected]>

* Apply automatic changes

* Update device: ZD2105 by Vision_Security (#452)

Co-authored-by: m4ha7m4 <[email protected]>

* Apply automatic changes

* Update device: DMS01 by Elexa_Consumer_Products_Inc (#454)

Co-authored-by: m4ha7m4 <[email protected]>

* Apply automatic changes

* Update device: SPZB0001 by Eurotronic (#456)

Co-authored-by: o0shojo0o <[email protected]>

* Apply automatic changes

* Update device: U_BOLT_PRO_ZWAVE by Ultraloq (#458)

Co-authored-by: m4ha7m4 <[email protected]>

* Apply automatic changes

* Update device: TS0601_thermostat by TuYa (#460)

Co-authored-by: o0shojo0o <[email protected]>

* Apply automatic changes

* Update device: NAS_AB06B2 by Neo (#462)

Co-authored-by: emilianogetino <[email protected]>

* Apply automatic changes

* add missing battery info (#463)

* Apply automatic changes

* Update device: Water_sensor_3315_S by SmartThings (#466)

Co-authored-by: ajaymdesai <[email protected]>

* Apply automatic changes

* Update device: CP1500PFCLCDa by CPS (#468)

Co-authored-by: ajaymdesai <[email protected]>

* Apply automatic changes

* Lint fix

---------

Co-authored-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com>
Co-authored-by: 4D4M-Github <[email protected]>
Co-authored-by: andrew-codechimp <[email protected]>
Co-authored-by: KevinBowdler <[email protected]>
Co-authored-by: hawkcapl <[email protected]>
Co-authored-by: stijnb1234 <[email protected]>
Co-authored-by: m4ha7m4 <[email protected]>
Co-authored-by: pswid <[email protected]>
Co-authored-by: o0shojo0o <[email protected]>
Co-authored-by: emilianogetino <[email protected]>
Co-authored-by: Jean-François Auger <[email protected]>
Co-authored-by: ajaymdesai <[email protected]>
  • Loading branch information
13 people authored Jan 12, 2024
1 parent 5dc8203 commit debf4db
Show file tree
Hide file tree
Showing 12 changed files with 171 additions and 57 deletions.
4 changes: 2 additions & 2 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -22,10 +22,10 @@ Track both the battery type and also when the battery was replaced.

Platform | Name | Description
-- | -- | --
`sensor` | Battery Type | Show battery type.
`sensor` | Battery Type | Show battery type with attributes for separation of type & quantity.
`sensor` | Battery last replaced | Date & Time the battery was last replaced.
`button` | Battery replaced | Update Battery last replaced to now.
`service` | Set battery replaced | Update Battery last replaced.
`service` | Set battery replaced | Update Battery last replaced, optionally set a date other than now.

## Installation

Expand Down
45 changes: 44 additions & 1 deletion custom_components/battery_notes/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@

import homeassistant.helpers.config_validation as cv
import voluptuous as vol
import re

from awesomeversion.awesomeversion import AwesomeVersion
from homeassistant.config_entries import ConfigEntry
Expand All @@ -19,6 +20,8 @@
from homeassistant.helpers import device_registry as dr
from homeassistant.util import dt as dt_util

from .config_flow import CONFIG_VERSION

from .discovery import DiscoveryManager
from .library_updater import (
LibraryUpdater,
Expand All @@ -42,7 +45,9 @@
DATA_COORDINATOR,
ATTR_REMOVE,
ATTR_DEVICE_ID,
ATTR_DATE_TIME_REPLACED
ATTR_DATE_TIME_REPLACED,
CONF_BATTERY_TYPE,
CONF_BATTERY_QUANTITY,
)

MIN_HA_VERSION = "2023.7"
Expand Down Expand Up @@ -137,6 +142,44 @@ async def async_remove_entry(hass: HomeAssistant, config_entry: ConfigEntry) ->
_LOGGER.debug("Removed Device %s", device_id)


async def async_migrate_entry(hass, config_entry: ConfigEntry):
"""Migrate old config."""
new_version = CONFIG_VERSION

if config_entry.version == 1:
# Version 1 had a single config for qty & type, split them
_LOGGER.debug("Migrating config entry from version %s", config_entry.version)

matches: re.Match = re.search(
r"^(\d+)(?=x)(?:x\s)(\w+$)|([\s\S]+)", config_entry.data[CONF_BATTERY_TYPE]
)
if matches:
_qty = matches.group(1) if matches.group(1) is not None else "1"
_type = (
matches.group(2) if matches.group(2) is not None else matches.group(3)
)
else:
_qty = 1
_type = config_entry.data[CONF_BATTERY_TYPE]

new_data = {**config_entry.data}
new_data[CONF_BATTERY_TYPE] = _type
new_data[CONF_BATTERY_QUANTITY] = _qty

config_entry.version = new_version

hass.config_entries.async_update_entry(
config_entry, title=config_entry.title, data=new_data
)

_LOGGER.info(
"Entry %s successfully migrated to version %s.",
config_entry.entry_id,
new_version,
)

return True

@callback
async def async_update_options(hass: HomeAssistant, entry: ConfigEntry) -> None:
"""Update options."""
Expand Down
34 changes: 32 additions & 2 deletions custom_components/battery_notes/config_flow.py
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,7 @@
from .const import (
DOMAIN,
CONF_BATTERY_TYPE,
CONF_BATTERY_QUANTITY,
CONF_DEVICE_NAME,
CONF_MANUFACTURER,
CONF_MODEL,
Expand All @@ -39,6 +40,8 @@

_LOGGER = logging.getLogger(__name__)

CONFIG_VERSION = 2

DEVICE_SCHEMA_ALL = vol.Schema(
{
vol.Required(CONF_DEVICE_ID): selector.DeviceSelector(
Expand Down Expand Up @@ -76,7 +79,7 @@
class BatteryNotesFlowHandler(config_entries.ConfigFlow, domain=DOMAIN):
"""Config flow for BatteryNotes."""

VERSION = 1
VERSION = CONFIG_VERSION

data: dict

Expand Down Expand Up @@ -133,6 +136,9 @@ async def async_step_user(

library = Library.factory(self.hass)

# Set defaults if not found in library
self.data[CONF_BATTERY_QUANTITY] = 1

device_battery_details = await library.get_device_battery_details(
device_entry.manufacturer, device_entry.model
)
Expand All @@ -146,7 +152,11 @@ async def async_step_user(
)
self.data[
CONF_BATTERY_TYPE
] = device_battery_details.battery_type_and_quantity
] = device_battery_details.battery_type

self.data[
CONF_BATTERY_QUANTITY
] = device_battery_details.battery_quantity

return await self.async_step_battery()

Expand All @@ -172,6 +182,7 @@ async def async_step_battery(self, user_input: dict[str, Any] | None = None):
errors: dict[str, str] = {}
if user_input is not None:
self.data[CONF_BATTERY_TYPE] = user_input[CONF_BATTERY_TYPE]
self.data[CONF_BATTERY_QUANTITY] = int(user_input[CONF_BATTERY_QUANTITY])

device_id = self.data[CONF_DEVICE_ID]
unique_id = f"bn_{device_id}"
Expand Down Expand Up @@ -204,6 +215,16 @@ async def async_step_battery(self, user_input: dict[str, Any] | None = None):
type=selector.TextSelectorType.TEXT
),
),
vol.Required(
CONF_BATTERY_QUANTITY,
default=int(self.data.get(CONF_BATTERY_QUANTITY))
): selector.NumberSelector(
selector.NumberSelectorConfig(
min=1,
max=100,
mode=selector.NumberSelectorMode.BOX
),
),
}
),
errors=errors,
Expand All @@ -220,6 +241,7 @@ def __init__(self, config_entry: ConfigEntry) -> None:
self.source_device_id: str = self.current_config.get(CONF_DEVICE_ID) # type: ignore
self.name: str = self.current_config.get(CONF_NAME)
self.battery_type: str = self.current_config.get(CONF_BATTERY_TYPE)
self.battery_quantity: int = self.current_config.get(CONF_BATTERY_QUANTITY)

async def async_step_init(
self,
Expand All @@ -231,6 +253,7 @@ async def async_step_init(

schema = self.build_options_schema()
if user_input is not None:
user_input[CONF_BATTERY_QUANTITY] = int(user_input[CONF_BATTERY_QUANTITY])
errors = await self.save_options(user_input, schema)
if not errors:
return self.async_create_entry(title="", data={})
Expand Down Expand Up @@ -289,6 +312,13 @@ def build_options_schema(self) -> vol.Schema:
vol.Required(CONF_BATTERY_TYPE): selector.TextSelector(
selector.TextSelectorConfig(type=selector.TextSelectorType.TEXT),
),
vol.Required(CONF_BATTERY_QUANTITY): selector.NumberSelector(
selector.NumberSelectorConfig(
min=1,
max=100,
mode=selector.NumberSelectorMode.BOX
),
),
}
)

Expand Down
1 change: 1 addition & 0 deletions custom_components/battery_notes/const.py
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,7 @@
DOMAIN_CONFIG = "config"

CONF_BATTERY_TYPE = "battery_type"
CONF_BATTERY_QUANTITY = "battery_quantity"
CONF_SENSORS = "sensors"
CONF_ENABLE_AUTODISCOVERY = "enable_autodiscovery"
CONF_USER_LIBRARY = "user_library"
Expand Down
2 changes: 1 addition & 1 deletion custom_components/battery_notes/manifest.json
Original file line number Diff line number Diff line change
Expand Up @@ -9,5 +9,5 @@
"integration_type": "device",
"iot_class": "calculated",
"issue_tracker": "https://github.com/andrew-codechimp/ha-battery-notes/issues",
"version": "1.3.5"
"version": "1.4.1"
}
28 changes: 13 additions & 15 deletions custom_components/battery_notes/sensor.py
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,6 @@
from datetime import datetime
from dataclasses import dataclass
import voluptuous as vol
import re

from homeassistant.components.sensor import (
PLATFORM_SCHEMA,
Expand Down Expand Up @@ -40,6 +39,7 @@
DOMAIN,
PLATFORMS,
CONF_BATTERY_TYPE,
CONF_BATTERY_QUANTITY,
DATA_COORDINATOR,
LAST_REPLACED,
DOMAIN_CONFIG,
Expand Down Expand Up @@ -70,6 +70,7 @@ class BatteryNotesSensorEntityDescription(
vol.Optional(CONF_NAME): cv.string,
vol.Required(CONF_DEVICE_ID): cv.string,
vol.Required(CONF_BATTERY_TYPE): cv.string,
vol.Required(CONF_BATTERY_QUANTITY): cv.positive_int,
}
)

Expand All @@ -96,6 +97,10 @@ async def async_setup_entry(

device_id = config_entry.data.get(CONF_DEVICE_ID)
battery_type = config_entry.data.get(CONF_BATTERY_TYPE)
try:
battery_quantity = int(config_entry.data.get(CONF_BATTERY_QUANTITY))
except ValueError:
battery_quantity = 1

async def async_registry_updated(event: Event) -> None:
"""Handle entity registry update."""
Expand Down Expand Up @@ -165,6 +170,7 @@ async def async_registry_updated(event: Event) -> None:
device_id,
f"{config_entry.entry_id}{type_sensor_entity_description.unique_id_suffix}",
battery_type,
battery_quantity,
),
BatteryNotesLastReplacedSensor(
hass,
Expand Down Expand Up @@ -201,6 +207,7 @@ def __init__(
device_id: str,
unique_id: str,
battery_type: str | None = None,
battery_quantity: str | None = None,
) -> None:
"""Initialize the sensor."""
super().__init__()
Expand All @@ -221,6 +228,7 @@ def __init__(
self.entity_id = f"sensor.{device.name}_{description.key}"

self._battery_type = battery_type
self._battery_quantity = battery_quantity

async def async_added_to_hass(self) -> None:
"""Handle added to Hass."""
Expand All @@ -244,27 +252,17 @@ async def async_added_to_hass(self) -> None:
def native_value(self) -> str:
"""Return the native value of the sensor."""

if self._battery_quantity and int(self._battery_quantity) > 1:
return str(self._battery_quantity) + "x " + self._battery_type
return self._battery_type

@property
def extra_state_attributes(self) -> dict[str, str] | None:
"""Return the state attributes of the battery type."""

matches: re.Match = re.search(
r"^(\d+)(?=x)(?:x\s)(\w+$)|([\s\S]+)", self._battery_type
)
if matches:
_qty = matches.group(1) if matches.group(1) is not None else "1"
_type = (
matches.group(2) if matches.group(2) is not None else matches.group(3)
)
else:
_qty = 1
_type = self._battery_type

attrs = {
ATTR_BATTERY_QUANTITY: _qty,
ATTR_BATTERY_TYPE: _type,
ATTR_BATTERY_QUANTITY: self._battery_quantity,
ATTR_BATTERY_TYPE: self._battery_type,
}

super_attrs = super().extra_state_attributes
Expand Down
19 changes: 13 additions & 6 deletions custom_components/battery_notes/translations/da.json
Original file line number Diff line number Diff line change
Expand Up @@ -13,10 +13,8 @@
},
"battery": {
"data": {
"battery_type": "Batteri type"
},
"data_description": {
"battery_type": "Tilføj eventuelt batterimængden, hvis mere end 1 f.eks. 2x AAA"
"battery_type": "Batteri type",
"battery_quantity": "Antal batterier"
}
}
},
Expand All @@ -33,7 +31,8 @@
"description": "Hvis du har brug for hjælp til konfigurationen, så kig her: https://github.com/andrew-codechimp/ha-battery-notes",
"data": {
"name": "Navn",
"battery_type": "Batteri type"
"battery_type": "Batteri type",
"battery_quantity": "Antal batterier"
},
"data_description": {
"name": "Hvis du lader det være tomt, hentes navnet fra kildeenheden"
Expand All @@ -52,7 +51,15 @@
},
"sensor": {
"battery_type": {
"name": "Batteri type"
"name": "Batteri type",
"state_attributes": {
"battery_type": {
"name": "Batteri type"
},
"battery_quantity": {
"name": "Antal batterier"
}
}
},
"battery_last_replaced": {
"name": "Batteri sidst skiftet"
Expand Down
19 changes: 13 additions & 6 deletions custom_components/battery_notes/translations/de.json
Original file line number Diff line number Diff line change
Expand Up @@ -13,10 +13,8 @@
},
"battery": {
"data": {
"battery_type": "Batterieart"
},
"data_description": {
"battery_type": "Optional: Anzahl der Batterien eingeben, wenn es mehr als eine Batterie ist, z. B. 2x AAA"
"battery_type": "Batterieart",
"battery_quantity": "Batteriemenge"
}
}
},
Expand All @@ -33,7 +31,8 @@
"description": "Hilfe zur Konfiguration findest du unter: https://github.com/andrew-codechimp/ha-battery-notes",
"data": {
"name": "Name",
"battery_type": "Batterieart"
"battery_type": "Batterieart",
"battery_quantity": "Batteriemenge"
},
"data_description": {
"name": "Wenn du nichts eingibst, wird der Name vom Quellgerät übernommen"
Expand All @@ -52,7 +51,15 @@
},
"sensor": {
"battery_type": {
"name": "Batterieart"
"name": "Batterieart",
"state_attributes": {
"battery_type": {
"name": "Batterieart"
},
"battery_quantity": {
"name": "Batteriemenge"
}
}
},
"battery_last_replaced": {
"name": "Batterie zuletzt ersetzt"
Expand Down
Loading

0 comments on commit debf4db

Please sign in to comment.