Skip to content

Commit

Permalink
added run_unendless configuration option
Browse files Browse the repository at this point in the history
  • Loading branch information
ZuinigeRijder committed Dec 17, 2024
1 parent b8d7986 commit eb2e576
Show file tree
Hide file tree
Showing 3 changed files with 26 additions and 16 deletions.
16 changes: 10 additions & 6 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@

# SolisCloud to PVOutput, Domoticz and/or MQTT Broker (e.g. HomeAssistant, ioBroker)
Simple Python3 script to copy latest (normally once per 5 minutes) SolisCloud portal inverter update to PVOutput portal, Domoticz, and/or MQTT Broker (e.g. HomeAssistant, ioBroker).
Python 3.6 or higher is required.

The soliscloud_to_pvoutput.py script will get the station id via the configured soliscloud_station_index (default the first station) with the secrets of SolisCloud (see next section). Thereafter it will get the inverter id and serial number via the configured soliscloud_inverter_index (default the first inverter). Then in an endless loop the inverter details are fetched and the following information is used:
* timestamp
Expand All @@ -28,12 +29,12 @@ The soliscloud_to_pvoutput.py script will get the station id via the configured
This information is used to compute the new information to be send to PVOutput and/or Domoticz, when the timestamp is changed.

Notes
* only between 5 and 23 hour data is fetched from SolisCloud and copied to PVOutput and/or Domoticz
* the script will exit outside 5 and 23
* Each new day the "watthour today" starts with 0
* Because the resolution of the SolisCloud watthour is in 100 Watt, a higher resolution is computed with current Watt
* the script will exit outside 5 and 23, unless you have configured "run_unendless = True" in soliscloud_to_pvoutput.cfg
* each new day the "watthour today" starts with 0
* because the resolution of the SolisCloud watthour is in 100 Watt, a higher resolution is computed with current Watt
* if you have more than 1 station [you need to configure each inverter in different directories](#configuration-with-multiple-inverters-in-one-soliscloud-station)
* If you have more than 4 strings or a 3 phase inverter, you need to adapt the script (sorry, not supported yet)
* if you have more than 4 strings or a 3 phase inverter, you need to adapt the script (sorry, not supported yet)
* there is a dependency to package paho_mqtt, you need to install this e.g. by command "python3 -m pip install paho_mqtt==1.6.1"

## SolisCloud
[SolisCloud](https://www.soliscloud.com/) is the next generation Portal for Solis branded PV systems from Ginlong.
Expand Down Expand Up @@ -83,6 +84,7 @@ soliscloud_station_index = 0
soliscloud_inverter_index = 0
pvoutput_api_key = 0f2dd8190d00369ec893b059034dde1123456789
pvoutput_system_id = 12345
run_unendless = False
[PVOutput]
send_to_pvoutput = True
Expand Down Expand Up @@ -155,8 +157,10 @@ soliscloud_to_pvoutput.py scripts runs on my Raspberry pi with Raspbian GNU/Linu
Steps:
* create a directory solis in your home directory
* copy solis.sh, soliscloud_to_pvoutput.py, soliscloud_to_pvoutput.cfg and logging_config.ini in this solis directory
* make sure there are no Windows CRLF in the copied files, e.g. make sure by running dos2unix on the copied files
* if "python --version" refers to 2.x, then you need to change solis.sh to use python3 instead of python
* change inside soliscloud_to_pvoutput.cfg the API secrets
* chmod +x solis.sh
* chmod +r+x solis.sh
* add the following line in your crontab -e:

```
Expand Down
1 change: 1 addition & 0 deletions soliscloud_to_pvoutput.cfg
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ soliscloud_station_index = 0
soliscloud_inverter_index = 0
pvoutput_api_key = 0f2dd8190d00369ec893b059034dde1123456789
pvoutput_system_id = 12345
run_unendless = False

[PVOutput]
send_to_pvoutput = True
Expand Down
25 changes: 15 additions & 10 deletions soliscloud_to_pvoutput.py
Original file line number Diff line number Diff line change
Expand Up @@ -66,6 +66,7 @@ def get_bool(dictionary: dict, key: str, default: bool = True) -> bool:
SOLISCLOUD_INVERTER_INDEX = int(get(api_secrets, "soliscloud_inverter_index", "0"))
PVOUTPUT_API_KEY = get(api_secrets, "pvoutput_api_key")
PVOUTPUT_SYSTEM_ID = get(api_secrets, "pvoutput_system_id")
RUN_UNENDLESS = get_bool(api_secrets, "run_unendless", False)

SOLISCLOUD_INVERTER_SN = "SN" # to be filled later by program

Expand Down Expand Up @@ -142,9 +143,6 @@ def get_bool(dictionary: dict, key: str, default: bool = True) -> bool:
PVOUTPUT_ADD_URL = "http://pvoutput.org/service/r2/addbatchstatus.jsp"


TODAY = datetime.now().strftime("%Y%m%d") # format yyyymmdd


# == post ====================================================================
def execute_request(url: str, data: str, headers: dict) -> str:
"""execute request and handle errors"""
Expand Down Expand Up @@ -378,13 +376,20 @@ def do_work():
time.sleep(60)
timestamp_previous = "0"
energy_generation = 0
today_yyymmdd = datetime.now().strftime("%Y%m%d") # format yyyymmdd
while True:
time.sleep(60) # wait 1 minute before checking again
datetime_now = datetime.now()
# only check between 5 and 23 hours
if datetime_now.hour < 5 or datetime_now.hour > 22:
logging.info("Outside solar generation hours (5..23)")
sys.exit("Exiting program to start fresh tomorrow")
if RUN_UNENDLESS:
if datetime_now.hour == 0 and datetime_now.minute < 4: # reset needed
timestamp_previous = "0"
energy_generation = 0
today_yyymmdd = datetime_now.strftime("%Y%m%d") # format yyyymmdd
else:
# only check between 5 and 23 hours
if datetime_now.hour < 5 or datetime_now.hour > 22:
logging.info("Outside solar generation hours (5..23)")
sys.exit("Exiting program to start fresh tomorrow")

content = get_solis_cloud_data(INVERTER_DETAIL, inverter_detail_body)
inverter_detail = json.loads(content)["data"]
Expand Down Expand Up @@ -444,7 +449,7 @@ def do_work():

current_time = datetime_current.strftime("%H:%M")
if logging.DEBUG >= logging.root.level:
debug_string = f"date={TODAY}, time={current_time}, energy_generation={energy_generation}, solar_power={solar_power}, battery_power={battery_power}, battery_soc={battery_soc}, grid_power={grid_power}, family_load={family_load}, home_consumption={home_consumption}, inverter_temperature={inverter_temperature}, dc_voltage={dc_voltage}, ac_voltage={ac_voltage}" # noqa
debug_string = f"date={today_yyymmdd}, time={current_time}, energy_generation={energy_generation}, solar_power={solar_power}, battery_power={battery_power}, battery_soc={battery_soc}, grid_power={grid_power}, family_load={family_load}, home_consumption={home_consumption}, inverter_temperature={inverter_temperature}, dc_voltage={dc_voltage}, ac_voltage={ac_voltage}" # noqa
logging.debug(debug_string)

if SEND_TO_PVOUTPUT:
Expand Down Expand Up @@ -475,7 +480,7 @@ def do_work():
# Temperature No decimal celsius 23.4
# Voltage No decimal volts 240.7

pvoutput_string = f"data={TODAY},{current_time},{energy_generation},{solar_power},{energy_consumption},{power_consumption},{temperature},{voltage}" # noqa
pvoutput_string = f"data={today_yyymmdd},{current_time},{energy_generation},{solar_power},{energy_consumption},{power_consumption},{temperature},{voltage}" # noqa
send_pvoutput_data(pvoutput_string)

if SEND_TO_DOMOTICZ:
Expand All @@ -495,7 +500,7 @@ def do_work():
send_to_domoticz(DOMOTICZ_HOMECONSUMPTION_ID, str(home_consumption))

if SEND_TO_MQTT:
send_to_mqtt(MQTT_LAST_UPDATE_ID, f"{TODAY} {current_time}")
send_to_mqtt(MQTT_LAST_UPDATE_ID, f"{today_yyymmdd} {current_time}")
send_to_mqtt(
MQTT_POWER_GENERATED_ID,
str(solar_power) + ";" + str(energy_generation),
Expand Down

0 comments on commit eb2e576

Please sign in to comment.