Skip to content

Commit

Permalink
Const and Bug Fixes
Browse files Browse the repository at this point in the history
  • Loading branch information
frlequ committed Jan 3, 2025
1 parent 7bdf222 commit f51048b
Show file tree
Hide file tree
Showing 4 changed files with 151 additions and 82 deletions.
72 changes: 50 additions & 22 deletions custom_components/energy_and_tariff_costs/__init__.py
Original file line number Diff line number Diff line change
@@ -1,10 +1,38 @@
# __init__.py

from homeassistant.core import HomeAssistant
from homeassistant.config_entries import ConfigEntry
from homeassistant.helpers import device_registry as dr
from .const import (
DOMAIN, VT_PRICE, MT_PRICE, TAX,
BLOK_1_CONS_PRICE, BLOK_2_CONS_PRICE, BLOK_3_CONS_PRICE, BLOK_4_CONS_PRICE, BLOK_5_CONS_PRICE,
BLOK_1_TAR_PRICE, BLOK_2_TAR_PRICE, BLOK_3_TAR_PRICE, BLOK_4_TAR_PRICE, BLOK_5_TAR_PRICE
DOMAIN,
VT_PRICE,
MT_PRICE,
TAX,
ADDITIONAL_PRICE,
BLOK_1_CONS_PRICE,
BLOK_2_CONS_PRICE,
BLOK_3_CONS_PRICE,
BLOK_4_CONS_PRICE,
BLOK_5_CONS_PRICE,
BLOK_1_TAR_PRICE,
BLOK_2_TAR_PRICE,
BLOK_3_TAR_PRICE,
BLOK_4_TAR_PRICE,
BLOK_5_TAR_PRICE,
VT_PRICE_INITIAL,
MT_PRICE_INITIAL,
TAX_INITIAL,
ADDITIONAL_PRICE_INITIAL,
BLOK_1_CONS_PRICE_INITIAL,
BLOK_2_CONS_PRICE_INITIAL,
BLOK_3_CONS_PRICE_INITIAL,
BLOK_4_CONS_PRICE_INITIAL,
BLOK_5_CONS_PRICE_INITIAL,
BLOK_1_TAR_PRICE_INITIAL,
BLOK_2_TAR_PRICE_INITIAL,
BLOK_3_TAR_PRICE_INITIAL,
BLOK_4_TAR_PRICE_INITIAL,
BLOK_5_TAR_PRICE_INITIAL,
)

async def async_setup(hass: HomeAssistant, config: dict):
Expand All @@ -17,30 +45,30 @@ async def async_setup_entry(hass: HomeAssistant, entry: ConfigEntry):
device_registry.async_get_or_create(
config_entry_id=entry.entry_id,
identifiers={identifiers},
name="Energy Costs Device",
manufacturer="Test Manufacturer",
model="Test Model"
name="Energy & Tariff Costs",
manufacturer="Energy & Tariff Costs",
model="Beta"
)

hass.data.setdefault(DOMAIN, {})
hass.data[DOMAIN][entry.entry_id] = {
"device_identifiers": identifiers,
"vt_price_initial": 0.084000,
"mt_price_initial": 0.070000,
"tax_initial": 22.0,
"additional_price_initial": 1.96,

"blok_1_consumption_price_initial": 0.019580,
"blok_2_consumption_price_initial": 0.018440,
"blok_3_consumption_price_initial": 0.018370,
"blok_4_consumption_price_initial": 0.018380,
"blok_5_consumption_price_initial": 0.0,

"blok_1_tariff_price_initial": 3.613240,
"blok_2_tariff_price_initial": 0.882400,
"blok_3_tariff_price_initial": 0.191370,
"blok_4_tariff_price_initial": 0.013160,
"blok_5_tariff_price_initial": 0.0,
VT_PRICE: VT_PRICE_INITIAL,
MT_PRICE: MT_PRICE_INITIAL,
TAX: TAX_INITIAL,
ADDITIONAL_PRICE: ADDITIONAL_PRICE_INITIAL,

BLOK_1_CONS_PRICE: BLOK_1_CONS_PRICE_INITIAL,
BLOK_2_CONS_PRICE: BLOK_2_CONS_PRICE_INITIAL,
BLOK_3_CONS_PRICE: BLOK_3_CONS_PRICE_INITIAL,
BLOK_4_CONS_PRICE: BLOK_4_CONS_PRICE_INITIAL,
BLOK_5_CONS_PRICE: BLOK_5_CONS_PRICE_INITIAL,

BLOK_1_TAR_PRICE: BLOK_1_TAR_PRICE_INITIAL,
BLOK_2_TAR_PRICE: BLOK_2_TAR_PRICE_INITIAL,
BLOK_3_TAR_PRICE: BLOK_3_TAR_PRICE_INITIAL,
BLOK_4_TAR_PRICE: BLOK_4_TAR_PRICE_INITIAL,
BLOK_5_TAR_PRICE: BLOK_5_TAR_PRICE_INITIAL,
}

await hass.config_entries.async_forward_entry_setup(entry, "number")
Expand Down
28 changes: 26 additions & 2 deletions custom_components/energy_and_tariff_costs/const.py
Original file line number Diff line number Diff line change
@@ -1,27 +1,51 @@
# const.py

DOMAIN = "energy_and_tariff_costs"
INITIALS = "etc"

# Price Keys
VT_PRICE = "energy_high_tariff_price"
MT_PRICE = "energy_low_tariff_price"
TAX = "tax"
ADDITIONAL_PRICE = "additional_price"

# Consumption Price Keys
BLOK_1_CONS_PRICE = "blok_1_consumption_price"
BLOK_2_CONS_PRICE = "blok_2_consumption_price"
BLOK_3_CONS_PRICE = "blok_3_consumption_price"
BLOK_4_CONS_PRICE = "blok_4_consumption_price"
BLOK_5_CONS_PRICE = "blok_5_consumption_price"

# Tariff Price Keys
BLOK_1_TAR_PRICE = "blok_1_tariff_price"
BLOK_2_TAR_PRICE = "blok_2_tariff_price"
BLOK_3_TAR_PRICE = "blok_3_tariff_price"
BLOK_4_TAR_PRICE = "blok_4_tariff_price"
BLOK_5_TAR_PRICE = "blok_5_tariff_price"

# Initial Values (Januar 2025)
VT_PRICE_INITIAL = 0.084000
MT_PRICE_INITIAL = 0.070000
TAX_INITIAL = 22.0
ADDITIONAL_PRICE_INITIAL = 1.96

BLOK_1_CONS_PRICE_INITIAL = 0.01998
BLOK_2_CONS_PRICE_INITIAL = 0.01833
BLOK_3_CONS_PRICE_INITIAL = 0.01809
BLOK_4_CONS_PRICE_INITIAL = 0.01855
BLOK_5_CONS_PRICE_INITIAL = 0.01873

BLOK_1_TAR_PRICE_INITIAL = 3.42250
BLOK_2_TAR_PRICE_INITIAL = 0.91224
BLOK_3_TAR_PRICE_INITIAL = 0.16297
BLOK_4_TAR_PRICE_INITIAL = 0.00407
BLOK_5_TAR_PRICE_INITIAL = 0.0

# Sensor Definitions
MOJELEKTRO_PEAK = "sensor.moj_elektro_monthly_input_peak"
MOJELEKTRO_OFFPEAK = "sensor.moj_elektro_monthly_input_offpeak"

# New block sensors
# New Block Sensors
MOJELEKTRO_BLOK_1 = "sensor.moj_elektro_casovni_blok_1"
MOJELEKTRO_BLOK_2 = "sensor.moj_elektro_casovni_blok_2"
MOJELEKTRO_BLOK_3 = "sensor.moj_elektro_casovni_blok_3"
Expand All @@ -32,4 +56,4 @@
MOJELEKTRO_DAILY_BLOK_2 = "sensor.moj_elektro_daily_input_blok_2"
MOJELEKTRO_DAILY_BLOK_3 = "sensor.moj_elektro_daily_input_blok_3"
MOJELEKTRO_DAILY_BLOK_4 = "sensor.moj_elektro_daily_input_blok_4"
MOJELEKTRO_DAILY_BLOK_5 = "sensor.moj_elektro_daily_input_blok_5"
MOJELEKTRO_DAILY_BLOK_5 = "sensor.moj_elektro_daily_input_blok_5"
67 changes: 40 additions & 27 deletions custom_components/energy_and_tariff_costs/number.py
Original file line number Diff line number Diff line change
@@ -1,42 +1,42 @@
# number.py

from homeassistant.config_entries import ConfigEntry
from homeassistant.core import HomeAssistant
from homeassistant.components.number import NumberEntity, NumberMode
from homeassistant.helpers.entity_platform import AddEntitiesCallback
from homeassistant.helpers.restore_state import RestoreEntity
from .const import (
DOMAIN, INITIALS, VT_PRICE, MT_PRICE, TAX,ADDITIONAL_PRICE,
DOMAIN, INITIALS, VT_PRICE, MT_PRICE, TAX, ADDITIONAL_PRICE,
BLOK_1_CONS_PRICE, BLOK_2_CONS_PRICE, BLOK_3_CONS_PRICE, BLOK_4_CONS_PRICE, BLOK_5_CONS_PRICE,
BLOK_1_TAR_PRICE, BLOK_2_TAR_PRICE, BLOK_3_TAR_PRICE, BLOK_4_TAR_PRICE, BLOK_5_TAR_PRICE
)

def friendly_name_from_id(name: str) -> str:
return name.replace("_", " ").title()

async def async_setup_entry(hass: HomeAssistant, entry: ConfigEntry, async_add_entities: AddEntitiesCallback):
async def async_setup_entry(
hass: HomeAssistant,
entry: ConfigEntry,
async_add_entities: AddEntitiesCallback
):
data = hass.data[DOMAIN][entry.entry_id]
device_identifiers = data["device_identifiers"]


to_create = [
(VT_PRICE, data["vt_price_initial"]),
(MT_PRICE, data["mt_price_initial"]),
(TAX, data["tax_initial"]),

(BLOK_1_CONS_PRICE, data["blok_1_consumption_price_initial"]),
(BLOK_2_CONS_PRICE, data["blok_2_consumption_price_initial"]),
(BLOK_3_CONS_PRICE, data["blok_3_consumption_price_initial"]),
(BLOK_4_CONS_PRICE, data["blok_4_consumption_price_initial"]),
(BLOK_5_CONS_PRICE, data["blok_5_consumption_price_initial"]),

(BLOK_1_TAR_PRICE, data["blok_1_tariff_price_initial"]),
(BLOK_2_TAR_PRICE, data["blok_2_tariff_price_initial"]),
(BLOK_3_TAR_PRICE, data["blok_3_tariff_price_initial"]),
(BLOK_4_TAR_PRICE, data["blok_4_tariff_price_initial"]),
(BLOK_5_TAR_PRICE, data["blok_5_tariff_price_initial"]),

(ADDITIONAL_PRICE, data["additional_price_initial"])


(VT_PRICE, data[VT_PRICE]),
(MT_PRICE, data[MT_PRICE]),
(TAX, data[TAX]),
(ADDITIONAL_PRICE, data[ADDITIONAL_PRICE]),
(BLOK_1_CONS_PRICE, data[BLOK_1_CONS_PRICE]),
(BLOK_2_CONS_PRICE, data[BLOK_2_CONS_PRICE]),
(BLOK_3_CONS_PRICE, data[BLOK_3_CONS_PRICE]),
(BLOK_4_CONS_PRICE, data[BLOK_4_CONS_PRICE]),
(BLOK_5_CONS_PRICE, data[BLOK_5_CONS_PRICE]),
(BLOK_1_TAR_PRICE, data[BLOK_1_TAR_PRICE]),
(BLOK_2_TAR_PRICE, data[BLOK_2_TAR_PRICE]),
(BLOK_3_TAR_PRICE, data[BLOK_3_TAR_PRICE]),
(BLOK_4_TAR_PRICE, data[BLOK_4_TAR_PRICE]),
(BLOK_5_TAR_PRICE, data[BLOK_5_TAR_PRICE]),
]

entities = [
Expand All @@ -47,7 +47,13 @@ async def async_setup_entry(hass: HomeAssistant, entry: ConfigEntry, async_add_e
async_add_entities(entities, True)

class EnergyCostNumber(NumberEntity, RestoreEntity):
def __init__(self, entry: ConfigEntry, name: str, initial_value: float, device_identifiers):
def __init__(
self,
entry: ConfigEntry,
name: str,
initial_value: float,
device_identifiers
):
self._entry = entry
self._name_id = name
self.entity_id = f"number.{INITIALS}_{name}"
Expand All @@ -62,8 +68,6 @@ def __init__(self, entry: ConfigEntry, name: str, initial_value: float, device_i
self._attr_max_value = 10.0
self._attr_step = 0.0001
self._attr_icon = "mdi:currency-eur"

# Don't set self._state here; wait for restore or fallback to initial value in async_added_to_hass

async def async_added_to_hass(self):
await super().async_added_to_hass()
Expand All @@ -79,7 +83,8 @@ async def async_added_to_hass(self):
self._state = self._initial_value

@property
def state(self):
def native_value(self) -> float:
"""Return the current value."""
return self._state

@property
Expand All @@ -91,6 +96,14 @@ def device_info(self):
"model": "Beta",
}

async def async_set_value(self, value: float):
async def async_set_native_value(self, value: float):
"""Set the new value."""
self._state = value
self.async_write_ha_state()
# Here you can add any additional logic needed when the value is set,
# such as updating `hass.data` or interacting with other components.

# Optional: If you prefer to use async_set_value instead of async_set_native_value
async def async_set_value(self, value: float):
"""Set the new value."""
await self.async_set_native_value(value)
66 changes: 35 additions & 31 deletions custom_components/energy_and_tariff_costs/sensor.py
Original file line number Diff line number Diff line change
Expand Up @@ -152,9 +152,9 @@ def device_info(self) -> dict:
"""Return device information for the sensor."""
return {
"identifiers": {tuple(self._device_identifiers)}, # e.g., {('unique_device_identifier',)}
"name": "Energy Costs Device",
"manufacturer": "Test Manufacturer",
"model": "Test Model",
"name": "Energy & Tariff Costs",
"manufacturer": "Energy & Tariff Costs",
"model": "Beta",
}

@property
Expand Down Expand Up @@ -199,10 +199,12 @@ def _find_entity_id(self, name: str) -> Optional[str]:

async def _get_monthly_sum_if_daily_sensor(self, sensor_id: str) -> Optional[float]:
"""
Sum the monthly consumption from a daily sensor, ignoring the first value of each day
if a second value exists.
Sum the monthly consumption from a daily sensor by using only the last state of each day.
Ignores all other states within the same day.
"""
if not sensor_id.startswith(f"sensor.moj_elektro_daily_input_"):
DAILY_SENSOR_PREFIX = "sensor.moj_elektro_daily_input_"

if not sensor_id.startswith(DAILY_SENSOR_PREFIX):
_LOGGER.debug("Sensor %s is not a daily sensor", sensor_id)
return None # Not a daily sensor

Expand Down Expand Up @@ -243,34 +245,36 @@ async def _get_monthly_sum_if_daily_sensor(self, sensor_id: str) -> Optional[flo
total = 0.0
for day, day_states in states_by_day.items():
_LOGGER.debug("Processing day: %s with %d states", day, len(day_states))
if len(day_states) > 1:
_LOGGER.debug(
"Multiple states found for %s on %s. Ignoring the first state.",
sensor_id, day
)
# Ignore the first state
states_to_sum = day_states[1:]

if not day_states:
_LOGGER.debug("No states to process for %s on %s", sensor_id, day)
continue # Skip days with no states

# Identify the last state of the day based on last_changed timestamp
last_state = max(day_states, key=lambda s: s.last_changed)
_LOGGER.debug(
"Last state for %s on %s: %s",
sensor_id, day, last_state.state
)

if last_state.state not in (None, "unknown", "unavailable"):
try:
val = float(last_state.state)
total += val
_LOGGER.debug(
"Added value %f from sensor %s on %s",
val, sensor_id, day
)
except ValueError:
_LOGGER.error(
"Invalid state value '%s' in sensor %s on %s",
last_state.state, sensor_id, day
)
else:
_LOGGER.debug(
"Single state found for %s on %s. Including it in the sum.",
sensor_id, day
"Ignoring state '%s' for sensor %s on %s",
last_state.state, sensor_id, day
)
states_to_sum = day_states

for s in states_to_sum:
if s.state not in (None, "unknown", "unavailable"):
try:
val = float(s.state)
total += val
_LOGGER.debug(
"Added value %f from sensor %s on %s",
val, sensor_id, day
)
except ValueError:
_LOGGER.error(
"Invalid state value '%s' in sensor %s on %s",
s.state, sensor_id, day
)

_LOGGER.debug("Monthly sum for sensor %s: %f", sensor_id, total)
return total
Expand Down

0 comments on commit f51048b

Please sign in to comment.