Skip to content

Commit

Permalink
feat: add icon and 4 digits of the Dong/Ho
Browse files Browse the repository at this point in the history
  • Loading branch information
lunDreame authored Oct 11, 2024
1 parent 23d7078 commit 25c8150
Show file tree
Hide file tree
Showing 5 changed files with 98 additions and 49 deletions.
2 changes: 1 addition & 1 deletion custom_components/apti/const.py
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@
from homeassistant.const import Platform

DOMAIN = "apti"
VERSION = "1.0.2"
VERSION = "1.0.3"

PLATFORMS: list[Platform] = [
Platform.SENSOR
Expand Down
24 changes: 24 additions & 0 deletions custom_components/apti/helper.py
Original file line number Diff line number Diff line change
@@ -1,6 +1,8 @@
"""Defines helper function."""

from typing import Any
import aiofiles
import json
import re

from .const import LOGGER
Expand Down Expand Up @@ -32,3 +34,25 @@ def find_value_by_condition(data_dict: dict, condition) -> Any | None:
def is_phone_number(id_value: str) -> bool:
phone_number_pattern = r'^010\d{8}$'
return bool(re.match(phone_number_pattern, id_value))

async def get_icon(
category: str,
key: str,
json_file_path: str = "custom_components/apti/icons/icon.json"
) -> str:
try:
async with aiofiles.open(json_file_path, "r", encoding="utf-8") as file:
content = await file.read()
data = json.loads(content)

if category in data:
icon = data[category].get(key, None)
if icon is None:
LOGGER.warning(f"Icon for key '{key}' in category '{category}' not found.")
return icon
else:
LOGGER.warning(f"Category '{category}' not found in icon data.")
return None
except (FileNotFoundError, json.JSONDecodeError) as e:
LOGGER.error(f"Error reading or decoding '{json_file_path}': {e}")
return None
34 changes: 34 additions & 0 deletions custom_components/apti/icons/icon.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
{
"maint_item": {
"건물보험료": "mdi:home-lock",
"경비비": "mdi:security",
"공동수도료": "mdi:water-pump",
"공동전기료": "mdi:lightbulb-group",
"관리비 납부 금액": "mdi:currency-krw",
"기본난방비": "mdi:radiator",
"세대수도료": "mdi:water-outline",
"세대전기료": "mdi:flash-outline",
"소독비": "mdi:biohazard",
"수선유지비": "mdi:tools",
"승강기유지비": "mdi:elevator",
"승강기전기": "mdi:elevator-passenger-outline",
"위탁관리수수료": "mdi:account-cash",
"일반관리비": "mdi:clipboard-outline",
"입주자대표회의운": "mdi:account-group-outline",
"장기수선충당금": "mdi:hammer-wrench",
"청소비": "mdi:broom",
"커뮤니티사용료": "mdi:account-multiple-outline",
"커뮤니티시설유지": "mdi:account-group",
"홈네트워크": "mdi:network",
"TV수신료": "mdi:television-classic"
},
"energy_detail": {
"수도": "mdi:water",
"온수": "mdi:water-boiler",
"전기": "mdi:power-plug"
},
"energy_type": {
"열": "mdi:fire",
"전기": "mdi:currency-krw"
}
}
5 changes: 3 additions & 2 deletions custom_components/apti/manifest.json
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,8 @@
"iot_class": "local_polling",
"issue_tracker": "https://github.com/lunDreame/homeassistant-apti/issues",
"requirements": [
"beautifulsoup4"
"beautifulsoup4",
"aiofiles"
],
"version": "1.0.2"
"version": "1.0.3"
}
82 changes: 36 additions & 46 deletions custom_components/apti/sensor.py
Original file line number Diff line number Diff line change
Expand Up @@ -13,68 +13,69 @@

from .coordinator import APTiDataUpdateCoordinator
from .entity import APTiDevice
from .helper import find_value_by_condition
from .helper import find_value_by_condition, get_icon


@dataclass(kw_only=True)
class APTiSensorEntityDescription(SensorEntityDescription):
"""Describes APT.i sensor entity."""

format_id: str
chepter_name: str
format_id: str # unique_id
chepter_name: str # device_info
exists_fn: Callable[..., bool] = lambda _: True
icon_fn: Callable[..., str] = lambda _: None
trans_ph: Callable[..., dict] = lambda _: {}
value_fn: Callable[..., datetime | str]
extra_attributes: Callable[..., dict] = lambda _: {}


SENSORS: tuple[APTiSensorEntityDescription, ...] = (
APTiSensorEntityDescription(
key="maint_item",
translation_key="maint_item",
translation_placeholders=lambda key: {"category": key["항목"]},
format_id=lambda key: f"{key['항목']}_maint_item",
native_unit_of_measurement="원",
format_id=lambda k: f"{k['항목']}_maint_item",
chepter_name="관리비",
unit_of_measurement = "원",
value_fn=lambda value: find_value_by_condition(value, lambda k: k.startswith("당월")),
extra_attributes=lambda value: value,
icon_fn=lambda c, k: get_icon(c, k["항목"]),
trans_ph=lambda k: {"category": k["항목"]},
value_fn=lambda v: find_value_by_condition(v, lambda k: k.startswith("당월")),
),
APTiSensorEntityDescription(
key="maint_payment",
icon="mdi:currency-krw",
translation_key="maint_payment",
native_unit_of_measurement="원",
format_id="maint_payment",
chepter_name="관리비",
unit_of_measurement = "원",
value_fn=lambda value: find_value_by_condition(value, lambda k: k.startswith("납부할 금액")),
extra_attributes=lambda value: value,
value_fn=lambda v: find_value_by_condition(v, lambda k: k.startswith("납부할 금액")),
),
APTiSensorEntityDescription(
key="energy_usage",
icon="mdi:flash",
translation_key="energy_usage",
native_unit_of_measurement="원",
format_id="energy_usage",
chepter_name="에너지",
unit_of_measurement = "원",
value_fn=lambda value: find_value_by_condition(value, lambda k: k.endswith("사용")),
extra_attributes=lambda value: value,
value_fn=lambda v: find_value_by_condition(v, lambda k: k.endswith("사용")),
),
APTiSensorEntityDescription(
key="energy_detail",
translation_key="energy_detail",
translation_placeholders=lambda key: {"category": key["유형"]},
format_id=lambda key: f"{key['유형']}_energy_detail",
native_unit_of_measurement="",
format_id=lambda k: f"{k['유형']}_energy_detail",
chepter_name="에너지",
unit_of_measurement = "",
value_fn=lambda value: find_value_by_condition(value, lambda k: k.startswith("사용량")),
extra_attributes=lambda value: value,
icon_fn=lambda c, k: get_icon(c, k["유형"]),
trans_ph=lambda k: {"category": k["유형"]},
value_fn=lambda v: find_value_by_condition(v, lambda k: k.startswith("사용량")),
),
APTiSensorEntityDescription(
key="energy_type",
translation_key="energy_type",
translation_placeholders=lambda key: {"category": key["유형"]},
format_id=lambda key: f"{key['유형']}_energy_type",
native_unit_of_measurement="원",
format_id=lambda k: f"{k['유형']}_energy_type",
chepter_name="에너지",
unit_of_measurement = "원",
value_fn=lambda value: find_value_by_condition(value, lambda k: k.startswith("총액")),
extra_attributes=lambda value: value,
icon_fn=lambda c, k: get_icon(c, k["유형"]),
trans_ph=lambda k: {"category": k["유형"]},
value_fn=lambda v: find_value_by_condition(v, lambda k: k.startswith("총액")),
),
)

Expand Down Expand Up @@ -114,19 +115,15 @@ def __init__(
"""Initialize the sensor."""
super().__init__(coordinator, entity_description)
self.entity_description = entity_description
self._value = coordinator.data[self.description.key]

self._attr_extra_state_attributes = self._value
self._attr_unique_id = self.description.format_id
self._attr_extra_state_attributes = self.description.extra_attributes(
coordinator.data[self.description.key]
)

self._attr_native_unit_of_measurement = self.description.unit_of_measurement

@property
def native_value(self) -> str:
"""Return the state of the sensor."""
value = self.coordinator.data[self.description.key]
return self.description.value_fn(value)
return self.description.value_fn(self._value)


class APTiCategorySensor(APTiDevice, SensorEntity):
Expand All @@ -143,23 +140,16 @@ def __init__(
self.category = category
self.entity_description = entity_description

self._attr_extra_state_attributes = category
self._attr_translation_placeholders = self.description.trans_ph(category)
self._attr_unique_id = self.description.format_id(category)
self._attr_extra_state_attributes = self.description.extra_attributes(
category
)

self._attr_native_unit_of_measurement = self.description.unit_of_measurement

async def async_added_to_hass(self) -> None:
"""Called when added to Hass."""
self._attr_icon = await self.description.icon_fn(self.description.key, self.category)
await super().async_added_to_hass()

@property
def native_value(self) -> datetime | str:
"""Return the state of the sensor."""
return self.description.value_fn(self.category)

@property
def translation_placeholders(self) -> dict[str, str] | None:
"""Return the translation placeholders."""
if self.category:
return self.description.translation_placeholders(
self.category
)
return None

0 comments on commit 25c8150

Please sign in to comment.