Skip to content

Commit

Permalink
Feature/15 energidataservice (#23)
Browse files Browse the repository at this point in the history
* #15

Co-authored-by: magnuselden <magnu@DESKTOP-ACV2GPT>
  • Loading branch information
elden1337 and magnuselden authored Aug 15, 2023
1 parent 3dffe7c commit 9cbe2c4
Show file tree
Hide file tree
Showing 13 changed files with 369 additions and 212 deletions.
2 changes: 1 addition & 1 deletion custom_components/peaqnext/manifest.json
Original file line number Diff line number Diff line change
Expand Up @@ -13,5 +13,5 @@
"integration_type": "hub",
"iot_class": "calculated",
"issue_tracker": "https://github.com/elden1337/hass-peaqnext/issues",
"version": "0.3.0"
"version": "0.4.0b151"
}
5 changes: 4 additions & 1 deletion custom_components/peaqnext/sensors/next_sensor.py
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,7 @@ def __init__(self, hub: Hub, entry_id, given_name):
self._duration_in_minutes = None
self._consumption_in_kwh = None
self._raw_start = None
self._price_source: str|None = None
self._non_hours_start = []
self._non_hours_end = []
self._closest_cheap_hour = None
Expand All @@ -53,6 +54,7 @@ async def async_update(self) -> None:
self._non_hours_start = status.get("non_hours_start", [])
self._non_hours_end = status.get("non_hours_end", [])
self._closest_cheap_hour = status.get("closest_cheap_hour", 12)
self._price_source = status.get("price_source", "unknown").capitalize()

@property
def extra_state_attributes(self) -> dict:
Expand All @@ -68,6 +70,7 @@ def extra_state_attributes(self) -> dict:
if len(self._non_hours_end) > 0:
attr_dict["Non hours end"] = self._non_hours_end
attr_dict["raw_start"]= self._raw_start
attr_dict["price_source"] = self._price_source
return attr_dict

@property
Expand All @@ -94,7 +97,7 @@ def _make_dict(self, model: list[HourModel]) -> list[str]:
def _make_price(self, model: HourModel) -> str:
if model is None:
return ""
return f"({model.price} {self.hub.nordpool.currency})"
return f"({model.price} {self.hub.spotprice.currency})"

def _make_string(self, model: HourModel) -> str:
if not self._check_hourmodel(model):
Expand Down
25 changes: 14 additions & 11 deletions custom_components/peaqnext/service/hub.py
Original file line number Diff line number Diff line change
Expand Up @@ -3,12 +3,14 @@
from typing import Any
from datetime import datetime
from custom_components.peaqnext.service.models.sensor_model import NextSensor
from custom_components.peaqnext.service.nordpool.nordpool import NordPoolUpdater
from custom_components.peaqnext.service.spotprice.ispotprice import ISpotPrice
from custom_components.peaqnext.service.spotprice.spotprice_factory import SpotPriceFactory
from homeassistant.core import HomeAssistant, callback
from homeassistant.helpers.event import async_track_state_change

_LOGGER = logging.getLogger(__name__)
NORDPOOL_UPDATE_FORCE = 60
SPOTPRICE_UPDATE_FORCE = 60



class Hub:
Expand All @@ -21,13 +23,13 @@ def __init__(self, hass, test:bool = False) -> Any:
self.sensors: list[NextSensor] = []
self._current_minute: int = None
self.prices: tuple[list,list] = ([], [])
self.nordpool = NordPoolUpdater(self, test)
self.latest_nordpool_update = 0
self.spotprice: ISpotPrice = SpotPriceFactory.create(self, test)
self.latest_spotprice_update = 0
self.sensors_dict: dict[str:NextSensor] = {}
if not test:
async_track_state_change(
self.state_machine,
[self.nordpool.nordpool_entity],
[self.spotprice.entity],
self.async_state_changed,
)

Expand All @@ -40,18 +42,18 @@ async def async_update_prices(self, prices: tuple[list,list]) -> None:
self.prices = prices
for s in self.sensors:
try:
await s.async_update_sensor(prices, self.nordpool.use_cent, self.nordpool.currency)
await s.async_update_sensor(prices, self.spotprice.use_cent, self.spotprice.currency)
except Exception as e:
_LOGGER.error(
f"Unable to update sensor: {s.hass_entity_id}. Exception: {e}"
)

async def async_get_updates(self, sensor_id: str) -> dict:
if time.time() - self.latest_nordpool_update > NORDPOOL_UPDATE_FORCE:
await self.nordpool.async_update_nordpool()
self.latest_nordpool_update = time.time()
if time.time() - self.latest_spotprice_update > SPOTPRICE_UPDATE_FORCE:
await self.spotprice.async_update_spotprice()
self.latest_spotprice_update = time.time()
await self.async_update_prices(
(self.nordpool.prices, self.nordpool.prices_tomorrow)
(self.spotprice.prices, self.spotprice.prices_tomorrow)
)
active_sensor: NextSensor = self.sensors_dict.get(sensor_id, None)
return await self.async_get_sensor_updates(active_sensor)
Expand All @@ -72,14 +74,15 @@ async def async_get_sensor_updates(self, active_sensor: NextSensor) -> dict:
"non_hours_start": active_sensor.non_hours_start,
"non_hours_end": active_sensor.non_hours_end,
"closest_cheap_hour": active_sensor.default_closest_cheap,
"price_source": self.spotprice.source,
}

@callback
async def async_state_changed(self, entity_id, old_state, new_state):
if entity_id is not None:
try:
if old_state is None or old_state != new_state:
await self.nordpool.async_update_nordpool()
await self.spotprice.async_update_spotprice()
except Exception as e:
msg = f"Unable to handle data-update: {entity_id} {old_state}|{new_state}. Exception: {e}"
_LOGGER.error(msg)
123 changes: 0 additions & 123 deletions custom_components/peaqnext/service/nordpool/nordpool.py

This file was deleted.

38 changes: 0 additions & 38 deletions custom_components/peaqnext/service/nordpool/nordpool_dto.py

This file was deleted.

3 changes: 3 additions & 0 deletions custom_components/peaqnext/service/spotprice/const.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
NORDPOOL = "nordpool"
ENERGIDATASERVICE = "energidataservice"
ENERGIDATASERVICE_SENSOR = "sensor.energi_data_service"
40 changes: 40 additions & 0 deletions custom_components/peaqnext/service/spotprice/energidataservice.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,40 @@
from custom_components.peaqnext.service.spotprice.ispotprice import ISpotPrice
from custom_components.peaqnext.service.spotprice.spotprice_dto import EnergiDataServiceDTO
from custom_components.peaqnext.service.spotprice.const import ENERGIDATASERVICE, ENERGIDATASERVICE_SENSOR
import asyncio
import logging

_LOGGER = logging.getLogger(__name__)


class EnergiDataServiceUpdater(ISpotPrice):
def __init__(self, hub, test:bool = False):
super().__init__(hub=hub, source=ENERGIDATASERVICE, test=test)

async def async_set_dto(self, ret) -> None:
_result = EnergiDataServiceDTO()
await _result.set_model(ret)
if await self.async_update_set_prices(_result):
await self.hub.async_update_prices(
(self.prices, self.prices_tomorrow)
)
self._is_initialized = True

def setup(self):
try:
sensor = self.state_machine.states.get(ENERGIDATASERVICE_SENSOR)
if not sensor.state:
raise Exception("no entities found for Spotprice.")
else:
self._entity = ENERGIDATASERVICE_SENSOR
_LOGGER.debug(
f"EnergiDataService has been set up and is ready to be used with {self.entity}"
)
asyncio.run_coroutine_threadsafe(
self.async_update_spotprice(),
self.state_machine.loop,
)
except Exception as e:
_LOGGER.error(
f"I was unable to get a Spotprice-entity. Cannot continue.: {e}"
)
Loading

0 comments on commit 9cbe2c4

Please sign in to comment.