mampfes / ha_epex_spot

Adds EPEX Spot data to Home Assistant.
MIT License
117 stars 20 forks source link

APEX charts example is broken #71

Closed Glennvd closed 6 months ago

Glennvd commented 8 months ago

With the latest version (2.2.0) the example of the apex charts including the lowest period is broken.

https://github.com/mampfes/ha_epex_spot#3-i-want-to-combine-and-view-everything

The cause seems to be sensor.epex_start_low_period that no longer exists.

Is there any way to achieve an indication of the lowest hours of the day using the price_rank sensor or the low period service? I'm trying to visually indicate on a chart when some appliances would start.

mampfes commented 7 months ago

You can still add the template sensor from the previous chapter. But indeed, the example will not work with the new sensors and services anymore.

The example was provided by an user, I don't know apex charts good enough to fix it. Maybe s.o. with better apex chart skills can help, please.

drahdiwaberl commented 7 months ago

came here to ask for the same.

indeed - examples in the docs have to be read from top down to understand .. epex_start_low_period is a template sensor which has to be set up manually, which still works fine.

after that (and adopting the main sensor to sensor.epex_spot_data_price) the graph isn't just showing a 'loading' message but an empty graph, so it seems to think it's done all it should.

what does @mampfes think that might be not compatible with the new version?

feutl commented 7 months ago

If it does not work, perhaps a note would be nice, if not fixed, as I ran into the same problem. But the one in the HA community works https://community.home-assistant.io/t/epex-spot-and-awattar-electricity-prices/519151/42?u=h3rb3rt and perhaps "webwude" can help you out on this, as it seems he has good apex skills ;)

drahdiwaberl commented 7 months ago

(i think) i have it working. since it's past midnight, i can't tell for sure, as i don't have data for the 'next day'.

not knowing what changed in this integration recently, just wild guesses based on what i see in my setup:

the logic of the chart: the first series draws the line plus extremas of the first 24 hours, to also get extremas shown for the second 24 hours there's the separate second series, again drawing a line. the third series is the green bar for the cheapest 2 hours.

so, here goes the apexchart card:

header:
  show: false
graph_span: 48h
span:
  start: day
now:
  show: true
  label: now
experimental:
  color_threshold: true
series:
  - entity: sensor.epex_spot_data_net_price
    yaxis_id: preis
    float_precision: 2
    type: line
    stroke_width: 4
    curve: stepline
    extend_to: false
    show:
      extremas: true
    data_generator: >
      return entity.attributes.data.map((entry, index) => { return [new
      Date(entry.start_time).getTime(), entry.price_ct_per_kwh]; }).slice(0,24);
    color_threshold:
      - value: 2
        color: 00ed01
      - value: 4
        color: 3af901
      - value: 6
        color: 87fa00
      - value: 8
        color: cefb02
      - value: 10
        color: eeff00
      - value: 12
        color: ffde1a
      - value: 14
        color: ffa700
      - value: 16
        color: ff8d00
      - value: 18
        color: ff7400
      - value: 20
        color: ff4d00
      - value: 22
        color: ff4d00
      - value: 24
        color: ff0000
      - value: 26
        color: e60000
      - value: 28
        color: cc0000
      - value: 30
        color: b30000
      - value: 32
        color: '990000'
      - value: 34
        color: '800000'
      - value: 36
        color: '660000'
      - value: 38
        color: 4d0000
      - value: 40
        color: '330000'
  - entity: sensor.epex_spot_data_net_price
    type: line
    stroke_width: 4
    curve: stepline
    extend_to: end
    float_precision: 3
    yaxis_id: preis
    show:
      extremas: true
    data_generator: |
      return entity.attributes.data.map((entry) => {
        return [new Date(entry.start_time), entry.price_ct_per_kwh]; }).slice(23,47);
    color_threshold:
      - value: 2
        color: 00ed01
      - value: 4
        color: 3af901
      - value: 6
        color: 87fa00
      - value: 8
        color: cefb02
      - value: 10
        color: eeff00
      - value: 12
        color: ffde1a
      - value: 14
        color: ffa700
      - value: 16
        color: ff8d00
      - value: 18
        color: ff7400
      - value: 20
        color: ff4d00
      - value: 22
        color: ff4d00
      - value: 24
        color: ff0000
      - value: 26
        color: e60000
      - value: 28
        color: cc0000
      - value: 30
        color: b30000
      - value: 32
        color: '990000'
      - value: 34
        color: '800000'
      - value: 36
        color: '660000'
      - value: 38
        color: 4d0000
      - value: 40
        color: '330000'
  - entity: sensor.epex_spot_data_net_price
    yaxis_id: preis
    color: green
    float_precision: 2
    type: area
    stroke_width: 0
    curve: stepline
    extend_to: false
    data_generator: >
      return entity.attributes.data.map((entry, index) => { return [new
      Date(entry.start_time).getTime(),
      entry.price_ct_per_kwh];}).slice(parseInt(hass.states['sensor.epex_start_low_period'].state.substring(0,2)),parseInt(hass.states['sensor.epex_start_low_period'].state.substring(0,2))+4);
yaxis:
  - id: preis
    decimals: 0
    apex_config:
      title:
        text: ct/kWh
      tickAmount: 5
apex_config:
  legend:
    show: false
  tooltip:
    x:
      show: true
      format: HH:00 - HH:59

and that's what the template sensor looks like for me (adding it as a helper via the ui doesn't work as there seems to be a limit of characters there, so i had to put it in the configuration.yaml):

- name: epex_start_low_period
        state: >-
          {% set ns = namespace(attr_dict=[]) %}
          {% for item in (state_attr('sensor.epex_spot_data_price', 'data'))[0:24] %}
              {%- set ns.attr_dict = ns.attr_dict + [(loop.index-1,item["price_eur_per_mwh"])] %}
          {% endfor %}
          {%- set price_map = dict(ns.attr_dict) %}
          {%- set price_sort = price_map.values()|list %}
          {%- set keys_list = price_map.keys()|list %}
          {%- set ns = namespace(combo=[]) %}
          {%- for p in keys_list %}
            {%- set p = p|int %}
            {%- if p < 22 %}
              {%- set ns.combo = ns.combo + [(p, ((price_sort)[p] + (price_sort)[p+1] + (price_sort)[p+2])|round(2))] %}
            {%- endif %}
          {%- endfor %}
          {%- set ns.combo = ns.combo[6:22] %}
          {%- set mapper = dict(ns.combo) %}
          {%- set key = mapper.keys()|list %}
          {%- set val = mapper.values()|list %}
          {%- set val_min = mapper.values()|min %}
          {{ key[val.index(val_min)]|string + ":00" }}
EBB5 commented 6 months ago

I was it able to get it work like drahdiwaberl said. But I was able to create the ,epex_start_low_period sensor via Settings>Devices&Services>Helpers Then choose a Template type helper and choose Template a sensor. Content of the template starts then from line : {% set ns = namespace(attr_dict=[]) %}

WimDeceuninck commented 6 months ago

Hi, thank you drahdiwaberl; I got the card working. However the apexchart does not load automaticaly. I need to swith to another view and then go back. Then the card shows the loaded apexchart. Do you have any idea how I can resolve this?

drahdiwaberl commented 6 months ago

However the apexchart does not load automaticaly. I need to swith to another view and then go back. Then the card shows the loaded apexchart. Do you have any idea how I can resolve this?

this sounds like an issue with the apexchart integration or limited ressources for it .. mind you it's quite demanding, so might not work too well on weaker hosts (often read from people giving up on it for that reason).