fboundy / pv_opt

Home Assistant PV Optimisation for Solis Inverters
MIT License
20 stars 4 forks source link

Flux charging periods seem to be ignored in favour of peak rate charging #52

Closed ThomasPrior closed 6 months ago

ThomasPrior commented 7 months ago

Describe the bug

Octopus flux customer, cheap rates between 02:00 and 05:00 daily.

PV_OPT seems to be wanting to charge 3500W between 00:00 and 00:30 at a higher rate, rather than wait for the cheap period at 02:00

Expected behavior I would have thought the optimum approach on Flux to be to consume from the grid when the battery is discharged until the cheaper period starts at 02:00.

Screenshots

pv_opt

Additional context Logs: pv_opt.log

pv_opt config:

# Internal configuration --- DO NOT EDIT ---
pvpy:
  module: pvpy
  global: true

inverters:
  module: inverters
  global: true

pv_opt:
  module: pv_opt
  class: PVOpt
  log: pv_opt_log
  prefix: pvopt
  inverter_type: "SOLIS_SOLAX_MODBUS"
  # inverter_type: "SOLIS_CORE_MODBUS"

  # User configuration ---  EDIT AWAY! ---

  # ========================================
  # Plant parameters
  # ========================================

  # All parameters can be a number or point to an entity UNLESS they start with 'id_'. All of
  # these are required but will be defaulted if not specified

  battery_capacity_Wh: 9400
  # inverter_efficiency_percent: 97 # Default: 97
  # charger_efficiency_percent: 91 # Default: 91
  maximum_dod_percent: 12
  charger_power_watts: 3500
  inverter_power_watts: 5000
  # inverter_loss_watts: 100
  battery_voltage: sensor.solis_battery_voltage

  # ========================================
  # Solcast configuration
  # ========================================
  #
  # id_solcast_today: sensor.solcast_pv_forecast_forecast_today
  # id_solcast_tomorrow: sensor.solcast_pv_forecast_forecast_tomorrow

  # ========================================
  # Solar and consumption forecast parameters
  # ========================================
  #
  # Valid options are:
  #
  # Solcast         - the Solcast mid-case forecast [Default]
  # Solcast_p90     - the Solcast high estimate
  # Solcast_p10     - the Solcast high estimate
  #
  # Set this using an "input_select" helper and it can be varied on the fly

  # solar_forecast:
  # - input_select.solar_forecast_source
  #   - Solcast

  # # consumption estimation
  # consumption_history_days:
  #   - 7
  # consumption_margin:
  #   - input_number.solar_opt_consumption_margin
  #  
  # ========================================
  # Octopus account parameters
  # ========================================

  octopus_auto: True # Read tariffs from the Octopus Energy integration. If successful this over-rides the following parameters

  octopus_account: !secret octopus_account
  octopus_api_key: !secret octopus_api_key

  # The following Can be omitted if either of the above options is working correctly:

  octopus_import_tariff_code: E-1R-FLUX-IMPORT-23-02-14-A
  octopus_export_tariff_code: E-1R-FLUX-EXPORT-23-02-14-A

  # octopus_import_tariff_code: E-1R-FLUX-IMPORT-23-02-14-G
  # octopus_export_tariff_code: E-1R-FLUX-EXPORT-23-02-14-G

  # ===============================================================================================================
  # Brand / Integration Specific Config: SOLIS_SOLAX_MODBUS: https://github.com/wills106/homeassistant-solax-modbus
  # ===============================================================================================================
  #
  # These are the default entities used with the Solis Solax Modbus integration. You can change them here and over-ride the defaults

  battery_voltage: sensor.solis_battery_voltage

  id_consumption:
    - sensor.solis_house_load
    - sensor.solis_bypass_load

  id_battery_soc: sensor.solis_battery_soc
  id_timed_charge_start_hours: number.solis_timed_charge_start_hours
  id_timed_charge_start_minutes: number.solis_timed_charge_start_minutes
  id_timed_charge_end_hours: number.solis_timed_charge_end_hours
  id_timed_charge_end_minutes: number.solis_timed_charge_end_minutes
  id_timed_charge_current: number.solis_timed_charge_current

  id_timed_discharge_start_hours: number.solis_timed_discharge_start_hours
  id_timed_discharge_start_minutes: number.solis_timed_discharge_start_minutes
  id_timed_discharge_end_hours: number.solis_timed_discharge_end_hours
  id_timed_discharge_end_minutes: number.solis_timed_discharge_end_minutes
  id_timed_discharge_current: number.solis_timed_discharge_current

  id_timed_charge_discharge_button: button.solis_update_charge_discharge_times
  id_inverter_mode: select.solis_energy_storage_control_switch

  # ==============================================================================================================
  # Brand / Integration Specific Config: SOLIS_CORE_MODBUS: https://github.com/fboundy/ha_solis_modbus
  # ==============================================================================================================
  #
  # These are the default entities used with the Solis Core Modbus integration. You can change them here and over-ride the defaults

  # modbus_hub: solis
  # modbus_slave: 1
  # battery_voltage: sensor.solis_battery_voltage
  # maximum_dod_percent: sensor.solis_overdischarge_soc
  #
  # id_consumption:
  #   - sensor.solis_house_load_power
  #   - ensor.solis_backup_load_power

  # id_grid_power: sensor.solis_grid_active_power
  # id_inverter_ac_power": sensor.solis_inverter_ac_power
  # id_battery_soc: sensor.solis_battery_soc

  # id_timed_charge_start_hours: sensor.solis_timed_charge_start_hour
  # id_timed_charge_start_minutes: sensor.solis_timed_charge_start_minute
  # id_timed_charge_end_hours: sensor.solis_timed_charge_end_hour
  # id_timed_charge_end_minutes: sensor.solis_timed_charge_end_minute
  # id_timed_charge_current: sensor.solis_timed_charge_current_limit

  # id_timed_discharge_start_hours: sensor.solis_timed_discharge_start_hour
  # id_timed_discharge_start_minutes: sensor.solis_timed_discharge_start_minute
  # id_timed_discharge_end_hours: sensor.solis_timed_discharge_end_hour
  # id_timed_discharge_end_minutes: sensor.solis_timed_discharge_end_minute
  # id_timed_discharge_current: sensor.solis_timed_discharge_current_limit

  # id_timed_charge_discharge_button: button.solis_update_charge_discharge_times
  # id_inverter_mode: select.solis_energy_storage_control_switch
fboundy commented 7 months ago

I found a bug relating to how flux prices were being loaded which is fixed in v 3.2.2

Your price chart should look like this with the Flux tariffs continuing into tomorrow: image

Just releasing 3.2.2 now so let me know if it makes more sense.

ThomasPrior commented 7 months ago

Thanks, I'll upgrade and see how things go

ThomasPrior commented 7 months ago

Upgaded, I now see the 02:00 to 05:00 period reflected in prediction, thank you!:

image

After disabling read-only mode and updating the inverter, I see charge time slot 1 is filled with a period of 16:22 to 16:22. Is this expected?

Screenshot_20231214-162530_SolisCloud

fboundy commented 7 months ago

Yes as charging is currently disabled to allow for discharging during the Saving Session. It should switch back on again 10 minuted before the 02:00 session starts. I try to minimise writing to the inverter until its really needed as the EEPROMs have a limited number of write cycles (apparently)

fboundy commented 7 months ago

Also good to see that it is maximising the discharge for the Saving session at the cost of less discharge outside of that hour

fboundy commented 7 months ago

Though for tomorrow it is discharging in two slots at 5000w when it might make more sense to do a continuous 3 hours slot at a lower rate. I haven't played around with the discharge logic very much since I went onto Agile from Flux but I can simulate Flux to see if what it is doing makes sense.

ThomasPrior commented 7 months ago

The curse of the broken up charging continues! :)

Looks like you're addressing this in #61 but I wanted to report it anyway as extra evidence usually helps.

image pv_opt.log

fboundy commented 7 months ago

Yes - that's helpful as Flux has different optimisation that Agile. I think 100% SOC should be maintained OK with the current setup but using Backup SOC at 100% until 15:00 would be more elegant. Looks like you are using the Solax integration which should be quite easy to implement it with.

ThomasPrior commented 7 months ago

Installed 3.3.0 to evaluate, things seem to go a little sideways again with the charging periods.

I didn't grab the logs before downgrading to 3.2.2 so can't give you anything solid to work from. I'll swap back to 3.3.0 and try to replicate tomorrow.

Screenshot_20231216-022748_Home_Assistant.jpg

fboundy commented 7 months ago

Yes - 3.3.0 may have a few bugs in it still. On 16 Dec 2023 at 02:36 +0000, Thomas Prior @.***>, wrote:

Installed 3.3.0 to evaluate, things seem to go a little sideways again with the charging periods. I didn't grab the logs before downgrading to 3.2.2 so can't give you anything solid to work from. I'll swap back to 3.3.0 and try to replicate tomorrow. Screenshot_20231216-022748_Home_Assistant.jpg — Reply to this email directly, view it on GitHub, or unsubscribe. You are receiving this because you commented.Message ID: @.***>

fboundy commented 7 months ago

Can you try 3.3.1 and see how you get on?

ThomasPrior commented 7 months ago

Upgraded to 3.3.1, the charging behaviour has changed for the worse. The only calculated charge period starts at 02:00 as expected with Flux, but ends 30 minutes early at 04:30 with the battery targetting 83% SOC instead of 100%.

Screenshot and logs attached. Expecting a slow week at work this week so will have some more time to test.

image pv_opt.txt

fboundy commented 7 months ago

Thanks - can you try playing with the two threshold settings? Dropping them to zero may get you a marginally lower net cost.

It may also change after midnight when it has the next day to look at as well. I’ll add another plot to the dashboard for the next release which shows the forecasts from 12, 8, 4 and 1 hour ahead and is a good QC (shamelessly nicked from PredBat…) On 17 Dec 2023 at 22:27 +0000, Thomas Prior @.***>, wrote:

Upgraded to 3.3.1, the charging behaviour has changed for the worse. The only calculated charge period starts at 02:00 as expected with Flux, but ends 30 minutes early at 04:30 with the battery targetting 83% SOC instead of 100%. Screenshot and logs attached. Expecting a slow week at work this week so will have some more time to test. image.png (view on web) pv_opt.txt — Reply to this email directly, view it on GitHub, or unsubscribe. You are receiving this because you commented.Message ID: @.***>

ThomasPrior commented 6 months ago

I've tried a clean install of 3.3.1 to try to address some issues I've been experiencing there. Unfortunately the functionality has regressed quite some way.

If there are any further items you'd like me to test I remain at your disposal.

image

ThomasPrior commented 6 months ago

Some more entries that might be of interest:

from appdaemon error.log:

23:20:55 WARNING pv_opt: ------------------------------------------------------------
23:25:28 WARNING pv_opt: ------------------------------------------------------------
23:25:28 WARNING pv_opt: Unexpected error in worker for App pv_opt:
23:25:28 WARNING pv_opt: Worker Ags: {'id': '04ee31e5af714d2ca8f8c419b483c67c', 'name': 'pv_opt', 'objectid': 'de7db8edc21847b6b005873c09ac3a3c', 'type': 'scheduler', 'function': <bound method PVOpt.optimise_time of <pv_opt.PVOpt object at 0x7fd4738e0370>>, 'pin_app': True, 'pin_thread': 1, 'kwargs': {'interval': 300.0, '__thread_id': 'thread-1'}}
23:25:28 WARNING pv_opt: ------------------------------------------------------------
23:25:28 WARNING pv_opt: Traceback (most recent call last):
  File "/usr/local/lib/python3.10/site-packages/appdaemon/threading.py", line 1022, in worker
    funcref(self.AD.sched.sanitize_timer_kwargs(app, args["kwargs"]))
  File "/usr/local/lib/python3.10/site-packages/appdaemon/adbase.py", line 35, in f_app_lock
    return f(*args, **kw)
  File "/conf/apps/pv_opt/pv_opt.py", line 1120, in optimise_time
    self.optimise()
  File "/usr/local/lib/python3.10/site-packages/appdaemon/adbase.py", line 35, in f_app_lock
    return f(*args, **kw)
  File "/conf/apps/pv_opt/pv_opt.py", line 1366, in optimise
    self.inverter.control_discharge(enable=False)
  File "/conf/apps/pv_opt/inverters.py", line 211, in control_discharge
    self.enable_timed_mode()
  File "/conf/apps/pv_opt/inverters.py", line 204, in enable_timed_mode
    self._solis_set_mode_switch(SelfUse=True, Timed=True, GridCharge=True)
  File "/conf/apps/pv_opt/inverters.py", line 389, in _solis_set_mode_switch
    status = self._solis_solax_mode_switch()
AttributeError: 'InverterController' object has no attribute '_solis_solax_mode_switch'

23:25:28 WARNING pv_opt: ------------------------------------------------------------
23:25:57 WARNING pv_opt: ------------------------------------------------------------
23:25:57 WARNING pv_opt: Unexpected error in worker for App pv_opt:
23:25:57 WARNING pv_opt: Worker Ags: {'id': '172b593b33d34adda694b28b15d1fef9', 'name': 'pv_opt', 'objectid': 'de7db8edc21847b6b005873c09ac3a3c', 'type': 'scheduler', 'function': <bound method PVOpt.optimise_time of <pv_opt.PVOpt object at 0x7fd4738e0370>>, 'pin_app': True, 'pin_thread': 1, 'kwargs': {'interval': 300.0, '__thread_id': 'thread-1'}}
23:25:57 WARNING pv_opt: ------------------------------------------------------------
23:25:57 WARNING pv_opt: Traceback (most recent call last):
  File "/usr/local/lib/python3.10/site-packages/appdaemon/threading.py", line 1022, in worker
    funcref(self.AD.sched.sanitize_timer_kwargs(app, args["kwargs"]))
  File "/usr/local/lib/python3.10/site-packages/appdaemon/adbase.py", line 35, in f_app_lock
    return f(*args, **kw)
  File "/conf/apps/pv_opt/pv_opt.py", line 1120, in optimise_time
    self.optimise()
  File "/usr/local/lib/python3.10/site-packages/appdaemon/adbase.py", line 35, in f_app_lock
    return f(*args, **kw)
  File "/conf/apps/pv_opt/pv_opt.py", line 1366, in optimise
    self.inverter.control_discharge(enable=False)
  File "/conf/apps/pv_opt/inverters.py", line 211, in control_discharge
    self.enable_timed_mode()
  File "/conf/apps/pv_opt/inverters.py", line 204, in enable_timed_mode
    self._solis_set_mode_switch(SelfUse=True, Timed=True, GridCharge=True)
  File "/conf/apps/pv_opt/inverters.py", line 389, in _solis_set_mode_switch
    status = self._solis_solax_mode_switch()
AttributeError: 'InverterController' object has no attribute '_solis_solax_mode_switch'

From main.log:

15:09:30 INFO AppDaemon: /conf/apps/pv_opt/config/config.yaml added or modified
15:09:30 WARNING AppDaemon: App 'pvpy' missing 'class' or 'module' entry - ignoring
15:09:30 WARNING AppDaemon: App 'inverters' missing 'class' or 'module' entry - ignoring
15:09:30 INFO AppDaemon: App 'pv_opt' added
15:09:30 INFO AppDaemon: Found 1 active apps
15:09:30 INFO AppDaemon: Found 0 inactive apps
15:09:30 INFO AppDaemon: Found 2 global libraries
15:09:30 INFO AppDaemon: Adding thread 0
15:09:30 INFO AppDaemon: Adding /conf/apps/pv_opt to module import path
15:09:30 INFO AppDaemon: Adding /conf/apps/pv_opt/config to module import path
15:09:30 WARNING AppDaemon: No app description found for: /conf/apps/pv_opt/solis.py - ignoring
15:09:30 INFO AppDaemon: Loading Global Module: /conf/apps/pv_opt/pvpy.py
15:09:30 INFO AppDaemon: Loading App Module: /conf/apps/pv_opt/pv_opt.py
15:09:30 WARNING AppDaemon: Unable to find app solis in dependencies for pv_opt
15:09:30 WARNING AppDaemon: Ignoring app pv_opt
15:09:30 INFO AppDaemon: Loading app pv_opt using class PVOpt from module pv_opt
15:09:30 INFO AppDaemon: Calling initialize() for pv_opt
15:09:31 INFO AppDaemon: pv_opt: Entity sensor.pvopt_status created in namespace: default
15:09:57 INFO AppDaemon: pv_opt: Entity sensor.pvopt_optimiser_elapsed created in namespace: default
15:09:57 INFO AppDaemon: pv_opt: Entity sensor.pvopt_base_cost created in namespace: default
15:09:58 INFO AppDaemon: pv_opt: Entity sensor.pvopt_opt_cost created in namespace: default
15:09:58 INFO AppDaemon: pv_opt: Entity sensor.pvopt_charge_start created in namespace: default
15:09:58 INFO AppDaemon: pv_opt: Entity sensor.pvopt_charge_end created in namespace: default
15:09:58 INFO AppDaemon: pv_opt: Entity sensor.pvopt_charge_current created in namespace: default
15:09:58 INFO AppDaemon: pv_opt: Entity sensor.pvopt_soc_h1 created in namespace: default
15:09:58 INFO AppDaemon: pv_opt: Entity sensor.pvopt_soc_h4 created in namespace: default
15:09:58 INFO AppDaemon: pv_opt: Entity sensor.pvopt_soc_h8 created in namespace: default
15:09:58 INFO AppDaemon: pv_opt: Entity sensor.pvopt_soc_h12 created in namespace: default
15:09:58 WARNING AppDaemon: Excessive time spent in utility loop: 28278.0ms, 28278.0ms in check_app_updates(), 0.0ms in other
15:09:59 INFO AppDaemon: Reading config
15:09:59 WARNING AppDaemon: ------------------------------------------------------------
15:09:59 WARNING AppDaemon: Unexpected error loading config file: /conf/apps/apps.yaml
15:09:59 WARNING AppDaemon: ------------------------------------------------------------
15:09:59 WARNING AppDaemon: Traceback (most recent call last):
  File "/usr/local/lib/python3.10/site-packages/appdaemon/app_management.py", line 578, in read_config_file
    return utils.read_config_file(file)
  File "/usr/local/lib/python3.10/site-packages/appdaemon/utils.py", line 586, in read_config_file
    return read_yaml_config(path)
  File "/usr/local/lib/python3.10/site-packages/appdaemon/utils.py", line 724, in read_yaml_config
    if "secrets" in config:
TypeError: argument of type 'NoneType' is not iterable

15:09:59 WARNING AppDaemon: ------------------------------------------------------------
15:09:59 WARNING AppDaemon: File '/conf/apps/apps.yaml' invalid structure - ignoring
15:09:59 INFO AppDaemon: /conf/apps/apps.yaml added or modified
15:09:59 INFO AppDaemon: App 'pvpy' changed
15:09:59 INFO AppDaemon: App 'inverters' changed
15:09:59 INFO AppDaemon: Found 1 active apps
15:09:59 INFO AppDaemon: Found 0 inactive apps
15:09:59 INFO AppDaemon: Found 2 global libraries
15:09:59 WARNING AppDaemon: Unable to find app solis in dependencies for pv_opt
15:09:59 WARNING AppDaemon: Ignoring app pv_opt
15:09:59 INFO AppDaemon: Terminating pv_opt
15:09:59 INFO AppDaemon: Reloading Module: /conf/apps/pv_opt/pvpy.py
15:09:59 INFO AppDaemon: Reloading Module: /conf/apps/pv_opt/pv_opt.py
15:09:59 WARNING AppDaemon: Unable to find app solis in dependencies for pv_opt
15:09:59 WARNING AppDaemon: Ignoring app pv_opt
15:09:59 INFO AppDaemon: Loading app pv_opt using class PVOpt from module pv_opt
15:09:59 INFO AppDaemon: Calling initialize() for pv_opt
15:10:06 INFO AppDaemon: Client disconnection from Admin Client
15:10:06 INFO AppDaemon: New client Admin Client connected
15:10:22 WARNING AppDaemon: Excessive time spent in utility loop: 23030.0ms, 23030.0ms in check_app_updates(), 0.0ms in other
15:29:25 INFO AppDaemon: Client disconnection from Admin Client
15:29:25 INFO AppDaemon: New client Admin Client connected
15:29:50 INFO AppDaemon: Client disconnection from Admin Client
15:29:50 INFO AppDaemon: New client Admin Client connected
15:32:48 INFO AppDaemon: Reading config
15:32:48 INFO AppDaemon: /conf/apps/apps.yaml deleted
15:32:48 INFO AppDaemon: Found 1 active apps
15:32:48 INFO AppDaemon: Found 0 inactive apps
15:32:48 INFO AppDaemon: Found 2 global libraries
15:33:04 INFO AppDaemon: SIGTERM Received
15:33:04 INFO AppDaemon: AppDaemon is shutting down
15:33:05 INFO MQTT: Stopping MQTT Plugin and Unsubscribing from URL docker_host:1883
15:33:05 INFO HASS: Disconnecting from Home Assistant
15:33:05 INFO AppDaemon: Removing module /conf/apps/pv_opt/solis.py
15:33:05 INFO AppDaemon: Removing module /conf/apps/pv_opt/pvpy.py
15:33:05 INFO AppDaemon: Removing module /conf/apps/pv_opt/pv_opt.py
15:33:05 WARNING AppDaemon: Unable to find app solis in dependencies for pv_opt
15:33:05 WARNING AppDaemon: Ignoring app pv_opt
15:33:05 INFO AppDaemon: Terminating pv_opt
15:33:05 INFO AppDaemon: Shutting down webserver
15:33:07 INFO AppDaemon: Saving all namespaces
15:33:07 INFO AppDaemon: AppDaemon is stopped.
15:33:12 INFO AppDaemon: AppDaemon Version 4.4.2 starting
15:33:12 INFO AppDaemon: Python version is 3.10.11
15:33:12 INFO AppDaemon: Configuration read from: /conf/appdaemon.yaml
15:33:12 INFO AppDaemon: Added log: AppDaemon
15:33:12 INFO AppDaemon: Added log: Error
15:33:12 INFO AppDaemon: Added log: Access
15:33:12 INFO AppDaemon: Added log: Diag
15:33:12 INFO AppDaemon: Added log: PV_Opt
15:33:12 INFO AppDaemon: Loading Plugin HASS using class HassPlugin from module hassplugin
15:33:12 INFO HASS: HASS Plugin Initializing
15:33:12 INFO HASS: HASS Plugin initialization complete
15:33:12 INFO AppDaemon: Loading Plugin MQTT using class MqttPlugin from module mqttplugin
15:33:12 INFO MQTT: MQTT Plugin Initializing
15:33:12 INFO MQTT: Using 'docker-appdaemon/status' as Will Topic
15:33:12 INFO MQTT: Using 'docker-appdaemon/status' as Birth Topic
15:33:12 INFO AppDaemon: Initializing HTTP
15:33:12 INFO AppDaemon: Using 'ws' for event stream
15:33:12 INFO AppDaemon: Starting API
15:33:12 INFO AppDaemon: Starting Admin Interface
15:33:12 INFO AppDaemon: Starting Dashboards
15:33:12 INFO HASS: Connected to Home Assistant 2023.12.3
15:33:12 INFO MQTT: Connected to Broker at URL docker_host:1883
15:33:12 INFO AppDaemon: Got initial state from namespace mqtt
15:33:12 INFO MQTT: MQTT Plugin initialization complete
15:33:12 INFO AppDaemon: App 'hello_world' added
15:33:12 INFO AppDaemon: App 'pv_opt' added
15:33:12 INFO AppDaemon: Found 2 active apps
15:33:12 INFO AppDaemon: Found 0 inactive apps
15:33:12 INFO AppDaemon: Found 2 global libraries
15:33:12 INFO AppDaemon: Starting Apps with 2 workers and 2 pins
15:33:12 INFO AppDaemon: Running on port 5050
15:33:12 INFO HASS: Evaluating startup conditions
15:33:12 INFO HASS: Startup condition met: hass state=RUNNING
15:33:12 INFO HASS: All startup conditions met
15:33:13 INFO AppDaemon: Got initial state from namespace default
15:33:13 INFO AppDaemon: New client Admin Client connected
15:33:14 INFO AppDaemon: Scheduler running in realtime
15:33:14 INFO AppDaemon: Adding /conf/apps to module import path
15:33:14 INFO AppDaemon: Adding /conf/apps/pv_opt to module import path
15:33:14 INFO AppDaemon: Adding /conf/apps/pv_opt/config to module import path
15:33:14 WARNING AppDaemon: No app description found for: /conf/apps/pv_opt/solis.py - ignoring
15:33:14 INFO AppDaemon: Loading Global Module: /conf/apps/pv_opt/pvpy.py
15:33:15 INFO AppDaemon: Loading App Module: /conf/apps/pv_opt/pv_opt.py
15:33:15 WARNING AppDaemon: Unable to find app solis in dependencies for pv_opt
15:33:15 WARNING AppDaemon: Ignoring app pv_opt
15:33:15 INFO AppDaemon: Loading app pv_opt using class PVOpt from module pv_opt
15:33:15 INFO AppDaemon: Calling initialize() for pv_opt
15:33:24 INFO AppDaemon: Client disconnection from Admin Client
15:33:24 INFO AppDaemon: New client Admin Client connected
15:33:27 INFO AppDaemon: Client disconnection from Admin Client
15:33:28 INFO AppDaemon: New client Admin Client connected
15:33:29 INFO AppDaemon: Client disconnection from Admin Client
15:33:29 INFO AppDaemon: New client Admin Client connected
15:33:39 INFO AppDaemon: App initialization complete
fboundy commented 6 months ago

This is a bug I spotted late last night and will be fixed in 3.3.2


From: Thomas Prior @.> Sent: 18 December 2023 15:37 To: fboundy/pv_opt @.> Cc: fboundy @.>; Comment @.> Subject: Re: [fboundy/pv_opt] Flux charging periods seem to be ignored in favour of peak rate charging (Issue #52)

Some more entries that might be of interest:

from appdaemon error.log:

23:20:55 WARNING pv_opt: ------------------------------------------------------------ 23:25:28 WARNING pv_opt: ------------------------------------------------------------ 23:25:28 WARNING pv_opt: Unexpected error in worker for App pv_opt: 23:25:28 WARNING pv_opt: Worker Ags: {'id': '04ee31e5af714d2ca8f8c419b483c67c', 'name': 'pv_opt', 'objectid': 'de7db8edc21847b6b005873c09ac3a3c', 'type': 'scheduler', 'function': <bound method PVOpt.optimise_time of <pv_opt.PVOpt object at 0x7fd4738e0370>>, 'pin_app': True, 'pin_thread': 1, 'kwargs': {'interval': 300.0, '__thread_id': 'thread-1'}} 23:25:28 WARNING pv_opt: ------------------------------------------------------------ 23:25:28 WARNING pv_opt: Traceback (most recent call last): File "/usr/local/lib/python3.10/site-packages/appdaemon/threading.py", line 1022, in worker funcref(self.AD.sched.sanitize_timer_kwargs(app, args["kwargs"])) File "/usr/local/lib/python3.10/site-packages/appdaemon/adbase.py", line 35, in f_app_lock return f(*args, *kw) File "/conf/apps/pv_opt/pv_opt.py", line 1120, in optimise_time self.optimise() File "/usr/local/lib/python3.10/site-packages/appdaemon/adbase.py", line 35, in f_app_lock return f(args, **kw) File "/conf/apps/pv_opt/pv_opt.py", line 1366, in optimise self.inverter.control_discharge(enable=False) File "/conf/apps/pv_opt/inverters.py", line 211, in control_discharge self.enable_timed_mode() File "/conf/apps/pv_opt/inverters.py", line 204, in enable_timed_mode self._solis_set_mode_switch(SelfUse=True, Timed=True, GridCharge=True) File "/conf/apps/pv_opt/inverters.py", line 389, in _solis_set_mode_switch status = self._solis_solax_mode_switch() AttributeError: 'InverterController' object has no attribute '_solis_solax_mode_switch'

23:25:28 WARNING pv_opt: ------------------------------------------------------------ 23:25:57 WARNING pv_opt: ------------------------------------------------------------ 23:25:57 WARNING pv_opt: Unexpected error in worker for App pv_opt: 23:25:57 WARNING pv_opt: Worker Ags: {'id': '172b593b33d34adda694b28b15d1fef9', 'name': 'pv_opt', 'objectid': 'de7db8edc21847b6b005873c09ac3a3c', 'type': 'scheduler', 'function': <bound method PVOpt.optimise_time of <pv_opt.PVOpt object at 0x7fd4738e0370>>, 'pin_app': True, 'pin_thread': 1, 'kwargs': {'interval': 300.0, '__thread_id': 'thread-1'}} 23:25:57 WARNING pv_opt: ------------------------------------------------------------ 23:25:57 WARNING pv_opt: Traceback (most recent call last): File "/usr/local/lib/python3.10/site-packages/appdaemon/threading.py", line 1022, in worker funcref(self.AD.sched.sanitize_timer_kwargs(app, args["kwargs"])) File "/usr/local/lib/python3.10/site-packages/appdaemon/adbase.py", line 35, in f_app_lock return f(*args, *kw) File "/conf/apps/pv_opt/pv_opt.py", line 1120, in optimise_time self.optimise() File "/usr/local/lib/python3.10/site-packages/appdaemon/adbase.py", line 35, in f_app_lock return f(args, **kw) File "/conf/apps/pv_opt/pv_opt.py", line 1366, in optimise self.inverter.control_discharge(enable=False) File "/conf/apps/pv_opt/inverters.py", line 211, in control_discharge self.enable_timed_mode() File "/conf/apps/pv_opt/inverters.py", line 204, in enable_timed_mode self._solis_set_mode_switch(SelfUse=True, Timed=True, GridCharge=True) File "/conf/apps/pv_opt/inverters.py", line 389, in _solis_set_mode_switch status = self._solis_solax_mode_switch() AttributeError: 'InverterController' object has no attribute '_solis_solax_mode_switch'

From main.log:

15:09:30 INFO AppDaemon: /conf/apps/pv_opt/config/config.yaml added or modified 15:09:30 WARNING AppDaemon: App 'pvpy' missing 'class' or 'module' entry - ignoring 15:09:30 WARNING AppDaemon: App 'inverters' missing 'class' or 'module' entry - ignoring 15:09:30 INFO AppDaemon: App 'pv_opt' added 15:09:30 INFO AppDaemon: Found 1 active apps 15:09:30 INFO AppDaemon: Found 0 inactive apps 15:09:30 INFO AppDaemon: Found 2 global libraries 15:09:30 INFO AppDaemon: Adding thread 0 15:09:30 INFO AppDaemon: Adding /conf/apps/pv_opt to module import path 15:09:30 INFO AppDaemon: Adding /conf/apps/pv_opt/config to module import path 15:09:30 WARNING AppDaemon: No app description found for: /conf/apps/pv_opt/solis.py - ignoring 15:09:30 INFO AppDaemon: Loading Global Module: /conf/apps/pv_opt/pvpy.py 15:09:30 INFO AppDaemon: Loading App Module: /conf/apps/pv_opt/pv_opt.py 15:09:30 WARNING AppDaemon: Unable to find app solis in dependencies for pv_opt 15:09:30 WARNING AppDaemon: Ignoring app pv_opt 15:09:30 INFO AppDaemon: Loading app pv_opt using class PVOpt from module pv_opt 15:09:30 INFO AppDaemon: Calling initialize() for pv_opt 15:09:31 INFO AppDaemon: pv_opt: Entity sensor.pvopt_status created in namespace: default 15:09:57 INFO AppDaemon: pv_opt: Entity sensor.pvopt_optimiser_elapsed created in namespace: default 15:09:57 INFO AppDaemon: pv_opt: Entity sensor.pvopt_base_cost created in namespace: default 15:09:58 INFO AppDaemon: pv_opt: Entity sensor.pvopt_opt_cost created in namespace: default 15:09:58 INFO AppDaemon: pv_opt: Entity sensor.pvopt_charge_start created in namespace: default 15:09:58 INFO AppDaemon: pv_opt: Entity sensor.pvopt_charge_end created in namespace: default 15:09:58 INFO AppDaemon: pv_opt: Entity sensor.pvopt_charge_current created in namespace: default 15:09:58 INFO AppDaemon: pv_opt: Entity sensor.pvopt_soc_h1 created in namespace: default 15:09:58 INFO AppDaemon: pv_opt: Entity sensor.pvopt_soc_h4 created in namespace: default 15:09:58 INFO AppDaemon: pv_opt: Entity sensor.pvopt_soc_h8 created in namespace: default 15:09:58 INFO AppDaemon: pv_opt: Entity sensor.pvopt_soc_h12 created in namespace: default 15:09:58 WARNING AppDaemon: Excessive time spent in utility loop: 28278.0ms, 28278.0ms in check_app_updates(), 0.0ms in other 15:09:59 INFO AppDaemon: Reading config 15:09:59 WARNING AppDaemon: ------------------------------------------------------------ 15:09:59 WARNING AppDaemon: Unexpected error loading config file: /conf/apps/apps.yaml 15:09:59 WARNING AppDaemon: ------------------------------------------------------------ 15:09:59 WARNING AppDaemon: Traceback (most recent call last): File "/usr/local/lib/python3.10/site-packages/appdaemon/app_management.py", line 578, in read_config_file return utils.read_config_file(file) File "/usr/local/lib/python3.10/site-packages/appdaemon/utils.py", line 586, in read_config_file return read_yaml_config(path) File "/usr/local/lib/python3.10/site-packages/appdaemon/utils.py", line 724, in read_yaml_config if "secrets" in config: TypeError: argument of type 'NoneType' is not iterable

15:09:59 WARNING AppDaemon: ------------------------------------------------------------ 15:09:59 WARNING AppDaemon: File '/conf/apps/apps.yaml' invalid structure - ignoring 15:09:59 INFO AppDaemon: /conf/apps/apps.yaml added or modified 15:09:59 INFO AppDaemon: App 'pvpy' changed 15:09:59 INFO AppDaemon: App 'inverters' changed 15:09:59 INFO AppDaemon: Found 1 active apps 15:09:59 INFO AppDaemon: Found 0 inactive apps 15:09:59 INFO AppDaemon: Found 2 global libraries 15:09:59 WARNING AppDaemon: Unable to find app solis in dependencies for pv_opt 15:09:59 WARNING AppDaemon: Ignoring app pv_opt 15:09:59 INFO AppDaemon: Terminating pv_opt 15:09:59 INFO AppDaemon: Reloading Module: /conf/apps/pv_opt/pvpy.py 15:09:59 INFO AppDaemon: Reloading Module: /conf/apps/pv_opt/pv_opt.py 15:09:59 WARNING AppDaemon: Unable to find app solis in dependencies for pv_opt 15:09:59 WARNING AppDaemon: Ignoring app pv_opt 15:09:59 INFO AppDaemon: Loading app pv_opt using class PVOpt from module pv_opt 15:09:59 INFO AppDaemon: Calling initialize() for pv_opt 15:10:06 INFO AppDaemon: Client disconnection from Admin Client 15:10:06 INFO AppDaemon: New client Admin Client connected 15:10:22 WARNING AppDaemon: Excessive time spent in utility loop: 23030.0ms, 23030.0ms in check_app_updates(), 0.0ms in other 15:29:25 INFO AppDaemon: Client disconnection from Admin Client 15:29:25 INFO AppDaemon: New client Admin Client connected 15:29:50 INFO AppDaemon: Client disconnection from Admin Client 15:29:50 INFO AppDaemon: New client Admin Client connected 15:32:48 INFO AppDaemon: Reading config 15:32:48 INFO AppDaemon: /conf/apps/apps.yaml deleted 15:32:48 INFO AppDaemon: Found 1 active apps 15:32:48 INFO AppDaemon: Found 0 inactive apps 15:32:48 INFO AppDaemon: Found 2 global libraries 15:33:04 INFO AppDaemon: SIGTERM Received 15:33:04 INFO AppDaemon: AppDaemon is shutting down 15:33:05 INFO MQTT: Stopping MQTT Plugin and Unsubscribing from URL docker_host:1883 15:33:05 INFO HASS: Disconnecting from Home Assistant 15:33:05 INFO AppDaemon: Removing module /conf/apps/pv_opt/solis.py 15:33:05 INFO AppDaemon: Removing module /conf/apps/pv_opt/pvpy.py 15:33:05 INFO AppDaemon: Removing module /conf/apps/pv_opt/pv_opt.py 15:33:05 WARNING AppDaemon: Unable to find app solis in dependencies for pv_opt 15:33:05 WARNING AppDaemon: Ignoring app pv_opt 15:33:05 INFO AppDaemon: Terminating pv_opt 15:33:05 INFO AppDaemon: Shutting down webserver 15:33:07 INFO AppDaemon: Saving all namespaces 15:33:07 INFO AppDaemon: AppDaemon is stopped. 15:33:12 INFO AppDaemon: AppDaemon Version 4.4.2 starting 15:33:12 INFO AppDaemon: Python version is 3.10.11 15:33:12 INFO AppDaemon: Configuration read from: /conf/appdaemon.yaml 15:33:12 INFO AppDaemon: Added log: AppDaemon 15:33:12 INFO AppDaemon: Added log: Error 15:33:12 INFO AppDaemon: Added log: Access 15:33:12 INFO AppDaemon: Added log: Diag 15:33:12 INFO AppDaemon: Added log: PV_Opt 15:33:12 INFO AppDaemon: Loading Plugin HASS using class HassPlugin from module hassplugin 15:33:12 INFO HASS: HASS Plugin Initializing 15:33:12 INFO HASS: HASS Plugin initialization complete 15:33:12 INFO AppDaemon: Loading Plugin MQTT using class MqttPlugin from module mqttplugin 15:33:12 INFO MQTT: MQTT Plugin Initializing 15:33:12 INFO MQTT: Using 'docker-appdaemon/status' as Will Topic 15:33:12 INFO MQTT: Using 'docker-appdaemon/status' as Birth Topic 15:33:12 INFO AppDaemon: Initializing HTTP 15:33:12 INFO AppDaemon: Using 'ws' for event stream 15:33:12 INFO AppDaemon: Starting API 15:33:12 INFO AppDaemon: Starting Admin Interface 15:33:12 INFO AppDaemon: Starting Dashboards 15:33:12 INFO HASS: Connected to Home Assistant 2023.12.3 15:33:12 INFO MQTT: Connected to Broker at URL docker_host:1883 15:33:12 INFO AppDaemon: Got initial state from namespace mqtt 15:33:12 INFO MQTT: MQTT Plugin initialization complete 15:33:12 INFO AppDaemon: App 'hello_world' added 15:33:12 INFO AppDaemon: App 'pv_opt' added 15:33:12 INFO AppDaemon: Found 2 active apps 15:33:12 INFO AppDaemon: Found 0 inactive apps 15:33:12 INFO AppDaemon: Found 2 global libraries 15:33:12 INFO AppDaemon: Starting Apps with 2 workers and 2 pins 15:33:12 INFO AppDaemon: Running on port 5050 15:33:12 INFO HASS: Evaluating startup conditions 15:33:12 INFO HASS: Startup condition met: hass state=RUNNING 15:33:12 INFO HASS: All startup conditions met 15:33:13 INFO AppDaemon: Got initial state from namespace default 15:33:13 INFO AppDaemon: New client Admin Client connected 15:33:14 INFO AppDaemon: Scheduler running in realtime 15:33:14 INFO AppDaemon: Adding /conf/apps to module import path 15:33:14 INFO AppDaemon: Adding /conf/apps/pv_opt to module import path 15:33:14 INFO AppDaemon: Adding /conf/apps/pv_opt/config to module import path 15:33:14 WARNING AppDaemon: No app description found for: /conf/apps/pv_opt/solis.py - ignoring 15:33:14 INFO AppDaemon: Loading Global Module: /conf/apps/pv_opt/pvpy.py 15:33:15 INFO AppDaemon: Loading App Module: /conf/apps/pv_opt/pv_opt.py 15:33:15 WARNING AppDaemon: Unable to find app solis in dependencies for pv_opt 15:33:15 WARNING AppDaemon: Ignoring app pv_opt 15:33:15 INFO AppDaemon: Loading app pv_opt using class PVOpt from module pv_opt 15:33:15 INFO AppDaemon: Calling initialize() for pv_opt 15:33:24 INFO AppDaemon: Client disconnection from Admin Client 15:33:24 INFO AppDaemon: New client Admin Client connected 15:33:27 INFO AppDaemon: Client disconnection from Admin Client 15:33:28 INFO AppDaemon: New client Admin Client connected 15:33:29 INFO AppDaemon: Client disconnection from Admin Client 15:33:29 INFO AppDaemon: New client Admin Client connected 15:33:39 INFO AppDaemon: App initialization complete

— Reply to this email directly, view it on GitHubhttps://github.com/fboundy/pv_opt/issues/52#issuecomment-1860837304, or unsubscribehttps://github.com/notifications/unsubscribe-auth/ABHJ7PNXII3EIB6Z2UTWH5DYKBPLXAVCNFSM6AAAAABAVBG7K6VHI2DSMVQWIX3LMV43OSLTON2WKQ3PNVWWK3TUHMYTQNRQHAZTOMZQGQ. You are receiving this because you commented.

fboundy commented 6 months ago

The first two bullets are related to way the MQTT entities are initialised. I thought this had been fixed in 3.3.1 but I have noticed that sometimes AppDaemon created duplicate entities. Can you please check whether you have any such as number_pvopt_xxx_2 and also whether they are shown as MQTT or just Number entities.

[cid:8a41b290-c795-4ec1-bf67-4f75b877ef43]


From: Thomas Prior @.> Sent: 18 December 2023 15:27 To: fboundy/pv_opt @.> Cc: fboundy @.>; Comment @.> Subject: Re: [fboundy/pv_opt] Flux charging periods seem to be ignored in favour of peak rate charging (Issue #52)

I've tried a clean install of 3.3.1 to try to address some issues I've been experiencing there. Unfortunately the functionality has regressed quite some way.

If there are any

image.png (view on web)https://github.com/fboundy/pv_opt/assets/34111848/6791e80a-590c-4d43-a329-5d76a5d7029b

— Reply to this email directly, view it on GitHubhttps://github.com/fboundy/pv_opt/issues/52#issuecomment-1860811858, or unsubscribehttps://github.com/notifications/unsubscribe-auth/ABHJ7PN2WRBQE7FJ5LPKXRLYKBOGTAVCNFSM6AAAAABAVBG7K6VHI2DSMVQWIX3LMV43OSLTON2WKQ3PNVWWK3TUHMYTQNRQHAYTCOBVHA. You are receiving this because you commented.

fboundy commented 6 months ago

Let me know if 3.3.2 fixes this. On my machine Flux looks as I would expect:

image

ThomasPrior commented 6 months ago

Thanks for the pointers regarding MQTT - manually cleared the entries, removed the appdaemon directory and started again.

Unfortunately I'm not able to get this version to load. Log files are attached.

error.log main.log pv_opt.log

ThomasPrior commented 6 months ago

The up side is that 3.2.2 still works, albeit not perfectly. I greatly appreciate the fast turnaround on each update.

fboundy commented 6 months ago

Ok - so I think I can see what’s happening. It’s got into a bit of a loop because all the config entities are changing state and each one triggers a restart.

Just needs a bit of logic to pause the state change handler until all the config items have been reset to default. On 18 Dec 2023 at 22:38 +0000, Thomas Prior @.***>, wrote:

The up side is that 3.2.2 still works, albeit not perfectly. I appreciate the fast turnaround on each update and I want to say that I appreciate the effort. — Reply to this email directly, view it on GitHub, or unsubscribe. You are receiving this because you commented.Message ID: @.***>