fboundy / pv_opt

Home Assistant PV Optimisation for Solis Inverters
MIT License
22 stars 5 forks source link

EV charging support/integration #121

Open mergwyn opened 7 months ago

mergwyn commented 7 months ago

Is your feature request related to a problem? Please describe. I'm all electric at home with ASHP, Solar, storage and and an EV charger. PV Opt does a good job of managing my solar and storage but I also need to be able schedule EV charging

Describe the solution you'd like I'd really like pvopt to ensure that charging the EV is synchronised such that ir does not discharge the storage battery. At its simplest level the EV is just another battery which needs be charged to a target SOC in the cheapest slots so hopefully there is an overlap in the algorithm. This could either be done fully within PV Opt or via hooks that allow users to build their own automation using the results (eg publishing x cheapest slots)

Describe alternatives you've considered At the moment, I am using zappi 'agile knowledge' to set a schedule that only charges when the tariff is below a certain level, but obviously this may or may not cause the storage battery to discharge. (I also have to change schedule manually depending on the latest tariff)

I've tried using Predbat, but this is soo complicated and I've not been able to understand the charging plans it puts together and am struggling with the amount of 'hold' and 'reserve' charging that does on.

Additional context I understand that this might not be where you want or need to take PV Opt and appreciate all that you have done so far. I wish I could program in python to help out but that it beyond me! If I can help in any other way please let me know.

mergwyn commented 5 months ago

I installed 3.14.6 last night and waited for the IOG EV charge! It looks like the charge took place between 0400 and 0600 which implies that Octopus gave me an extra dispatch slot after 0530.

Screenshot 2024-04-28 at 13 42 56

It looks like the battery was discharging between 0400 and 0430 and then 0530 and 0600:

Screenshot 2024-04-28 at 13 44 03

Here are the logs I downloaded at 0825 this morning: pv_opt.3.log pv_opt.2.log pv_opt.1.log pv_opt.log error.log

stevebuk1 commented 5 months ago

I'm nearing completion of code changes for this but have a query on the following if statement within _create_windows:

            if self.config["supports_hold_soc"]:
                self.log("Checking for Hold SOC slots")
                self.windows.loc[
                    ((self.windows["soc_end"] - self.windows["soc"]).abs() < HOLD_TOLERANCE)
                    & (self.windows["soc"] > self.get_config("maximum_dod_percent")),
                    "hold_soc",
                ] = "<="'

What is the purpose of & (self.windows["soc"] > self.get_config("maximum_dod_percent")),?

Its currently preventing an a "<=" tag being added for an IOG slot when Pv_opt is forecasting the discharge limit to be reached.

As I've set this limit a bit higher than my inverters actual limit to act as a battery charge buffer, I'd definitely want a hold SOC slot otherwise the car charging slot will empty whats left of the house battery.

I can overide this and add hold slots for IOG slots afterwards, but I'd rather not do that unless I understand what its for.

mergwyn commented 4 months ago

I’m happy to test when you have something ready!

stevebuk1 commented 4 months ago

A few days more I think. I've written and tested all the code to interlace/override with house charge slots but need to deal with discharge slots, which I can't test. So will be looking for your help there!

On Sat, 11 May 2024, 08:32 mergwyn, @.***> wrote:

I’m happy to test when you have something ready!

— Reply to this email directly, view it on GitHub https://github.com/fboundy/pv_opt/issues/121#issuecomment-2105615421, or unsubscribe https://github.com/notifications/unsubscribe-auth/ASVRJMFW3HZU6BHVHQAGKUDZBXCP3AVCNFSM6AAAAABDG4TRJOVHI2DSMVQWIX3LMV43OSLTON2WKQ3PNVWWK3TUHMZDCMBVGYYTKNBSGE . You are receiving this because you were mentioned.Message ID: @.***>

stevebuk1 commented 4 months ago

@mergwyn : ready for test. Code is at a fork here: https://github.com/stevebuk1/pv_opt/tree/dev

You'll need to copy in pv_opt.py and pypy.py. I think solis.py didnt change but to be sure, probably best copy in solis.py as well.

I've also made some fixes to the optimization algorithm to ensure that it works as intended for IOG - that of creating a single charge rate to cover the 6 hours at 7.5p. I don't think any of these fixes will imact Agile at all.

Assuming no overnight charging is planned (as I've found to be the case over the last week), IOG car charging slots will now display with "<=IOG" in the Hold SOC column, as follows:

image

If there is house charging planned that fully covers the car charging periods, you will see a series of windows all at identical power that cover each non-contiguous IO charge slot rather than as single window. I'm still working to fix this, as this will cause extra writes to the inverter to change start and end times so is undesirable.

The code should deal with a mix of house charge windows and EV charge slots should it be necessary, but to be honest unless the solar forecast changes overnight I doubt we will see it.

At the moment discharge slots are not suppressed during EV charging. I can't imagine that Pv_opt will schedule a discharge at the same time the EV is charging, but it is a relatively easy mod to make.

I've yet to have any slots allocated outside the 23:30 to 05:30 period so would be interested in the log files for these.

Please give it a run and post logs, and note anything where you think it isn't doing what you expect, especially on how it effects discharges for the next day.

@fboundy : I haven't created a PR for this until I fix the points above, but I'd appreciate a sanity check on your system to make sure nothing is broken on Agile. (I don't think it will be because the code has to cope with no EV plugged in as well as an EV plugged in). It might be worth taking a look at the changes I've made to the factors the "forced" value when a slot is midway through, which I've also written up in closed issue #203 and is fully completed.

stevebuk1 commented 4 months ago

IOG car charging slots will now display with "<=IOG" in the Hold SOC column

I forgot to add that the IOG hold slots that have Start SOC and End SOC do NOT show in the "Battery SOC Forecast v Actual" graph, because the IOG hold slots have been inserted quite near the end of the whole calculation process.

This will make no difference for when IO slots fall into 23:30 to 05:30 where it is expect the house battery will be scheduled to charge for the full 6 hours, which will be what happens the majority of the time in winter.

In summer, when the (house) charge plan will be blank most nights, the additional hold SOC slots during car charging will mean the house battery will end the night with a bit more charge in it than originally predicted, because Pv_opt will still think the inverter is in Self use during car charging when making its energy flow predictions. The optimiser runs during the actual car charging will recalculate based on house battery SOC which should mean the effect does not persist, and may even be compensated for towards the end of the charge window (this is not tested).

mergwyn commented 4 months ago

Great, I’ll install it later and let you know how it goes.

mergwyn commented 4 months ago

Right, installed at approx 1551 and then plugged car in. Got good slots for debugging: 23:00 - 06:30 07:00 - 07:30

and the results:

Screenshot 2024-05-13 at 16 43 02 Screenshot 2024-05-13 at 16 48 20

Looks mostly as you'd expect it (I think). My only questions are:

Here are the logs: pv_opt.1.log pv_opt.log

Nothing recent in the error log.

stevebuk1 commented 4 months ago

@mergwyn, thanks for the logs. Pleased its generally seems to be working.

Regarding your questions:

For the 2nd question, the car side of things that does the holding works from the dispatching sensor which is read every time the optimiser runs. However, the import and export rates that the energy flows calculation uses only load at fixed times - basically midnight, 4am and 4pm. This is fine if all the slots are within 23:30 to 05:30 but not if you have extra slots. Pv_opt had planned to get you to 100% and hold you there until 5.30am, and then supply the house load from 5.30am to 7am. The IOG hold slot from 5:30 to 6:30 would have held you at 100%, but the Pv_opt plan knows nothing about that so it correctly forecasts by 7am you would have discharged to 92% and thus holds you at that. In reality, at 7am it would be higher. Anyway, I need to add some code that forces a contract load once a car plugin event is detected - an easy fix. What you would have then got is a charge plan that spanned 23:00 to 7:30, with no IOG slots needed.

For the first question, I can't immediately explain. Prior to any mods being made for IOG, and even taking into account Pv_opt was working on the basis of cheap rate starting at 23:30 rather than 23:00, I see no planned discharge. This bit is prior to any of the mods I've made other than a fix for BST that was applying a partial slot factor one hour ahead of where it should have been, which can't affect something that far in the future. I'd certainly concur that a 44% battery should be discharged 1/2 hour before the cheap rates starts.

I've spotted a few other things that I think might need looking at. Your first charge slot says its a 5kW charge rate for 6 hours, but the log tells me the plan wanted 5kW for an hour and then 100W to maintain 100%, which I think should have generated two separate windows. My questions to you:

1) Can I just check you have a 5kW battery charger and a 10kWh battery? 2) Before the code changes did you mostly always see a single window for the 6 hour period, or two windows - a burst of 5kW charging for around an hour and then a lower rate (100W) for the rest of the night?

(This area of the code is the bit I mentioned I was still working on so I'm not convinced I've got it right)

mergwyn commented 4 months ago

Hi, that’s roughly correct: my inverter can charge at 5kW and I have 10kW of storage.

I usually had a single charge window covering the cheap rate period.

stevebuk1 commented 4 months ago

Interesting. If a charge only plan is selected, then any charging to meet house load the next day is split evenly between all of the cheap overnight slots. But if a discharging plan is selected, the required extra charging is then crammed it into the earliest slots possible, even if all of the later ones are the same price. I'll leave this as is.

Code updated to reload the IOG tariff on car plugin. Upon car plugin it will await the next optimser run before reloading the tariff to allow the extra slots to ripple through. It may need longer.

Code at https://github.com/stevebuk1/pv_opt/tree/dev/apps/pv_opt as before, both pv_opt.py and pypy.py. If you dare, overnight logs with readonly = false would be appreciated! I've now left mine in this state for around a week with no ill effects.

stevebuk1 commented 4 months ago

I forgot to add that I've set the Power Resolution to a step size of 50W, but have struggled to get that new step size through MQTT and into HA. To resolve I've just changed the name and will wait for HA to recognise its no longer being used and delete it, after which I'll rename it back. Unless you've changed this from its default setting of 100W this will be invisible, but if you have changed it, the entity name is now "number.pvopt_forced_power_group_tolerance1".

mergwyn commented 4 months ago

I installed the latest code at 07:57 yesterday. Here are the logs from this morning: pv_opt.3.log pv_opt.2.log pv_opt.1.log pv_opt.log error.log

stevebuk1 commented 4 months ago

I installed the latest code at 07:57 yesterday. Here are the logs from this morning:

Thanks for these. The problem with Pv_opt not picking up your extra cheap IO slots remains even when reloading the contract hours after the car has been plugged in. This may a be a problem with the "Botttlecap Dave" Octopus Energy integration. I'll re-enable some debug logging that I've seen in the code to try and capture this, as soon as I've stabilized the hold charging code. and sorted out what appears to be a regular read error with the charge current (using the Solax modbus integration) on each optimiser run:

image

@fboundy - using the "charge current = 0" for all holding has meant the Inverter "backup SOC" is not updated, but that value is still used throughout the code for managing the hold slots.

I'm therefore planning to call routine "hold_soc_old" for hold slots where the start and end SOCs < 3% (as before), but will use the modified "hold_soc" for IOG slots. I just need to ensure the IOG slots take priority over the hold slots (<3% SOC change) which I've yet to verify in test. Please let me know if you'd prefer I take a different tack.

fboundy commented 4 months ago

Hi @stevebuk1 - when you are ready it might be helpful to submit a PR and I'll pull it into my dev branch for testing on a non-EV system

stevebuk1 commented 4 months ago

Hi @stevebuk1 - when you are ready it might be helpful to submit a PR and I'll pull it into my dev branch for testing on a non-EV system

Hi @fboundy - will do. I've reset the hold logic to use backup mode for SOC <3% and solved the read error issue in my last post (it was Predbat which had come out of readonly mode!!) but still working on the additional IO slots problem - its more involved than I thought as the 1/2 hour rates have to be loaded from something user specific and triggered when the car is plugged in.

After this is done I'll raise a PR on my Dev fork. The whole lot will need a good test not only on a non-EV system but also for Agile in general to make sure its not affected.

mergwyn commented 4 months ago

Let me know when you want me to test something.

is the trigger when the car is plugged in or when Octopus create a charging plan which in my experience is not instantly but a short time later. I’ve not measured it but this seems to be 10 minutes or more sometimes)

stevebuk1 commented 4 months ago

The reload is triggered by the car being plugged in, but the actual reload occurs in the next optimiser run, so a guaranteed 10 mins minimum.

The code I last posted that you produced logs for has this 10 min delay in it already, but the load only prevents car discharge at the moment. It also needs to update prices for any extra slots outside the 6 hour window, so you start the day with a full battery.

I agree that it's probably better to wait for the intelligent dispatching sensor to update and then trigger a tariff reload, but that's a lot of extra code and may trigger a lot of necessary price reloads if Octopus fiddle with the power to be dispatched in each slot (as they often do).

On Mon, 27 May 2024, 09:29 mergwyn, @.***> wrote:

Let me know when you want me to test something.

is the trigger when the car is plugged in or when Octopus create a charging plan which in my experience is not instantly but a short time later. I’ve not measured it but this seems to be 10 minutes or more sometimes)

— Reply to this email directly, view it on GitHub https://github.com/fboundy/pv_opt/issues/121#issuecomment-2132941613, or unsubscribe https://github.com/notifications/unsubscribe-auth/ASVRJMHHLIX43ODHKNSHBP3ZELVHJAVCNFSM6AAAAABDG4TRJOVHI2DSMVQWIX3LMV43OSLTON2WKQ3PNVWWK3TUHMZDCMZSHE2DCNRRGM . You are receiving this because you were mentioned.Message ID: @.***>

fboundy commented 4 months ago

Hi @stevebuk1 - when you are ready it might be helpful to submit a PR and I'll pull it into my dev branch for testing on a non-EV system

Hi @fboundy - will do. I've reset the hold logic to use backup mode for SOC <3% and solved the read error issue in my last post (it was Predbat which had come out of readonly mode!!) but still working on the additional IO slots problem - its more involved than I thought as the 1/2 hour rates have to be loaded from something user specific and triggered when the car is plugged in.

After this is done I'll raise a PR on my Dev fork. The whole lot will need a good test not only on a non-EV system but also for Agile in general to make sure its not affected.

It would probably help if you merge in the latest changes from 3.15.0 and make sure they don't bust anything in your code. You will see that I have made some of the more verbose logging in _load_consumption dependent on self.debug which keeps things clean for everyone else.

stevebuk1 commented 4 months ago

It would probably help if you merge in the latest changes from 3.15.0 and make sure they don't bust anything in your code. You will see that I have made some of the more verbose logging in _load_consumption dependent on self.debug which keeps things clean for everyone else.

I'm working in the Dev branch only now, hopefully this should help.

IOG tariff loads from BottlecapDave is now coded and ready for test. I tried a sync of my fork of your Dev, but the contents wouldn't auto merge so I've opened a PR so I can see the conflicts. I'll fix those now with some additional commits.

The PR still contains fairly verbose commenting in the load_contract routine as I need @mergwyn to trial as I don't often get extra IOG slots. The code is also still in test - I need to test the slot transitions e.g. charge to hold, IOG to hold, hold to IOG but all this fine weather has meant little opportunity. Testing has also been compounded by Solcast issues (and the subsequent deletion of the integration I note!) and 2 outages of the Octopus API.

stevebuk1 commented 4 months ago

I'll fix those now with some additional commits.

Now done. Other than sillies that are just additional lines etc, there is one section of code that has a code addition but I don't see any conflict, it just seems to be the automerger that can't cope.

mergwyn commented 4 months ago

@stevebuk1 sorry, I hadn’t realised you had made the tariff loading changes. I’ll install your current dev version and try and send some logs tomorrow.

mergwyn commented 4 months ago

I downloaded the latest code at 09:09 and seem to immediately get stuck "Loading tariffs". Here are the logs: pv_opt.log error.log

stevebuk1 commented 4 months ago

I downloaded the latest code at 09:09 and seem to immediately get stuck "Loading tariffs". Here are the logs: pv_opt.log error.log

You'll need to uncomment the "octopus_account" setting within config.yaml and add your Octopus Account number to this. (you don't need the API key).

  # ========================================
  # Octopus account parameters
  # ========================================

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

  octopus_account: A-<fill details in here>
  # octopus_api_key:

Reason for this is that I've had to move the detection of the "intelligent_dispatching sensor earlier in the process so I can gate out downloading the slot prices from the two events in the Octopus Energy Integration, which in turn has to occur before all of the exiting tariff loads as they are done in a Class that doesn't have the ability to read from HA sensors. This is on the to do list, after which the octopus_account field can be blanked again.

mergwyn commented 4 months ago

Gets further but seems to hang updating inverter. error.log pv_opt.log

stevebuk1 commented 4 months ago

This is due to an added entity called "sleep_soc" that was added by Francis recently for another inverter type. I think I had to restart HA and also appdeamon to get Pv_opt to create this in MQTT.

On Wed, 5 Jun 2024, 09:43 mergwyn, @.***> wrote:

Gets further but seems to hang updating inverter. error.log https://github.com/user-attachments/files/15581382/error.log pv_opt.log https://github.com/user-attachments/files/15581387/pv_opt.log

— Reply to this email directly, view it on GitHub https://github.com/fboundy/pv_opt/issues/121#issuecomment-2149228915, or unsubscribe https://github.com/notifications/unsubscribe-auth/ASVRJMCSDRFHSVFUDBN7XE3ZF3FUTAVCNFSM6AAAAABDG4TRJOVHI2DSMVQWIX3LMV43OSLTON2WKQ3PNVWWK3TUHMZDCNBZGIZDQOJRGU . You are receiving this because you were mentioned.Message ID: @.***>

mergwyn commented 3 months ago

I added the config entry sleep_soc (guessed at 15), and this appeared to work. Strangely enough, the entity never appeared in mosquito despite multiple restarts. Even more weirdly, my battery storage did not charge overnight - I don't know if this is related to sleep_soc.

Screenshot 2024-06-07 at 09 56 54

Here are the logs, though because of the amount of debug logging, the earliest log only starts at 05:15 this morning: pv_opt.3.log pv_opt.2.log pv_opt.1.log pv_opt.log error.log

fboundy commented 3 months ago

sleep_soc shouldn’t need to be set to anything other than zero unless your inverter goes to sleep below a certain SOC On 7 Jun 2024 at 10:00 +0100, mergwyn @.***>, wrote:

I added the config entry sleep_soc (guessed at 15), and this appeared to work. Strangely enough, the entity never appeared in mosquito despite multiple restarts. Even more weirdly, my battery storage did not charge overnight - I don't know if this is related to sleep_soc. Screenshot.2024-06-07.at.09.56.54.png (view on web) Here are the logs, though because of the amount of debug logging, the earliest log only starts at 05:15 this morning: pv_opt.3.log pv_opt.2.log pv_opt.1.log pv_opt.log error.log — Reply to this email directly, view it on GitHub, or unsubscribe. You are receiving this because you were mentioned.Message ID: @.***>

stevebuk1 commented 3 months ago

That is strange. Can you upload the older log files as the earliest one starts at around 5am when the battery is already almost flat.

Note the code attempts to default sleep_soc to zero so if its in HA now set it at that. I'll have a look at the logs you've sent this evening.

On Fri, 7 Jun 2024, 10:00 mergwyn, @.***> wrote:

I added the config entry sleep_soc (guessed at 15), and this appeared to work. Strangely enough, the entity never appeared in mosquito despite multiple restarts. Even more weirdly, my battery storage did not charge overnight - I don't know if this is related to sleep_soc. Screenshot.2024-06-07.at.09.56.54.png (view on web) https://github.com/fboundy/pv_opt/assets/18122481/a2c55136-c6fe-41d0-8dba-b866ed321c7a

Here are the logs, though because of the amount of debug logging, the earliest log only starts at 05:15 this morning: pv_opt.3.log https://github.com/user-attachments/files/15727215/pv_opt.3.log pv_opt.2.log https://github.com/user-attachments/files/15727222/pv_opt.2.log pv_opt.1.log https://github.com/user-attachments/files/15727223/pv_opt.1.log pv_opt.log https://github.com/user-attachments/files/15727228/pv_opt.log error.log https://github.com/user-attachments/files/15727233/error.log

— Reply to this email directly, view it on GitHub https://github.com/fboundy/pv_opt/issues/121#issuecomment-2154404548, or unsubscribe https://github.com/notifications/unsubscribe-auth/ASVRJMG3OXJFWQI3SZ2DGTTZGFZDHAVCNFSM6AAAAABDG4TRJOVHI2DSMVQWIX3LMV43OSLTON2WKQ3PNVWWK3TUHMZDCNJUGQYDINJUHA . You are receiving this because you were mentioned.Message ID: @.***>

stevebuk1 commented 3 months ago

Sorry I missed your bit about not having earlier log files. I'll make an update to restrict the logging to just the charge/discharge planning until we get back to where we're were.

On Fri, 7 Jun 2024, 10:10 Steve Bevan, @.***> wrote:

That is strange. Can you upload the older log files as the earliest one starts at around 5am when the battery is already almost flat.

Note the code attempts to default sleep_soc to zero so if its in HA now set it at that. I'll have a look at the logs you've sent this evening.

On Fri, 7 Jun 2024, 10:00 mergwyn, @.***> wrote:

I added the config entry sleep_soc (guessed at 15), and this appeared to work. Strangely enough, the entity never appeared in mosquito despite multiple restarts. Even more weirdly, my battery storage did not charge overnight - I don't know if this is related to sleep_soc. Screenshot.2024-06-07.at.09.56.54.png (view on web) https://github.com/fboundy/pv_opt/assets/18122481/a2c55136-c6fe-41d0-8dba-b866ed321c7a

Here are the logs, though because of the amount of debug logging, the earliest log only starts at 05:15 this morning: pv_opt.3.log https://github.com/user-attachments/files/15727215/pv_opt.3.log pv_opt.2.log https://github.com/user-attachments/files/15727222/pv_opt.2.log pv_opt.1.log https://github.com/user-attachments/files/15727223/pv_opt.1.log pv_opt.log https://github.com/user-attachments/files/15727228/pv_opt.log error.log https://github.com/user-attachments/files/15727233/error.log

— Reply to this email directly, view it on GitHub https://github.com/fboundy/pv_opt/issues/121#issuecomment-2154404548, or unsubscribe https://github.com/notifications/unsubscribe-auth/ASVRJMG3OXJFWQI3SZ2DGTTZGFZDHAVCNFSM6AAAAABDG4TRJOVHI2DSMVQWIX3LMV43OSLTON2WKQ3PNVWWK3TUHMZDCNJUGQYDINJUHA . You are receiving this because you were mentioned.Message ID: @.***>

mergwyn commented 3 months ago

I've taken a look at the AppDaemon docs and have added log_generations: 15 for now - that should keep enough logs around!

mergwyn commented 3 months ago

Note that the entity number.pvopt_sleep_soc still hasn’t appeared in HA

stevebuk1 commented 3 months ago

Note that the entity number.pvopt_sleep_soc still hasn’t appeared in HA

I've fixed this now, the file on my dev fork was slightly behind my local copy which included the generation of the sleep_soc sensor. Due to the number of changes now made the github automerging function is no longer working so I'm having to keep my fork manually in sync with the original until the PR is accepted.

I've also reduced all the debug logging.

Copy all of pv_opt.py, pypy.py and solis.py to your local area from: https://github.com/stevebuk1/pv_opt/tree/dev/apps/pv_opt

stevebuk1 commented 3 months ago

I've taken a look at the AppDaemon docs and have added log_generations: 15 for now - that should keep enough logs around!

Yes I set mine to 9, I find that tends to cover 24 hours of fairly verbose logging.

stevebuk1 commented 3 months ago

edit - sorry, hyperlink was to main and not dev, now updated

@mergwyn I can't tell whether your battery charging didnt occur solely due to sleep_soc problems but I did notice from your logs that IOG hold slots were overiding charging slots which we don't want, so I've now fixed that.

If you've already imported the files from my post around an hour ago, redownload pv_opt.py from https://github.com/stevebuk1/pv_opt/tree/dev/apps/pv_opt

mergwyn commented 3 months ago

I set sleep_soc to 0 yesterday but there was still no significant charge overnight (6% was added at about 12:10 - odd). Unfortunately, the log_generations change didn't so I don't have 24 hours of logs meaning the 12:10 period was not covered. I've changed log_generations to 9 and that has at least created alog.4 file! I've installed your latest version this morning, so we can see how that goes overnight.

Screenshot 2024-06-08 at 11 38 36

Here are the logs: pv_opt.03.log pv_opt.02.log pv_opt.01.log pv_opt.log error.log

stevebuk1 commented 3 months ago

@mergwyn, I went for 9 too, not sure if it does more than that. I'd also increase your logsize - heres my logs section of appdeamon.yaml at /addon_configs/a0d7b954_appdaemon:

logs:
  main_log:
    filename: /homeassistant/appdaemon/appdaemon.log
    date_format: '%H:%M:%S'
    log_generations: 9
    log_size: 10000000
  error_log:
    filename: /homeassistant/appdaemon/error.log
    date_format: '%H:%M:%S'    
  pv_opt_log:
     name: PV_Opt
     filename: /homeassistant/appdaemon/pv_opt.log
     log_generations: 9
     log_size: 10000000
     date_format: '%H:%M:%S'      
     format: '{asctime} {levelname:>8s}: {message}'
stevebuk1 commented 3 months ago

Here are the logs: pv_opt.03.log pv_opt.02.log pv_opt.01.log pv_opt.log error.log

Thanks, I've checked these and I think the tariff prices download changes I've made are working as your charge plan went out to 8am which matched the extra slots yo got, its just the bug that I fixed yesterday was causing all of the slots that had car charging in to then be overidden to zero charge current. Hopefully you'll get a good run tonight.

mergwyn commented 3 months ago

Good news, charge was successful overnight - thanks for the fix! In case you need there, here are the logs from last night (there was only a very small 2% charge for the EV): pv_opt.09.log pv_opt.08.log pv_opt.07.log pv_opt.06.log pv_opt.05.log pv_opt.04.log pv_opt.03.log pv_opt.02.log pv_opt.01.log pv_opt.log error.log

mergwyn commented 3 months ago

I think the only thing outstanding for IOG might be stopping the EV charging on a forced discharge of the battery. I think this is an issue because IOG puts the Zappi charger into Eco++ mode so that it only charges when export is greater than 1.7kW. So on a forced discharge the EV will be charged form the solar battery which doesn't make sense when there is a differential of 7.5p between cheap rate and export.

Is it this something the integration should do, or is it best to do this in an automation?

stevebuk1 commented 3 months ago

Is it this something the integration should do, or is it best to do this in an automation?

The basis of the IOG tariff is that Octopus control when the car charges. This is both in what 1/2 hour slot, and also how much in each slot (I've seen plenty of 1/2 hour slots that are not 3.5kWh, e.g. not charging for the full 1/2 hour).

The Octopus servers place the Zappi in Eco+ mode and command a boost charge in kWh for the 1/2 hour slots they are scheduling. Trying to change mode to STOP or FAST using the Zappi front screen or App is detected by the Octopus server and it soon commands it back to Eco+. I guess you could do this at a fast rate with HomeAssistant but I'm fairly sure this is all detectable by Octopus and outside of their Ts&Cs. MyEnergi have this to say about it here: https://support.myenergi.com/hc/en-gb/articles/18470101583377-zappi-Intelligent-Octopus-Go

A note on Home Assistant Some customers use Home Assistant (HA) to control their zappi and flip it to different modes depending on the time of day. As previously mentioned IO eligibility requires Octopus to control your zappi to control charging.

We have asked Octopus about this and the current position is:

"usage of HA's to dictate charging behaviour will often result in the customer acting outside of the Intelligent Octopus Fair Use Policy"

So be aware if you use HA to control your zappi you may be removed from the IO tariff. We strongly advise you disable HA control of your zappi before switching tariff. If this is an unacceptable change then you should not join IO.

If you're using home assistant to prevent your home battery from discharging perhaps look at the situation differently. If your Zappi is boosting under IO then power is at the lower rate, perhaps charge your home batteries or put your batteries into "stop" mode.

Ultimately this means Pv_opt is limited to deciding what to do with the house battery during the car charging.

I can think of two options:

1) Prevent discharge during car charging

When first thinking about this I wondered what to do with discharge slots and thought it best just to let them run as is. However, as you say, it might not be optimal cost as discharges should go to grid at 15p rather than into the car where it would be better off just charging the car at 7.5p. I have no export tariff so right now I'm easy either way, its a relatively simple fix to just override any discharge slots when the car is charging. I think Pv_opt will recalculate on the fly and just dump the battery when it is eventually allowed to, but if you have cyclic charge/discharge enabled this might limit the number of cycles?

2) Zero the export tariff to 0p during any car charge slots.

By far the best way would be to tell the discharge algorithm up front not to use car charging slots for discharge, and thats relatively easily achieved by zeroing the export price to 0p for these slots so they don't get considered for discharging.

I think right now Option 2 I'd have to consider as long term. Its taken many weeks/months for me to get my head around the charge algorithm to insert the IOG tariff into it. The discharge one runs afterwards, is quite different, and I have no real way of testing it as I don't have an export tariff. Where we've got to so far is still in development and there are other things that need fixing/enhancing, e.g a tariff reload if the % to add is modified after the car is plugged in, a fix for negative values in the power consumption tables, and some enhancements to the dashboard to display the car charging plan. Theres also still the small issue that none of what I've written has been proved on a non-EV system running Agile, which worst case might need some more work. After that I'd also then probably prioritize getting the EV bit working for Agile as per the original request.

Let me know your thoughts.....

stevebuk1 commented 3 months ago

and some enhancements to the dashboard to display the car charging plan.

Latest code now includes a sensor "sensor.pvopt_iog_slots" which contains all the IOG car charging windows as an attribute.

I've uploaded an example dashboard which displays this here: https://github.com/stevebuk1/pv_opt/blob/dev/pv_opt_dashboard_iog.yaml Search for "Car charging" within the Yaml.

Here is what it looks like (no car charge plan this evening)

image

mergwyn commented 3 months ago

@stevebuk1 Many thanks for your comments and your work on this. I agree entirely with the priorities you suggest for now until/unless this becomes a bigger issue once your code is merged. I'll continue to run your coded monitor what's going to see if a solution becomes more apparent!

stevebuk1 commented 3 months ago

there are other things that need fixing/enhancing, e.g a tariff reload if the % to add is modified after the car is plugged in

Above is now done. Version 3.15.5 at https://github.com/stevebuk1/pv_opt/tree/dev/apps/pv_opt

Also fixed a bug where non-contiguous IO slots were being joined together. If no charging plan, hold slots should now equal smart charge slots.

stevebuk1 commented 3 months ago

@stevebuk1 Many thanks for your comments and your work on this. I agree entirely with the priorities you suggest for now until/unless this becomes a bigger issue once your code is merged. I'll continue to run your coded monitor what's going to see if a solution becomes more apparent!

No problem. Whilst Option 2 is complex, Option 1 is easily doable so let me know if you want to try it out.

mergwyn commented 3 months ago

Thanks - I've just installed 13.15.5.

For the time being, I've just created some automations to detect when if the battery is discharging when there is no IOG slot and change the zappi mode to 'Stopped' and revert back to 'Eco+' after the discharge. Not sure this will work if I use the IOG boost, but that rarely happens.

The optimiser creates a forced discharge most afternoons, so I'll take a look tomorrow to see what happened.

stevebuk1 commented 3 months ago

If you are overriding the Zappi I'd use the Octopus integration to also turn off smart charging, this keeps you safely inside the Ts&Cs. I know switching to Fast using the Zappi screen is then reset back to Eco++ by Octopus/MyEngeri just a few seconds later regardless of what the car is doing and even if its not plugged in, you may find the changing it to STOP trigggers the same reset. Disabling smart charging gets round that issue.

I'm now away for a weeks holiday so no updates from me for a while, if you see anything that doesnt look right feel free to post a log and I'll take a look on my return.

fboundy commented 3 months ago

Hi both - I've finally got around to pulling your PR into my dev branch. Will test it for a days and if all is well I will release as 3.16.0 - would be helpful @stevebuk1 could provide some Release Notes

fboundy commented 3 months ago

@stevebuk1:

I'm getting this error in _check_for_io():

  File "/homeassistant/appdaemon/apps/Github/pv_opt/apps/pv_opt/pv_opt.py", line 599, in _check_for_io
    entity_id = f"binary_sensor.octopus_energy_{self.get_config('octopus_account').lower().replace('-', '_')}_intelligent_dispatching"
                                                ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
AttributeError: 'NoneType' object has no attribute 'lower'

I think this is because you are calling _check_for_io() before the contract is loaded. You have this comment at line 959:

    ### SVB - we are doing this before doing any contract detects as the values need to be passed into the Tariff class within pypy.
    ### However it should be done within the Tariffs class as that is where the prices from the website are loaded
    ### The function "get_state_retry" would be needed to load from the Octopus Energy integration, but  is in the PvOpt class.
    #   Perhaps make a copy in the Tariff class and then shift all of the below code into it?

If you need to call function from pv_opt.py within pvypy.py you can use host.function for host.get_state_retry() in this case. I think this would allow you to move the code as you sugggest

fboundy commented 3 months ago

PS - suggest we stick with 3.16.0 as version number and append -beta-1 etc as we test this for release