diff --git a/apps/predbat/predbat.py b/apps/predbat/predbat.py index e1f72ca84..22581d3d5 100644 --- a/apps/predbat/predbat.py +++ b/apps/predbat/predbat.py @@ -18,7 +18,7 @@ import os import yaml -THIS_VERSION = "v7.15.5" +THIS_VERSION = "v7.15.6" TIME_FORMAT = "%Y-%m-%dT%H:%M:%S%z" TIME_FORMAT_SECONDS = "%Y-%m-%dT%H:%M:%S.%f%z" TIME_FORMAT_OCTOPUS = "%Y-%m-%d %H:%M:%S%z" @@ -1011,7 +1011,7 @@ def find_charge_curve(self): clean_increment=False, smoothing=False, divide_by=1.0, - scale=1.0, + scale=self.base.battery_scaling, ) charge_rate = self.base.minute_data( charge_rate_data[0], @@ -1386,6 +1386,12 @@ def update_status(self, minutes_now, quiet=False): def mimic_target_soc(self, current_charge_limit): """ Function to turn on/off charging based on the current SOC and the set charge limit + + Parameters: + current_charge_limit (float): The target SOC (State of Charge) limit for charging. + + Returns: + None """ if self.soc_percent >= float(current_charge_limit): # If current SOC is above Target SOC, turn Grid Charging off @@ -2221,6 +2227,9 @@ def press_and_poll_button(self, entity_id): def rest_readData(self, api="readData"): """ Get inverter status + + :param api: The API endpoint to retrieve data from (default is "readData") + :return: The JSON response containing the inverter status, or None if there was an error """ url = self.rest_api + "/" + api try: @@ -3397,24 +3406,35 @@ def dp1(self, value): """ Round to 1 decimal place """ - return round(value * 10) / 10 + return round(value, 1) def dp2(self, value): """ Round to 2 decimal places """ - return round(value * 100) / 100 + return round(value, 2) def dp3(self, value): """ Round to 3 decimal places """ - return round(value * 1000) / 1000 + return round(value, 3) def hit_charge_window(self, charge_window, start, end): + """ + Determines if the given start and end time falls within any of the charge windows. + + Parameters: + charge_window (list): A list of dictionaries representing charge windows, each containing "start" and "end" keys. + start (int): The start time of the interval to check. + end (int): The end time of the interval to check. + + Returns: + int: The index of the charge window that the interval falls within, or -1 if it doesn't fall within any charge window. + """ window_n = 0 for window in charge_window: - if end > window["start"] and start <= window["end"]: + if end > window["start"] and start < window["end"]: return window_n window_n += 1 return -1 @@ -3422,11 +3442,25 @@ def hit_charge_window(self, charge_window, start, end): def in_charge_window(self, charge_window, minute_abs): """ Work out if this minute is within the a charge window + + Parameters: + charge_window (list): A sorted list of dictionaries representing charge windows. + Each dictionary should have "start" and "end" keys + representing the start and end minutes of the window. + + minute_abs (int): The absolute minute value to check. + + Returns: + int: The index of the charge window if the minute is within a window, + otherwise -1. """ window_n = 0 for window in charge_window: if minute_abs >= window["start"] and minute_abs < window["end"]: return window_n + elif window["start"] > minute_abs: + # As windows are sorted, we can stop searching once we've passed the minute + break window_n += 1 return -1 @@ -8365,6 +8399,12 @@ def optimise_charge_windows_manual(self): def optimise_charge_windows_reset(self, reset_all): """ Reset the charge windows to min + + Parameters: + - reset_all (bool): If True, reset all charge windows. If False, reset only the charge windows that are in the record window. + + Returns: + None """ if self.charge_window_best and self.calculate_best_charge: # Set all to max