I have now added a simple GUI to the script and added some more safety features :)
I wish I could juts edit my last post, I found a bug in the logic that allowed for premature restart after low voltage events. this has been fixed and the GUI improved :)
Aloha from Kekeha!
This is very similar to what I am trying to implement.
How are you reading the battery bank voltage?
Are you monitoring the house load and the inverter capacity as part of the EV charge current/load?
Any time of day limitations (don't start charging until batteries are a certain % of max voltage & its after 8am??)
So glad to have found your efforts. Thanks for posting! - Randy / boulderwise@proton.me
My home battery off-grid system is 48VDC. So my battery range is 47 to 57.
Is yours 24VDC, or do you use a voltage divider to measure your batteries (and power the Shelly UNI?)
Thanks, Randy
I actually have this script running on 3 separate systems that are not yet tied together, long story LOL. 2 of them are 48V and 1 is 24. The 48V systems I use a voltage divider for the ADC (voltage) measurement, and a 48VDC to 12V DC converter to power the UNI. You could also use something simple like a wall wort power supply to feed the UNI power, I didn't because I like to see teh DC voltage even if the inverter is faulted.
I used this voltage divider. It gives 1/5th the supply voltage. amazon supplied voltage divider
Wow! I just got an Openevse kit and got it running. I largely chose it because I'm interested in (need) this off-grid self regulating concept. (off-grid for 50 years)
However I'm not much with the "computer" stuff so this looks pretty daunting. But it's also new territory and "maybe" I can muddle my way through. Might you be setting any of these up for sale by any chance?
Gary
James,
You may be done looking at this but if not I'll ask a few questions. (I have pretty much zero knowledge of any of this.) What you are doing sounds brilliant and just what I need/want.
What is "talking" to what? Your script is aimed at the Shelly or the EVSE? Maybe that will all become apparent as I dig in deeper....?
And the divider you linked is for 25 V so that must not be what you used on your 48V system...?
Thanks!!
Aloha Gary :) Setting up python and running the script is very simple, you just need a device that can stay on and connected to the same network as the OPEN EVSE and Shelly uni (has to be the V1 version). The more interesting part can be dialing in the voltages because there is absolutely going to be a variance between the inverter DC V, Uni "ADC" and actual DC voltage of the battery. For whatever reason one of my UNI is always 3.5V low, another is spot on... The script is setup so you can make adjustments from a user interface and immediately apply them to the loop :)
Installing python on a windows PC is as easy as any other program... https://www.digitalocean.com/community/tutorials/install-python-windows-10
The script I supplied will then become executable. Open it like any program
Input your Open EVSE ID and Shelly uni IP address in the UI (Make them static for reliability, very straight forward in the shelly UI)
Put your voltage setpoints in the UI, Press "Update Settings" then "start auto" and thats it :)
I just realized I never published the newest version of this.... This iteration is much more user friendly :)
You can see in these images the rate control happening on the float current, its adjusting to the voltage rise and fall of the battery.
The other image is the GUI of the script. This is where you can make adjustments easily to the needed variables. The red boxes are site specific and need to be set based on you equipment. The voltage settings all need to be tailored to your specific needs also. Once you have it all dialed in you can edit the script in notepad to change your values to the defaults. Hopefully that makes the process less daunting :)
I saw this thread and exactly what I needed. Thanks for the post!
Gary, yes if you don't have any experience in computers it will be slightly challenging. Otherwise it's not so bad. I already have a raspberry pi (mini computer) that runs linux, which the python script above will run easily on it. Everything on it is pretty straightforward you just change the IP addresses of the devices and it should work (minus if you run a 48V system so have to buy that additional voltage divider and change some values in the script). You technically can even run the script on your computer, but that means leaving your computer running 24/7.
There is a delay in posting this message (due to moderators reviewing it) that makes it hard to have a quick discussion like other forums.
James and KL,
Thanks so much for keeping this topic going! I will certainly have some challenges with this as computer "stuff" is far from easy for me. But this is really what makes sense for our off-grid set-ups. So is it sort of like this?
The computer (pi maybe) is where the script is stored and runs from. The Shelly sends the voltage readings to the computer and the computer sends directions to the EVSE? And all via WiFi...?
All the voltage tweaking and adjusting is right up my alley......
I am going to be chipping away at this slowly so hopefully we can keep the discussion going....
Thanks!!!
Gary Off-grid in Vermont
James,
So incredibly helpful!! This is exactly what makes sense. Really the same as controllers do for float. I think I will just get a pi as it seems they are fairly cheap and probably don't use a lot of power. And it will live in my shop where all this will get set up. Certainly will have learning curves over that! If I start with my MacBook is it easy to then set up a pi for the long term?
Still working out kinks on the station wifi but have a Shelly and divider ordered......
I sure hope you stick with this forum!!!!
Thanks so much!!!
Gary
james whipple
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"
shelly_username = "XXXXXXXXX"
shelly_password = "XXXXXXXXXX"
# 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:
response = requests.get(shelly_api_url, auth=(shelly_username, shelly_password))
if response.status_code == 200:
data = response.json()
adc_voltage = data.get("adcs", [])[0].get("voltage", None)
if adc_voltage is not None:
return adc_voltage
else:
print("ADC voltage data not found in response")
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():
charge_current = 0 # Start with no 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
payload = {
"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:
response = requests.post(f"{openevse_api_url}/override", json=payload)
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