mirror of
https://github.com/home-assistant/core.git
synced 2025-10-21 09:39:36 +00:00
179 lines
5.5 KiB
Python
179 lines
5.5 KiB
Python
"""Sensor platform for Firefly III integration."""
|
|
|
|
from __future__ import annotations
|
|
|
|
from pyfirefly.models import Account, Category
|
|
|
|
from homeassistant.components.sensor import (
|
|
SensorDeviceClass,
|
|
SensorEntity,
|
|
SensorStateClass,
|
|
StateType,
|
|
)
|
|
from homeassistant.const import EntityCategory
|
|
from homeassistant.core import HomeAssistant
|
|
from homeassistant.helpers.entity_platform import AddConfigEntryEntitiesCallback
|
|
|
|
from .coordinator import FireflyConfigEntry, FireflyDataUpdateCoordinator
|
|
from .entity import FireflyAccountBaseEntity, FireflyCategoryBaseEntity
|
|
|
|
ACCOUNT_ROLE_MAPPING = {
|
|
"defaultAsset": "default_asset",
|
|
"sharedAsset": "shared_asset",
|
|
"savingAsset": "saving_asset",
|
|
"ccAsset": "cc_asset",
|
|
"cashWalletAsset": "cash_wallet_asset",
|
|
}
|
|
ACCOUNT_TYPE_ICONS = {
|
|
"expense": "mdi:cash-minus",
|
|
"asset": "mdi:account-cash",
|
|
"revenue": "mdi:cash-plus",
|
|
"liability": "mdi:hand-coin",
|
|
}
|
|
|
|
ACCOUNT_BALANCE = "account_balance"
|
|
ACCOUNT_ROLE = "account_role"
|
|
ACCOUNT_TYPE = "account_type"
|
|
CATEGORY = "category"
|
|
|
|
|
|
async def async_setup_entry(
|
|
hass: HomeAssistant,
|
|
entry: FireflyConfigEntry,
|
|
async_add_entities: AddConfigEntryEntitiesCallback,
|
|
) -> None:
|
|
"""Set up Firefly III sensors."""
|
|
coordinator = entry.runtime_data
|
|
entities: list[SensorEntity] = []
|
|
|
|
for account in coordinator.data.accounts:
|
|
entities.append(
|
|
FireflyAccountBalanceSensor(coordinator, account, ACCOUNT_BALANCE)
|
|
)
|
|
entities.append(FireflyAccountRoleSensor(coordinator, account, ACCOUNT_ROLE))
|
|
entities.append(FireflyAccountTypeSensor(coordinator, account, ACCOUNT_TYPE))
|
|
|
|
entities.extend(
|
|
[
|
|
FireflyCategorySensor(coordinator, category, CATEGORY)
|
|
for category in coordinator.data.category_details
|
|
]
|
|
)
|
|
|
|
async_add_entities(entities)
|
|
|
|
|
|
class FireflyAccountBalanceSensor(FireflyAccountBaseEntity, SensorEntity):
|
|
"""Account balance sensor."""
|
|
|
|
_attr_translation_key = "account_balance"
|
|
_attr_device_class = SensorDeviceClass.MONETARY
|
|
_attr_state_class = SensorStateClass.TOTAL
|
|
|
|
def __init__(
|
|
self,
|
|
coordinator: FireflyDataUpdateCoordinator,
|
|
account: Account,
|
|
key: str,
|
|
) -> None:
|
|
"""Initialize the account balance sensor."""
|
|
super().__init__(coordinator, account, key)
|
|
self._account = account
|
|
self._attr_native_unit_of_measurement = (
|
|
coordinator.data.primary_currency.attributes.code
|
|
)
|
|
|
|
@property
|
|
def native_value(self) -> StateType:
|
|
"""Return current account balance."""
|
|
return self._account.attributes.current_balance
|
|
|
|
|
|
class FireflyAccountRoleSensor(FireflyAccountBaseEntity, SensorEntity):
|
|
"""Account role diagnostic sensor."""
|
|
|
|
_attr_translation_key = "account_role"
|
|
_attr_entity_category = EntityCategory.DIAGNOSTIC
|
|
_attr_entity_registry_enabled_default = True
|
|
|
|
def __init__(
|
|
self,
|
|
coordinator: FireflyDataUpdateCoordinator,
|
|
account: Account,
|
|
key: str,
|
|
) -> None:
|
|
"""Initialize the account role sensor."""
|
|
super().__init__(coordinator, account, key)
|
|
self._account = account
|
|
|
|
@property
|
|
def native_value(self) -> StateType:
|
|
"""Return account role."""
|
|
|
|
# An account can be empty and then should resort to Unknown
|
|
account_role: str | None = self._account.attributes.account_role
|
|
if account_role is None:
|
|
return None
|
|
|
|
return ACCOUNT_ROLE_MAPPING.get(account_role, account_role)
|
|
|
|
|
|
class FireflyAccountTypeSensor(FireflyAccountBaseEntity, SensorEntity):
|
|
"""Account type diagnostic sensor."""
|
|
|
|
_attr_translation_key = "account_type"
|
|
_attr_entity_category = EntityCategory.DIAGNOSTIC
|
|
_attr_entity_registry_enabled_default = True
|
|
|
|
def __init__(
|
|
self,
|
|
coordinator: FireflyDataUpdateCoordinator,
|
|
account: Account,
|
|
key: str,
|
|
) -> None:
|
|
"""Initialize the account type sensor."""
|
|
super().__init__(coordinator, account, key)
|
|
acc_type = account.attributes.type
|
|
self._attr_icon = (
|
|
ACCOUNT_TYPE_ICONS.get(acc_type, "mdi:bank")
|
|
if acc_type is not None
|
|
else "mdi:bank"
|
|
)
|
|
|
|
@property
|
|
def native_value(self) -> StateType:
|
|
"""Return account type."""
|
|
return self._account.attributes.type
|
|
|
|
|
|
class FireflyCategorySensor(FireflyCategoryBaseEntity, SensorEntity):
|
|
"""Category sensor."""
|
|
|
|
_attr_translation_key = "category"
|
|
_attr_device_class = SensorDeviceClass.MONETARY
|
|
_attr_state_class = SensorStateClass.TOTAL
|
|
|
|
def __init__(
|
|
self,
|
|
coordinator: FireflyDataUpdateCoordinator,
|
|
category: Category,
|
|
key: str,
|
|
) -> None:
|
|
"""Initialize the category sensor."""
|
|
super().__init__(coordinator, category, key)
|
|
self._category = category
|
|
self._attr_native_unit_of_measurement = (
|
|
coordinator.data.primary_currency.attributes.code
|
|
)
|
|
|
|
@property
|
|
def native_value(self) -> StateType:
|
|
"""Return net spent+earned value for this category in the period."""
|
|
spent_items = self._category.attributes.spent or []
|
|
earned_items = self._category.attributes.earned or []
|
|
spent = sum(float(item.sum) for item in spent_items if item.sum is not None)
|
|
earned = sum(float(item.sum) for item in earned_items if item.sum is not None)
|
|
if spent == 0 and earned == 0:
|
|
return None
|
|
return spent + earned
|