Add SimpleFin sensor to show age of data (#122550)

This commit is contained in:
Jeef 2024-07-30 15:42:10 -06:00 committed by GitHub
parent 6999c6b0cf
commit 067acce4de
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
6 changed files with 401 additions and 5 deletions

View File

@ -7,5 +7,5 @@
"integration_type": "service",
"iot_class": "cloud_polling",
"loggers": ["simplefin"],
"requirements": ["simplefin4py==0.0.16"]
"requirements": ["simplefin4py==0.0.18"]
}

View File

@ -4,6 +4,7 @@ from __future__ import annotations
from collections.abc import Callable
from dataclasses import dataclass
from datetime import datetime
from simplefin4py import Account
@ -13,6 +14,7 @@ from homeassistant.components.sensor import (
SensorEntityDescription,
SensorStateClass,
)
from homeassistant.const import EntityCategory
from homeassistant.core import HomeAssistant
from homeassistant.helpers.entity_platform import AddEntitiesCallback
from homeassistant.helpers.typing import StateType
@ -25,7 +27,7 @@ from .entity import SimpleFinEntity
class SimpleFinSensorEntityDescription(SensorEntityDescription):
"""Describes a sensor entity."""
value_fn: Callable[[Account], StateType]
value_fn: Callable[[Account], StateType | datetime]
icon_fn: Callable[[Account], str] | None = None
unit_fn: Callable[[Account], str] | None = None
@ -40,6 +42,13 @@ SIMPLEFIN_SENSORS: tuple[SimpleFinSensorEntityDescription, ...] = (
unit_fn=lambda account: account.currency,
icon_fn=lambda account: account.inferred_account_type,
),
SimpleFinSensorEntityDescription(
key="age",
translation_key="age",
device_class=SensorDeviceClass.TIMESTAMP,
entity_category=EntityCategory.DIAGNOSTIC,
value_fn=lambda account: account.balance_date,
),
)
@ -70,7 +79,7 @@ class SimpleFinSensor(SimpleFinEntity, SensorEntity):
entity_description: SimpleFinSensorEntityDescription
@property
def native_value(self) -> StateType:
def native_value(self) -> StateType | datetime | None:
"""Return the state."""
return self.entity_description.value_fn(self.account_data)

View File

@ -24,6 +24,9 @@
"sensor": {
"balance": {
"name": "Balance"
},
"age": {
"name": "Data age"
}
}
}

View File

@ -2580,7 +2580,7 @@ sharp_aquos_rc==0.3.2
shodan==1.28.0
# homeassistant.components.simplefin
simplefin4py==0.0.16
simplefin4py==0.0.18
# homeassistant.components.sighthound
simplehound==0.3

View File

@ -2032,7 +2032,7 @@ sfrbox-api==0.0.8
sharkiq==1.0.2
# homeassistant.components.simplefin
simplefin4py==0.0.16
simplefin4py==0.0.18
# homeassistant.components.sighthound
simplehound==0.3

View File

@ -52,6 +52,54 @@
'state': '1000000.00',
})
# ---
# name: test_all_entities[sensor.investments_dr_evil_data_age-entry]
EntityRegistryEntrySnapshot({
'aliases': set({
}),
'area_id': None,
'capabilities': None,
'config_entry_id': <ANY>,
'device_class': None,
'device_id': <ANY>,
'disabled_by': None,
'domain': 'sensor',
'entity_category': <EntityCategory.DIAGNOSTIC: 'diagnostic'>,
'entity_id': 'sensor.investments_dr_evil_data_age',
'has_entity_name': True,
'hidden_by': None,
'icon': None,
'id': <ANY>,
'labels': set({
}),
'name': None,
'options': dict({
}),
'original_device_class': <SensorDeviceClass.TIMESTAMP: 'timestamp'>,
'original_icon': None,
'original_name': 'Data age',
'platform': 'simplefin',
'previous_unique_id': None,
'supported_features': 0,
'translation_key': 'age',
'unique_id': 'account_ACT-4k5l6m7n-8o9p-1q2r-3s4t_age',
'unit_of_measurement': None,
})
# ---
# name: test_all_entities[sensor.investments_dr_evil_data_age-state]
StateSnapshot({
'attributes': ReadOnlyDict({
'attribution': 'Data provided by SimpleFIN API',
'device_class': 'timestamp',
'friendly_name': 'Investments Dr Evil Data age',
}),
'context': <ANY>,
'entity_id': 'sensor.investments_dr_evil_data_age',
'last_changed': <ANY>,
'last_reported': <ANY>,
'last_updated': <ANY>,
'state': '2024-01-16T13:55:19+00:00',
})
# ---
# name: test_all_entities[sensor.investments_my_checking_balance-entry]
EntityRegistryEntrySnapshot({
'aliases': set({
@ -105,6 +153,54 @@
'state': '12345.67',
})
# ---
# name: test_all_entities[sensor.investments_my_checking_data_age-entry]
EntityRegistryEntrySnapshot({
'aliases': set({
}),
'area_id': None,
'capabilities': None,
'config_entry_id': <ANY>,
'device_class': None,
'device_id': <ANY>,
'disabled_by': None,
'domain': 'sensor',
'entity_category': <EntityCategory.DIAGNOSTIC: 'diagnostic'>,
'entity_id': 'sensor.investments_my_checking_data_age',
'has_entity_name': True,
'hidden_by': None,
'icon': None,
'id': <ANY>,
'labels': set({
}),
'name': None,
'options': dict({
}),
'original_device_class': <SensorDeviceClass.TIMESTAMP: 'timestamp'>,
'original_icon': None,
'original_name': 'Data age',
'platform': 'simplefin',
'previous_unique_id': None,
'supported_features': 0,
'translation_key': 'age',
'unique_id': 'account_ACT-1k2l3m4n-5o6p-7q8r-9s0t_age',
'unit_of_measurement': None,
})
# ---
# name: test_all_entities[sensor.investments_my_checking_data_age-state]
StateSnapshot({
'attributes': ReadOnlyDict({
'attribution': 'Data provided by SimpleFIN API',
'device_class': 'timestamp',
'friendly_name': 'Investments My Checking Data age',
}),
'context': <ANY>,
'entity_id': 'sensor.investments_my_checking_data_age',
'last_changed': <ANY>,
'last_reported': <ANY>,
'last_updated': <ANY>,
'state': '2024-01-16T13:55:19+00:00',
})
# ---
# name: test_all_entities[sensor.investments_nerdcorp_series_b_balance-entry]
EntityRegistryEntrySnapshot({
'aliases': set({
@ -158,6 +254,54 @@
'state': '13579.24',
})
# ---
# name: test_all_entities[sensor.investments_nerdcorp_series_b_data_age-entry]
EntityRegistryEntrySnapshot({
'aliases': set({
}),
'area_id': None,
'capabilities': None,
'config_entry_id': <ANY>,
'device_class': None,
'device_id': <ANY>,
'disabled_by': None,
'domain': 'sensor',
'entity_category': <EntityCategory.DIAGNOSTIC: 'diagnostic'>,
'entity_id': 'sensor.investments_nerdcorp_series_b_data_age',
'has_entity_name': True,
'hidden_by': None,
'icon': None,
'id': <ANY>,
'labels': set({
}),
'name': None,
'options': dict({
}),
'original_device_class': <SensorDeviceClass.TIMESTAMP: 'timestamp'>,
'original_icon': None,
'original_name': 'Data age',
'platform': 'simplefin',
'previous_unique_id': None,
'supported_features': 0,
'translation_key': 'age',
'unique_id': 'account_ACT-5k6l7m8n-9o0p-1q2r-3s4t_age',
'unit_of_measurement': None,
})
# ---
# name: test_all_entities[sensor.investments_nerdcorp_series_b_data_age-state]
StateSnapshot({
'attributes': ReadOnlyDict({
'attribution': 'Data provided by SimpleFIN API',
'device_class': 'timestamp',
'friendly_name': 'Investments NerdCorp Series B Data age',
}),
'context': <ANY>,
'entity_id': 'sensor.investments_nerdcorp_series_b_data_age',
'last_changed': <ANY>,
'last_reported': <ANY>,
'last_updated': <ANY>,
'state': '2024-01-16T13:55:19+00:00',
})
# ---
# name: test_all_entities[sensor.mythical_randomsavings_castle_mortgage_balance-entry]
EntityRegistryEntrySnapshot({
'aliases': set({
@ -211,6 +355,54 @@
'state': '7500.00',
})
# ---
# name: test_all_entities[sensor.mythical_randomsavings_castle_mortgage_data_age-entry]
EntityRegistryEntrySnapshot({
'aliases': set({
}),
'area_id': None,
'capabilities': None,
'config_entry_id': <ANY>,
'device_class': None,
'device_id': <ANY>,
'disabled_by': None,
'domain': 'sensor',
'entity_category': <EntityCategory.DIAGNOSTIC: 'diagnostic'>,
'entity_id': 'sensor.mythical_randomsavings_castle_mortgage_data_age',
'has_entity_name': True,
'hidden_by': None,
'icon': None,
'id': <ANY>,
'labels': set({
}),
'name': None,
'options': dict({
}),
'original_device_class': <SensorDeviceClass.TIMESTAMP: 'timestamp'>,
'original_icon': None,
'original_name': 'Data age',
'platform': 'simplefin',
'previous_unique_id': None,
'supported_features': 0,
'translation_key': 'age',
'unique_id': 'account_ACT-7a8b9c0d-1e2f-3g4h-5i6j_age',
'unit_of_measurement': None,
})
# ---
# name: test_all_entities[sensor.mythical_randomsavings_castle_mortgage_data_age-state]
StateSnapshot({
'attributes': ReadOnlyDict({
'attribution': 'Data provided by SimpleFIN API',
'device_class': 'timestamp',
'friendly_name': 'Mythical RandomSavings Castle Mortgage Data age',
}),
'context': <ANY>,
'entity_id': 'sensor.mythical_randomsavings_castle_mortgage_data_age',
'last_changed': <ANY>,
'last_reported': <ANY>,
'last_updated': <ANY>,
'state': '2024-01-16T18:16:42+00:00',
})
# ---
# name: test_all_entities[sensor.mythical_randomsavings_unicorn_pot_balance-entry]
EntityRegistryEntrySnapshot({
'aliases': set({
@ -264,6 +456,54 @@
'state': '10000.00',
})
# ---
# name: test_all_entities[sensor.mythical_randomsavings_unicorn_pot_data_age-entry]
EntityRegistryEntrySnapshot({
'aliases': set({
}),
'area_id': None,
'capabilities': None,
'config_entry_id': <ANY>,
'device_class': None,
'device_id': <ANY>,
'disabled_by': None,
'domain': 'sensor',
'entity_category': <EntityCategory.DIAGNOSTIC: 'diagnostic'>,
'entity_id': 'sensor.mythical_randomsavings_unicorn_pot_data_age',
'has_entity_name': True,
'hidden_by': None,
'icon': None,
'id': <ANY>,
'labels': set({
}),
'name': None,
'options': dict({
}),
'original_device_class': <SensorDeviceClass.TIMESTAMP: 'timestamp'>,
'original_icon': None,
'original_name': 'Data age',
'platform': 'simplefin',
'previous_unique_id': None,
'supported_features': 0,
'translation_key': 'age',
'unique_id': 'account_ACT-6a7b8c9d-0e1f-2g3h-4i5j_age',
'unit_of_measurement': None,
})
# ---
# name: test_all_entities[sensor.mythical_randomsavings_unicorn_pot_data_age-state]
StateSnapshot({
'attributes': ReadOnlyDict({
'attribution': 'Data provided by SimpleFIN API',
'device_class': 'timestamp',
'friendly_name': 'Mythical RandomSavings Unicorn Pot Data age',
}),
'context': <ANY>,
'entity_id': 'sensor.mythical_randomsavings_unicorn_pot_data_age',
'last_changed': <ANY>,
'last_reported': <ANY>,
'last_updated': <ANY>,
'state': '2024-01-16T18:16:42+00:00',
})
# ---
# name: test_all_entities[sensor.random_bank_costco_anywhere_visa_r_card_balance-entry]
EntityRegistryEntrySnapshot({
'aliases': set({
@ -317,6 +557,54 @@
'state': '-532.69',
})
# ---
# name: test_all_entities[sensor.random_bank_costco_anywhere_visa_r_card_data_age-entry]
EntityRegistryEntrySnapshot({
'aliases': set({
}),
'area_id': None,
'capabilities': None,
'config_entry_id': <ANY>,
'device_class': None,
'device_id': <ANY>,
'disabled_by': None,
'domain': 'sensor',
'entity_category': <EntityCategory.DIAGNOSTIC: 'diagnostic'>,
'entity_id': 'sensor.random_bank_costco_anywhere_visa_r_card_data_age',
'has_entity_name': True,
'hidden_by': None,
'icon': None,
'id': <ANY>,
'labels': set({
}),
'name': None,
'options': dict({
}),
'original_device_class': <SensorDeviceClass.TIMESTAMP: 'timestamp'>,
'original_icon': None,
'original_name': 'Data age',
'platform': 'simplefin',
'previous_unique_id': None,
'supported_features': 0,
'translation_key': 'age',
'unique_id': 'account_ACT-3a4b5c6d-7e8f-9g0h-1i2j_age',
'unit_of_measurement': None,
})
# ---
# name: test_all_entities[sensor.random_bank_costco_anywhere_visa_r_card_data_age-state]
StateSnapshot({
'attributes': ReadOnlyDict({
'attribution': 'Data provided by SimpleFIN API',
'device_class': 'timestamp',
'friendly_name': 'Random Bank Costco Anywhere Visa® Card Data age',
}),
'context': <ANY>,
'entity_id': 'sensor.random_bank_costco_anywhere_visa_r_card_data_age',
'last_changed': <ANY>,
'last_reported': <ANY>,
'last_updated': <ANY>,
'state': '2024-01-16T18:16:42+00:00',
})
# ---
# name: test_all_entities[sensor.the_bank_of_go_prime_savings_balance-entry]
EntityRegistryEntrySnapshot({
'aliases': set({
@ -370,6 +658,54 @@
'state': '9876.54',
})
# ---
# name: test_all_entities[sensor.the_bank_of_go_prime_savings_data_age-entry]
EntityRegistryEntrySnapshot({
'aliases': set({
}),
'area_id': None,
'capabilities': None,
'config_entry_id': <ANY>,
'device_class': None,
'device_id': <ANY>,
'disabled_by': None,
'domain': 'sensor',
'entity_category': <EntityCategory.DIAGNOSTIC: 'diagnostic'>,
'entity_id': 'sensor.the_bank_of_go_prime_savings_data_age',
'has_entity_name': True,
'hidden_by': None,
'icon': None,
'id': <ANY>,
'labels': set({
}),
'name': None,
'options': dict({
}),
'original_device_class': <SensorDeviceClass.TIMESTAMP: 'timestamp'>,
'original_icon': None,
'original_name': 'Data age',
'platform': 'simplefin',
'previous_unique_id': None,
'supported_features': 0,
'translation_key': 'age',
'unique_id': 'account_ACT-2a3b4c5d-6e7f-8g9h-0i1j_age',
'unit_of_measurement': None,
})
# ---
# name: test_all_entities[sensor.the_bank_of_go_prime_savings_data_age-state]
StateSnapshot({
'attributes': ReadOnlyDict({
'attribution': 'Data provided by SimpleFIN API',
'device_class': 'timestamp',
'friendly_name': 'The Bank of Go PRIME SAVINGS Data age',
}),
'context': <ANY>,
'entity_id': 'sensor.the_bank_of_go_prime_savings_data_age',
'last_changed': <ANY>,
'last_reported': <ANY>,
'last_updated': <ANY>,
'state': '2024-01-16T18:14:21+00:00',
})
# ---
# name: test_all_entities[sensor.the_bank_of_go_the_bank_balance-entry]
EntityRegistryEntrySnapshot({
'aliases': set({
@ -423,3 +759,51 @@
'state': '7777.77',
})
# ---
# name: test_all_entities[sensor.the_bank_of_go_the_bank_data_age-entry]
EntityRegistryEntrySnapshot({
'aliases': set({
}),
'area_id': None,
'capabilities': None,
'config_entry_id': <ANY>,
'device_class': None,
'device_id': <ANY>,
'disabled_by': None,
'domain': 'sensor',
'entity_category': <EntityCategory.DIAGNOSTIC: 'diagnostic'>,
'entity_id': 'sensor.the_bank_of_go_the_bank_data_age',
'has_entity_name': True,
'hidden_by': None,
'icon': None,
'id': <ANY>,
'labels': set({
}),
'name': None,
'options': dict({
}),
'original_device_class': <SensorDeviceClass.TIMESTAMP: 'timestamp'>,
'original_icon': None,
'original_name': 'Data age',
'platform': 'simplefin',
'previous_unique_id': None,
'supported_features': 0,
'translation_key': 'age',
'unique_id': 'account_ACT-1a2b3c4d-5e6f-7g8h-9i0j_age',
'unit_of_measurement': None,
})
# ---
# name: test_all_entities[sensor.the_bank_of_go_the_bank_data_age-state]
StateSnapshot({
'attributes': ReadOnlyDict({
'attribution': 'Data provided by SimpleFIN API',
'device_class': 'timestamp',
'friendly_name': 'The Bank of Go The Bank Data age',
}),
'context': <ANY>,
'entity_id': 'sensor.the_bank_of_go_the_bank_data_age',
'last_changed': <ANY>,
'last_reported': <ANY>,
'last_updated': <ANY>,
'state': '2024-01-16T14:04:03+00:00',
})
# ---