diff --git a/apps/pv_opt/config/config.yaml b/apps/pv_opt/config/config.yaml index 48b5d42..51f6aa2 100644 --- a/apps/pv_opt/config/config.yaml +++ b/apps/pv_opt/config/config.yaml @@ -23,6 +23,7 @@ pv_opt: # inverter_type: "SOLIS_CORE_MODBUS" # inverter_type: SOLIS_SOLARMAN device_name: solis + consumption_history_days: 2 # ======================================== # Plant parameters @@ -125,7 +126,7 @@ pv_opt: # battery_voltage: sensor.{device_name}_battery_voltage # maximum_dod_percent: sensor.{device_name}_overdischarge_soc # update_cycle_seconds: 60 - + # id_consumption_today: sensor.{device_name}_house_load_today # id_consumption: # - sensor.{device_name}_house_load_power # - sensor.{device_name}_backup_load_power diff --git a/apps/pv_opt/pv_opt.py b/apps/pv_opt/pv_opt.py index 8b6615e..a057db2 100644 --- a/apps/pv_opt/pv_opt.py +++ b/apps/pv_opt/pv_opt.py @@ -19,7 +19,7 @@ # USE_TARIFF = True -VERSION = "3.4.5-alpha" +VERSION = "3.4.5-beta-02" DEBUG = True DATE_TIME_FORMAT_LONG = "%Y-%m-%d %H:%M:%S%z" @@ -231,17 +231,17 @@ def importName(modulename, name): class PVOpt(hass.Hass): def hass2df(self, entity_id, days=2, log=False): if log: - self.log(f">>> Getting {days} history for {entity_id}") + self.log(f">>> Getting {days} days' history for {entity_id}") self.log(f">>> Entity exits: {self.entity_exists(entity_id)}") hist = self.get_history(entity_id=entity_id, days=days) - if log: - self.log(f">>> {hist}") + # if log: + # self.log(f">>> {hist}") df = pd.DataFrame(hist[0]).set_index("last_updated")["state"] df.index = pd.to_datetime(df.index, format="ISO8601") - if log: - self.log(f">>> {df}") + # if log: + # self.log(f">>> {df}") df = df.sort_index() df = df[df != "unavailable"] @@ -1762,30 +1762,47 @@ def load_consumption(self): self.log("Getting expected consumption data") consumption = pd.Series(index=self.static.index, data=0) - for entity_id in self.config["id_consumption"]: - try: - df = self.hass2df( - entity_id, - days=int(self.get_config("consumption_history_days")), - log=self.debug, - ) - except Exception as e: - self.log( - f"Unable to get historical consumption from {entity_id}. {e}", - level="ERROR", - ) - return False + if self.entity_exists(self.config["id_consumption_today"]): + entity_ids = self.config["id_consumption_today"] + consumption_daily = True + else: + entity_ids = self.config["id_consumption"] + consumption_daily = False - df.index = pd.to_datetime(df.index) - df = ( - pd.to_numeric(df, errors="coerce") - .dropna() - .resample("30T") - .mean() - .fillna(0) + if not isinstance(entity_ids, list): + entity_ids = [entity_ids] + + for entity_id in entity_ids: + df = self.hass2df( + entity_id, + days=int(self.get_config("consumption_history_days")), + log=self.debug, ) + # except Exception as e: + # self.log( + # f"Unable to get historical consumption from {entity_id}. {e}", + # level="ERROR", + # ) + # return False + + df.index = pd.to_datetime(df.index) + + if consumption_daily: # + df = pd.to_numeric(df, errors="coerce") + df = ( + df.diff(-1).fillna(0).clip(upper=0).cumsum().resample("30T") + ).ffill().fillna(0).diff(-1) * 2000 + else: + df = ( + pd.to_numeric(df, errors="coerce") + .dropna() + .resample("30T") + .mean() + .fillna(0) + ) + df = df * (1 + self.get_config("consumption_margin") / 100) dfx = pd.Series(index=df.index, data=df.to_list()) # Group by time and take the mean diff --git a/apps/pv_opt/pvpy.py b/apps/pv_opt/pvpy.py index cefa156..fa7bc64 100644 --- a/apps/pv_opt/pvpy.py +++ b/apps/pv_opt/pvpy.py @@ -511,6 +511,8 @@ def flows(self, initial_soc, static_flows, slots=[], soc_now=None, **kwargs): df["chg"] = chg[:-1] df["chg"] = df["chg"].ffill() + df["chg_end"] = chg[1:] + df["chg_end"] = df["chg_end"].bfill() df["battery"] = (pd.Series(chg).diff(-1) / freq)[:-1].to_list() df.loc[df["battery"] > 0, "battery"] = ( df["battery"] * self.inverter.inverter_efficiency @@ -521,7 +523,7 @@ def flows(self, initial_soc, static_flows, slots=[], soc_now=None, **kwargs): df["grid"] = -(solar - consumption + df["battery"]).round(0) df["forced"] = forced_charge df["soc"] = (df["chg"] / self.battery.capacity) * 100 - df["soc_end"] = df["soc"].shift(-1) + df["soc_end"] = (df["chg_end"] / self.battery.capacity) * 100 return df diff --git a/apps/pv_opt/solis.py b/apps/pv_opt/solis.py index a397a4f..3043f52 100644 --- a/apps/pv_opt/solis.py +++ b/apps/pv_opt/solis.py @@ -32,6 +32,7 @@ "default_config": { "maximum_dod_percent": "number.{device_name}_battery_minimum_soc", "id_battery_soc": "sensor.{device_name}_battery_soc", + "id_consumption_today": "sensor.{device_name}_house_load_today", "id_consumption": [ "sensor.{device_name}_house_load", "sensor.{device_name}_bypass_load",