Myenergi Zappi automation to protect hybrid battery during Eco Tariff

Post Reply
Dave Foster
Posts: 990
Joined: Thu Oct 13, 2022 7:21 pm

This automation was written for systems that have the Zappi and Foxess Hybrid systems and use eco tariffs to charge the EV overnight.

When the Zappi charger is on it will draw power from the batteries as well as the grid, unless the batteries are themselves being protected from discharge by a force charge window.

This automation ensures that if the Zappi charger starts up during the eco tariff hours and starts to draw power from the batteries (i.e. no charge window exists) that a force charge window is set in 'Period 2' for the entire duration of the Eco period, and once the eco period is over it will clear the charge period in Period 2.

It needs a home assistant and the RS485 Foxess Modbus integration to operate.

There are 2 datetime helpers creating for Eco Start Period and Eco End Period.

The helpers are created under Settings, Devices & Services, Helpers (at the top), click on + Create Helpers, then choose 'Date and/or Time' and set them as follows -
ecostart.jpg
ecoend.jpg
Once created, click on the Helpers and set them to your Eco tariff i.e. for Economy 7 it would be 1:30am for start and 08:30am for the end.

The Automation works by monitoring the Zappi charger and the battery discharge and if both are above 3kW then it will set a Force Charge in Period 2 (but Grid charge turned off) for the Eco tariff period which will protect the batteries from any further discharge.

Once the Eco tariff period is over it will clear Period 2 - Note: this will not affect whatever has been set in Period 1.

It will log all it's actions in Logbook.

The Automation code is as follows, please note that you will have to enter some information that is unique to your system, they are detailed below the code.

Code: Select all

alias: Zappi Home Battery Protect with EM
description: >-
  IF Zappi starts charging at high power and no charge windows are set then auto
  set a force charge window for eco tariff period and reset when eco tariff has
  ended
trigger:
  - platform: time_pattern
    minutes: /1
condition:
  - condition: or
    conditions:
      - condition: template
        value_template: >-
          {{ now().strftime('%H:%M') ==
          states('input_datetime.eco_end_period')[:5] }}
      - condition: and
        conditions:
          - condition: numeric_state
            entity_id: sensor.myenergi_lymm_6_greenacres_power_charging
            above: 4000
          - condition: numeric_state
            entity_id: sensor.battery_discharge
            above: 3
action:
  - if:
      - condition: time
        before: input_datetime.eco_end_period
        after: input_datetime.eco_start_period
    then:
      - service: foxess_modbus.update_charge_period
        data:
          inverter: 84609677d0bc2a5f9fb29beba3f27565
          enable_force_charge: true
          enable_charge_from_grid: false
          start: "{{ states('input_datetime.eco_start_period') }}"
          end: "{{ states('input_datetime.eco_end_period') }}"
          charge_period: "2"
        enabled: true
      - service: logbook.log
        data:
          name: Battery Protect
          message: >-
            EV Charging and no charge period set, Protecting batteries - Start
            {{states('input_datetime.eco_start_period')}}, End
            {{states('input_datetime.eco_end_period')}}
    else:
      - if:
          - condition: template
            value_template: >-
              {{ now().strftime('%H:%M') ==
              states('input_datetime.eco_end_period')[:5] }}
        then:
          - delay:
              hours: 0
              minutes: 5
              seconds: 0
              milliseconds: 0
          - if:
              - condition: state
                entity_id: binary_sensor.time_period_2_enable_force_charge
                state: "on"
            then:
              - service: foxess_modbus.update_charge_period
                data:
                  inverter: 84609677d0bc2a5f9fb29beba3f27565
                  enable_force_charge: false
                  enable_charge_from_grid: false
                  start: "00:00:00"
                  end: "00:00:00"
                  charge_period: "2"
                enabled: true
              - service: logbook.log
                data:
                  name: Battery Protect
                  message: Removing period 2 settings
            else:
              - service: logbook.log
                data:
                  name: Battery Protect
                  message: Period 2 was already reset
mode: single
max_exceeded: silent

As the Zappi sensor name is unique to your installation you will need to update the 'conditions:' line that contains the Zappi sensor in it and replace it with your sensor.myenergi name, it looks like this 'sensor.myenergi_xxxxxxx_power_charging'

As the Inverter 'device' is also unique to your installation you will need to update the device name in the code with your inverter device - you can find your inverter device_ID by creating a new blank automation, click '+Add Action', and choose 'Call Service', in the 'Service' box start to type 'Foxess - modbus' and choose the item in the list 'FoxESS - Modbus: Update Charge Period'

In the box below for 'Inverter' click in the 'Device' box and choose your inverter (there will usually only be one unless you have multiple inverters), now click on the three dots in the right corner of this action and select 'Edit in Yaml'.

You will see your inverter device ID (see the image below), this is your unique inverter device ID and must be copy and pasted into the automation code above in the 2 places that you see 'inverter: xxxxxxxxxxxxxxxxxxxxxxxxxx'
inverter.jpg
You can exit this screen by clicking the <- Arrow in the top left corner of the New Automation screen and choose 'Leave' to exit without saving.


And that's that, the automation will check each minute to see if the Zappi is charging and the Home Battery being discharged and if it is during the Eco Tariff period, it will set Period 2 for the duration of the Eco Tariff and clear it when finished.
AndyB
Posts: 4
Joined: Fri Nov 11, 2022 2:33 pm

Thank you so much for this Dave.
I have managed to get it onto my HA and updated a few bits (I already had helpers in place for the off peak period to allow me to work out billing prices)
Going to give it a test one night to make sure it all works, then ill report back

That Call Service instruction is game changing. That's the main bit I couldn't work out how to use to change the charge period and state.
Dave Foster
Posts: 990
Joined: Thu Oct 13, 2022 7:21 pm

AndyB wrote: Mon Sep 11, 2023 9:30 am Thank you so much for this Dave.
I have managed to get it onto my HA and updated a few bits (I already had helpers in place for the off peak period to allow me to work out billing prices)
Going to give it a test one night to make sure it all works, then ill report back

That Call Service instruction is game changing. That's the main bit I couldn't work out how to use to change the charge period and state.
Your welcome, until that service call was introduced you used to have to keep track of time period 1 & 2 independently, and now the integration does all of that for you - as you say game changing :)

If you have any problems just let me know, here or on FB
Dave Foster
Posts: 990
Joined: Thu Oct 13, 2022 7:21 pm

This is for Frank, it simply protects batteries if the Zappi is charging and the battery is discharging heavily.

You will need to put in your zappi‘s named sensor for myenergi_youzappiname_power_charging and you’ll need your inverters device name from the modbus - if you read the main post at the top it’ll tell you how to find your inverter device.

Code: Select all


alias: Zappi EV Home Battery Discharge Protect
description: >-
  IF Zappi starts charging at high power and no charge windows are set then auto
  set a force charge window for 30 minutes and reset whem delay has elapsed
trigger:
  - platform: time_pattern
    seconds: /20
condition:
  - condition: numeric_state
    entity_id: sensor.myenergi_yourzappiname_power_charging
    above: 4000
    enabled: true
  - condition: numeric_state
    entity_id: sensor.battery_discharge
    above: 3
    enabled: true
action:
  - variables:
      initial_delay: 15
  - service: foxess_modbus.update_charge_period
    data:
      enable_force_charge: true
      enable_charge_from_grid: false
      start: "{% set tstart= now().strftime('%H:%M:00') %}{{ tstart }}"
      end: >
        {% set thnow=now().strftime('%H')|int %} {% set
        tmnow=now().strftime('%M')|int %} {% if thnow==23 and tmnow>=30 %}{% set
        tendmins=0 %}{% else %}{% set tendmins=(thnow*60+tmnow)|int(0)+30 %}{%
        endif %} {% set thours = tendmins//60 %}{% set
        tmins=tendmins-(thours*60) %} {% if thours > 23 %} {% set thours=23
        %}{%endif%} {% if tmins > 59 %}{% set tmins=59 %}{%endif%} {% set
        tend=('0'+thours|string)[-2:]+':'+('0'+tmins|string)[-2:]+':00'
        %}{{tend}}
      charge_period: "2"
      inverter: 84609677d0bc2a5f9fb29beba3f27565
  - variables:
      initial_delay: |
        {% set thnow=now().strftime('%H')|int %}
        {% set tmnow=now().strftime('%M')|int %}
        {% if thnow==23 and tmnow >=30 %}
          {% set tdiff=60-tmnow %}
        {% else %}
          {% set tdiff=30 %}
        {% endif %}
        {{ tdiff|int }}
  - service: logbook.log
    data:
      message: EV Charging, protect batteries, delay for {{ initial_delay|int(30) }}
      name: Battery Protect
  - delay:
      hours: 0
      minutes: "{{ initial_delay|int(30) }}"
      seconds: 0
      milliseconds: 0
  - service: foxess_modbus.update_charge_period
    data:
      enable_force_charge: false
      enable_charge_from_grid: false
      start: "00:00:00"
      end: "00:00:00"
      charge_period: "2"
      inverter: 84609677d0bc2a5f9fb29beba3f27565
  - service: logbook.log
    data:
      message: End of Protect, reset charge times
      name: Battery Protect
mode: single
max_exceeded: silent

digital
Posts: 3
Joined: Tue Jan 10, 2023 1:43 pm

Dave Foster wrote: Fri Sep 22, 2023 6:52 pm This is for Frank, it simply protects batteries if the Zappi is charging and the battery is discharging heavily.

You will need to put in your zappi‘s named sensor for myenergi_youzappiname_power_charging and you’ll need your inverters device name from the modbus - if you read the main post at the top it’ll tell you how to find your inverter device.
That was amazingly kind of you. Thank you! :D
AndyB
Posts: 4
Joined: Fri Nov 11, 2022 2:33 pm

Dave Foster wrote: Tue Sep 12, 2023 10:28 am
AndyB wrote: Mon Sep 11, 2023 9:30 am Thank you so much for this Dave.
I have managed to get it onto my HA and updated a few bits (I already had helpers in place for the off peak period to allow me to work out billing prices)
Going to give it a test one night to make sure it all works, then ill report back

That Call Service instruction is game changing. That's the main bit I couldn't work out how to use to change the charge period and state.
Your welcome, until that service call was introduced you used to have to keep track of time period 1 & 2 independently, and now the integration does all of that for you - as you say game changing :)

If you have any problems just let me know, here or on FB
Apologies for the huge delay in updating, because annoyingly I haven't needed to charge the car for a while.
Anyway, did it last night and all worked perfectly.
Big thumbs up for writing this one Dave.
AndyB
Posts: 4
Joined: Fri Nov 11, 2022 2:33 pm

Dave Foster wrote: Tue Sep 12, 2023 10:28 am
AndyB wrote: Mon Sep 11, 2023 9:30 am Thank you so much for this Dave.
I have managed to get it onto my HA and updated a few bits (I already had helpers in place for the off peak period to allow me to work out billing prices)
Going to give it a test one night to make sure it all works, then ill report back

That Call Service instruction is game changing. That's the main bit I couldn't work out how to use to change the charge period and state.
Your welcome, until that service call was introduced you used to have to keep track of time period 1 & 2 independently, and now the integration does all of that for you - as you say game changing :)

If you have any problems just let me know, here or on FB
Hi @Dave Foster

Would you be so kind as to cast your eye over this automation please.
Now i have managed to sign up to Intelligent Octopus with the Zappi, the charging requirements have changed slightly. Now, when IO is giving me a charge outside the normal off peak period (23:30 to 0530) i would like the battery to start charging at the same time to give it a boost, if required.

So far, i have taken the original automation and tweaked it to say, if the car is charging at high power, set the charge period 2 to 05:30 to 23:30 (ie cover the rest of the day) and then set the force charge to yes. This should stop the battery discharging (just like the original automation), but also boost it as well.

My input_datetime.off_peak_energy_end is set as 05:30 and my input_datetime.off_peak_energy_start is set as 23:30 (i use these helpers to calculate my bill prices based on energy used during the day / night)

If this looks OK to you, would you be able to confirm where i would put an entry that would only start charging the battery if it was below say 30% at that time. I'm guessing this would be at the start with the trigger.
Thinking about it though, that would generate a different outcome, as if the battery is above the set limit (say 30%), then i'd be back to wanting it to save the battery and just run the house from the mains (thinking emoji)

Code: Select all

alias: Zappi Home Battery Charge when using IO
description: >-
  If Zappi starts charging at high power due to IO and no charge windows are set then auto
  set a force charge window outside eco tariff period and charge battery, then reset when IO has
  ended
trigger:
  - platform: time_pattern
    minutes: /1
condition:
  - condition: or
    conditions:
      - condition: template
        value_template: >-
          {{ now().strftime('%H:%M') ==
          states('input_datetime.off_peak_energy_end')[:5] }}
      - condition: and
        conditions:
          - condition: numeric_state
            entity_id: sensor.myenergi_home_power_charging
            above: 4000
          - condition: numeric_state
            entity_id: sensor.battery_discharge
            above: 3
action:
  - if:
      - condition: time
        before: input_datetime.off_peak_energy_end
        after: input_datetime.off_peak_energy_start
    then:
      - service: foxess_modbus.update_charge_period
        data:
          inverter: SerialNumber
          enable_force_charge: true
          enable_charge_from_grid: true
          start: "{{ states('input_datetime.off_peak_energy_end') }}"
          end: "{{ states('input_datetime.off_peak_energy_start') }}"
          charge_period: "2"
        enabled: true
      - service: logbook.log
        data:
          name: Battery Protect
          message: >-
            EV Charging and no charge period set, Protecting batteries - Start
            {{states('input_datetime.off_peak_energy_start')}}, End
            {{states('input_datetime.off_peak_energy_end')}}
    else:
      - if:
          - condition: template
            value_template: >-
              {{ now().strftime('%H:%M') ==
              states('input_datetime.off_peak_energy_end')[:5] }}
        then:
          - delay:
              hours: 0
              minutes: 5
              seconds: 0
              milliseconds: 0
          - if:
              - condition: state
                entity_id: binary_sensor.time_period_2_enable_force_charge
                state: "on"
            then:
              - service: foxess_modbus.update_charge_period
                data:
                  inverter: SerialNumber
                  enable_force_charge: false
                  enable_charge_from_grid: false
                  start: "00:00:00"
                  end: "00:00:00"
                  charge_period: "2"
                enabled: true
              - service: logbook.log
                data:
                  name: Battery Protect
                  message: Removing period 2 settings
            else:
              - service: logbook.log
                data:
                  name: Battery Protect
                  message: Period 2 was already reset
mode: single
max_exceeded: silent
Dave Foster
Posts: 990
Joined: Thu Oct 13, 2022 7:21 pm

Just had a quick look, I think i'm a bit confused by what it's doing, i'll tell you what I think it's going to do and you tell me if that's right :)

You check every minute the conditions,

There are 2 conditions which are OR'd

The first is a template check to see if the time now HH:MM is equal to input_datetime.off_peak_energy_end (which is 05:30)

So if it is 05:30 in the morning the condition will be true, and the rest of the automation will run.

The second condition is the test for your Zappi on so that's > 4,000W AND battery discharging > 3kw - if that true the rest of the automation will run.

This is the bit I get confused with, the first 'IF' test is checking to see if the time now is before peak_end (05:30) and after peak_start (23:30) so that will only be true when the time is between 23:31-05:29am (low tariff)

If it is between 23:31 & 05-29am it will set the inverter charge period 2 to start at 05:30 and end at 23:30 and to charge from grid (high tariff?)

The 'ELSE' at the bottom will only activate when the time now HH:MM is 05:30, it checks to see if a charge has been set and if it has it will clear charge period 2

So, a couple of things -

It feels like the first IF test should be the other way round *after* peak_end and *before* peak_start - then it will only do this if it detects Zappi charging between 05:30 & 23:30 (which implies you've got a free slot during the day)

The second thing that worries me is if you only get 2 hours outside the normal low tariff, you've set your battery to charge for the entirety of the day, and won't reset it until 05:30 the next day - sounds expensive?.

I'm thinking in an ideal world because of the 30 minute charging windows Octopus give you, you would have another automation check every minute and look to see if Period 2 has been set, if it has and the Zappi has stopped charging > 4,000W then you clear Charge Period 2 and stop the battery as well.

The two automations would then work together, one turning it on, the other turning it off (You could do it all in one automation but it would be easier to add your battery test to it if you leave it as 2 separate ones).

I'll leave you to see if I read that right, let me know what you think - i'm happy to help review / code something :)
AndyB
Posts: 4
Joined: Fri Nov 11, 2022 2:33 pm

Dave Foster wrote: Wed Nov 15, 2023 3:28 pm Just had a quick look, I think i'm a bit confused by what it's doing, i'll tell you what I think it's going to do and you tell me if that's right :)

You check every minute the conditions,

There are 2 conditions which are OR'd

The first is a template check to see if the time now HH:MM is equal to input_datetime.off_peak_energy_end (which is 05:30)

So if it is 05:30 in the morning the condition will be true, and the rest of the automation will run.

The second condition is the test for your Zappi on so that's > 4,000W AND battery discharging > 3kw - if that true the rest of the automation will run.

This is the bit I get confused with, the first 'IF' test is checking to see if the time now is before peak_end (05:30) and after peak_start (23:30) so that will only be true when the time is between 23:31-05:29am (low tariff)

If it is between 23:31 & 05-29am it will set the inverter charge period 2 to start at 05:30 and end at 23:30 and to charge from grid (high tariff?)

The 'ELSE' at the bottom will only activate when the time now HH:MM is 05:30, it checks to see if a charge has been set and if it has it will clear charge period 2

So, a couple of things -

It feels like the first IF test should be the other way round *after* peak_end and *before* peak_start - then it will only do this if it detects Zappi charging between 05:30 & 23:30 (which implies you've got a free slot during the day)

The second thing that worries me is if you only get 2 hours outside the normal low tariff, you've set your battery to charge for the entirety of the day, and won't reset it until 05:30 the next day - sounds expensive?.

I'm thinking in an ideal world because of the 30 minute charging windows Octopus give you, you would have another automation check every minute and look to see if Period 2 has been set, if it has and the Zappi has stopped charging > 4,000W then you clear Charge Period 2 and stop the battery as well.

The two automations would then work together, one turning it on, the other turning it off (You could do it all in one automation but it would be easier to add your battery test to it if you leave it as 2 separate ones).

I'll leave you to see if I read that right, let me know what you think - i'm happy to help review / code something :)
Hi Dave

Thanks for having a look. Sorry I am tinkering with your original script that works and trying to understand it so I can make changes all at the same time.
With the original script it was designed to stop the house battery being drained if it wasnt being charged on the off peak, but the car was. With this update, the plan is to update that as the car could charge at any time during the day and therefore, if possible, might as well charge the house battery at the same time.

Yes the first two timers are the wrong way round, missed those. I'll update that.

If the car starts to charge outside the 23:30 to 05:30 window (Zappi is pulling 4kW, battery is draining at 3kW), set Charge Period 2 to 05:30 to 23:30 and turn on forced charge. This will charge the house and car at the same time.
Once the IO charge period stops, the Zappi returns to 0. At this point, if I understand the original script, the last THEN statement should kick in, set the Charge Period 2 back to 00:00 to 00:00 and turn off the force charge from grid, stopping the house battery charging.
Dave Foster
Posts: 990
Joined: Thu Oct 13, 2022 7:21 pm

Hi Andy,

I think this is more what you are looking for, you need the template test in conditions to check for the time being between 05:30 and 23:30 combined with the other 2 conditions.

So basically it will proceed if it's between 05:30 & 23:30 OR your (Zappi is charging >4000W and the battery is discharging > 3kw).

If the Zappi is charging and battery discharging, it will then set Period 2 on and force charge the battery, but if the Zappi isn't charging, it will then check and reset the charge period if it is set.

I can't test it as my variables are different to yours but it looks to be ok.

Code: Select all

alias: Zappi Home Battery Charge when using IO
description: >-
  If Zappi starts charging at high power due to IO and no charge windows are set
  then auto set a force charge window outside eco tariff period and charge
  battery, then reset when IO has ended
trigger:
  - platform: time_pattern
    minutes: /1
condition:
  - condition: or
    conditions:
      - condition: and
        conditions:
          - condition: numeric_state
            entity_id: sensor.myenergi_home_power_charging
            above: 4000
          - condition: numeric_state
            entity_id: sensor.battery_discharge
            above: 3
      - condition: template
        value_template: >-
          {{ (now().strftime('%H:%M') >=
          states('input_datetime.off_peak_energy_end')[:5]) and
          (now().strftime('%H:%M') <=
          states('input_datetime.off_peak_energy_start')[:5]) }}
action:
  - if:
      - condition: and
        conditions:
          - condition: numeric_state
            entity_id: sensor.myenergi_home_power_charging
            above: 4000
          - condition: numeric_state
            entity_id: sensor.battery_discharge
            above: 3
    then:
      - service: foxess_modbus.update_charge_period
        data:
          inverter: SerialNumber
          enable_force_charge: true
          enable_charge_from_grid: true
          start: "{{ states('input_datetime.off_peak_energy_end') }}"
          end: "{{ states('input_datetime.off_peak_energy_start') }}"
          charge_period: "2"
        enabled: true
      - service: logbook.log
        data:
          name: Battery Protect
          message: >-
            EV Charging and no charge period set, Protecting batteries - Start
            {{states('input_datetime.off_peak_energy_start')}}, End
            {{states('input_datetime.off_peak_energy_end')}}
    else:
      - if:
          - condition: and
            conditions:
              - condition: numeric_state
                entity_id: sensor.myenergi_home_power_charging
                below: 100
        then:
          - if:
              - condition: state
                entity_id: binary_sensor.time_period_2_enable_force_charge
                state: "on"
            then:
              - service: foxess_modbus.update_charge_period
                data:
                  inverter: SerialNumber
                  enable_force_charge: false
                  enable_charge_from_grid: false
                  start: "00:00:00"
                  end: "00:00:00"
                  charge_period: "2"
                enabled: true
              - service: logbook.log
                data:
                  name: Battery Protect
                  message: Removing period 2 settings
            else:
              - service: logbook.log
                data:
                  name: Battery Protect
                  message: Period 2 was already reset
mode: single
max_exceeded: silent

Andy Pymer
Posts: 1
Joined: Sun Dec 17, 2023 6:58 pm

Hi Dave

I gave this automation a go, but it didn't work, and then I noticed that some of the entities seem to be different - namely

## Battery: Discharge sensor.inverter_modbus_invbatpower

## Time Period 2 Enable Charge from grid: binary_sensor.inverter_modbus_time_period_2_enable_charge_from_grid

## Flag: Clear / Detected

## Period 2 Start: sensor.inverter_modbus_time_period_2_start

## Period 2 Stop: sensor.inverter_modbus_time_period_2_end

I'm wondering why this is, and if this is the case, will the inverter fields be different??

Thanks
Dave Foster
Posts: 990
Joined: Thu Oct 13, 2022 7:21 pm

Andy Pymer wrote: Sun Dec 17, 2023 7:05 pm Hi Dave

I gave this automation a go, but it didn't work, and then I noticed that some of the entities seem to be different - namely

## Battery: Discharge sensor.inverter_modbus_invbatpower

## Time Period 2 Enable Charge from grid: binary_sensor.inverter_modbus_time_period_2_enable_charge_from_grid

## Flag: Clear / Detected

## Period 2 Start: sensor.inverter_modbus_time_period_2_start

## Period 2 Stop: sensor.inverter_modbus_time_period_2_end

I'm wondering why this is, and if this is the case, will the inverter fields be different??

Thanks
This thread has become a bit confusing as there are three different automations on here, the one at the top is still valid for protecting your batteries and is documented for the standard sensor names from the Foxess modbus integration https://github.com/nathanmarlor/foxess_modbus if you have the older StealthChesnut sensors they may be named slightly differently.

Can you tell me which integration you have - if it is Nathan's it looks like you have given it a name 'inverter_modbus' which is then appended to all your sensor names, the sensor names referenced here are the standard default with no inverter name specified (that's normally only used with multiple inverter configurations) so you should just find adding 'inverter_modbus' to all the sensor names in the automation then matches up to yours.

Your battery discharge sensor should be called sensor.inverter_modbus.battery_discharge, the sensor sensor.inverter_modbus_invbatpower is similar but swings positive and negative depending on whether you are charging or discharging.

The Zappi always has a name specific to your installation so you will have to use the sensor it provides that matches and the inverter always has a unique device name (specific to your installation), the top post shows you how to find it.
Post Reply