This commit is contained in:
Thomas Luther 2024-03-27 11:53:59 +01:00
parent abd35546eb
commit 2c44a5e931
2 changed files with 86 additions and 56 deletions

View File

@ -325,7 +325,7 @@ class SolixDefaults:
PRESET_MIN: int = 0
PRESET_MAX: int = 800
PRESET_DEF: int = 100
ALLOW_DISCHARGE: bool = True
ALLOW_EXPORT: bool = True
CHARGE_PRIORITY_MIN: int = 0
CHARGE_PRIORITY_MAX: int = 100
CHARGE_PRIORITY_DEF: int = 80
@ -364,7 +364,7 @@ class SolarbankTimeslot:
start_time: datetime
end_time: datetime
appliance_load: int | None = None # mapped to appliance_loads setting using a default 50% share for dual solarbank setups
allow_discharge: bool | None = None # mapped to the turn_on boolean
allow_export: bool | None = None # mapped to the turn_on boolean
charge_priority_limit: int | None = None # mapped to charge_priority setting
@ -718,7 +718,7 @@ class AnkerSolixApi:
device.update({"schedule": dict(value)})
# default active presets to None
device.pop("preset_system_output_power", None)
device.pop("preset_allow_discharge", None)
device.pop("preset_allow_export", None)
device.pop("preset_charge_priority", None)
# get actual presets from current slot
now = datetime.now().time().replace(microsecond=0)
@ -746,9 +746,7 @@ class AnkerSolixApi:
"preset_system_output_power": (
slot.get("appliance_loads") or [{}]
)[0].get("power"),
"preset_allow_discharge": slot.get(
"turn_on"
),
"preset_allow_export": slot.get("turn_on"),
"preset_charge_priority": slot.get(
"charge_priority"
),
@ -1934,7 +1932,7 @@ class AnkerSolixApi:
deviceSn: str,
all_day: bool = False,
preset: int = None,
discharge: bool = None,
export: bool = None,
charge_prio: int = None,
set_slot: SolarbankTimeslot = None,
insert_slot: SolarbankTimeslot = None,
@ -1959,7 +1957,7 @@ class AnkerSolixApi:
preset = None
if (
preset is None
and discharge is None
and export is None
and charge_prio is None
and set_slot is None
and insert_slot is None
@ -2068,9 +2066,9 @@ class AnkerSolixApi:
)
insert.update(
{
"turn_on": SolixDefaults.ALLOW_DISCHARGE
if discharge is None
else discharge
"turn_on": SolixDefaults.ALLOW_EXPORT
if export is None
else export
}
)
insert.update(
@ -2100,6 +2098,7 @@ class AnkerSolixApi:
or idx == len(ranges)
):
# copy slot, update and insert the new slot
# re-use old slot parms if insert slot has not defined optional parms
insert = copy.deepcopy(slot)
insert.update(
{
@ -2115,43 +2114,56 @@ class AnkerSolixApi:
).replace("23:59", "24:00")
}
)
(insert.get("appliance_loads") or [{}])[0].update(
{
"power": min(
max(
int(
SolixDefaults.PRESET_DEF
if insert_slot.appliance_load is None
else insert_slot.appliance_load
if insert_slot.appliance_load is not None or (
insert_slot.start_time.time() < start_time
and insert_slot.end_time.time() != end_time
):
(insert.get("appliance_loads") or [{}])[0].update(
{
"power": min(
max(
int(
SolixDefaults.PRESET_DEF
if insert_slot.appliance_load is None
else insert_slot.appliance_load
),
min_load,
),
min_load,
max_load,
),
max_load,
),
}
)
insert.update(
{
"turn_on": SolixDefaults.ALLOW_DISCHARGE
if insert_slot.allow_discharge is None
else insert_slot.allow_discharge
}
)
insert.update(
{
"charge_priority": min(
max(
int(
SolixDefaults.CHARGE_PRIORITY_DEF
if insert_slot.charge_priority_limit is None
else insert_slot.charge_priority_limit
}
)
if insert_slot.allow_export is not None or (
insert_slot.start_time.time() < start_time
and insert_slot.end_time.time() != end_time
):
insert.update(
{
"turn_on": SolixDefaults.ALLOW_EXPORT
if insert_slot.allow_export is None
else insert_slot.allow_export
}
)
if insert_slot.charge_priority_limit is not None or (
insert_slot.start_time.time() < start_time
and insert_slot.end_time.time() != end_time
):
insert.update(
{
"charge_priority": min(
max(
int(
SolixDefaults.CHARGE_PRIORITY_DEF
if insert_slot.charge_priority_limit
is None
else insert_slot.charge_priority_limit
),
SolixDefaults.CHARGE_PRIORITY_MIN,
),
SolixDefaults.CHARGE_PRIORITY_MIN,
),
SolixDefaults.CHARGE_PRIORITY_MAX,
)
}
)
SolixDefaults.CHARGE_PRIORITY_MAX,
)
}
)
# insert slot before current slot if not last
if insert_slot.start_time.time() <= start_time:
new_ranges.append(insert)
@ -2221,6 +2233,24 @@ class AnkerSolixApi:
)
}
)
# re-use old slot parms for insert if end time of insert slot is same as original slot
if insert_slot.end_time.time() == end_time:
if insert_slot.appliance_load is None:
insert_slot.appliance_load = int(
(slot.get("appliance_loads") or [{}])[0].get(
"power"
)
or SolixDefaults.PRESET_DEF
)
if insert_slot.allow_export is None:
insert_slot.allow_export = bool(
slot.get("turn_on") or SolixDefaults.ALLOW_EXPORT
)
if insert_slot.charge_priority_limit is None:
insert_slot.charge_priority_limit = int(
slot.get("charge_priority")
or SolixDefaults.CHARGE_PRIORITY_DEF
)
elif next_start and next_start < end_time:
# delay start of slot following an insert
@ -2244,8 +2274,8 @@ class AnkerSolixApi:
)
}
)
if discharge is not None:
slot.update({"turn_on": discharge})
if export is not None:
slot.update({"turn_on": export})
if charge_prio is not None:
slot.update(
{
@ -2300,9 +2330,9 @@ class AnkerSolixApi:
appliance_load=SolixDefaults.PRESET_DEF
if preset is None
else preset,
allow_discharge=SolixDefaults.ALLOW_DISCHARGE
if discharge is None
else discharge,
allow_export=SolixDefaults.ALLOW_EXPORT
if export is None
else export,
charge_priority_limit=SolixDefaults.CHARGE_PRIORITY_DEF
if charge_prio is None
else charge_prio,
@ -2313,9 +2343,9 @@ class AnkerSolixApi:
"end_time": datetime.strftime(set_slot.end_time, "%H:%M").replace(
"23:59", "24:00"
),
"turn_on": SolixDefaults.ALLOW_DISCHARGE
if set_slot.allow_discharge is None
else set_slot.allow_discharge,
"turn_on": SolixDefaults.ALLOW_EXPORT
if set_slot.allow_export is None
else set_slot.allow_export,
"appliance_loads": [
{
"power": min(
@ -2521,7 +2551,7 @@ class AnkerSolixApi:
elif (startDay + timedelta(days=numDays)) > today:
numDays = (today - startDay).days + 1
numDays = min(366, max(1, numDays))
# first get solarbank discharge
# first get solarbank export
resp = await self.energy_analysis(
siteId=siteId,
deviceSn=deviceSn,

View File

@ -118,7 +118,7 @@ async def main() -> ( # noqa: C901 # pylint: disable=too-many-locals,too-many-b
t1 = 2
t2 = 5
t3 = 5
t4 = 9
t4 = 6
t5 = 6
t6 = 10
t7 = 6
@ -210,7 +210,7 @@ async def main() -> ( # noqa: C901 # pylint: disable=too-many-locals,too-many-b
f"{'Schedule (Now)':<{col1}}: {now.strftime('%H:%M:%S UTC %z'):<{col2}} {'System Preset':<{col3}}: {str(site_preset).replace('W',''):>4} W"
)
CONSOLE.info(
f"{'ID':<{t1}} {'Start':<{t2}} {'End':<{t3}} {'Discharge':<{t4}} {'Output':<{t5}} {'ChargePrio':<{t6}} {'SB1':>{t7}} {'SB2':>{t8}} Name"
f"{'ID':<{t1}} {'Start':<{t2}} {'End':<{t3}} {'Export':<{t4}} {'Output':<{t5}} {'ChargePrio':<{t6}} {'SB1':>{t7}} {'SB2':>{t8}} Name"
)
# for slot in (data.get("home_load_data",{})).get("ranges",[]):
for slot in data.get("ranges", []):