batpred icon indicating copy to clipboard operation
batpred copied to clipboard

Freeze Charge not working as expected - Sigenergy

Open F17HEH opened this issue 2 months ago • 17 comments

When ESS Max Discharging Limit is being updated its not actioning the change on the plant when in Freeze Charge

{% elif is_state('input_select.predbat_requested_mode', "Freeze Charging") %}Maximum Self Consumption

This is setting to a mode that cannot action ESS Max Discharging Limit as the inverter needs to be in state 5 or 6

Image Image
              option: >
                {% if is_state('input_select.predbat_requested_mode', "Demand") %}Maximum Self Consumption
                {% elif is_state('input_select.predbat_requested_mode', "Charging") %}Command Charging (PV First)
                {% elif is_state('input_select.predbat_requested_mode', "Freeze Charging") %}Maximum Self Consumption
                {% elif is_state('input_select.predbat_requested_mode', "Discharging") %}Command Discharging (PV First)
                {% elif is_state('input_select.predbat_requested_mode', "Freeze Discharging") %}Maximum Self Consumption
                {% endif %}
          - choose:
              # Set charging limit to 0 when requested mode is Freeze Charging
              # Docs:
              #  Freeze charging - The battery is charging but the current battery level (SoC) is frozen (held). Think of it
              #  as a charge to the current battery level. The grid or solar covers any house load. If there is a shortfall of
              #  Solar power to meet house load, the excess house load is met from grid import, but if there is excess Solar
              #  power above the house load, the excess solar will be used to charge the battery
              # In Sigenergy, this is effectively "self consumption" mode with discharging prohibited
              - conditions:
                  - condition: state
                    entity_id: input_select.predbat_requested_mode
                    state: "Freeze Charging"
                sequence:
                  - service: number.set_value
                    data_template:
                      entity_id: number.sigen_plant_ess_max_discharging_limit
                      value: 0

So with some testing Discharge PV first with the following settings {% elif is_state('input_select.predbat_requested_mode', "Freeze Charging") %}Command Discharging (PV First)

          - choose:
              # Set charging limit to 0 when requested mode is Freeze Charging
              # Docs:
              #  Freeze charging - The battery is charging but the current battery level (SoC) is frozen (held). Think of it
              #  as a charge to the current battery level. The grid or solar covers any house load. If there is a shortfall of
              #  Solar power to meet house load, the excess house load is met from grid import, but if there is excess Solar
              #  power above the house load, the excess solar will be used to charge the battery
              # In Sigenergy, this is effectively "self consumption" mode with discharging prohibited
              - conditions:
                  - condition: state
                    entity_id: input_select.predbat_requested_mode
                    state: "Freeze Charging"
                sequence:
                  - service: number.set_value
                    data_template:
                      entity_id: number.sigen_plant_ess_max_discharging_limit
                      value: 0
                  - service: number.set_value
                    data_template:
                      entity_id: number.sigen_plant_grid_export_limitation
                      value: 0

this looks to do whats needed. You do have to enable some things on the config side of the sig integration tho

Image

Excess solar is put in the battery.

Might also need to set the number.sigen_plant_grid_export_limitation & number.sigen_plant_grid_export_limitation back to either 0 or 100 on the other automatons when changing mode to make sure its all reset to what it should be

F17HEH avatar Nov 07 '25 15:11 F17HEH

Ok this also looks to effect the Freeze discharge also as this is only available in 3 & 4

Image

Currently dont have export (awaiting DNO) so cant test this fully but think this should work

If you set to Command Charging (PV First)

number.sigen_plant_ess_max_charging_limit == 0 number.sigen_plant_grid_export_limitation == 100

F17HEH avatar Nov 07 '25 15:11 F17HEH

is this part of your feedback of testing the Sigenergy configuration you mentioned in #2077 ?

I'm more than happy to make requested changes based on your experience of using what's documented, wonder whether this might be better to keep in the 2077 thread rather than start a new one

gcoan avatar Nov 07 '25 16:11 gcoan

didnt know if it was easier to split out the issues or keep as 1 big one, happy either way

Currently in automations.yaml i have

  alias: "Predbat Requested Mode Action"
  description: "Acts as a mapper for the input_select.predbat_requested_mode to the select.sigen_plant_remote_ems_control_mode"
  mode: restart
  triggers:
    - trigger: state
      entity_id:
        - input_select.predbat_requested_mode
  conditions: []
  actions:
    - action: select.select_option
      metadata: {}
      target:
        entity_id: select.sigen_plant_remote_ems_control_mode
      data:
        option: >
          {% if is_state('input_select.predbat_requested_mode', "Demand") %}Maximum Self Consumption
          {% elif is_state('input_select.predbat_requested_mode', "Charging") %}Command Charging (PV First)
          {% elif is_state('input_select.predbat_requested_mode', "Freeze Charging") %}Command Discharging (PV First)
          {% elif is_state('input_select.predbat_requested_mode', "Discharging") %}Command Discharging (PV First)
          {% elif is_state('input_select.predbat_requested_mode', "Freeze Discharging") %}Maximum Self Consumption
          {% endif %}
    - choose:
        # Set charging limit to 0 when requested mode is Freeze Charging
        # Docs:
        #  Freeze charging - The battery is charging but the current battery level (SoC) is frozen (held). Think of it
        #  as a charge to the current battery level. The grid or solar covers any house load. If there is a shortfall of
        #  Solar power to meet house load, the excess house load is met from grid import, but if there is excess Solar
        #  power above the house load, the excess solar will be used to charge the battery
        # In Sigenergy, this is effectively "self consumption" mode with discharging prohibited
        - conditions:
            - condition: state
              entity_id: input_select.predbat_requested_mode
              state: "Freeze Charging"
          sequence:
            - service: number.set_value
              data_template:
                entity_id: number.sigen_plant_ess_max_discharging_limit
                value: 0
            - service: number.set_value
              data_template:
                entity_id: number.sigen_plant_grid_export_limitation
                value: 0

        # Set charging limit to 0 when requested mode is Freeze Discharging
        # Docs:
        #  Freeze exporting (mapped to Freeze Discharging in sigenergy_sigenstor.yaml) - The battery is in demand mode,
        #  but with charging disabled. The battery or solar covers the house load. As charging is disabled, if there is
        #  excess solar generated, the current SoC level will be held and the excess solar will be exported. If there is
        #  a shortfall of generated solar power to meet the house load, the battery will discharge to meet the extra load.
        # In Sigenergy, this is effectively "self consumption" mode with charging prohibited
        - conditions:
            - condition: state
              entity_id: input_select.predbat_requested_mode
              state: "Freeze Discharging"
          sequence:
            - service: number.set_value
              data_template:
                entity_id: number.sigen_plant_ess_max_charging_limit
                value: 0

        # If neither of the above conditions are met, set the limits to the input numbers
        - conditions:
            - condition: not
              conditions:
                - condition: state
                  entity_id: input_select.predbat_requested_mode
                  state: "Freeze Charging"
                - condition: state
                  entity_id: input_select.predbat_requested_mode
                  state: "Freeze Discharging"
          sequence:
            - service: number.set_value
              data_template:
                entity_id: number.sigen_plant_ess_max_charging_limit
                value: "{{ [(states('input_number.charge_rate') | float / 1000) | round(2), states('sensor.sigen_inverter_ess_rated_charge_power') | float] | min}}"
            - service: number.set_value
              data_template:
                entity_id: number.sigen_plant_ess_max_discharging_limit
                value: "{{ [(states('input_number.discharge_rate') | float / 1000) | round(2), states('sensor.sigen_inverter_ess_rated_discharge_power') | float] | min}}"

- id: "automation_sigen_ess_max_charging_limit_input_number_action"
  alias: "Predbat max charging limit action"
  description: "Mapper from input_number.charge_rate to number.sigen_plant_ess_max_charging_limit"
  triggers:
    - trigger: state
      entity_id: input_number.charge_rate
  action:
    - action: number.set_value
      target:
        entity_id: number.sigen_plant_ess_max_charging_limit
      data:
        value: "{{ (states('input_number.charge_rate')| float / 1000) | round(2) }}"
  mode: single

- id: "automation_sigen_ess_max_discharging_limit_input_number_action"
  alias: "Predbat max discharging limit action"
  description: "Mapper from input_number.discharge_rate to number.sigen_plant_ess_max_discharging_limit"
  triggers:
    - trigger: state
      entity_id: input_number.discharge_rate
  action:
    - action: number.set_value
      target:
        entity_id: number.sigen_plant_ess_max_discharging_limit
      data:
        value: "{{ (states('input_number.discharge_rate')| float / 1000) | round(2) | int }}"
  mode: single

- id: "automation_sigen_ess_backup_state_of_charge_input_number_action"
  alias: "Predbat Set Reserve Min action"
  description: "Mapper from input_number.predbat_set_reserve_min to number.sigen_plant_ess_backup_state_of_charge"
  triggers:
    - trigger: state
      entity_id: input_number.predbat_set_reserve_min
  action:
    - action: number.set_value
      target:
        entity_id: number.sigen_plant_ess_backup_state_of_charge
      data:
        value: "{{ states('input_number.predbat_set_reserve_min') | int }}"
  mode: single

F17HEH avatar Nov 07 '25 16:11 F17HEH

looping in @azebro and @TypQxQ

thanks for this, just to confirm, your changes are to the EMS control mode for Freeze Charging (was 'Maximum Self Consumption', now 'Command Discharging (PV First)' - same as Charging) AND additionally set 'number.sigen_plant_grid_export_limitation' to zero as well as setting 'number.sigen_plant_ess_max_discharging_limit' to zero?

The charge_stop_service (which is also called to stop Freeze Charge, Freeze Discharge and Discharging) sets Predbat to Demand mode

Looking at the automation, the else branch of the conditions (not freeze charge and not freeze discharge) only sets number.sigen_plant_ess_max_charging_limit and number.sigen_plant_ess_max_discharging_limit

Surely it should be reversing the effects of any other modes, so needs to set number.sigen_plant_grid_export_limitation to a default value?

You also said:

Ok this also looks to effect the Freeze discharge also as this is only available in 3 & 4

Image Currently dont have export (awaiting DNO) so cant test this fully but think this should work

If you set to Command Charging (PV First)

number.sigen_plant_ess_max_charging_limit == 0 number.sigen_plant_grid_export_limitation == 100

I don't see any changes to freeze discharge in the automation

gcoan avatar Nov 08 '25 20:11 gcoan

So from the testing ive done when its setting to demand the values are set correctly, might be worth including the reset of the values on the change away from Freeze charging as a catch all. Max value on the field is 100 iirc.

F17HEH avatar Nov 08 '25 20:11 F17HEH

might be worth holding off on any changes to this until i get export and can make sure its not impacting that side of the code.

F17HEH avatar Nov 08 '25 20:11 F17HEH

side note, is there a discord or slack - id like to get more involved if possible?

F17HEH avatar Nov 08 '25 20:11 F17HEH

So from the testing ive done when its setting to demand the values are set correctly, might be worth including the reset of the values on the change away from Freeze charging as a catch all. Max value on the field is 100 iirc.

It just seemed concerning that you set the export limit when freeze charging but never set it back when going to Demand mode.

I'm in no rush to incorporate changes, do you know when you will get your export MPAN? I'd also like input from the other people involved in the Sig template just to make sure they're happy as I don't have one so have to rely on what others tell me.

There isn't a discord or slack channel, there's a predbat facebook group but I don't have FB so have never seen it. I help Trefor (the author of Predbat) out with responding to github issues. Most of the documentation is re-written and expanded by me, and I do do some bug fixes but all the heavy lifting is Trefor. There's also a small group of other predbat users I chat with on the givenergy beta forum, can join you in there, but we all have givenergy inverters not Sig (although at least one does lust after a Sig!).

gcoan avatar Nov 08 '25 20:11 gcoan

So from the testing ive done when its setting to demand the values are set correctly, might be worth including the reset of the values on the change away from Freeze charging as a catch all. Max value on the field is 100 iirc.

It just seemed concerning that you set the export limit when freeze charging but never set it back when going to Demand mode.

How would I do that? Sorry can't work it out in the code. As I think your logic is correct. When coming out of freeze charge it will need to set to 100 again.

Hoping to get mpan for export in a few weeks

UPDATE

Think ive spotted it in the automation. Have added and now it looks like this.

choose:
  - conditions:
      - condition: state
        entity_id: input_select.predbat_requested_mode
        state: Freeze Charging
    sequence:
      - data_template:
          entity_id: number.sigen_plant_ess_max_discharging_limit
          value: 0
        action: number.set_value
      - data_template:
          entity_id: number.sigen_plant_grid_export_limitation
          value: 0
        action: number.set_value
  - conditions:
      - condition: state
        entity_id: input_select.predbat_requested_mode
        state: Freeze Discharging
    sequence:
      - data_template:
          entity_id: number.sigen_plant_ess_max_charging_limit
          value: 0
        action: number.set_value
  - conditions:
      - condition: not
        conditions:
          - condition: state
            entity_id: input_select.predbat_requested_mode
            state: Freeze Charging
          - condition: state
            entity_id: input_select.predbat_requested_mode
            state: Freeze Discharging
    sequence:
      - data_template:
          entity_id: number.sigen_plant_ess_max_charging_limit
          value: >-
            {{ [(states('input_number.charge_rate') | float / 1000) | round(2),
            states('sensor.sigen_inverter_ess_rated_charge_power') | float] |
            min}}
        action: number.set_value
      - data_template:
          entity_id: number.sigen_plant_ess_max_discharging_limit
          value: >-
            {{ [(states('input_number.discharge_rate') | float / 1000) |
            round(2), states('sensor.sigen_inverter_ess_rated_discharge_power')
            | float] | min}}
        action: number.set_value
      - data_template:
          entity_id: number.sigen_plant_grid_export_limitation
          value: 100
        action: number.set_value

F17HEH avatar Nov 09 '25 23:11 F17HEH

That's the sort of thing I was expecting 👍

gcoan avatar Nov 10 '25 00:11 gcoan

OK so this needs some more thought, With freeze charging setting the export to 0 ive got into a situation that my battery is full so need to export and its not.

Ive changed it back to not setting this and will monitor but can @TypQxQ maybe weigh in with some thoughts?

The issues are

In Command Discharge PV First

  • Excess solar is exported and not put in the battery

In Command Charging consume PV first

  • The battery charges from the grid

In Max self consumption

  • Options to restrict the battery discharge do not work

This is what im working from for info on what will work when. Just frustrating you cant set some things in some modes.

https://b2b.aprilice.com/se_fi/mpattachment/file/download/id/778/

Only thing i can think is to put in some automation that changes the export limit when the battery is at 100% and the generation is over demand. What you think?

F17HEH avatar Nov 11 '25 13:11 F17HEH

Only thing i can think is to put in some automation that changes the export limit when the battery is at 100% and the generation is over demand. What you think?

that would be a horrible bodge, especially as generation and demand can vary all the time, you risk having an automation pinging on and off frequently.

gcoan avatar Nov 11 '25 14:11 gcoan

Yeah that was also my thoughts. Really not sure where to go with this now.

Could look to change the mode selected when solar production is predicted to be high to Demand, this would get round the export issue?

F17HEH avatar Nov 11 '25 14:11 F17HEH

or do i have to just suck it up and use Max consumption and just see how it goes with using the battery when the plan is expecting it to be held? Feel this is a fail for me (hate to be beaten)

F17HEH avatar Nov 11 '25 14:11 F17HEH

Suggest you get input from other sig openers as to their thoughts, but from a predbat perspective, predbat can cope fine if you decide your inverter doesn't have a freeze charge setting, it just won't use try to apply it.

The advantage of freeze charge for me is that predbat can run the house off grid import when rates are such that it's not worth charging the battery from the grid. I'm on Octopus Cosy at the moment, import is 14.05p, my export is 15p, so after losses they're about the same and there's no material advantage to charging, basically predbat uses it like a charge hold, holding the current SoC level and running off grid import less any solar generation. Charging the battery off excess solar is almost a secondary consideration.

e.g. you can see periods of freeze charge in the cheap Cosy periods:

image

Whilst its not what Predbat expects, how about you use:

In Command Discharge PV First

Excess solar is exported and not put in the battery

Predbat will get the calculation of PV charging the battery wrong, but this is almost a secondary consideration, and it'll recalculate the plan every 10 minutes anyway to correct the discrepancy

gcoan avatar Nov 11 '25 16:11 gcoan

So im using Agile so charging for me is a good thing when the rates are cheap :).

Ill see what its like without freeze charge and let you know.

F17HEH avatar Nov 11 '25 16:11 F17HEH

Reading through the sequence under the "Else" condition (not Freeze Charging/Discharging), I'm surprised by the steps to set number.sigen_plant_ess_max_charging_limit based on input_number.charge_rate (and ditto discharge limit), because the two automations immediately below set that output based on that input already.

Is the reasoning for this that Predbat might change mode without altering input_number.charge_rate, requiring the values to be (re-)sent to the Sigenergy system?

(If the automations below are needed, and the clamping of the specified value to sensor.sigen_inverter_ess_rated_charge_power is required/best practice, that should be applied in those automations as well)

DFEvans avatar Nov 16 '25 20:11 DFEvans

Reading through the sequence under the "Else" condition (not Freeze Charging/Discharging), I'm surprised by the steps to set number.sigen_plant_ess_max_charging_limit based on input_number.charge_rate (and ditto discharge limit), because the two automations immediately below set that output based on that input already.

Is the reasoning for this that Predbat might change mode without altering input_number.charge_rate, requiring the values to be (re-)sent to the Sigenergy system?

(If the automations below are needed, and the clamping of the specified value to sensor.sigen_inverter_ess_rated_charge_power is required/best practice, that should be applied in those automations as well)

I agree, removed from the first automation as the input_number automations will handle this as soon as predbat sets the charge/discharge rate https://github.com/springfall2008/batpred/issues/2077#issuecomment-3559824440

gcoan avatar Nov 20 '25 20:11 gcoan