Skip to content

Commit

Permalink
Support price integration with prices in one attribute.
Browse files Browse the repository at this point in the history
  • Loading branch information
jonasbkarlsson authored Jan 12, 2025
1 parent 1c734f3 commit 7633de5
Show file tree
Hide file tree
Showing 3 changed files with 51 additions and 5 deletions.
14 changes: 14 additions & 0 deletions custom_components/ev_smart_charging/helpers/coordinator.py
Original file line number Diff line number Diff line change
Expand Up @@ -229,6 +229,20 @@ def to_local(self):
item["end"] = dt.as_local(item["end"])
return self

def today(self):
"""Only keep today's data"""
today = dt.now().date()
self.data = [item for item in self.data if item["start"].date() == today]
self.valid = len(self.data) > 12
return self

def tomorrow(self):
"""Only keep tomorrow's data"""
tomorrow = dt.now().date() + timedelta(days=1)
self.data = [item for item in self.data if item["start"].date() == tomorrow]
self.valid = len(self.data) > 12
return self


def get_lowest_hours(
start_hour: datetime,
Expand Down
28 changes: 24 additions & 4 deletions custom_components/ev_smart_charging/helpers/price_adaptor.py
Original file line number Diff line number Diff line change
Expand Up @@ -49,20 +49,36 @@ def initiate(self, price_state: State) -> bool:
# This should only happen when testing
return True

# First try for the attributes used by integration using
# separate attributes for today and tomorrow.
if "prices_today" in price_state.attributes:
self._price_attribute_today = "prices_today"
self._price_attribute_tomorrow = "prices_tomorrow"
elif "raw_today" in price_state.attributes:
self._price_attribute_today = "raw_today"
self._price_attribute_tomorrow = "raw_tomorrow"

# Then try for the attributes used by integration using
# the same attribute for today and tomorrow.
else:
self._price_attribute_today = next(
(
attr
for attr in ["prices", "data", "forecast"]
if attr in price_state.attributes
),
None,
)
self._price_attribute_tomorrow = self._price_attribute_today

if not self._price_attribute_today:
return False

# Set _price_key.start and _price_key.value
try:
keys = price_state.attributes[self._price_attribute_today][0]
start_keys = ["time", "start", "hour"]
value_keys = ["price", "value"]
start_keys = ["time", "start", "hour", "start_time", "datetime"]
value_keys = ["price", "value", "price_ct_per_kwh", "electricity_price"]

self._price_format.start = next(
(key for key in start_keys if key in keys), None
Expand Down Expand Up @@ -120,11 +136,15 @@ def is_price_state(self, price_state: State) -> bool:

def get_raw_today_local(self, state) -> Raw:
"""Get the today's prices in local timezone"""
return Raw(state.attributes[self._price_attribute_today], self._price_format)
return Raw(
state.attributes[self._price_attribute_today], self._price_format
).today()

def get_raw_tomorrow_local(self, state) -> Raw:
"""Get the tomorrow's prices in local timezone"""
return Raw(state.attributes[self._price_attribute_tomorrow], self._price_format)
return Raw(
state.attributes[self._price_attribute_tomorrow], self._price_format
).tomorrow()

def get_current_price(self, state) -> float:
"""Return current price."""
Expand Down
14 changes: 13 additions & 1 deletion tests/helpers/test_coordinator.py
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
"""Test ev_smart_charging/helpers/coordinator.py"""

from datetime import datetime

from homeassistant.util import dt as dt_util
Expand Down Expand Up @@ -42,16 +43,20 @@


# pylint: disable=unused-argument
async def test_raw(hass, set_cet_timezone):
async def test_raw(hass, set_cet_timezone, freezer):
"""Test Raw"""

freezer.move_to("2022-09-30T00:10:00+02:00")

price = Raw(PRICE_20220930)
assert price.get_raw() == PRICE_20220930
assert price.is_valid()
assert price.copy().get_raw() == PRICE_20220930
assert price.max_value() == 388.65
assert price.last_value() == 49.64
assert price.number_of_nonzero() == 24
assert len(price.copy().today().get_raw()) == 24
assert len(price.copy().tomorrow().get_raw()) == 0

time = datetime(
2022, 9, 30, 8, 0, 0, tzinfo=dt_util.get_time_zone("Europe/Stockholm")
Expand All @@ -77,6 +82,8 @@ async def test_raw(hass, set_cet_timezone):
assert price.get_raw() == PRICE_20220930
price.extend(price2)
assert price.number_of_nonzero() == 48
assert len(price.copy().today().get_raw()) == 24
assert len(price.copy().tomorrow().get_raw()) == 24

start = price.data[0]["start"]
assert start.tzinfo == dt_util.get_time_zone("Europe/Stockholm")
Expand All @@ -94,6 +101,9 @@ async def test_raw(hass, set_cet_timezone):
assert not price.is_valid()
assert price.last_value() is None

price = Raw(PRICE_20221001)
assert len(price.copy().today().get_raw()) == 0


async def test_raw_energidataservice(hass, set_cet_timezone):
"""Test Raw"""
Expand Down Expand Up @@ -205,6 +215,7 @@ async def test_raw_entsoe(hass, set_cet_timezone, freezer):
assert not price.is_valid()
assert price.last_value() is None


async def test_raw_tge(hass, set_cet_timezone):
"""Test Raw"""

Expand Down Expand Up @@ -258,6 +269,7 @@ async def test_raw_tge(hass, set_cet_timezone):
assert not price.is_valid()
assert price.last_value() is None


async def test_get_lowest_hours_non_continuous(hass, set_cet_timezone, freezer):
"""Test get_lowest_hours()"""

Expand Down

0 comments on commit 7633de5

Please sign in to comment.