|
|
|
@@ -8,7 +8,6 @@ from time import time, sleep
|
|
|
|
|
import json
|
|
|
|
|
from threading import Thread
|
|
|
|
|
import requests
|
|
|
|
|
import urllib3 # only for exception handling
|
|
|
|
|
import math
|
|
|
|
|
|
|
|
|
|
|
|
|
|
@@ -45,9 +44,12 @@ power_target_min = float(os.getenv('POWER_TARGET_MIN', 0))
|
|
|
|
|
power_target_max = float(os.getenv('POWER_TARGET_MAX', 100))
|
|
|
|
|
power_damping_factor = float(os.getenv('POWER_DAMPING_FACTOR', 0.3))
|
|
|
|
|
power_limit_change_treshold = float(os.getenv('POWER_LIMIT_CHANGE_TRESHOLD', 0.5))
|
|
|
|
|
power_limit_type = int(os.getenv('POWER_LIMIT_TYPE', 1))
|
|
|
|
|
dry_run = bool(int(os.getenv('DRY_RUN', 1)))
|
|
|
|
|
|
|
|
|
|
# set other important variables
|
|
|
|
|
power_limit_type = 1 # only set the limit temporary to avoid memory damage; see also: https://github.com/tbnobody/OpenDTU/discussions/742
|
|
|
|
|
version = "v1.1" # the version number
|
|
|
|
|
|
|
|
|
|
# some checks for the correctness of supplied data
|
|
|
|
|
if power_target_min < 0: power_target_min = 0
|
|
|
|
|
if power_target_max > 100: power_target_max = 100
|
|
|
|
@@ -55,6 +57,9 @@ if power_damping_factor < 0: power_damping_factor = 0.0
|
|
|
|
|
if power_damping_factor > 1: power_damping_factor = 1.0
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
print(f"{bcolors.OKCYAN}Welcome to {bcolors.ENDC}{bcolors.OKBLUE}{bcolors.BOLD}SolarControl{bcolors.ENDC}{bcolors.OKCYAN} ({version})!{bcolors.ENDC}")
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
# create the powers dict (containing the current use) and data variables (for thread sharing)
|
|
|
|
|
powers_raw = {"solar": 0, "solar_ts": 0, "house": 0, "house_ts": 0}
|
|
|
|
|
powers = {"total": None, "total_house": None, "total_solar": None, "timestamp": 0}
|
|
|
|
@@ -106,8 +111,8 @@ def threaded_solar_power_limit_setting():
|
|
|
|
|
# Get current openDTU current limit status
|
|
|
|
|
try:
|
|
|
|
|
status = requests.get(opendtu_address.strip("/") + "/api/limit/status", auth=(opendtu_user, opendtu_pwd)).json().copy()
|
|
|
|
|
except (requests.exceptions.RequestException, urllib3.exceptions.HTTPError) as e:
|
|
|
|
|
print(f"{bcolors.ERROR}Some error occured while trying to reach out to OpenDTU to get latest data about the inverter limit status. Skipping for now.{bcolors.ENDC}\n==== START OF EXCEPTION ====\n{e}\n==== END OF EXCEPTION ====")
|
|
|
|
|
except BaseException as e:
|
|
|
|
|
print(f"{bcolors.FAIL}Some error occured while trying to reach out to OpenDTU to get latest data about the inverter limit status. Skipping for now.{bcolors.ENDC}\n==== START OF EXCEPTION ====\n{e}\n==== END OF EXCEPTION ====")
|
|
|
|
|
sleep(0.2) # wait some time (to avaid cpu overload on continuous unavailability of the service)
|
|
|
|
|
continue # skip this loop pass
|
|
|
|
|
|
|
|
|
@@ -156,7 +161,7 @@ def threaded_solar_power_limit_setting():
|
|
|
|
|
else:
|
|
|
|
|
print(f"{bcolors.WARNING}Now the new limit would be set via the API (but DRY_RUN is either not specified or True): {str(new_limit)}%")
|
|
|
|
|
elif status[opendtu_inverter_sn]["max_power"] == 0:
|
|
|
|
|
print(f"{bcolors.ERROR}OpenDTU is reporting strange values for the inverter's maximum power output. Skipping it for now.{bcolors.ENDC}")
|
|
|
|
|
print(f"{bcolors.FAIL}OpenDTU is reporting strange values for the inverter's maximum power output. Skipping it for now.{bcolors.ENDC}")
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
while (time() - last_time) < limit_update_interval:
|
|
|
|
|