Physical PV Solar Energy and Battery SoC Dashboard

Hi Friends,
what I want to present to you is not a digital dashboard but a physical device to hang on your wall:


The two gauges display the current amount of PV energy produced and the state of charge of the battery.
It is implemented by querying the HA REST API to get the real-time values and uses a Raspberry Pi pico running MicroPython to drive the servo motors with the arrows attached.
If you like the project I’m happy to share some more details and code.
Cheers Wido

4 Likes

Oh man, a few months ago I was researching some retro style gauges to create something similar to this… If you could provide more detail on setup and hardware that would be much appreciated!!!

1 Like

Thanks Tommy!
I’m happy to share setup and code with you. I’ll prepare the code and post it here soon.

import time
import network
import urequests as requests
from machine import Pin, PWM
import json

led = Pin("LED", Pin.OUT)
led.on()

servo1 = PWM(Pin(0))
servo1.freq(50)
servo2 = PWM(Pin(1))
servo2.freq(50)

#while True:
for position in range(2000,8000,50):
    servo1.duty_u16(position)
    time.sleep(0.01)
for position in range(8000,2000,-50):
    servo1.duty_u16(position)
    time.sleep(0.01)

for position in range(2000,8000,50):
    servo2.duty_u16(position)
    time.sleep(0.01)
for position in range(8000,2000,-50):
    servo2.duty_u16(position)
    time.sleep(0.01)

led.off()

# Wifi connection
ssid = 'your wifi SSID'
password = 'your wifi password'

# home assistant bearer token
bearerToken = "your bearer token"

wlan = network.WLAN(network.STA_IF)
wlan.active(True)
wlan.connect(ssid, password)

# Wait for connect or fail
max_wait = 10
while max_wait > 0:
    if wlan.status() < 0 or wlan.status() >= 3:
        break
max_wait -= 1
print('waiting for connection...')
time.sleep(1)

# Handle connection error
if wlan.status() != 3:
    led.off()
    raise RuntimeError('network connection failed')
else:
    print('connected')
    led.on()
status = wlan.ifconfig()
print( 'ip = ' + status[0] )

Battery = 0
PvPower = 0

while True:
    # connect to the hoemassistant data source that you want to display
    urlPvPower = "http://homeassistant.local:8123/api/states/sensor.pv_power_now"
    urlBattery = "http://homeassistant.local:8123/api/states/sensor.battery_soc"
    headers = {"Authorization": "Bearer " + bearerToken}

    # Then send it in a try/except block
    try:
        print("querying...")
        led.on()
        response = requests.get(urlPvPower, headers=headers)
        print("sent (" + str(response.status_code) + "), status = " + str(wlan.status()) )
        resJson = json.loads(response.content)
        PvPowerStr = resJson["state"]
        print("PV Leistung: " + PvPowerStr)
        PvPower = int(float(PvPowerStr))
        response = requests.get(urlBattery, headers=headers)
        print("sent (" + str(response.status_code) + "), status = " + str(wlan.status()) )
        resJson = json.loads(response.content)
        BatteryStr = resJson["state"]
        print("BatterieStr: " + BatteryStr)
        Battery = int(BatteryStr)
        response.close()
        led.off()
    except Exception as e:
        print("***\nException while calling HA API. ex: " + str(e))
        print("could not connect (status =" + str(wlan.status()) + ")")
    if wlan.status() < 0 or wlan.status() > 3:
        print("trying to reconnect...")
        wlan.disconnect()
        wlan.connect(ssid, password)
    if wlan.status() == 3:
        print('connected')
    else:
        print('failed')

    # control servos
    #for position in range(2000,8000,50):
    position = int(7900 - Battery * 60)
    servo1.duty_u16(position)
    print("Battery servo position: " + str(position))
    
    position = 7900 - PvPower
    servo2.duty_u16(position)
    print("PvPower servo position: " + str(position))
    time.sleep(8)

Hardware:
attach two standard analog servers to “Raspberry Pi Pico W” with their signal lines to GP0 and GP1 on the pico.
Software:
Get started with pi pico and Micropython.
Find the data URL that you want to use in home assistant and enter them in line 67 and 68 of the source code
Get a long-lived access token like described here and paste it into line 69

If you have further questions, get back to me. And tell me what you built.
Cheers Wido

Awesome thanks!!!
First job will be to find the right servos… Do you have a link for th eones you got?

1 Like

Doesn’t matter too much. Just don’t buy the very cheap blue ones. They are loud and not precise. Just search for “MG90 Servo” on amazon, alibaba or your favourite seller.
Good luck and keep me/us posted.
Cheers, Wido