Closed MilanAra88 closed 5 days ago
Please provide states of the sensors you used in the integration input.
Also check the cost sensor attributes, what do you have there.
I don't know why it's off. Could you please send the picture of the power entity graph?
Does your device have also energy sensor (kWh) and could you test it with the energy sensor?
Calculation with energy sensor is more precise than using the integration left method with power sensor. However difference should be marginal not 10x
hi Marin,
This is strange - the real time costs seem to be calculating correctly by the daily, monthly, and year figures are way out.
Have you seen any other users with similar feedback?
hi Marin,
This is strange - the real time costs seem to be calculating correctly by the daily, monthly, and year figures are way out.
Have you seen any other users with similar feedback?
No, i haven't. I have a few power based test sensors running and they are correct.
Does your device have energy sensor as well and did you try with it?
EDIT: I found one bug in the power based sensors code. Please try latest 0.4.1 version
@MilanAra88 , i did some testing and compared it to the HA reiman sum + utility meter method and looks like its working properly.
I feed in my sensor.ss_load_power: state_class: measurement unit_of_measurement: W device_class: power friendly_name: SS Load power
and sensor.nordpool_import (price sensor) unit_of_measurement: EUR/kWh friendly_name: nordpool_import
About an hour and cost is 0.35€. Real time cost fluctuates, but average is about 0.35€/h, so it shpould be correct. It's not 10x off at least.
Comparison with my integration and reimann sum + utility meter method:
EDIT: Maybe you feed in sensor that gives kW not W?
Same problem, consumption of the kettle after switching on twice
The workaround i have used seems to work great! : https://community.home-assistant.io/t/solved-calculate-cost-for-individual-device-cost-kwh/523880/8?u=baljci333
I still use this nice work from Martin for the real time costs as this seems to be right!
I'm still puzzled why this 10x error occurs.
Btw, @MilanAra88 , @andiukas do you have energy (kwh) sensor for your device?
Hi @martinarva, the monitor i use is the Tapo energy monitor. The "current consumption" is in W.
As i say, your live cost is spot on - but its the daily, monthly, yearly that seems to be off for me :(
See image:
Maybe someone have any idea why this happens. Code that calculates the cost increment:
@callback
def _handle_real_time_cost_update(self, event):
"""Update cumulative cost based on the real-time cost sensor updates."""
new_state = event.data.get('new_state')
if new_state is None or new_state.state in ('unknown', 'unavailable'):
_LOGGER.debug("Skipping update due to unavailable state")
return
try:
current_cost = Decimal(new_state.state)
_LOGGER.debug(f"Current cost retrieved from state: {current_cost}") # Log current cost
if current_cost <= 0: # Skip updates if the new cost is not positive
_LOGGER.debug(f"Skipping update as the calculated cost {current_cost} is not positive.")
return
time_difference = now() - self._last_update
hours_passed = Decimal(time_difference.total_seconds()) / Decimal(3600) # Convert time difference to hours as Decimal
_LOGGER.debug(f"Time difference calculated as: {time_difference}, which is {hours_passed} hours.") # Log time difference in hours
self._state += (current_cost * hours_passed).quantize(Decimal('0.01'))
self._last_update = now()
self.async_write_ha_state()
_LOGGER.debug(f"Updated state to: {self._state} using cost: {current_cost} over {hours_passed} hours")
except (InvalidOperation, TypeError) as e:
_LOGGER.error(f"Error updating cumulative cost: {e}")
Method Decoration and Definition:
@callback
: This decorator is used to tell Home Assistant that this function should be run in the event loop, optimizing it for fast execution. It's important in the context of asynchronous programming, ensuring that this method does not block other operations._handle_real_time_cost_update(self, event)
: This method is designed to handle updates triggered by a change in another sensor's state, with the event
parameter carrying data related to this change.Handling of Event Data:
new_state = event.data.get('new_state')
: This line extracts the new_state
from the event data. The new_state
typically contains the latest state information about the sensor that triggered the event.State Validity Check:
new_state
is None
or its state is 'unknown'
or 'unavailable'
. If any of these conditions are true, the method logs a debug message and returns early without doing any further processing. This is crucial to ensure that the method only processes valid and available data.Cost Retrieval and Validation:
current_cost = Decimal(new_state.state)
: This line converts the state of the triggering sensor into a Decimal
, which is a data type that provides precise fixed-point arithmetic. This step is necessary to handle financial calculations accurately.current_cost
is less than or equal to zero. If so, it logs this and returns early, as negative or zero costs do not contribute to cumulative calculations in this context.Time Difference Calculation:
time_difference = now() - self._last_update
: Here, now()
represents the current time, and self._last_update
is the time when the last update occurred. This line calculates how much time has passed since the last update.hours_passed = Decimal(time_difference.total_seconds()) / Decimal(3600)
: Converts the time_difference
to the total number of seconds, and then divides by 3600 to convert this into hours. The result is stored as a Decimal
for precision.State Update:
self._state += (current_cost * hours_passed).quantize(Decimal('0.01'))
: This line updates the sensor's state by adding the product of current_cost
and hours_passed
, quantized to two decimal places. This represents the accrued cost over the elapsed time, scaled to the cost rate per hour.self._last_update = now()
: Updates the last update timestamp to the current time.self.async_write_ha_state()
: Calls Home Assistant's method to write the updated state back to the system, ensuring that the state change is registered.Error Handling:
InvalidOperation
or TypeError
. This is important for debugging and ensuring the component doesn't crash from unhandled exceptions.@martinarva
I would increase the accuracy
self._state += (current_cost * hours_passed).quantize(Decimal('0.01'))
to
self._state += (current_cost * hours_passed).quantize(Decimal('0.0001'))
If calculation is every 5 seconds, hours is a very small number. hours times a very little cost is 0.00 So add every 5 seconds 0.00 to the state makes sensor not accurate. Don't know if this will help in the factor 10 issue here but at least the state will become more accurate
@DutchKillerbee , thanks for the insight. I increased accuracy and whis will be available in next release
Version 0.5.0 released: https://github.com/martinarva/dynamic_energy_cost/releases/tag/v0.5.0
Please test and reopen, if still issues
problem unsolved
Hi there,
The pricing that is calculated incorrectly by a factor of 10.
For instance, when the elec rate is £0.17/kwh and the appliance has used 0.315 kwh - it should £0.059 but it is showing at £0.59 . See images. Any idea?
Many thanks,
Milan