MattJeanes / TeslaMateAgile

Integration to automatically fill in prices for charge data captured by TeslaMate for smart energy providers
MIT License
76 stars 9 forks source link

Updating price from Home Assistant fails because "The input string 'unavailable' was not in a correct format." #49

Closed AlbertoZen closed 5 months ago

AlbertoZen commented 5 months ago

Hi, I'm on Octopus tracker, Home Assistant is importing the cost of electricity prices via the Octopus add-on and of course I configured teslamate to import the rate of electricity from Home Assistant, this morning something has gone wrong with the add-on and it stored "unavailable" in the data.


Timestamp | State
15/01/2024 18:44 | 0.1764
16/01/2024 00:00 | 0.18396
17/01/2024 00:00 | 0.187845
18/01/2024 00:00 | 0.1722
19/01/2024 00:00 | 0.16653
20/01/2024 00:00 | 0.162015
20/01/2024 00:45 | unavailable
20/01/2024 07:51 | 0.162015

It also happened that my car was in charge at the time, which I think it is causing the issue and it is stopping teslamateagile from adjusting the cost of charge in the database.

In my opinion the software shouldn't try parsing a string which is not a number, and should fill the gap by forward filling the last correct data, which in my specific case would have worked perfectly fine, but I appreciate that it might not be the case in other configuration, but in any case it is better than no data at all.

See log here below.

teslamateagile_1  | info: TeslaMateAgile.PriceHelper[0]
teslamateagile_1  |       Calculating cost for charges 01/19/2024 20:00:51 UTC - 01/20/2024 04:32:35 UTC
teslamateagile_1  | fail: TeslaMateAgile.PriceHelper[0]
teslamateagile_1  |       Failed to calculate charging cost / energy for charging process 3
teslamateagile_1  |       System.FormatException: The input string 'unavailable' was not in a correct format.
teslamateagile_1  |          at System.Number.ThrowFormatException[TChar](ReadOnlySpan`1 value)
teslamateagile_1  |          at System.Number.ParseDecimal[TChar](ReadOnlySpan`1 value, NumberStyles styles, NumberFormatInfo info)
teslamateagile_1  |          at System.Decimal.Parse(String s)
teslamateagile_1  |          at TeslaMateAgile.Services.HomeAssistantService.GetPriceData(DateTimeOffset from, DateTimeOffset to) in /src/TeslaMateAgile/Services/HomeAssistantService.cs:line 44
teslamateagile_1  |          at TeslaMateAgile.PriceHelper.CalculateChargeCost(IEnumerable`1 charges) in /src/TeslaMateAgile/Helpers/PriceHelper.cs:line 96
teslamateagile_1  |          at TeslaMateAgile.PriceHelper.Update() in /src/TeslaMateAgile/Helpers/PriceHelper.cs:line 74
teslamateagile_1  | info: TeslaMateAgile.PriceService[0]
teslamateagile_1  |       Waiting 300 seconds until next update
MattJeanes commented 5 months ago

Interesting! You should be able to work around this by using an automation to update an input_number integration when the Octopus integration entity changes rather than using the value of it directly. This should avoid the entity becoming unavailable if it depends on cloud sources such as the Octopus one and also allows it to be updated by other sources too if you have e.g. incoming solar energy.

In my case, I use Octopus Intelligent and I have a similar automation because that integration doesn't tell me the price, only if it's currently on the "low" or "high" prices, so I use that to update my input_number appropriately.

I don't think it would necessarily always be a good idea to ignore "unavailable" states as this could result in silent inaccurate measurements, which as you say may not be the correct fix for every use case, so for you and anyone else with similar issues, I would recommend doing this.

AlbertoZen commented 5 months ago

Thanks @MattJeanes what you suggested is actually a very good idea, I created a simple automation

alias: Copy Octopus Tracker Electricity Rate to Teslamate
description: ""
trigger:
  - platform: state
    entity_id:
      - sensor.octopus_energy_electricity_xxxxxxxxxxx_xxxxxxxxxxxxx_current_rate
condition:
  - condition: not
    conditions:
      - condition: state
        entity_id: >-
          sensor.octopus_energy_electricity_xxxxxxxxxxx_xxxxxxxxxxxxx_current_rate
        state: unavailable
      - condition: state
        entity_id: >-
          sensor.octopus_energy_electricity_xxxxxxxxxxx_xxxxxxxxxxxxx_current_rate
        state: unknown
action:
  - service: input_number.set_value
    metadata: {}
    data:
      value: >-
        {{
        states('sensor.octopus_energy_electricity_xxxxxxxxxxx_xxxxxxxxxxxxx_current_rate')
        | float }}
    target:
      entity_id: input_number.teslamateoctopustracker
mode: single

This should copy the electricity rate from the Octopus add-on to a numeric input "input_number.teslamateoctopustracker" when the status is not "unknown" or "unavailable", I'm sure it can be massively improved (I'm not great with templating) but it seems to do the job.

MattJeanes commented 5 months ago

That looks perfect to me, nice!

Hopefully that does the job for you, so I'll go ahead and close this :)