Myenergi Eddi & Raspberry Pi
SOLAR POWER LEVEL INDICATOR
You can turn a Raspberry Pi into a visual level indicator to see the status of your solar energy production at a glance.
This simple DIY solution is based on a solar system with a Myenergi Eddi energy diverter installed, with both CT clamps in use (one to measure production and one to measure the grid). The script is easily adaptable to other systems or configurations.
You will need the Blinkt led strip from Pimoroni and of course a Raspberry Pi.
The first steps are:
- Get an API key for your Myenergi product
- Add a bash script to download the Myenergi JSON file
- Add a Python script to set the LEDs
- Create a crontab to run every 2 minutes from 04:00 to 20:00
Log into your myenergi account and look for your product to get the serial number & click the Advanced option to get the API key (password). Don’t mind the API warning, this only applies to the API key being generated. You need these details for the bash script further below.
The bash script uses curl to download the JSON file and upon successful download starts the Python script to set the LEDs. You can use crontab to run this bash script at regular intervals. In this example we use the user “pi” and a subdirectory “pilevel”. Go to this directory and enter “nano eddi-json.sh”:
#!/bin/bash if curl --silent --anyauth -u #SERIAL:#API -H 'accept: application/json' -H 'content-type: application/json' --compressed 'https://s18.myenergi.net/cgi-jstatus-*' > /tmp/eddi.json; then chmod 777 /tmp/eddi.json python /home/pi/pilevel/eddi-status.py fi
Make the bash script executable with “chmod +x eddi-json.sh”.
To install Blinkt on the Raspberry use:
sudo apt-get install python-blinkt
Next one to create is the Python script, use “nano eddi-status.py”
#!/usr/bin/env python # (c) JF Nutbroek # 14/11/2022 import json import math import blinkt import time # User defined input threshold = 0.03 # Minimum threshold power % for LED activation brightness = 0.05 # Brightness of the LEDs # ********* Start # Clear all LEDs blinkt.set_clear_on_exit(False) blinkt.set_brightness(brightness) blinkt.clear() blinkt.show() # Read the JSON file try: json_file = open("/tmp/eddi.json", "r") myenergi = json_file.read() data = json.loads(myenergi)[0]['eddi'][0] except: exit() # Obtain the power usage if 'div' in data: diverted_power = data['div'] else: diverted_power = 0 if 'gen' in data: solar_power = data['gen'] else: solar_power = 0 if 'grd' in data: grid_power = data['grd'] else: grid_power = 0 # Calculate the power per LED total_leds = blinkt.NUM_PIXELS if grid_power > 0: pwr_per_led = (grid_power + solar_power) / total_leds else: pwr_per_led = solar_power / total_leds # Threshold conditions if diverted_power < threshold * (pwr_per_led * total_leds): diverted_power = 0 if solar_power < threshold * (pwr_per_led * total_leds): grid_power = grid_power + solar_power if abs(grid_power) < threshold * (pwr_per_led * total_leds): grid_power = 0 # LEDs red_leds = 0 blue_leds = 0 white_leds = 0 # Calculate the colors if diverted_power > 0: blue_leds = max(1, math.floor(diverted_power / pwr_per_led)) if grid_power > 0: red_leds = max(1, math.floor(grid_power / pwr_per_led)) if grid_power < 0: white_leds = max(1, math.floor(abs(grid_power) / pwr_per_led)) # Set all LEDs to GREEN for led in range(0, int(total_leds)): blinkt.set_pixel(led, 0, 255, 0) time.sleep(1.0 - (0.1 * led)) blinkt.show() # BLUE if blue_leds > 0: for led in range(0, int(blue_leds)): blinkt.set_pixel(led, 0, 0, 255) time.sleep(1) blinkt.show() # RED if red_leds > 0: for led in reversed(range(int(total_leds - red_leds), int(total_leds))): blinkt.set_pixel(led, 255, 0, 0) time.sleep(1) blinkt.show() # WHITE if white_leds > 0: for led in reversed(range(int(total_leds - white_leds), int(total_leds))): blinkt.set_pixel(led, 255, 255, 255) time.sleep(1) blinkt.show() # Debug # print("Status: " + "B " * int(blue_leds) + "G " * int(total_leds - blue_leds - red_leds - white_leds) + "R " * int(red_leds) + "W " * int(white_leds))
Make this script executable by typing “chmod +x eddi-status.py”
Finally we need a crontab to allow a two minute run of the script between 04:00h and 20:00h. Optionally reboot the Pi every day at midnight. Type”sudo crontab -e”.
0 0 * * * root reboot */2 4-20 * * * sh /home/pi/pilevel/eddi-json.sh 2>/home/pi/pilevel/cronlog
The LEDs have the following meaning:
- BLUE : The Eddi is diverting solar power
- GREEN: Solar power consumed in the house
- RED: Power pulled from the grid
- WHITE: Surplus solar power exported to the grid
The amount of LEDs show the level of power, all leds = 100% of the power. So if you have 4 green leds and 4 red leds, you are 50% energy independent. If you have 6 green and 2 white LEDs, it means you’re 100% energy independent and exporting 25% of the solar power.
That should be it, have fun!
Taking it to the next Level
You can take this to the next level, by only downloading the myenergi json file and switching the Pi Level indicator on between sunrise and sunset. For this purpose we need to add a new crontab, bash script and update the python script.
First of all, get a free API key to download a daily JSON astro file which contains the sunrise and sunset times for your location, at ipgeolocation.com.
Create the following bash script, “nano eddi-sunrise.sh”
#!/bin/bash curl --silent -H 'accept: application/json' -H 'content-type: application/json' --compressed 'https://api.ipgeolocation.io/astronomy?apiKey=#YOURKEY&lat=45.98&long=6.3' > /tmp/eddi-sunrise.json chmod 777 /tmp/eddi-sunrise.json
Enter your own latitude and longitude information (in the example it’s 45.9 by 6.3). Make the bash script executable with “chmod +x eddi-sunrise.sh”.
Next create a new crontab to download the JSON file once per day at 02:00. Type”sudo crontab -e” and add:
* 02 * * * sh /home/pi/pilevel/eddi-sunrise.sh 2>/home/pi/pilevel/cronlog
We need to add a new code section in our python script, insert this above the “# Obtain the power usage” section, so the script will stop excecution when it’s still dark and writes the sunrise and sunset times on to a bash script readable file for later use. Type “nano eddi-status.py”.
# Check if we are between sunrise & sunset try: json_file = open("/tmp/eddi-sunrise.json", "r") geodata = json_file.read() sundata = json.loads(geodata) if 'sunrise' in sundata: sunrise = sundata['sunrise'].split(":") else: sunrise = ["04", "00"] if 'sunset' in sundata: sunset = sundata['sunset'].split(":") else: sunset = ["20", "00"] startday = int(sunrise[0]) * 60 * 60 + int(sunrise[1]) * 60 endday = int(sunset[0]) * 60 * 60 + int(sunset[1]) * 60 except: startday = 4 * 60 * 60 endday = 20 * 60 * 60 now = time.localtime() inday = now.tm_hour * 60 * 60 + now.tm_min * 60 if inday < startday or inday > endday: f = open("/tmp/sunrise.txt", "w") f.write("startday=" + str(startday) + "\n") f.write("endday=" + str(endday) + "\n") f.close() exit()
To prevent downloading unnecessary json files, we can update our eddi-json.sh script as follows. Type”nano eddi-json.sh”:
#!/bin/bash if [ -f "/tmp/sunrise.txt" ]; then . "/tmp/sunrise.txt" now=$(( $(date '+%-H *3600 + %-M *60 + %-S') )) if [ $now -lt $startday ] || [ $now -gt $endday ]; then python /home/pi/pilevel/blinktoff.py exit 0 fi fi if curl --silent --anyauth -u $SERIAL:#API -H 'accept: application/json' -H 'content-type: application/json' --compressed 'https://s18.myenergi.net/cgi-jstatus-*' > /tmp/eddi.json; then chmod 777 /tmp/eddi.json python /home/pi/pilevel/eddi-status.py fi
To switch the Blinkt off add this script, type “nano blinktoff.py”:
#!/usr/bin/env python import blinkt blinkt.clear() blinkt.show()
Make the script executable with “chmod +x blinktoff.py”.
Now your system is able to switch the level indicator on at sunrise and start downloading json files every 2 minutes, and switch the downloading and level indicator off at sunset.
That’s all, success !!