"""Support for N26 bank account sensors.""" import logging from homeassistant.helpers.entity import Entity from . import DEFAULT_SCAN_INTERVAL, DOMAIN, timestamp_ms_to_date from .const import DATA _LOGGER = logging.getLogger(__name__) SCAN_INTERVAL = DEFAULT_SCAN_INTERVAL ATTR_IBAN = "account" ATTR_USABLE_BALANCE = "usable_balance" ATTR_BANK_BALANCE = "bank_balance" ATTR_ACC_OWNER_TITLE = "owner_title" ATTR_ACC_OWNER_FIRST_NAME = "owner_first_name" ATTR_ACC_OWNER_LAST_NAME = "owner_last_name" ATTR_ACC_OWNER_GENDER = "owner_gender" ATTR_ACC_OWNER_BIRTH_DATE = "owner_birth_date" ATTR_ACC_OWNER_EMAIL = "owner_email" ATTR_ACC_OWNER_PHONE_NUMBER = "owner_phone_number" ICON_ACCOUNT = "mdi:currency-eur" ICON_CARD = "mdi:credit-card" ICON_SPACE = "mdi:crop-square" def setup_platform(hass, config, add_entities, discovery_info=None): """Set up the N26 sensor platform.""" if discovery_info is None: return api_list = hass.data[DOMAIN][DATA] sensor_entities = [] for api_data in api_list: sensor_entities.append(N26Account(api_data)) for card in api_data.cards: sensor_entities.append(N26Card(api_data, card)) for space in api_data.spaces["spaces"]: sensor_entities.append(N26Space(api_data, space)) add_entities(sensor_entities) class N26Account(Entity): """Sensor for a N26 balance account. A balance account contains an amount of money (=balance). The amount may also be negative. """ def __init__(self, api_data) -> None: """Initialize a N26 balance account.""" self._data = api_data self._iban = self._data.balance["iban"] def update(self) -> None: """Get the current balance and currency for the account.""" self._data.update_account() @property def unique_id(self): """Return the unique ID of the entity.""" return self._iban[-4:] @property def name(self) -> str: """Friendly name of the sensor.""" return f"n26_{self._iban[-4:]}" @property def state(self) -> float: """Return the balance of the account as state.""" if self._data.balance is None: return None return self._data.balance.get("availableBalance") @property def unit_of_measurement(self) -> str: """Use the currency as unit of measurement.""" if self._data.balance is None: return None return self._data.balance.get("currency") @property def device_state_attributes(self) -> dict: """Additional attributes of the sensor.""" attributes = { ATTR_IBAN: self._data.balance.get("iban"), ATTR_BANK_BALANCE: self._data.balance.get("bankBalance"), ATTR_USABLE_BALANCE: self._data.balance.get("usableBalance"), ATTR_ACC_OWNER_TITLE: self._data.account_info.get("title"), ATTR_ACC_OWNER_FIRST_NAME: self._data.account_info.get("kycFirstName"), ATTR_ACC_OWNER_LAST_NAME: self._data.account_info.get("kycLastName"), ATTR_ACC_OWNER_GENDER: self._data.account_info.get("gender"), ATTR_ACC_OWNER_BIRTH_DATE: timestamp_ms_to_date( self._data.account_info.get("birthDate") ), ATTR_ACC_OWNER_EMAIL: self._data.account_info.get("email"), ATTR_ACC_OWNER_PHONE_NUMBER: self._data.account_info.get( "mobilePhoneNumber" ), } for limit in self._data.limits: limit_attr_name = f"limit_{limit['limit'].lower()}" attributes[limit_attr_name] = limit["amount"] return attributes @property def icon(self) -> str: """Set the icon for the sensor.""" return ICON_ACCOUNT class N26Card(Entity): """Sensor for a N26 card.""" def __init__(self, api_data, card) -> None: """Initialize a N26 card.""" self._data = api_data self._account_name = api_data.balance["iban"][-4:] self._card = card def update(self) -> None: """Get the current balance and currency for the account.""" self._data.update_cards() self._card = self._data.card(self._card["id"], self._card) @property def unique_id(self): """Return the unique ID of the entity.""" return self._card["id"] @property def name(self) -> str: """Friendly name of the sensor.""" return f"{self._account_name.lower()}_card_{self._card['id']}" @property def state(self) -> float: """Return the balance of the account as state.""" return self._card["status"] @property def device_state_attributes(self) -> dict: """Additional attributes of the sensor.""" attributes = { "apple_pay_eligible": self._card.get("applePayEligible"), "card_activated": timestamp_ms_to_date(self._card.get("cardActivated")), "card_product": self._card.get("cardProduct"), "card_product_type": self._card.get("cardProductType"), "card_settings_id": self._card.get("cardSettingsId"), "card_Type": self._card.get("cardType"), "design": self._card.get("design"), "exceet_actual_delivery_date": self._card.get("exceetActualDeliveryDate"), "exceet_card_status": self._card.get("exceetCardStatus"), "exceet_expected_delivery_date": self._card.get( "exceetExpectedDeliveryDate" ), "exceet_express_card_delivery": self._card.get("exceetExpressCardDelivery"), "exceet_express_card_delivery_email_sent": self._card.get( "exceetExpressCardDeliveryEmailSent" ), "exceet_express_card_delivery_tracking_id": self._card.get( "exceetExpressCardDeliveryTrackingId" ), "expiration_date": timestamp_ms_to_date(self._card.get("expirationDate")), "google_pay_eligible": self._card.get("googlePayEligible"), "masked_pan": self._card.get("maskedPan"), "membership": self._card.get("membership"), "mpts_card": self._card.get("mptsCard"), "pan": self._card.get("pan"), "pin_defined": timestamp_ms_to_date(self._card.get("pinDefined")), "username_on_card": self._card.get("usernameOnCard"), } return attributes @property def icon(self) -> str: """Set the icon for the sensor.""" return ICON_CARD class N26Space(Entity): """Sensor for a N26 space.""" def __init__(self, api_data, space) -> None: """Initialize a N26 space.""" self._data = api_data self._space = space def update(self) -> None: """Get the current balance and currency for the account.""" self._data.update_spaces() self._space = self._data.space(self._space["id"], self._space) @property def unique_id(self): """Return the unique ID of the entity.""" return f"space_{self._data.balance['iban'][-4:]}_{self._space['name'].lower()}" @property def name(self) -> str: """Friendly name of the sensor.""" return self._space["name"] @property def state(self) -> float: """Return the balance of the account as state.""" return self._space["balance"]["availableBalance"] @property def unit_of_measurement(self) -> str: """Use the currency as unit of measurement.""" return self._space["balance"]["currency"] @property def device_state_attributes(self) -> dict: """Additional attributes of the sensor.""" goal_value = "" if "goal" in self._space: goal_value = self._space.get("goal").get("amount") attributes = { "name": self._space.get("name"), "goal": goal_value, "background_image_url": self._space.get("backgroundImageUrl"), "image_url": self._space.get("imageUrl"), "is_card_attached": self._space.get("isCardAttached"), "is_hidden_from_balance": self._space.get("isHiddenFromBalance"), "is_locked": self._space.get("isLocked"), "is_primary": self._space.get("isPrimary"), } return attributes @property def icon(self) -> str: """Set the icon for the sensor.""" return ICON_SPACE