Skip to content

Displaying prices in Apexchart card

Malene Trab edited this page Jan 9, 2024 · 10 revisions

Prerequisites

It is required to have the custom apexchart card installed before this will work! Follow the instructions here: https://github.com/RomRider/apexcharts-card

Option 1 - Static colors

image

Lovelace card

Edit your dashboard and select Add Card.
Scroll to the bottom and select Manual

Replace the code in the window with this:

type: custom:apexcharts-card
apex_config:
  chart:
    height: 350px
experimental:
  color_threshold: true
graph_span: 24h
header:
  title: Elpriser pr. time (kr/kWh)
  show: true
span:
  start: hour
  offset: '-2h'
now:
  show: true
  label: Nu
yaxis:
  - min: 0
    apex_config:
      tickAmount: 5
series:
  - entity: sensor.energi_data_service
    type: column
    data_generator: |
      var today = entity.attributes.raw_today.map((start, index) => {
        return [new Date(start["hour"]).getTime(), entity.attributes.raw_today[index]["price"]];
      });
      if (entity.attributes.tomorrow_valid) {
        var tomorrow = entity.attributes.raw_tomorrow.map((start, index) => {
          return [new Date(start["hour"]).getTime(), entity.attributes.raw_tomorrow[index]["price"]];
        });

        var data = today.concat(tomorrow);
      } else {
        var data = today
      }
      return data;
    float_precision: 2
    color_threshold:
      - value: 0
        color: green
      - value: 2
        color: orange
      - value: 3.5
        color: red
      - value: 5
        color: darkred

Option 2 - Dynamic background colors

image

This option requires config-template-card to be installed along side Apex chart.

Template sensors

Create these sensors (remember to rename the entity_id property to match your Energidata Service sensor name):

sensor:
  - platform: statistics
    name: Average energy price last 30d mean
    entity_id: sensor.energi_data_service
    state_characteristic: mean
    sampling_size: 760
    max_age:
      days: 30

  - platform: statistics
    name: Energy price last 30d (std)
    entity_id: sensor.energi_data_service
    state_characteristic: standard_deviation
    sampling_size: 512
    max_age:
      days: 30

template:
  - sensor:
    - name: Historic Energy Price Percentiles
      unique_id: historic_energy_price_percentiles
      state: OK
      attributes:
        25th: "{{ states('sensor.average_energy_price_last_30d_mean') | float(0) + states('sensor.energy_price_last_30d_std') | float(0) * -0.63 }}"
        50th: "{{ states('sensor.average_energy_price_last_30d_mean') | float(0) + states('sensor.energy_price_last_30d_std') | float(0) * 0 }}"
        75th: "{{ states('sensor.average_energy_price_last_30d_mean') | float(0) + states('sensor.energy_price_last_30d_std') | float(0) * 0.57 }}"
        90th: "{{ states('sensor.average_energy_price_last_30d_mean') | float(0) + states('sensor.energy_price_last_30d_std') | float(0) * 1.29 }}"
        95th: "{{ states('sensor.average_energy_price_last_30d_mean') | float(0) + states('sensor.energy_price_last_30d_std') | float(0) * 1.65 }}"
        99th: "{{ states('sensor.average_energy_price_last_30d_mean') | float(0) + states('sensor.energy_price_last_30d_std') | float(0) * 2.33 }}"
        100th: "{{ states('sensor.average_energy_price_last_30d_mean') | float(0) + states('sensor.energy_price_last_30d_std') | float(0) * 3.9 }}"

Lovelace card

Edit your dashboard and select Add Card.
Scroll to the bottom and select Manual

Replace the code in the window with this:

type: custom:config-template-card
entities:
  - sensor.energi_data_service
  - sensor.historic_energy_price_percentiles
config_templates: default
variables:
  max_price_threshold: |
    () => {
      return states['sensor.historic_energy_price_percentiles'].attributes['99th']
    }
  get_yellow_threshold: |
    () => {
      return states['sensor.historic_energy_price_percentiles'].attributes['25th']
    }
  get_orange_threshold: |
    () => {
      return states['sensor.historic_energy_price_percentiles'].attributes['75th']
    }
  get_darkred_threshold: |
    () => {
      return states['sensor.historic_energy_price_percentiles'].attributes['95th']
    }
card:
  type: custom:apexcharts-card
  graph_span: 47h
  span:
    end: day
    offset: +23h
  apex_config:
    chart:
      height: 200px
    grid:
      show: true
      borderColor: rgb(158, 158, 158)
      strokeDashArray: 2
    annotations:
      position: back
      yaxis:
        - 'y': 0
          y2: ${ get_yellow_threshold() }
          fillColor: rgb(76, 175, 80)
          strokeDashArray: 0
          borderColor: '#00000000'
        - 'y': ${ get_yellow_threshold() }
          y2: ${ get_orange_threshold() }
          fillColor: rgb(255, 193, 7)
          strokeDashArray: 0
          borderColor: '#00000000'
        - 'y': ${ get_orange_threshold() }
          y2: ${ get_darkred_threshold() }
          fillColor: rgb(255, 152, 0)
          strokeDashArray: 0
          borderColor: '#00000000'
        - 'y': ${ get_darkred_threshold() }
          y2: ${ max_price_threshold() }
          fillColor: rgb(244, 67, 54)
          strokeDashArray: 0
          borderColor: '#00000000'
        - 'y': ${ max_price_threshold() }
          y2: 100
          fillColor: rgb(255, 0, 0)
          strokeDashArray: 0
          borderColor: '#00000000'
  header:
    show: true
    title: Elpriser pr. time (DKK/kWh)
    show_states: true
    colorize_states: true
  now:
    label: Nu
    show: true
    color: black
  yaxis:
    - min: '|-0.5|'
      max: '|+0.5|'
      apex_config:
        tickAmount: 4
        forceNiceScale: false
        decimalsInFloat: 1
  series:
    - name: Nu
      entity: sensor.energi_data_service
      color: rgb(33, 150, 243)
      float_precision: 2
      data_generator: |
        return [[new Date(), entity.state]]
      show:
        in_chart: false
    - name: Current
      entity: sensor.energi_data_service
      stroke_width: 3
      float_precision: 2
      type: line
      color: rgb(33, 150, 243)
      extend_to: false
      show:
        in_header: false
      data_generator: |
        var today = entity.attributes.raw_today.map((start, index) => {
          return [new Date(start["hour"]).getTime(), entity.attributes.raw_today[index]["price"]];
        });
        if (entity.attributes.tomorrow_valid) {
          var tomorrow = entity.attributes.raw_tomorrow.map((start, index) => {
            return [new Date(start["hour"]).getTime(), entity.attributes.raw_tomorrow[index]["price"]];
          });

          var data = today.concat(tomorrow);
        } else {
          var data = today
        }
        return data;

Option 3 - Include forecast data in chart

image

This option requires config-template-card to be installed along side Apex chart.

Template sensors

Create these sensors (remember to rename the entity_id property to match your Energidata Service sensor name):

sensor:
  - platform: statistics
    name: Average energy price last 30d mean
    entity_id: sensor.energi_data_service
    state_characteristic: mean
    sampling_size: 760
    max_age:
      days: 30

  - platform: statistics
    name: Energy price last 30d (std)
    entity_id: sensor.energi_data_service
    state_characteristic: standard_deviation
    sampling_size: 512
    max_age:
      days: 30

  - platform: statistics
    name: Energy price last 30d (mean)
    entity_id: sensor.energi_data_service
    state_characteristic: mean
    sampling_size: 512
    max_age:
      days: 30

template:
  - sensor:
    - name: Historic Energy Price Percentiles
      unique_id: historic_energy_price_percentiles
      state: OK
      attributes:
        25th: "{{ states('sensor.average_energy_price_last_30d_mean') | float(0) + states('sensor.energy_price_last_30d_std') | float(0) * -0.63 }}"
        50th: "{{ states('sensor.average_energy_price_last_30d_mean') | float(0) + states('sensor.energy_price_last_30d_std') | float(0) * 0 }}"
        75th: "{{ states('sensor.average_energy_price_last_30d_mean') | float(0) + states('sensor.energy_price_last_30d_std') | float(0) * 0.57 }}"
        90th: "{{ states('sensor.average_energy_price_last_30d_mean') | float(0) + states('sensor.energy_price_last_30d_std') | float(0) * 1.29 }}"
        95th: "{{ states('sensor.average_energy_price_last_30d_mean') | float(0) + states('sensor.energy_price_last_30d_std') | float(0) * 1.65 }}"
        99th: "{{ states('sensor.average_energy_price_last_30d_mean') | float(0) + states('sensor.energy_price_last_30d_std') | float(0) * 2.33 }}"
        100th: "{{ states('sensor.average_energy_price_last_30d_mean') | float(0) + states('sensor.energy_price_last_30d_std') | float(0) * 3.9 }}"

Lovelace card

Edit your dashboard and select Add Card.
Scroll to the bottom and select Manual

Replace the code in the window with this:

type: custom:config-template-card
entities:
  - sensor.energi_data_service
  - sensor.historic_energy_price_percentiles
config_templates: default
variables:
  max_price_threshold: |
    () => {
      return states['sensor.historic_energy_price_percentiles'].attributes['99th']
    }
  get_yellow_threshold: |
    () => {
      return states['sensor.historic_energy_price_percentiles'].attributes['25th']
    }
  get_orange_threshold: |
    () => {
      return states['sensor.historic_energy_price_percentiles'].attributes['75th']
    }
  get_darkred_threshold: |
    () => {
      return states['sensor.historic_energy_price_percentiles'].attributes['95th']
    }
card:
  type: custom:apexcharts-card
  graph_span: 132h
  span:
    end: day
    offset: +108h
  apex_config:
    chart:
      height: 200px
    grid:
      show: true
      borderColor: rgb(158, 158, 158)
      strokeDashArray: 2
    annotations:
      position: back
      yaxis:
        - 'y': 0
          y2: ${ get_yellow_threshold() }
          fillColor: rgb(76, 175, 80)
          strokeDashArray: 0
          borderColor: '#00000000'
        - 'y': ${ get_yellow_threshold() }
          y2: ${ get_orange_threshold() }
          fillColor: rgb(255, 193, 7)
          strokeDashArray: 0
          borderColor: '#00000000'
        - 'y': ${ get_orange_threshold() }
          y2: ${ get_darkred_threshold() }
          fillColor: rgb(255, 152, 0)
          strokeDashArray: 0
          borderColor: '#00000000'
        - 'y': ${ get_darkred_threshold() }
          y2: ${ max_price_threshold() }
          fillColor: rgb(244, 67, 54)
          strokeDashArray: 0
          borderColor: '#00000000'
        - 'y': ${ max_price_threshold() }
          y2: 100
          fillColor: rgb(255, 0, 0)
          strokeDashArray: 0
          borderColor: '#00000000'
  header:
    show: true
    title: Elpriser pr. time (DKK/kWh)
    show_states: true
    colorize_states: true
  now:
    label: Nu
    show: true
    color: black
  yaxis:
    - min: '|-0.5|'
      max: '|+0.5|'
      apex_config:
        tickAmount: 4
        forceNiceScale: false
        decimalsInFloat: 1
  series:
    - name: Nu
      entity: sensor.energi_data_service
      color: rgb(33, 150, 243)
      float_precision: 2
      data_generator: |
        return [[new Date(), entity.state]]
      show:
        in_chart: false
    - name: Current
      entity: sensor.energi_data_service
      stroke_width: 3
      float_precision: 2
      type: line
      color: rgb(33, 150, 243)
      extend_to: false
      show:
        in_header: false
      data_generator: |
        var today = entity.attributes.raw_today.map((start, index) => {
          return [new Date(start["hour"]).getTime(), entity.attributes.raw_today[index]["price"]];
        });

        var extradata = entity.attributes.forecast.map((start, index) => {
          return [new Date(start["hour"]).getTime(), entity.attributes.forecast[index]["price"]];
        });

        if (entity.attributes.tomorrow_valid) {
          var tomorrow = entity.attributes.raw_tomorrow.map((start, index) => {
            return [new Date(start["hour"]).getTime(), entity.attributes.raw_tomorrow[index]["price"]];
          });
          today = today.concat(tomorrow)
        }

        return today.concat(extradata)