Skip to content

Commit

Permalink
v0.10.0
Browse files Browse the repository at this point in the history
  • Loading branch information
dudanov committed Nov 17, 2024
1 parent 2c781d0 commit 4ef3aa7
Show file tree
Hide file tree
Showing 7 changed files with 296 additions and 57 deletions.
46 changes: 26 additions & 20 deletions custom_components/elehant/config_flow.py
Original file line number Diff line number Diff line change
Expand Up @@ -9,11 +9,12 @@
BluetoothServiceInfoBleak,
async_discovered_service_info,
)
from homeassistant.const import CONF_ADDRESS
from homeassistant.const import CONF_UNIQUE_ID
from homeassistant.data_entry_flow import FlowResult

from .const import DOMAIN
from .elehant import ElehantData, ElehantError
from .helpers import get_device_name

_LOGGER = logging.getLogger(__name__)

Expand All @@ -32,28 +33,28 @@ def __init__(self) -> None:
async def async_step_bluetooth(self, info: BluetoothServiceInfoBleak) -> FlowResult:
"""Handle the Bluetooth discovery step."""

await self.async_set_unique_id(info.address)
self._abort_if_unique_id_configured()

try:
self._discovered_device = ElehantData.from_ble(
info.device, info.advertisement
)
device = ElehantData.from_ble(info.device, info.advertisement)

except ElehantError:
return self.async_abort(reason="not_supported")

await self.async_set_unique_id(info.address)
self._discovered_device = device

return await self.async_step_bluetooth_confirm()

async def async_step_bluetooth_confirm(
self, user_input: dict[str, Any] | None = None
) -> FlowResult:
"""Confirm discovery."""
assert (dev := self._discovered_device)
assert (device := self._discovered_device)

if user_input is not None:
return self.async_create_entry(title=dev.unique_id, data={})
return self.async_create_entry(title=device.unique_id, data={})

name = await get_device_name(self.hass, device)
self.context["title_placeholders"] = {"name": name}
self._set_confirm_only()

return self.async_show_form(step_id="bluetooth_confirm")
Expand All @@ -63,36 +64,41 @@ async def async_step_user(
) -> FlowResult:
"""Handle the user step to pick discovered device."""
if user_input is not None:
address = user_input[CONF_ADDRESS]
dev = self._discovered_devices[address]
unique_id = user_input[CONF_UNIQUE_ID]
device = self._discovered_devices[unique_id]

await self.async_set_unique_id(address, raise_on_progress=False)
await self.async_set_unique_id(device.address, raise_on_progress=False)
self._abort_if_unique_id_configured()

return self.async_create_entry(title=dev.unique_id, data={})
return self.async_create_entry(title=device.unique_id, data={})

current_addresses = self._async_current_ids()
current_ids = self._async_current_ids()

for info in async_discovered_service_info(self.hass, False):
address = info.address

if address in current_addresses or address in self._discovered_devices:
if info.address in current_ids:
continue

try:
dev = ElehantData.from_ble(info.device, info.advertisement)
device = ElehantData.from_ble(info.device, info.advertisement)

except ElehantError:
continue

self._discovered_devices[address] = dev
self._discovered_devices[device.unique_id] = device

if not self._discovered_devices:
return self.async_abort(reason="no_devices_found")

return self.async_show_form(
step_id="user",
data_schema=vol.Schema(
{vol.Required(CONF_ADDRESS): vol.In(self._discovered_devices)}
{
vol.Required(CONF_UNIQUE_ID): vol.In(
{
k: await get_device_name(self.hass, v)
for k, v in self._discovered_devices.items()
}
)
}
),
)
25 changes: 13 additions & 12 deletions custom_components/elehant/elehant.py
Original file line number Diff line number Diff line change
Expand Up @@ -29,20 +29,20 @@ class ElehantData:

_: dc.KW_ONLY

firmware: str
"""Версия ПО"""
sw_version: str
"""Версия прошивки"""
battery: int
"""Состояние батареи"""
"""Уровень заряда батареи"""
temperature: float
"""Температура среды"""
value_1: float
"""Показания 1"""
"""Показание 1"""
value_2: float | None = None
"""Показания 2"""
"""Показание 2"""
address: str
"""Адрес"""
rssi: int
"""RSSI"""
"""Уровень сигнала RSSI"""

@classmethod
def from_ble(cls, dev: BLEDevice, adv: AdvertisementData):
Expand All @@ -62,27 +62,28 @@ def from_ble(cls, dev: BLEDevice, adv: AdvertisementData):
"Device signatures in address and adverisement data aren't equals."
)

fw, packet = "{}.{}".format(*divmod(x[16], 10)), x[3]
sw_version, packet_version = "{}.{}".format(*divmod(x[16], 10)), x[3]

if packet == 0x01:
if packet_version == 0x01:
return cls(
*sign,
firmware=fw,
sw_version=sw_version,
battery=min(x[13], 100),
temperature=int.from_bytes(x[14:16], "little") / 1e2,
value_1=int.from_bytes(x[9:13], "little") / 1e4,
address=dev.address,
rssi=adv.rssi,
)

if packet == 0x05:
if packet_version == 0x05:
# Значения показаний 28-битные
v1, v2 = map(lambda x: x << 24, divmod(x[9], 16))
v1 += int.from_bytes(x[10:13], "big")
v2 += int.from_bytes(x[13:16], "big")

return cls(
*sign,
firmware=fw,
sw_version=sw_version,
battery=min(x[1], 100),
temperature=x[2],
value_1=v1 / 1e3,
Expand All @@ -91,7 +92,7 @@ def from_ble(cls, dev: BLEDevice, adv: AdvertisementData):
rssi=adv.rssi,
)

raise UnsupportedPacket("Packet version %d is not supported.", packet)
raise UnsupportedPacket("Packet version %d is not supported.", packet_version)

@property
def key_type(self) -> str:
Expand Down
29 changes: 29 additions & 0 deletions custom_components/elehant/helpers.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
from homeassistant.core import HomeAssistant
from homeassistant.helpers import translation as i18n

from .const import DOMAIN
from .elehant import ElehantData


async def get_translated_key(
hass: HomeAssistant,
category: str,
key: str,
placeholders: dict[str, str] | None = None,
fallback: str | None = None,
):
language = hass.config.language
tr = await i18n.async_get_translations(hass, language, category, [DOMAIN])

return tr.get(f"component.{DOMAIN}.{category}.{key}", fallback or "").format(
**placeholders or {}
)


def get_device_name(hass: HomeAssistant, device: ElehantData):
return get_translated_key(
hass,
"device",
key=f"{device.key_model}.name",
placeholders={"serial": device.str_serial},
)
4 changes: 2 additions & 2 deletions custom_components/elehant/manifest.json
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@
"name": "Elehant Meters",
"bluetooth": [
{
"connectable": false,
"connectable": false,
"manufacturer_id": 65535,
"manufacturer_data_start": [128]
}
Expand All @@ -15,5 +15,5 @@
"integration_type": "device",
"iot_class": "local_push",
"issue_tracker": "https://github.com/dudanov/hassio-elehant/issues",
"version": "0.9.1"
"version": "0.10.0"
}
7 changes: 4 additions & 3 deletions custom_components/elehant/sensor.py
Original file line number Diff line number Diff line change
Expand Up @@ -96,11 +96,12 @@ def _it():
connections={(dr.CONNECTION_BLUETOOTH, data.address)},
identifiers={(DOMAIN, data.unique_id)},
manufacturer="Элехант",
model_id=data.key_model,
# model_id=data.key_model,
# model=data.name_model,
serial_number=data.str_serial,
sw_version=data.firmware,
translation_key=data.key_type,
sw_version=data.sw_version,
translation_key=data.key_model,
translation_placeholders={"serial": data.str_serial},
)

result = PassiveBluetoothDataUpdate(
Expand Down
121 changes: 111 additions & 10 deletions custom_components/elehant/translations/en.json
Original file line number Diff line number Diff line change
Expand Up @@ -4,9 +4,8 @@
"step": {
"user": {
"title": "Select a meter",
"description": "Select a meter from the list below.",
"data": {
"address": "Discovered meters:"
"unique_id": "Select meter:"
}
},
"bluetooth_confirm": {
Expand All @@ -22,17 +21,119 @@
}
},
"device": {
"1": {
"name": "Gas meter"
"1-1": {
"name": "Gas meter DGM-1.8-{serial}"
},
"2": {
"name": "Water meter"
"1-2": {
"name": "Gas meter DGM-3.2-{serial}"
},
"3": {
"name": "Electricity meter"
"1-3": {
"name": "Gas meter DGM-4.0-{serial}"
},
"4": {
"name": "Heat meter"
"1-4": {
"name": "Gas meter DGM-6.0-{serial}"
},
"1-5": {
"name": "Gas meter DGM-1.6-{serial}"
},
"1-16": {
"name": "Gas meter GMDL-1.8-{serial}"
},
"1-17": {
"name": "Gas meter GMDL-3.2-{serial}"
},
"1-18": {
"name": "Gas meter GMDL-4.0-{serial}"
},
"1-19": {
"name": "Gas meter GMDL-6.0-{serial}"
},
"1-20": {
"name": "Gas meter GMDL-1.6-{serial}"
},
"1-32": {
"name": "Gas meter USGM-G1,6-{serial}"
},
"1-33": {
"name": "Gas meter USGM-G2,5-{serial}"
},
"1-34": {
"name": "Gas meter USGM-G4-{serial}"
},
"1-35": {
"name": "Gas meter USGM-G6-{serial}"
},
"1-36": {
"name": "Gas meter USGM-G10-{serial}"
},
"1-48": {
"name": "Gas meter GMDL-1.8TC-{serial}"
},
"1-49": {
"name": "Gas meter GMDL-3.2TC-{serial}"
},
"1-50": {
"name": "Gas meter GMDL-4.0TC-{serial}"
},
"1-51": {
"name": "Gas meter GMDL-6.0TC-{serial}"
},
"1-52": {
"name": "Gas meter GMDL-1.6TC-{serial}"
},
"1-64": {
"name": "Gas meter USGM-G1,6TC-{serial}"
},
"1-65": {
"name": "Gas meter USGM-G2,5TC-{serial}"
},
"1-66": {
"name": "Gas meter USGM-G4TC-{serial}"
},
"1-67": {
"name": "Gas meter USGM-G6TC-{serial}"
},
"1-68": {
"name": "Gas meter USGM-G10TC-{serial}"
},
"1-80": {
"name": "Gas meter DGM-1.8TC-{serial}"
},
"1-81": {
"name": "Gas meter DGM-3.2TC-{serial}"
},
"1-82": {
"name": "Gas meter DGM-4.0TC-{serial}"
},
"1-83": {
"name": "Gas meter DGM-6.0TC-{serial}"
},
"1-84": {
"name": "Gas meter DGM-1.6TC-{serial}"
},
"2-1": {
"name": "Water meter DWM-15-{serial}"
},
"2-2": {
"name": "Water meter DWM-20-{serial}"
},
"2-3": {
"name": "Water meter DTM-15-{serial}"
},
"2-4": {
"name": "Water meter DTM-15-{serial}"
},
"2-5": {
"name": "Water meter DTM-20-{serial}"
},
"2-6": {
"name": "Water meter DTM-20-{serial}"
},
"3-1": {
"name": "Electricity meter DEM-{serial}"
},
"4-1": {
"name": "Heat meter DTM-10-{serial}"
}
}
}
Loading

0 comments on commit 4ef3aa7

Please sign in to comment.