PowerLight: Difference between revisions

From RevSpace
Jump to navigation Jump to search
 
(74 intermediate revisions by the same user not shown)
Line 2: Line 2:
  |Name=PowerLight
  |Name=PowerLight
  |Picture=PowerLight.jpg
  |Picture=PowerLight.jpg
  |Omschrijving=Show energy mix of dutch power generation as a pie chart on a LED ring
  |Omschrijving=Shows mix of dutch electrical power generation as a pie chart on a LED ring
  |Status=Completed
  |Status=Completed
  |Contact=bertrik
  |Contact=bertrik
Line 8: Line 8:


== The concept ==
== The concept ==
Draw the current dutch electrical power generation-mix as pie chart on a LED ring light, with colors representing fractions of a specific power generation source.
Show the current dutch electrical power generation-mix as pie chart on a LED ring light, with colors representing fractions of a specific power generation source.


For example:
For example:
Line 15: Line 15:
* red: fossil
* red: fossil
* green: nuclear
* green: nuclear
* grey: other/waste
* purple: other/waste


== Power generation data ==
== Power generation data ==
=== ENTSO-E data ===
Information about energy in Europe is collected at the european organisation https://www.entsoe.eu/ .
Information about energy in Europe is collected at the european organisation https://www.entsoe.eu/ .
The section about electrical energy is collected in ENTSO-E.
The section about electrical energy is collected in ENTSO-E.
Line 30: Line 32:
https://static.electricitymap.org/api/docs/index.html#introduction
https://static.electricitymap.org/api/docs/index.html#introduction


==== Power generation categories ====
ENTSO-E distinguishes energy generation into several types ("PsrType").
The backend uses the following categories
This is how they are relevant to the data from the Netherlands:
 
ENTSO-E numbers the production types from B01 to B20 ("PsrType"), how these are filled for the netherlands:
* B01 (biomass): always 0, not useful
* B01 (biomass): always 0, not useful
* B02: not available
* B02: not available
Line 48: Line 48:
* B13 (marine): not available
* B13 (marine): not available
* <b>B14 (nuclear): useful</b>
* <b>B14 (nuclear): useful</b>
* <b>B15 (other renewable): not available</b>
* B15 (other renewable): not available
* B16 (solar): hugely underreported, *not* useful
* B16 (solar): hugely underreported, *not* useful
* <b>B17 (waste): useful</b>
* <b>B17 (waste): useful</b>
Line 55: Line 55:
* <b>B20 (other): useful</b>
* <b>B20 (other): useful</b>


==== The solar power problem ====
Additionally, ENTSO-E provides a day-ahead forecast for:
In particular the solar power fraction is incomplete, but also the biomass figures are missing. See:
* B16 (solar)
* https://berthub.eu/articles/posts/dutch-electrical-power-figures-2/ provides a nice overview of the current situation about dutch electrical power generation data
* B18 (wind offshore)
* https://energy-charts.info/charts/energy_pie/chart.htm?l=en&c=NL note how the solar part is tiny, even during the day
* B19 (wind onshore)
 
There is a model that estimates the solar fraction, also at a regional level, at https://api.netanders.io/, however use of this model requires a paid subscription.
 
What I'm currently doing for the solar fraction, is to use the ENTSO-E <b>forecast</b> instead of the actual solar numbers reported to them, see
[https://transparency.entsoe.eu/generation/r2/dayAheadGenerationForecastWindAndSolar/show?name=&defaultValue=false&viewType=GRAPH&areaType=CTY&atch=false&dateTime.dateTime=11.07.2022+00:00|CET|DAYTIMERANGE&dateTime.endDateTime=11.07.2022+00:00|CET|DAYTIMERANGE&area.values=CTY|10YNL----------L!CTY|10YNL----------L&productionType.values=B16&processType.values=A18&processType.values=A01&processType.values=A40&dateTime.timezone=CET_CEST&dateTime.timezone_input=CET+(UTC+1)+/+CEST+(UTC+2) yesterday's wind/solar forecast].
Perhaps this can also be done for the wind fraction.


==== Data schedule ====
==== Data schedule ====
Line 71: Line 65:
At that point, the most recent data is from an interval that ended 30 minutes ago.
At that point, the most recent data is from an interval that ended 30 minutes ago.
So, including the 5m20s minute processing delay, the most recent data available is about 35 minutes old.
So, including the 5m20s minute processing delay, the most recent data available is about 35 minutes old.
=== The model I use for the energy generation mix of the Netherlands ===
For me, most insightful information came from this article by Bert Hubert:
https://berthub.eu/articles/posts/dutch-electrical-power-figures-2/
Main points relevant for me:
* The solar part reported to entso-e is way too small. Note also at for example https://energy-charts.info/charts/energy_pie/chart.htm?l=en&c=NL that the solar part is tiny
* On-shore wind data is unreliable, but off-shore wind data is probably OK
* No biomass data is reported to entso-e
There is a model that estimates the solar fraction, also at a regional level and at fine time resolution, at https://api.netanders.io/
However use of this model requires a paid subscription, so I cant't use that.
In my backend application, energy generation fractions are calculated as follows:
* solar = B16 (from the time-shifted '''forecast''' document A69)
* wind = B18 (offshore, from '''generation''' document A75) + B19 (onshore, from time-shifted '''forecast''' document A69)
* fossil = B04 (gas) + B05 (coal)
* nuclear = B14
* waste = B17
* other = B20
Solar energy values from the forecast document show a systematic shift of about 30 minutes compared to other sources
(e.g. sunrise/sunset data from national weather institute KNMI, energieopwek.nl)
so forecast data from the ENTSO-E document is shifted by 30 minutes in my model.
In the end, all of the electrical generation data used in my backend application is ENTSO-E data.
=== Data model behind CO2monitor.nl ===
Analysis:
* Much of the data comes from ENTSO-E, except for at least solar, wind, biomass, WKK
* Biomass data seems to follow the coal data exactly in shape. The sum of the biomass and coal numbers at CO2monitor equal exactly the ENTSO-E hard coal number.
* CO2monitor must be assigning some fraction of the ENTSO-E hard-coal number to biomass, it is unknown how they arrive at this fraction
* The biomass fraction seems to be 1295/2740 = 47.3% (data from 18 november 2023)
Some data from CBS on energy use for electricity production in 2022: https://opendata.cbs.nl/statline/#/CBS/nl/dataset/80030NED/table?fromstatweb
* total energy from coal: 53315 TJ
* total energy from biomass: 34798 TJ
This means a ratio of 39.5% biomass vs (biomass + coal), not exactly the CO2monitor number, but on the same order
=== Nederlands energie dashboard API ===
Documentatie staat op https://ned.nl/nl/api .
Uitleg bronnen bij de definities https://ned.nl/nl/definities
Notes:
* Het content-type is standaard application/json+ld, je ontvangt dan JSON met 'linked data', data is dan gewrapped in een andere structuur. Content-type application/json werkt ook.
* De argumenten zijn case-sensitive, argumenten moeten met kleine letter beginnen. De documentatie toont hoofdletters.
* De volgorde van argumenten is belangrijk, een verkeerde volgorde leidt tot time-outs. Voor de 'juiste' volgorde kan je best de voorbeelden volgen. In ieder geval 'point' of 'validfrom' eerst.
* Het 'utilization' endpoint levert altijd tijdreeksen op. De fijnste resolutie van begin/eind een tijdreeks is een dag. De API heeft geen specifieke mogelijkheid voor opvragen van de meest recente / actuele  waarde, je kan de gegevens voor de hele dag opvragen en dan de meest recente waarde gebruiken. Voor verschillende bronnen moet je losse calls maken (let op: rate limit).
Mapping van ned.nl data naar energie-ring:
* solar = 2 (solar)
* wind = 1 (wind) + 51 (offshoreC)
* fossil = 18 (FossilGasPower) + 19 (FossilHardCoal) = zelfde data als ENTSO-E (minus de aanname over de biomassa-fractie?)
* nuclear = 20 (Nuclear) = zelfde data als ENTSO-E?
* waste = 21 (WastePower) = zelfde data als ENTSO-E?
* other = 26 (OtherPower)
Wat nog onduidelijk is / beetje raar:
* Timestamp van data lijkt 'te nieuw', veel van de data komt van entso-e, die loopt al 30-46 minuten achter.
* Bronnen lijken overlap te hebben, hoe voorkom je dat je dingen dubbel telt?
** Bijvoorbeeld biomass, bio-oil, bio-methane, "biomasspower", wood en cofiring, gaat allemaal over biomassa.
* Onderscheid verwarming / elektriciteitsopwek
** Other vs OtherPower, is de eerste inclusief warmte, en de tweede waarschijnlijk alleen elektriciteit
* Er zijn verschillende modellen voor offshore-wind, maar juist de onshore-wind heeft veel onzekerheid
* Hoe werkt het zonne-opwekmodel?
* Bron 'All' is *alleen* hernieuwbare fractie?
* Gerapporteerde wind-opwek vertoont hele grote fluctuaties tot ca 200%, oorzaak onduidelijk, mogelijk incomplete data?
* Opwek omgerekend naar instantaan vermogen (of KWh / uur) wordt 'capacity' genoemd, merkwaardige naamgeving.
Voorlopige conclusie: al-met-al lijkt ned.nl data *niet* betrouwbaar genoeg voor een semi-realtime weergave van opgewekt vermogen!


== Hardware ==
== Hardware ==


Parts:
Parts:
* LED ring light https://nl.aliexpress.com/item/1005003798658173.html
* LED ring light, for example
* Wemos D1 mini with an ESP8266
** 24-LED ring https://nl.aliexpress.com/item/32963152993.html I like this one, because it is in one piece and inexpensive
** 40-LED ring https://nl.aliexpress.com/item/1005003798658173.html this has 4 segments that you have to join/solder
** 60-LED ring https://nl.aliexpress.com/item/4000102576864.html also 4 segments
* Wemos D1 mini board + pin headers, containing an ESP8266 microcontroller
* "dupont"-cable, 4 wires
* angled pin header, some rings have 2.0 mm pitch, others have 2.54 mm pitch
* USB-A to USB-micro cable
* 5V USB adapter
 
Connecting it:
* Solder the straight pin headers that came with it on the wemos d1 mini
* Solder the angled pin to the LED ring
* Connect the dupont cable:
** Wemos 5V goes to 5V on the LED ring
** Wemos GND goes to GND on the LED ring
** Wemos D3 goes to DI on the LED ring
** Wemos D2 goes to DO on the LED ring
 
This [https://www.thingiverse.com/thing:3852495 picture stand] printed at 40% size works OK for the 24-LED ring.
 
Diffuser: https://www.thingiverse.com/thing:751894 resize to 89x89x8 mm


== Software ==
== Software ==
Line 86: Line 170:
Source code: https://github.com/bertrik/energymix-server
Source code: https://github.com/bertrik/energymix-server


Runs as a REST-like resource at http://stofradar.nl:9001/energy/latest
Runs as a REST-like resource, with the following endpoints:
(1-minute rate limit)
* http://stofradar.nl:9001/electricity/generation with details (every 15 minutes) about the current (35-50 minute ago) electricity generation mix, units are MW
* http://stofradar.nl:9001/electricity/capacity with currently (per year) installed generation capacity, by source, units are MW
* http://stofradar.nl:9001/electricity/price with day-ahead hourly electricity price-per-MWh for today, in euro/MWh, multiply by 0.001 to get euro/kWh
* http://stofradar.nl:9001/naturalgas/price with daily natural gas prices (neutral gas price) of [https://en.wikipedia.org/wiki/Title_Transfer_Facility TTF] spot market, in euro/MWh, multiply by 35.17/3600 (= divide by 102.36 approximately) to get euro/m3
* http://stofradar.nl:9001/naturalgas/flow with daily natural gas flows in/out the dutch natural gas system, units are (MWh/day)


Returns a JSON-structure like:
Returns JSON-structures like:
<pre>
<pre>{
{
   "time": 1700728200,
   "time": 1657057500,
  "datetime": "2023-11-23T09:30:00+01:00",
   "total": 9122,
   "total": 13552,
   "mix": [
   "mix": [  
     { "id": "solar", "power": 0, "color": "#FFFF00"},
     { "id": "solar", "power": 1232, "color": "#FFFF00"},  
     { "id": "wind", "power": 4, "color": "#0000FF"},
     { "id": "wind onshore", "power": 4241, "color": "#0000FF" },
     { "id": "fossil", "power": 86, "color": "#FF0000"},
    { "id": "wind offshore", "power": 2963, "color": "#0000FF"  },
     { "id": "nuclear", "power": 5, "color": "#FF00FF"},
    { "id": "fossil gas", "power": 2264, "color": "#FF0000"  },  
     { "id": "other", "power": 4, "color": "#444444"},
     { "id": "fossil coal", "power": 2051, "color": "#FF0000" },  
     { "id": "waste", "power": 1, "color": "#444444"}
     { "id": "nuclear", "power": 483, "color": "#00FF00" },  
     { "id": "waste", "power": 70, "color": "#FF00FF" },  
     { "id": "other", "power": 248, "color": "#FF00FF" }  
   ]
   ]
}
}</pre>
</pre>


* time is a unix time stamp in seconds, representing the end of the 15-minute period that the power figures refer to
* time is a unix time stamp in seconds, representing the end of the 15-minute period that the power figures refer to
* total is the total current electrical power (megawatt), suitable for display (on a numeric display inside the ring for example)
* dateime is ta user-readable time stamp, in dutch local time + offset
* energymix is an array of power sources, each with:
* total is the total most recent electrical power (megawatt), suitable for display (on a numeric display inside the ring for example)
* mix is an array of power sources, each with:
** a short unique id
** a short unique id
** most recent known power (megawatt)
** most recent known power (megawatt)
** hex color, for display on the led ring
** hex color, for display on the led ring


Energy generation sources are calculated from sources as follows, mostly from document A75:
<pre>
* solar = B16 (from the forecast document A69)
{
* wind = B18 + B19
  "current": { "date": "2022-10-30","price": 32.02 },
* fossil = B04 + B05
  "day-ahead": [
* nuclear = B14
    { "date": "2022-10-31", "price": 62.631 },
* waste = B17
    { "date": "2022-11-01", "price": 49.293 }
* other = B20
  ]
}
</pre>
 
=== Display ===
==== LED ring energy mix ====
[[File:electriciteitsmix.jpg|right|thumb]]


=== Light ===
Shows the dutch energy generation mix as a pie chart on a LED ring, one colour per source (solar/wind/fossil/etc)
Source code: https://github.com/bertrik/PowerLight
Source code: https://github.com/bertrik/PowerLight


The Arduino sketch polls the REST API using HTTP every minute.
The Arduino sketch polls the REST API using HTTP every minute.
The sketch auto-detects the number of LEDs in the ring, made possible by feeding the digital output of the last LED back into the microcontroller.


WiFi is managed by WifiManager. LEDs are controlled using FastLED. JSON content is parsed using ArduinoJSON.
WiFi is managed by WifiManager. LEDs are controlled using FastLED. JSON content is parsed using ArduinoJSON.
Hardware that I used:
* Wemos D1 mini, contains an ESP8266 + USB-serial converter
* 24-led pixel ring, for example this one https://nl.aliexpress.com/item/32963152993.html
* "dupont"-cable, you need 4 wires
** wemos 5V to LED ring 5V
** wemos GND to LED ring GND
** wemos D3 to LED ring DI
** wemos D2 to LED ring DO
Firmware installation:
* compiled using platformio
* clone the code from github, enter the PowerLight directory
* <pre>pio run -t upload</pre>
Configuration:
* connect over WiFi to the "ESP-POWERLIGHT" network (no password)
* open page at 192.168.4.1
* enter WiFi credentials (select a network + password)
==== LED ring price clock ====
Idea: display relative electricity price on a clock face.
* LED ring with 24 coloured leds, 2 leds per hour
* colour indicates relative price, green = low, red = high
* indicate current time by making the corresponding LED extra bright
Interesting links:
* https://hackaday.io/project/193697-octoclock-and-old-school-energy-meter
==== ElectricityPrice ====
Shows the current dutch electricity price, based on the day-ahead prices from yesterday.
Source code: https://github.com/bertrik/ElectricityPrice
The Arduino sketch polls the REST price API using HTTP every 5 minutes.
WiFi is managed by WifiManager. JSON content is parsed using ArduinoJSON.
Hardware is an ESP8266 controlling a 7-segment display based on a TM1637, on pins D3 and D4.
===== T-Display =====
[[File:Nlecprice_mockup.png|right]]
Alternative: use a TTGO ESP32 T-Display.
It has a 240x135 pixel display.
Plan is to show a kind of bar graph with 24 bars (one bar for each hour), each bar's height indicates the price of that hour.
The background color shows green/black/red, to indicate cheap/moderate/expensive.
Current price is shown as a big number.
Each bar is therefore 10 pixels wide, 9 pixels for the bar + 1 pixel separation.
===== SHA-badge =====
The SHA2017 badge has an ESP32 capable of performing the HTTP request, processing the JSON and displaying the result on its display.
These badges are limited-edition, a few thousand of them were made for the SHA-2017 event and they're no longer being produced.
It has a 296x128 pixel epaper panel.
So that could be a bar graph of 24 bars with a width of 12 pixels each, on the bottom 2/3rds of the display,
and a current price on the top 1/3rd of the display.
Could be run as a micropython sketch. Alternatively could be run as an Arduino sketch.
Micropython:
* ++ possibly quick development, script can be shared with other people
* ++ has working libs for fetching HTTP, decoding JSON, controlling the display
* -- script needs frequent garbage collection to avoid crashing?
* -- unclear how to get a python script on this thing
* -- sha badge firmware bootloops, currently unusable to me
Arduino:
* ++ I know this environment, don't have to debug existing bootlooping firmware, no compiler setup required
* ++ Already have HTTP and JSON working on Arduino
* ++ Code starts immediately, no user interaction required
* -- not sure if there is a usable epaper driver

Latest revision as of 17:22, 16 November 2024

Project PowerLight
PowerLight.jpg
Shows mix of dutch electrical power generation as a pie chart on a LED ring
Status Completed
Contact bertrik
Last Update 2024-11-16

The concept

Show the current dutch electrical power generation-mix as pie chart on a LED ring light, with colors representing fractions of a specific power generation source.

For example:

  • yellow: solar
  • blue: wind
  • red: fossil
  • green: nuclear
  • purple: other/waste

Power generation data

ENTSO-E data

Information about energy in Europe is collected at the european organisation https://www.entsoe.eu/ . The section about electrical energy is collected in ENTSO-E. Data is available from this platform at a 15-minute interval.

TenneT is the organisation that supplies ENTSO-E with data from the Netherlands.

Information about ENTSO-E generation domain API: https://transparency.entsoe.eu/content/static_content/Static%20content/web%20api/Guide.html#_generation_domain

Also possibly interesting (requires an API key), but might actually just use the entso-e data: https://static.electricitymap.org/api/docs/index.html#introduction

ENTSO-E distinguishes energy generation into several types ("PsrType"). This is how they are relevant to the data from the Netherlands:

  • B01 (biomass): always 0, not useful
  • B02: not available
  • B03: not available
  • B04 (fossil hard coal): useful
  • B05 (fossil gas): useful
  • B06: not available
  • B07: not available
  • B08: not available
  • B09 (geothermal): not available
  • B10 (hydro): not available
  • B11 (hydro): always 0
  • B12 (hydro): not available
  • B13 (marine): not available
  • B14 (nuclear): useful
  • B15 (other renewable): not available
  • B16 (solar): hugely underreported, *not* useful
  • B17 (waste): useful
  • B18 (wind offshore): useful
  • B19 (wind onshore): useful
  • B20 (other): useful

Additionally, ENTSO-E provides a day-ahead forecast for:

  • B16 (solar)
  • B18 (wind offshore)
  • B19 (wind onshore)

Data schedule

Entso-E provides data with a resolution of 15 minutes. It appears to become available about 5m20s after the start of each 15 minute period (:00, :15, :30, :45). At that point, the most recent data is from an interval that ended 30 minutes ago. So, including the 5m20s minute processing delay, the most recent data available is about 35 minutes old.

The model I use for the energy generation mix of the Netherlands

For me, most insightful information came from this article by Bert Hubert: https://berthub.eu/articles/posts/dutch-electrical-power-figures-2/

Main points relevant for me:

There is a model that estimates the solar fraction, also at a regional level and at fine time resolution, at https://api.netanders.io/ However use of this model requires a paid subscription, so I cant't use that.

In my backend application, energy generation fractions are calculated as follows:

  • solar = B16 (from the time-shifted forecast document A69)
  • wind = B18 (offshore, from generation document A75) + B19 (onshore, from time-shifted forecast document A69)
  • fossil = B04 (gas) + B05 (coal)
  • nuclear = B14
  • waste = B17
  • other = B20

Solar energy values from the forecast document show a systematic shift of about 30 minutes compared to other sources (e.g. sunrise/sunset data from national weather institute KNMI, energieopwek.nl) so forecast data from the ENTSO-E document is shifted by 30 minutes in my model.

In the end, all of the electrical generation data used in my backend application is ENTSO-E data.

Data model behind CO2monitor.nl

Analysis:

  • Much of the data comes from ENTSO-E, except for at least solar, wind, biomass, WKK
  • Biomass data seems to follow the coal data exactly in shape. The sum of the biomass and coal numbers at CO2monitor equal exactly the ENTSO-E hard coal number.
  • CO2monitor must be assigning some fraction of the ENTSO-E hard-coal number to biomass, it is unknown how they arrive at this fraction
  • The biomass fraction seems to be 1295/2740 = 47.3% (data from 18 november 2023)

Some data from CBS on energy use for electricity production in 2022: https://opendata.cbs.nl/statline/#/CBS/nl/dataset/80030NED/table?fromstatweb

  • total energy from coal: 53315 TJ
  • total energy from biomass: 34798 TJ

This means a ratio of 39.5% biomass vs (biomass + coal), not exactly the CO2monitor number, but on the same order

Nederlands energie dashboard API

Documentatie staat op https://ned.nl/nl/api . Uitleg bronnen bij de definities https://ned.nl/nl/definities

Notes:

  • Het content-type is standaard application/json+ld, je ontvangt dan JSON met 'linked data', data is dan gewrapped in een andere structuur. Content-type application/json werkt ook.
  • De argumenten zijn case-sensitive, argumenten moeten met kleine letter beginnen. De documentatie toont hoofdletters.
  • De volgorde van argumenten is belangrijk, een verkeerde volgorde leidt tot time-outs. Voor de 'juiste' volgorde kan je best de voorbeelden volgen. In ieder geval 'point' of 'validfrom' eerst.
  • Het 'utilization' endpoint levert altijd tijdreeksen op. De fijnste resolutie van begin/eind een tijdreeks is een dag. De API heeft geen specifieke mogelijkheid voor opvragen van de meest recente / actuele waarde, je kan de gegevens voor de hele dag opvragen en dan de meest recente waarde gebruiken. Voor verschillende bronnen moet je losse calls maken (let op: rate limit).

Mapping van ned.nl data naar energie-ring:

  • solar = 2 (solar)
  • wind = 1 (wind) + 51 (offshoreC)
  • fossil = 18 (FossilGasPower) + 19 (FossilHardCoal) = zelfde data als ENTSO-E (minus de aanname over de biomassa-fractie?)
  • nuclear = 20 (Nuclear) = zelfde data als ENTSO-E?
  • waste = 21 (WastePower) = zelfde data als ENTSO-E?
  • other = 26 (OtherPower)

Wat nog onduidelijk is / beetje raar:

  • Timestamp van data lijkt 'te nieuw', veel van de data komt van entso-e, die loopt al 30-46 minuten achter.
  • Bronnen lijken overlap te hebben, hoe voorkom je dat je dingen dubbel telt?
    • Bijvoorbeeld biomass, bio-oil, bio-methane, "biomasspower", wood en cofiring, gaat allemaal over biomassa.
  • Onderscheid verwarming / elektriciteitsopwek
    • Other vs OtherPower, is de eerste inclusief warmte, en de tweede waarschijnlijk alleen elektriciteit
  • Er zijn verschillende modellen voor offshore-wind, maar juist de onshore-wind heeft veel onzekerheid
  • Hoe werkt het zonne-opwekmodel?
  • Bron 'All' is *alleen* hernieuwbare fractie?
  • Gerapporteerde wind-opwek vertoont hele grote fluctuaties tot ca 200%, oorzaak onduidelijk, mogelijk incomplete data?
  • Opwek omgerekend naar instantaan vermogen (of KWh / uur) wordt 'capacity' genoemd, merkwaardige naamgeving.

Voorlopige conclusie: al-met-al lijkt ned.nl data *niet* betrouwbaar genoeg voor een semi-realtime weergave van opgewekt vermogen!

Hardware

Parts:

Connecting it:

  • Solder the straight pin headers that came with it on the wemos d1 mini
  • Solder the angled pin to the LED ring
  • Connect the dupont cable:
    • Wemos 5V goes to 5V on the LED ring
    • Wemos GND goes to GND on the LED ring
    • Wemos D3 goes to DI on the LED ring
    • Wemos D2 goes to DO on the LED ring

This picture stand printed at 40% size works OK for the 24-LED ring.

Diffuser: https://www.thingiverse.com/thing:751894 resize to 89x89x8 mm

Software

The software consists of two parts:

  • The backend part that collects the power generation data, written in Java, running on a VPS
  • The light part that visualizes the power generation as fractions on a LED ring, running on an Arduino

Backend

Source code: https://github.com/bertrik/energymix-server

Runs as a REST-like resource, with the following endpoints:

Returns JSON-structures like:

{
  "time": 1700728200,
  "datetime": "2023-11-23T09:30:00+01:00",
  "total": 13552,
  "mix": [ 
    { "id": "solar", "power": 1232, "color": "#FFFF00"}, 
    { "id": "wind onshore", "power": 4241, "color": "#0000FF"  }, 
    { "id": "wind offshore", "power": 2963, "color": "#0000FF"  }, 
    { "id": "fossil gas", "power": 2264, "color": "#FF0000"  }, 
    { "id": "fossil coal", "power": 2051, "color": "#FF0000"  }, 
    { "id": "nuclear", "power": 483, "color": "#00FF00"  }, 
    { "id": "waste", "power": 70, "color": "#FF00FF"  }, 
    { "id": "other", "power": 248, "color": "#FF00FF"  } 
  ]
}
  • time is a unix time stamp in seconds, representing the end of the 15-minute period that the power figures refer to
  • dateime is ta user-readable time stamp, in dutch local time + offset
  • total is the total most recent electrical power (megawatt), suitable for display (on a numeric display inside the ring for example)
  • mix is an array of power sources, each with:
    • a short unique id
    • most recent known power (megawatt)
    • hex color, for display on the led ring
{
  "current": { "date": "2022-10-30","price": 32.02 },
  "day-ahead": [
    { "date": "2022-10-31", "price": 62.631 },
    { "date": "2022-11-01", "price": 49.293 }
  ]
}

Display

LED ring energy mix

Electriciteitsmix.jpg

Shows the dutch energy generation mix as a pie chart on a LED ring, one colour per source (solar/wind/fossil/etc) Source code: https://github.com/bertrik/PowerLight

The Arduino sketch polls the REST API using HTTP every minute.

The sketch auto-detects the number of LEDs in the ring, made possible by feeding the digital output of the last LED back into the microcontroller.

WiFi is managed by WifiManager. LEDs are controlled using FastLED. JSON content is parsed using ArduinoJSON.

Hardware that I used:

  • Wemos D1 mini, contains an ESP8266 + USB-serial converter
  • 24-led pixel ring, for example this one https://nl.aliexpress.com/item/32963152993.html
  • "dupont"-cable, you need 4 wires
    • wemos 5V to LED ring 5V
    • wemos GND to LED ring GND
    • wemos D3 to LED ring DI
    • wemos D2 to LED ring DO

Firmware installation:

  • compiled using platformio
  • clone the code from github, enter the PowerLight directory
  • pio run -t upload

Configuration:

  • connect over WiFi to the "ESP-POWERLIGHT" network (no password)
  • open page at 192.168.4.1
  • enter WiFi credentials (select a network + password)

LED ring price clock

Idea: display relative electricity price on a clock face.

  • LED ring with 24 coloured leds, 2 leds per hour
  • colour indicates relative price, green = low, red = high
  • indicate current time by making the corresponding LED extra bright

Interesting links:

ElectricityPrice

Shows the current dutch electricity price, based on the day-ahead prices from yesterday. Source code: https://github.com/bertrik/ElectricityPrice

The Arduino sketch polls the REST price API using HTTP every 5 minutes. WiFi is managed by WifiManager. JSON content is parsed using ArduinoJSON.

Hardware is an ESP8266 controlling a 7-segment display based on a TM1637, on pins D3 and D4.

T-Display
Nlecprice mockup.png

Alternative: use a TTGO ESP32 T-Display.

It has a 240x135 pixel display. Plan is to show a kind of bar graph with 24 bars (one bar for each hour), each bar's height indicates the price of that hour. The background color shows green/black/red, to indicate cheap/moderate/expensive. Current price is shown as a big number.

Each bar is therefore 10 pixels wide, 9 pixels for the bar + 1 pixel separation.

SHA-badge

The SHA2017 badge has an ESP32 capable of performing the HTTP request, processing the JSON and displaying the result on its display. These badges are limited-edition, a few thousand of them were made for the SHA-2017 event and they're no longer being produced.

It has a 296x128 pixel epaper panel. So that could be a bar graph of 24 bars with a width of 12 pixels each, on the bottom 2/3rds of the display, and a current price on the top 1/3rd of the display.

Could be run as a micropython sketch. Alternatively could be run as an Arduino sketch.

Micropython:

  • ++ possibly quick development, script can be shared with other people
  • ++ has working libs for fetching HTTP, decoding JSON, controlling the display
  • -- script needs frequent garbage collection to avoid crashing?
  • -- unclear how to get a python script on this thing
  • -- sha badge firmware bootloops, currently unusable to me

Arduino:

  • ++ I know this environment, don't have to debug existing bootlooping firmware, no compiler setup required
  • ++ Already have HTTP and JSON working on Arduino
  • ++ Code starts immediately, no user interaction required
  • -- not sure if there is a usable epaper driver