Stromgedacht API "Integration"

Stromgedacht is an App from the Transmission System Operator “TransnetBW” of Baden-Württemberg in Germany which aims to reduce the amount of necessary redispatch operations by shifting electricity demand away from times where the grid is under high load. (which mostly triggers less then once per month)

I have created a configuration for the new Stromgedacht API. You should replace the PLZ (ZIP-Code) 70173 with your own PLZ.

sensor:
  - platform: rest
    resource: https://api.stromgedacht.de/v1/now?zip=70173
    name: Stromgedacht Status
    json_attributes: 
      - state
    value_template: >
      {% set mapper = {
          1: "Grün",
          3: "Orange",
          4: "Rot",
          -1: "SuperGrün",
      } %}
      {% set state = value_json.state %}
      {{ mapper[state] if state in mapper else state }}

This sensor could then be used to for example stop charging an EV or turning off other things.

EDIT: Added Support for SuperGrün (and removed yellow), which is activated when threre are high amounts of renewables available in the Grid of Baden-Württemberg. It also replaced the color yellow.

6 Likes

Very nice! I had the very same idea… :smiley:
Put the code on Github: GitHub - jpwenzel/homeassistant-stromgedacht: StromGedacht API sensor for Home Assistant

1 Like

A few days ago i was searching for this after i heard that there is an API. Thanks for sharing :slight_smile:
Works perfectly.

1 Like

Great. Works out of the box.
Would be great to show the forecast for the next e. g. 24 hours - like it is displayed in the app.

2 Likes

Didn’t work for me, so I re-wrote the code for configuration.yaml.
I also added the new status “supergrün” that replaced “gelb” in late 2023.

You still need to hard-code your ZIP.

rest:
  - resource: https://api.stromgedacht.de/v1/now?zip=71634
    sensor:
      - name: StromGedacht LB
        icon: mdi:power-socket-de
        json_attributes:
          - state
        value_template: >
          {% set mapper = {
              -1: "supergrün",
              1: "grün",
              2: "gelb",
              3: "orange",
              4: "rot" }
          %}
          {% set state = value_json.state %}
          {{ mapper[state] if state in mapper else state }}

3 Likes

Hey :slight_smile:

thanks for the information provided here - I just thought the last days 'it would be nice to have this within HA,…" glad, that I can start the new year with a small improvement in my setup :wink:

for anyone, interested in getting future information - this is an example which URL you need to request:

https://api.stromgedacht.de/v1/statesRelative?zip=70173&hoursInFuture=12&hoursInPast=0

And here’s the json raw data to work with:

{
  "states":
  [
   {
    "from":"2024-01-01T17:24:16.7757862+01:00",
    "to":"2024-01-01T18:00:00+01:00",
    "state":1
   },
   {
    "from":"2024-01-01T18:00:00+01:00",
    "to":"2024-01-02T00:00:00+01:00",
    "state":-1
   },
   {
    "from":"2024-01-02T00:00:00+01:00",
    "to":"2024-01-02T05:24:16.7757863+01:00",
    "state":1
    }
  ]
}

I am not very experienced in how to parse this within the sensors.yaml file…
But maybe, this might help someone :slight_smile:

I have not implemented exactly what you want, but I think you could make it work with some adjustments.

I have added the two charts to Home Assistant (the state is Supergreen when the Residual load (red) is lower than the threshold (light green)):

You have to install GitHub - RomRider/apexcharts-card: 📈 A Lovelace card to display advanced graphs and charts based on ApexChartsJS for Home Assistant for the card.

Code for the top Chart
type: custom:apexcharts-card
header:
  show: true
  title: Stromgedacht
graph_span: 48h
span:
  start: day
now:
  show: true
  label: Now
series:
  - entity: sensor.api_stromgedacht_residuallast
    color: red
    type: line
    stroke_width: 3
    extend_to: now
    data_generator: >
      return entity.attributes.residualLoad.map((entry, index) => { return [new
      Date(entry.dateTime).getTime(), entry.value]; });
  - entity: sensor.api_stromgedacht_supergrun_schwelle
    color: lightgreen
    type: line
    stroke_width: 3
    extend_to: now
    data_generator: >
      return entity.attributes.superGreenThreshold.map((entry, index) => {
      return [new Date(entry.dateTime).getTime(), entry.value]; });
Code for the bottom Chart
type: custom:apexcharts-card
header:
  show: true
  title: Stromgedacht
graph_span: 48h
span:
  start: day
now:
  show: true
  label: Now
series:
  - entity: sensor.api_stromgedacht_erneuerbar
    color: green
    type: line
    stroke_width: 3
    extend_to: now
    data_generator: >
      return entity.attributes.renewableEnergy.map((entry, index) => { return
      [new Date(entry.dateTime).getTime(), entry.value]; });
  - entity: sensor.api_stromgedacht_last
    color: yellow
    type: line
    stroke_width: 3
    extend_to: now
    data_generator: >
      return entity.attributes.load.map((entry, index) => { return [new
      Date(entry.dateTime).getTime(), entry.value]; });

This is in my rest_integration.yaml file (rest: !include rest_integration.yaml in configuration.yaml) (Please ignore the value and value template, it is not working correctly, maybe some knows how you can make it work properly)
I would also recommend disabling the recorder for these entities, because I dont know if it will record the the atrributes, which are very long.

- resource_template: "https://api.stromgedacht.de/v1/forecast?zip=71336&from={{ now().strftime('%Y-%m-%d') }}"
  scan_interval: 3600
  sensor:    
  - value_template: '{{ value_json.residualLoad | selectattr("dateTime", ">=", (utcnow() - timedelta(minutes=15)).strftime("%Y-%m-%dT%H:%M:%SZ")) | map(attribute="value") | first }}'
    name: "API Stromgedacht Residuallast"
    unit_of_measurement: "MW"
    device_class: power
    state_class: measurement
    unique_id: "API_Stromgedacht_Residuallast"
    json_attributes: "residualLoad" 

  - value_template: '{{ value_json.load | selectattr("dateTime", ">=", (utcnow() - timedelta(minutes=15)).strftime("%Y-%m-%dT%H:%M:%SZ")) | map(attribute="value") | first }}'
    name: "API Stromgedacht Last"
    unit_of_measurement: "MW"
    device_class: power
    state_class: measurement
    unique_id: "API_Stromgedacht_Last"
    json_attributes: "load" 

  - value_template: '{{ value_json.renewableEnergy | selectattr("dateTime", ">=", (utcnow() - timedelta(minutes=15)).strftime("%Y-%m-%dT%H:%M:%SZ")) | map(attribute="value") | first }}'
    name: "API Stromgedacht Erneuerbar"
    unit_of_measurement: "MW"
    device_class: power
    state_class: measurement
    unique_id: "API_Stromgedacht_RenewableEnergy"
    json_attributes: "renewableEnergy" 

  - value_template: '{{ value_json.superGreenThreshold | selectattr("dateTime", ">=", (utcnow() - timedelta(minutes=15)).strftime("%Y-%m-%dT%H:%M:%SZ")) | map(attribute="value") | first }}'
    name: "API Stromgedacht SuperGrün Schwelle"
    unit_of_measurement: "MW"
    device_class: power
    state_class: measurement
    unique_id: "API_Stromgedacht_superGreenThreshold"
    json_attributes: "superGreenThreshold" 
    

PS: Sorry for not answering this long. Can you set the forum to send e-mails?

2 Likes

I have posted my answer above, the forum would not let me answer you.

Hi! I included sensor.yaml to my configuration.yaml file, but I cannot find any device/service within HA. Maybe someone can me push into the right direction?

I optimized the integration a bit, here is my code:
sensor.yaml or sensor config in configuration.yaml (You need to fill your PLZ / ZIPCODE yourself)

#StromGedacht REST API
- name: StromGedacht Status Code
  unique_id: stromgedacht_status_code
  platform: rest
  resource_template: https://api.stromgedacht.de/v1/now?zip=ZIPCODE
  headers:
    User-Agent: HomeAssistant
    Content-Type: application/json
  json_attributes:
    - state
  value_template: >
    {{ value_json['state'] }}

and a modern template sensor also in the configuration.yaml

template:
  - sensor:
    - name: "StromGedacht Statusmeldung"
      unique_id: "stromgedacht_statusmeldung"
      state: >-
        {% set mapper = {
          '-1': {
            'state': 'Verbrauch verlegen',
            'message': 'Nutze nachhaltigen Strom und unterstütze die Netzdienlichkeit.',
          },
          '1': {
            'state': 'Normalbetrieb',
            'message': 'Alles in Ordnung! Du musst nichts weiter tun.',
          },
          '3': {
            'state': 'Verbrauch reduzieren',
            'message': 'Gemeinsam Kosten und CO2 sparen!',
          },
          '4': {
            'state': 'Verbrauch reduzieren',
            'message': 'Strommangel verhindern! Bitte schalte unnötige Geräte ab.',
          },
        } %}
        {% set state = states('sensor.stromgedacht_status_code') %}
        {{ mapper[state]['state'] if state in mapper else 'N/A' }}
      attributes:
        message: >-
          {% set mapper = {
            '-1': {
              'state': 'Verbrauch verlegen',
              'message': 'Nutze nachhaltigen Strom und unterstütze die Netzdienlichkeit.',
            },
            '1': {
              'state': 'Normalbetrieb',
              'message': 'Alles in Ordnung! Du musst nichts weiter tun.',
            },
            '3': {
              'state': 'Verbrauch reduzieren',
              'message': 'Gemeinsam Kosten und CO2 sparen!',
            },
            '4': {
              'state': 'Verbrauch reduzieren',
              'message': 'Strommangel verhindern! Bitte schalte unnötige Geräte ab.',
            },
          } %}
          {% set state = states('sensor.stromgedacht_status_code') %}
          {{ mapper[state]['message'] if state in mapper else 'N/A' }}