From 4332d27c4c54af384cc96e14be9bf21b2ae99a1d Mon Sep 17 00:00:00 2001 From: fboundy Date: Tue, 30 Jan 2024 14:48:47 +0000 Subject: [PATCH] 3.6.0 - Add over-write from YAML --- README.md | 6 ++-- apps/pv_opt/config/config.yaml | 7 ++++- apps/pv_opt/pv_opt.py | 56 +++++++++++++++++++++++++++------- 3 files changed, 55 insertions(+), 14 deletions(-) diff --git a/README.md b/README.md index 2035683..b161e01 100644 --- a/README.md +++ b/README.md @@ -1,4 +1,4 @@ -# PV Opt: Home Assistant Solar/Battery Optimiser v3.5.3 +# PV Opt: Home Assistant Solar/Battery Optimiser v3.6.0 Solar / Battery Charging Optimisation for Home Assistant. This appDaemon application attempts to optimise charging and discharging of a home solar/battery system to minimise cost electricity cost on a daily basis using freely available solar forecast data from SolCast. This is particularly beneficial for Octopus Agile but is also benefeficial for other time-of-use tariffs such as Octopus Flux or simple Economy 7. @@ -275,7 +275,9 @@ If you are running a different integration or inverter brand you will need to ed inverter_type: SOLIS_CORE_MODBUS device_name: solis -The `config.yaml` file also includes all the other configuration used by PV Opt. If you are using the default setup you shouldn't need to change this but you can edit anything by un-commenting the relevant line in the file. The configuration is grouped by inverter/integration and should be self-explanatory +The `config.yaml` file also includes all the other configuration used by PV Opt. If you are using the default setup you shouldn't need to change this but you can edit anything by un-commenting the relevant line in the file. The configuration is grouped by inverter/integration and should be self-explanatory. Once PV Opt is installed the config is stored within entities in Home Assistant. It you want these over-ritten please ensure that `overwrite_ha_on_restart` is set to `true`: + + overwrite_ha_on_restart: true PV_Opt needs to know the size of your battery and the power of your inverter: both when inverting battery to AC power and when chargingh tha battery. It will attempt to work these out from the data it has loaded (WIP) but you should check the following enitities in Home Assistant: diff --git a/apps/pv_opt/config/config.yaml b/apps/pv_opt/config/config.yaml index 789deb1..515c380 100644 --- a/apps/pv_opt/config/config.yaml +++ b/apps/pv_opt/config/config.yaml @@ -17,12 +17,17 @@ pv_opt: log: pv_opt_log prefix: pvopt + # User configuration --- EDIT AWAY! --- inverter_type: "SOLIS_SOLAX_MODBUS" # inverter_type: "SOLIS_CORE_MODBUS" # inverter_type: SOLIS_SOLARMAN device_name: solis + + # If true the current config in HA will be over-written with that in the config.yaml. + overwrite_ha_on_restart: true + consumption_history_days: 2 # ======================================== @@ -95,7 +100,7 @@ pv_opt: # update_cycle_seconds: 15 # maximum_dod_percent: number.{device_name}_battery_minimum_soc - id_consumption_today: sensor.{device_name}_consumption_today + # id_consumption_today: sensor.{device_name}_consumption_today # id_grid_import_today: sensor.{device_name}_grid_import_today # id_grid_export_today: sensor.{device_name}_grid_export_today diff --git a/apps/pv_opt/pv_opt.py b/apps/pv_opt/pv_opt.py index 653c8a2..de0fad5 100644 --- a/apps/pv_opt/pv_opt.py +++ b/apps/pv_opt/pv_opt.py @@ -19,7 +19,7 @@ # USE_TARIFF = True -VERSION = "3.5.3" +VERSION = "3.6.0" DEBUG = False DATE_TIME_FORMAT_LONG = "%Y-%m-%d %H:%M:%S%z" @@ -41,6 +41,15 @@ INVERTER_TYPES = ["SOLIS_SOLAX_MODBUS", "SOLIS_CORE_MODBUS", "SOLIS_SOLARMAN"] +SYSTEM_ARGS = [ + "module", + "class", + "prefix", + "log", + "dependencies", + "overwrite_ha_on_restart", +] + IMPEXP = ["import", "export"] MQTT_CONFIGS = { @@ -785,21 +794,21 @@ def _load_args(self, items=None): if self.debug: self.log(self.args) - self.prefix = self.args["prefix"] + self.prefix = self.args.get("prefix", "solis") self._status("Loading Configuation") + over_write = self.args.get("overwrite_ha_on_restart", False) change_entities = [] self.log("Reading arguments from YAML:") self.log("-----------------------------------") + if over_write: + self.log("") + self.log(" Over-write flag is set so YAML will over-write HA") if items is None: - items = [ - i - for i in self.args - if i not in ["module", "class", "prefix", "log", "dependencies"] - ] + items = [i for i in self.args if i not in SYSTEM_ARGS] for item in items: # Attempt to read entity states for all string paramters unless they start @@ -1035,9 +1044,7 @@ def _load_args(self, items=None): self.log("") - self.log("Exposing config to Home Assistant:") - self.log("----------------------------------") - self._expose_configs() + self._expose_configs(over_write) def _name_from_item(self, item): name = item.replace("_", " ") @@ -1057,7 +1064,7 @@ def _state_from_value(self, value): state = value return state - def _expose_configs(self): + def _expose_configs(self, over_write=True): mqtt_items = [ item for item in DEFAULT_CONFIG @@ -1068,6 +1075,8 @@ def _expose_configs(self): and "domain" in DEFAULT_CONFIG[item] ] + over_write_log = False + for item in mqtt_items: state = None domain = DEFAULT_CONFIG[item]["domain"] @@ -1118,6 +1127,28 @@ def _expose_configs(self): self.set_state(state=state, entity_id=entity_id) + elif item in self.config: + state = self.get_state(entity_id) + new_state = str(self._state_from_value(self.config[item])) + if over_write and state != new_state: + if not over_write_log: + self.log("") + self.log("Over-writing HA from YAML:") + self.log("--------------------------") + self.log("") + self.log( + f" {'Config Item':40s} {'HA Entity':42s} Old State New State" + ) + self.log( + f" {'-----------':40s} {'---------':42s} ---------- ----------" + ) + + self.log( + f" {item:40s} {entity_id:42s} {state:10s} {new_state:10s}" + ) + state = new_state + self.set_state(state=state, entity_id=entity_id) + else: state = self.get_state(entity_id) @@ -1125,6 +1156,9 @@ def _expose_configs(self): self.change_items[entity_id] = item self.config_state[item] = state + self.log("Syncing config with Home Assistant:") + self.log("-----------------------------------") + if self.change_items: self.log("") self.log(f" {'Config Item':40s} {'HA Entity':42s} Current State")