Skip to content

Commit 37ad73d

Browse files
authored
Merge pull request #167 from nickknissen/feat/latest-transaction-sensor
Feat/latest transaction sensor
2 parents cdec5d7 + 5c5899d commit 37ad73d

File tree

4 files changed

+91
-18
lines changed

4 files changed

+91
-18
lines changed

.vscode/launch.json

Lines changed: 10 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -8,10 +8,12 @@
88
// Debug by attaching to local Home Assistant server using Remote Python Debugger.
99
// See https://www.home-assistant.io/integrations/debugpy/
1010
"name": "Home Assistant: Attach Local",
11-
"type": "python",
11+
"type": "debugpy",
1212
"request": "attach",
13-
"port": 5678,
14-
"host": "localhost",
13+
"connect": {
14+
"port": 5678,
15+
"host": "localhost",
16+
},
1517
"pathMappings": [
1618
{
1719
"localRoot": "${workspaceFolder}",
@@ -23,10 +25,12 @@
2325
// Debug by attaching to remote Home Assistant server using Remote Python Debugger.
2426
// See https://www.home-assistant.io/integrations/debugpy/
2527
"name": "Home Assistant: Attach Remote",
26-
"type": "python",
28+
"type": "debugpy",
2729
"request": "attach",
28-
"port": 5678,
29-
"host": "homeassistant.local",
30+
"connect": {
31+
"port": 5678,
32+
"host": "homeassistant.local",
33+
},
3034
"pathMappings": [
3135
{
3236
"localRoot": "${workspaceFolder}",

custom_components/monta/const.py

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,7 @@
1212

1313
ATTR_CHARGE_POINTS = "charge_points"
1414
ATTR_WALLET = "wallet"
15+
ATTR_TRANSACTIONS = "transactions"
1516

1617
PREEMPTIVE_REFRESH_TTL_IN_SECONDS = 300
1718
STORAGE_KEY = "monta_auth"

custom_components/monta/coordinator.py

Lines changed: 9 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -10,10 +10,9 @@
1010
from homeassistant.helpers.update_coordinator import DataUpdateCoordinator, UpdateFailed
1111

1212
from .api import MontaApiClient, MontaApiClientAuthenticationError, MontaApiClientError
13-
from .const import ATTR_CHARGE_POINTS, ATTR_WALLET, DOMAIN, LOGGER
13+
from .const import ATTR_CHARGE_POINTS, ATTR_TRANSACTIONS, ATTR_WALLET, DOMAIN, LOGGER
1414

1515

16-
# https://developers.home-assistant.io/docs/integration_fetching_data#coordinated-single-api-poll-for-data-for-all-entities
1716
class MontaDataUpdateCoordinator(DataUpdateCoordinator):
1817
"""Class to manage fetching data from the API."""
1918

@@ -37,8 +36,15 @@ async def _async_update_data(self):
3736
charge_points[charge_point_id][
3837
"charges"
3938
] = await self.client.async_get_charges(charge_point_id)
39+
4040
personal_wallet = await self.client.async_get_personal_wallet()
41-
return {ATTR_CHARGE_POINTS: charge_points, ATTR_WALLET: personal_wallet}
41+
wallet_transactions = await self.client.async_get_wallet_transactions()
42+
43+
return {
44+
ATTR_CHARGE_POINTS: charge_points,
45+
ATTR_WALLET: personal_wallet,
46+
ATTR_TRANSACTIONS: wallet_transactions,
47+
}
4248
except MontaApiClientAuthenticationError as exception:
4349
raise ConfigEntryAuthFailed(exception) from exception
4450
except MontaApiClientError as exception:

custom_components/monta/sensor.py

Lines changed: 71 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -27,6 +27,7 @@
2727

2828
from .const import (
2929
ATTR_CHARGE_POINTS,
30+
ATTR_TRANSACTIONS,
3031
ATTR_WALLET,
3132
ATTRIBUTION,
3233
DOMAIN,
@@ -178,6 +179,16 @@ def _parse_date(chargedate: str):
178179
),
179180
)
180181

182+
TRANSACTION_ENTITY_DESCRIPTIONS: tuple[MontaSensorEntityDescription, ...] = (
183+
MontaSensorEntityDescription( # pylint: disable=unexpected-keyword-arg
184+
key="monta-latest-wallet-transactions",
185+
name="Monta - Latest Wallet Transactions",
186+
icon="mdi:wallet-outline",
187+
value_fn=lambda data: data,
188+
extra_state_attributes_fn=None,
189+
),
190+
)
191+
181192

182193
async def async_setup_entry(
183194
hass: HomeAssistant, entry: ConfigEntry, async_add_entities: AddEntitiesCallback
@@ -197,16 +208,19 @@ async def async_setup_entry(
197208
for description in CHARGE_POINT_ENTITY_DESCRIPTIONS
198209
]
199210
)
211+
200212
async_add_entities(
201213
[
202-
MontaWalletSensor(
203-
coordinator,
204-
entry,
205-
description,
206-
)
214+
MontaWalletSensor(coordinator, entry, description)
207215
for description in WALLET_ENTITY_DESCRIPTIONS
208216
]
209217
)
218+
async_add_entities(
219+
[
220+
MontaTransactionsSensor(coordinator, entry, description)
221+
for description in TRANSACTION_ENTITY_DESCRIPTIONS
222+
]
223+
)
210224

211225

212226
class MontaChargePointSensor(MontaEntity, SensorEntity):
@@ -276,10 +290,7 @@ def __init__(
276290
@property
277291
def native_unit_of_measurement(self) -> str | None:
278292
"""Return the unit of measurement of the sensor."""
279-
if (
280-
self.entity_description.key == "monta-wallet-amount"
281-
and self.coordinator.data
282-
):
293+
if self.coordinator.data:
283294
wallet_data = self.coordinator.data.get(ATTR_WALLET, {})
284295
if wallet_currency := wallet_data.get("currency"):
285296
return wallet_currency.get("identifier", "").upper()
@@ -302,3 +313,54 @@ def extra_state_attributes(self) -> dict[str, str] | None:
302313
self.coordinator.data[ATTR_WALLET]
303314
)
304315
return None
316+
317+
318+
class MontaTransactionsSensor(
319+
CoordinatorEntity[MontaDataUpdateCoordinator], SensorEntity
320+
):
321+
"""monta Sensor class."""
322+
323+
_attr_attribution = ATTRIBUTION
324+
_attr_has_entity_name = True
325+
326+
def __init__(
327+
self,
328+
coordinator: MontaDataUpdateCoordinator,
329+
_: ConfigEntry,
330+
entity_description: SensorEntityDescription,
331+
) -> None:
332+
"""Initialize the sensor class."""
333+
super().__init__(coordinator)
334+
335+
self.entity_description = entity_description
336+
self._attr_unique_id = generate_entity_id(
337+
ENTITY_ID_FORMAT,
338+
f"monta_{snake_case(entity_description.key)}",
339+
"monta_latest_transactions",
340+
)
341+
342+
@property
343+
def native_value(self) -> StateType:
344+
"""Return the state."""
345+
return self.entity_description.value_fn(
346+
self.coordinator.data[ATTR_TRANSACTIONS][0]["state"]
347+
)
348+
349+
@property
350+
def extra_attributes(self) -> str:
351+
"""Return extra attributes for the sensor."""
352+
return None
353+
354+
@property
355+
def extra_state_attributes(self) -> dict[str, str] | None:
356+
"""Converts the dates to correct home assitant format."""
357+
attributes = {}
358+
359+
if data := self.coordinator.data.get(ATTR_TRANSACTIONS, []):
360+
for transaction in data:
361+
for key in WALLET_DATE_KEYS:
362+
if key in transaction:
363+
transaction[key] = _parse_date(transaction[key])
364+
attributes["transactions"] = data
365+
366+
return attributes

0 commit comments

Comments
 (0)