Skip to content
Merged
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
52 changes: 46 additions & 6 deletions apps/predbat/predbat.py
Original file line number Diff line number Diff line change
Expand Up @@ -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"
Expand Down Expand Up @@ -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],
Expand Down Expand Up @@ -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
Expand Down Expand Up @@ -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:
Expand Down Expand Up @@ -3397,36 +3406,61 @@ 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

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

Expand Down Expand Up @@ -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
Expand Down