Start a new topic

## Off grid solar charging python script

Aloha from  Hawai'i :)  I have been searching this forum to see if anyone has posted this before, and it looks people have but didn't find a solution.

I have an off grid solar setup that I use to charge the 4 EV that our household has.  I use the Open EVSE and a Shelly UNI to modulate the EV charging rate.  I do this thru a python script.  The function of the script is to monitor the voltage of the battery connected to my solar inverter.  When the battery is full, the charge of the EV is started.  After starting the charge the script attempts to maintain a set voltage thru charge rate adjustments.  If the voltage falls below a set threshold then charging is ended until it rises above the start charge setpoint.

I'm sure there is plenty of room for improvement and maybe an easier way to accomplish this task, however I have hopes this helps those that are looking and maybe starts a discussion for and easier way :)

The Shelly uni is only \$12, it can do up to a 30V without any extras, much more with the addition of a voltage divider.  https://www.shelly.com/en-us/products/shop/shelly-uni-us

This is the script I wrote, my coding is not good and I have never had any training whatsoever in code :(

import requests

import traceback

import time

# Setpoint voltage for maintaining charging

setpoint_voltage = XX.X # Define the setpoint voltage

# Voltage at which charging should start

start_voltage = XX.X # Define the start voltage

# Voltage at which charging should stop

stop_voltage = XX.X # Define the stop voltage

# Minimum and maximum charge rates in amps

min_current = XX # Define the minimum charge rate

max_current = XX # Define the maximum charge rate

# Maximum number of retries

max_retries = 10

# Shelly device API URL

shelly_api_url = "http://192.168.1.XXX/status"

# OpenEVSE API URL

openevse_api_url = "http://openevse-XXXX.local"

openevse_client_id = 1 # Define the OpenEVSE client ID

# Function to get current voltage from Shelly device

def get_voltage():

retries = 0

while retries < max_retries:

try:

if response.status_code == 200:

data = response.json()

else:

return None

else:

print("Failed to fetch voltage data from Shelly device. Status code:", response.status_code)

return None

except requests.RequestException as e:

print("Request failed:", e)

retries += 1

print("Retrying...")

time.sleep(5) # Wait before retrying

print("Max retries reached. Could not fetch voltage data.")

return None

# Function to control OpenEVSE charging based on ADC voltage

def control_charging():

charging_started = False # Flag to track if charging was initiated

voltage_below_stop = False # Flag to track if voltage fell below stop voltage after charging started

manual_start = False # Flag to track manual start

# Manual start option (runs once at the beginning)

manual_start_input = input("Do you want to start charging manually? (yes/no): ").strip().lower()

if manual_start_input == "yes":

charging_started = True

manual_start = True

print("Charging started manually.")

else:

manual_start = False

while True:

voltage = get_voltage()

if voltage is not None:

print("Current voltage:", voltage)

# Start charging when voltage exceeds start voltage or manually started

if (voltage >= start_voltage and not charging_started) or manual_start:

charge_current = min_current

charging_started = True

voltage_below_stop = False # Reset the flag

manual_start = False # Reset manual start flag

print("Starting charging at minimum rate")

# Control charge current based on voltage

if charging_started:

if voltage > setpoint_voltage:

charge_current = min(max_current, charge_current + 1)

print("Increasing charge rate by 1 Amps. New charge rate:", charge_current)

elif voltage < setpoint_voltage:

if charge_current > min_current:

charge_current = max(min_current, charge_current - 1) # Enforce min_current

print("Decreasing charge rate by 1 Amps. New charge rate:", charge_current)

elif charge_current == min_current:

print("Charge rate is already at minimum.")

print("Charge current:", charge_current)

# Stop charging if voltage falls below stop_voltage

if charging_started and voltage <= stop_voltage:

charge_current = 0

voltage_below_stop = True

charging_started = False # Ensure charging is stopped

print("Stopping charging due to voltage below stop_voltage")

# Restart charging if voltage goes back above start_voltage after previously stopping

if voltage >= start_voltage and voltage_below_stop:

voltage_below_stop = False # Reset the flag

print("Voltage back above start_voltage. Waiting for start_voltage to restart charging.")

# Make/update claim on OpenEVSE with adjusted charge current

"state": "active" if charge_current > 0 else "disabled",

"charge_current": charge_current,

"max_current": max_current,

"auto_release": True

}

retries = 0

while retries < max_retries:

try:

print("Response from OpenEVSE API:", response.text)

break

except requests.RequestException as e:

print("Request failed:", e)

retries += 1

print("Retrying OpenEVSE command...")

time.sleep(5) # Wait before retrying

if retries == max_retries:

print("Max retries reached. Could not send command to OpenEVSE API.")

time.sleep(30) # Adjust the polling interval as needed

# Start controlling charging

try:

control_charging()

except Exception as e:

print("An unexpected error occurred:", e)

traceback.print_exc()

1 person likes this idea

Your Mac book will work for now :) but a pi would be better long term ;) there are plenty of recourses out there to help setting up the pi. I’m pretty sure python is built into the pi OS? So that saves a step :)

It sounds like a Pi3 uses less power and is less cost. What its yours?

G

Even the cheapest pi could run this with no drama. :). Whatever you get will be perfect ;)

OK! I think I have all parts ordered or here. I'll VERY likely post more questions when I start in on it.....

G