Skip to content

Instantly share code, notes, and snippets.

@klaasnicolaas
Last active December 7, 2024 18:40
Show Gist options
  • Save klaasnicolaas/ccfd1cd3da62a13b3199ff378480bdbb to your computer and use it in GitHub Desktop.
Save klaasnicolaas/ccfd1cd3da62a13b3199ff378480bdbb to your computer and use it in GitHub Desktop.
Collecting the hourly energy prices via a service in the EnergyZero or easyEnergy integration and using them in an ApexCharts card in your dashboard.
- type: custom:apexcharts-card
graph_span: 1d
header:
show: true
title: Electriciteitsprijzen Vandaag (€/kwh)
span:
start: day
now:
show: true
label: Now
yaxis:
- id: price
decimals: 2
apex_config:
tickAmount: 5
series:
- entity: sensor.energy_prices_today
name: Price this hour
yaxis_id: price
data_generator: |
return entity.attributes.prices.map((entry) => {
return [new Date(entry.timestamp).getTime(), entry.price];
});
type: column
show:
extremas: true
opacity: 0.8
float_precision: 2
---
# Today - Hourly energy prices
template:
- trigger:
- platform: homeassistant
event: start
- platform: time_pattern
hours: "*"
action:
- service: energyzero.get_energy_prices
response_variable: response
data:
config_entry: PUT_HERE_YOURS
incl_vat: True
sensor:
- name: Energy prices - Today
device_class: timestamp
state: "{{ now() }}"
attributes:
prices: '{{ response.prices }}'
# Tomorrow - Hourly energy prices
- trigger:
- platform: homeassistant
event: start
- platform: template
value_template: "{{ now() > today_at('14:00') and now().minute == 0 }}"
action:
- service: energyzero.get_energy_prices
response_variable: response
data:
config_entry: PUT_HERE_YOURS
start: "{{ now() + timedelta(days=1) }}"
end: "{{ now() + timedelta(days=1) }}"
incl_vat: True
sensor:
- name: Energy prices - Tomorrow
device_class: timestamp
state: "{{ now() + timedelta(days=1) }}"
attributes:
prices: '{{ response.prices }}'
@abij
Copy link

abij commented Dec 1, 2024

Thanks for sharing your example and code for the custom-sensor.

I have been playing around (after new BlackFriday gear) with my HA setup for connecting P1-meter etc. I was looking into a nice energy price overview (better then the energy supplier) and made this, see screenshot.

It's based on your initial code. I was struggling a lot with understanding the configuration.yaml and nested/included "things" and pointers to other files etc. When people have issues, let me know so I can post my triggers setup, to clarify how it works.

I managed to combine today and tomorrow (when sensor is triggered >14:00 hourly) into single apexchart, using only the sensor.energy_prices_tomorrow:

image

If you like it, feel free to grap the chart config.

YAML of the custom:apexcharts-card

I have added some comments to explain the choices. Note that I did not see the chart behaviour during most hours of the day, yet.

type: custom:apexcharts-card
header:
  show: true
  title: Electriciteitsprijs (€/kwh)

# I want to see just last 5 hours, not 2 complete days (24h).
# Otherwise you can simply set 2d, and set span.start to 'day'
graph_span: 30h
span:
  start: minute
  offset: "-5h"

now:
  show: true
  label: Nu

# For my version it's required to allow color_threshold functionality:
experimental:
  color_threshold: true

color_list:
  - gray

# The current market price is low, soft limit to 40 cent, but auto-grows when higher.
# Start at 0, but when price is negative, it should also auto-grow negative.
yaxis:
  - id: price
    decimals: 2
    min: ~0
    max: ~0.4
    apex_config:
      tickAmount: 5

# I have just used a single series, this 'energy_prices_tomorrow' keeps history, so after tomorrow you have the prices for today.
# This only works after at least 1 day has passed by.
series:
  - entity: sensor.energy_prices_tomorrow
    name: Uurprijs
    unit: €/kwh
    yaxis_id: price
    data_generator: |
      return entity.attributes.prices.map((entry) => {
        return [new Date(entry.timestamp).getTime(), entry.price];
      });
    type: column
    show:
      extremas: true
    opacity: 0.8
    float_precision: 2

    # I set some fixed thresholds...
    # with some colors I used from a website: https://www.color-hex.com/color-palette/1046801
    color_threshold:
      - value: -999
        color: "#1b9fd5"   # some blue color indicating we are negative, then green, yellow , orange red colouring.
      - value: 0
        color: "#1aa000"
      - value: 0.15
        color: "#8ada61"
      - value: 0.2
        color: "#f5ff57"
      - value: 0.4
        color: "#ff7400"
      - value: 0.6
        color: "#f24949"

@mkrkpr
Copy link

mkrkpr commented Dec 7, 2024

Hi,

Thanks voor het delen van jullie codes, heeft me enorm geholpen een mooie Apexchart te ontwikkelen met de prijzen van vandaag en van morgen, met een enkele sensor. Met wat knip- en plakwerk en dank aan AI heb ik nu deze code ontwikkeld die mij de perfecte chart geeft zoals ik hem graag zie. Wellicht heeft iemand er iets aan:

type: custom:apexcharts-card
header:
  show: true
  title: Electriciteitsprijs (€/kwh)
graph_span: 30h
span:
  start: minute
  offset: "-3h"
now:
  show: true
  label: Nu
experimental:
  color_threshold: true
color_list:
  - grey
yaxis:
  - id: price
    decimals: 2
    min: ~0
    max: ~0.30
    apex_config:
      tickAmount: 8
series:
  - entity: sensor.energy_prices_today_and_tomorrow
    name: Uurprijs
    unit: €/kwh
    yaxis_id: price
    data_generator: |
      const parsePrices = (prices) => {
        if (typeof prices === 'string') {
          try {
            prices = JSON.parse(prices);
          } catch (e) {
            console.error("Error parsing prices:", e);
            return [];
          }
        }
        if (!Array.isArray(prices)) {
          console.error("Prices is not an array:", prices);
          return [];
        }
        return prices;
      };

      const parsePrice = (price) => {
        if (typeof price === 'object' && price !== null) {
          return parseFloat(price.price) || null;
        }
        return parseFloat(price) || null;
      };

      const today = parsePrices(entity.attributes.today_prices).map((price, index) => {
        const parsedPrice = parsePrice(price);
        return [
          new Date().setHours(index, 0, 0, 0),
          parsedPrice
        ];
      });
      
      const tomorrow = parsePrices(entity.attributes.tomorrow_prices).map((price, index) => {
        const parsedPrice = parsePrice(price);
        return [
          new Date(new Date().setDate(new Date().getDate() + 1)).setHours(index, 0, 0, 0),
          parsedPrice
        ];
      });
      
      return today.concat(tomorrow);
    type: column
    show:
      extremas: true
    opacity: 0.8
    float_precision: 2
    color_threshold:
      - value: -999
        color: "#1b9fd5"
      - value: 0
        color: "#1aa000"
      - value: 0.12
        color: "#8ada61"
      - value: 0.2
        color: "#f5ff57"
      - value: 0.4
        color: "#ff7400"
      - value: 0.6
        color: "#f24949"

image

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment