GivEnergy Solar Inverter

These services were deprecated a couple of months ago because it’s not possible to dynamically change the slider limits in services. There are now entities for number.battery_charge_power and number.battery_discharge_power which change behaviour based on the detected model.

The best on offer at the moment is a combination of:

  • sensor.battery_mode which aims to mirror what you see in the GE app.
  • The 4 sensors binary_sensor.battery_dis/charge_slot_1/2 which indicate whether you’re actually in an active slot.

I don’t think there’s a case for extending the integration beyond these, as I think we’re in to the more user-specific setups which can be covered with template sensors.

Hopefully that gives you everything required but I’m always open to suggestions.

1 Like

Thanks I must have missed that somehow.

The only number entity I had in Home Assistant (from any integration) was number.battery_ac_charge_limit, so I checked HACS and for some reason I am still on 1.6.2 and have seen no notifications for updates - the latest is 1.8.0 (I receive updates for and update other integrations regularly so that’s weird). So, I’m downloading that, hopefully that will provide me with the new entities.

Maybe I am missing something obvious but if I add a new condition for Device => Inverter => I don’t see an option that lets me select the sensor.battery_mode value. This would probably cover what I’m asking for if I could do that.

I’m not that familiar with the YAML editing, maybe it can be done there directly if it’s not an option in the baked in ones, but I don’t know how to query against that parameter.

Quick update, the new switches for charge, discharge and eco work great, as do the new number entities for charge/discharge rate :+1:

It appears that if I turn on charge or discharge, these override eco, even if eco is turned on, so I haven’t yet seen a need to turn it off for any reason - has anyone seen the need?

I have an input_boolean containing Auto, Import, Export and Hold (essentially mirroring the app functionality) and use an automation to act on any change to the Boolean.

In case it’s helpful to anyone else, the following automation logic appears to work:

Auto:

  • turn off ac_charging
  • turn off dc_discharging
  • turn on eco (just in case it is off for some reason)
  • set charge_ and discharge_rate_limit to full (3600W)

Import:

  • turn off dc_discharging
  • turn on ac_charging
  • set charge_ and discharge_rate_limit to full (3600W)

Export:

  • turn off ac_charging
  • turn on dc_discharging
  • set charge_ and discharge_rate_limit to full (3600W)

Hold:

  • turn off dc_discharging
  • turn off ac_charging
  • turn on eco (not sure if this is needed)
  • set charge_rate_limit to full (3600W)
  • set discharge_rate_limit to zero (0W)
1 Like

Completely random observation but has anyone else noticed discharge_slot_2 being enabled? mine suddenly decided to turn itself on overnight, and thus the solar all day today wasn’t charging the battery. It was set to 00:00 - 16:00.

I have discharge_slot_1 set to 16:00 - 22:00 so the battery doesn’t charge after the Flux peak rate kicks in.

As I understand it, discharge_slot_1 is the only one which can be modified or used currently (same applies to both export and discharge modes), with GE having variables for slot_2 for both charge and discharge, but those not being something that is usable.

I don’t think this application ever updates slot_2 but I thought it was worth asking the question here.

Heya. Big congrats for how well this has developed in the last year. I’d been using a raspberry pi and didn’t get time to see that this has now progressed almost to the point where I can remove that. If you find time, can we get the following power readings added?

grid import power
battery to grid
battery to house
EPS power
grid to battery
grid to house
solar to battery
solar to grid
solar to house

I know some of these can be calculated, but they’re helpful for some of my automations including firing the immersion heater. They’re also great for setting up this kind of graphical display.

@cdpuk
I have been looking at adding the REBOOT function ( to givenergy-local) which I’ve done locally, but it needs the givenergy-modbus client to be updated, as REBOOT is only in pre-1.0.0. I’ve being looking at the latest givenergy-modbus and it has changed massively from 0.10.1. Do you have any plans to update to the new givenergy-modbus ? Looks like a big job to me. I have played around enough to work out I have no idea how to do it !

Sorry - realised that EPS is already there.

I’ve had a go at this. I followed the givtcp methodology for calculations and added extra classes to sensor.py. It feels a bit clunky - because of the class structure, each value is calculated from scratch - but it seems to work (except grid to battery giving an odd value - will look into this further).

I also replaced the grid export power (that I guess would have given a negative value in an import event) with grid import power and a new grid export power - derived the same way as in the givtcp code.

Hi Can anyone tell me what card is this please?
Is there a corresponding one for import

does GivTCP expose total energy entitles for individual CT clamps? I can see total PV but I’d like to monitor each array (north / south) separately.
Alternatively as I can access the myenergi CT clamp power directly, any tips getting a daily energy from that - I’ve tried utility meter but its giving me figures way off beam - like 43000w when I’ve generated maybe 15kwh from that array (looking at the solar inverter)

Hi,

Trying to setup a new Inverter/Battery installation, I’m getting the following error in the logs:

File “/usr/local/lib/python3.11/site-packages/givenergy_modbus/model/inverter.py”, line 39, in from_serial_number
raise UnknownModelError(f"Cannot determine model number from serial number {serial_number}")
givenergy_modbus.model.inverter.UnknownModelError: Cannot determine model number from serial number FA

Looking in the givenergy_modbus library, it seems the the prefix FA* isn’t recognised?

    serial_prefix_to_models_lut = {
        'CE': cls.AC,
        'ED': cls.Gen2,
        'EA': cls.Gen2,
        'SA': cls.Hybrid,
        'SD': cls.Hybrid,
    }

Any ideas on how/if I can proceed? The inverter should be the Gen3 Hybrid

To catch up on a few things:

@reidjr the intention is to update givenergy-modbus at some point. This will be much easier when it gets released formally.

@lexathon there’s definitely scope to add the derived power values. However summer is quite a busy time for me so it might take me a while to get around to. If you have a branch somewhere that can be used as a reference, that would help.

@hollytreecook that service is used to schedule grid export. For scheduled charging you’re looking for “GivEnergy Local: Enable timed charging”

@mrklawuk if that’s really a GivTCP specific question, I can’t comment - this integration is completely separate. The integration does not currently expose energy values for each array but this could be added.

@Geheee this is due to the old (but latest) givenergy-modbus version. This is becoming increasingly common so might have to consider some sort of tactical workaround.

Hi Andy2,
I am trying to replicate your logic, but the Inverter doesn’t seem to want to follow. Starting point is:

  • ac_charging: off
  • charge_rate_limit: 3600
  • dc_discharging: off
  • discharge_rate_limit: 3600
  • battery_eco_mode: on

battery_mode is reported as “Eco”

For export, if I:

  1. Turn off ac_charging: already off.
  2. Turn on dc_discharging: battery_mode changes to “Timed Discharge”
  3. set charge_ and discharge_rate_limit to 3600: already at 3600.

This only seems to disable charging? It does not discharge the battery, but exports excess solar generation to the grid.

I then tried adjusting the starting point by calling the “Activate timed export mode” service for 00:00 to 23:59. Running the above sequence then drained the battery. It seems the inverter needs a “Battery Discharge Slot” to be on to work?

Do you mind sharing your script/automation so I can understand better how you’ve made it work with just the switches?

TIA.

Thanks for the response.

Yes, I see there is a v1 version of the modbus library in the works, which looks to have a very different approach here!

For now, I have something working with a separate MQTT and the GivTCP container, but this solution does look neat, so I will continue to follow it and see when it can support my setup.

Thanks @cdpuk

Yeah - I did a branch with some additions and tweaks to sensor.py

I’ve tried to replicate the modbus calculation section as best as possible, but there’s a different class structure in place, so it feels a little clunky to me. My OOP skills may not be the best, and there may be a neater solution.

https://github.com/lexathon/givenergy-local/blob/5814fc840cb0b7d80e75e82b0663049066edbd77/

Solar was finally commissioned today, and this is absolutely wonderful! Thanks so much for this, it feels great to be able to take control of my own kit in my own house without an internet connection :slight_smile:

Hi there,

Here’s my automation code, it largely does what you have already tried in terms of export, so I’m not sure why it doesn’t work for you.

Note you might want to edit the Export action, I have something unique there to pace Export using the discharge limit, so that it exports whatever charge it has over the course of the 3 hour Flux Export window (otherwise you empty the battery and start paying peak rate). Obviously I usually charge it beforehand but sometimes it isn’t full, and the Gen2 can empty from full inside the two hours anyway.

Ps. I have what as far as I know is an unrelated bug to deal with at the moment (raised as an issue on Github): Hold appears to be unable.to limit discharge to zero, any number below 370-380 W changes the number entity successfully, but results in 370-382 W of discharge regardless (unless there is solar available).

Hope this helps!

alias: "Battery: Change Mode"
description: ""
trigger:
  - platform: state
    entity_id:
      - input_select.battery_mode
condition: []
action:
  - if:
      - condition: state
        entity_id: input_select.battery_mode
        state: Auto
    then:
      - service: switch.turn_off
        data: {}
        target:
          entity_id: switch.battery_ac_charging
      - service: switch.turn_off
        data: {}
        target:
          entity_id: switch.battery_dc_discharging
      - service: switch.turn_on
        data: {}
        target:
          entity_id: switch.battery_eco_mode
      - service: number.set_value
        data:
          value: "3600"
        target:
          entity_id: number.battery_charge_power_limit
      - service: number.set_value
        data:
          value: "3600"
        target:
          entity_id: number.battery_discharge_power_limit
    alias: Auto
  - if:
      - condition: state
        entity_id: input_select.battery_mode
        state: Discharge
      - condition: state
        entity_id: input_boolean.lock_battery_mode
        state: "off"
    then:
      - service: switch.turn_off
        data: {}
        target:
          entity_id: switch.battery_ac_charging
      - service: switch.turn_off
        data: {}
        target:
          entity_id: switch.battery_dc_discharging
      - service: switch.turn_on
        data: {}
        target:
          entity_id: switch.battery_eco_mode
      - service: number.set_value
        data:
          value: "0"
        target:
          entity_id: number.battery_charge_power_limit
      - service: number.set_value
        data:
          value: "3600"
        target:
          entity_id: number.battery_discharge_power_limit
    alias: Discharge
  - if:
      - condition: state
        entity_id: input_select.battery_mode
        state: Charge
    then:
      - service: switch.turn_off
        data: {}
        target:
          entity_id: switch.battery_dc_discharging
      - service: switch.turn_on
        data: {}
        target:
          entity_id: switch.battery_ac_charging
      - service: number.set_value
        data:
          value: "3600"
        target:
          entity_id: number.battery_charge_power_limit
      - service: number.set_value
        data:
          value: "3600"
        target:
          entity_id: number.battery_discharge_power_limit
    alias: Charge
  - if:
      - condition: state
        entity_id: input_select.battery_mode
        state: Hold
    then:
      - service: switch.turn_off
        data: {}
        target:
          entity_id: switch.battery_ac_charging
      - service: switch.turn_off
        data: {}
        target:
          entity_id: switch.battery_dc_discharging
      - service: switch.turn_on
        data: {}
        target:
          entity_id: switch.battery_eco_mode
      - service: number.set_value
        data:
          value: "3600"
        target:
          entity_id: number.battery_charge_power_limit
      - service: number.set_value
        data:
          value: "0"
        target:
          entity_id: number.battery_discharge_power_limit
    alias: Hold
  - if:
      - condition: state
        entity_id: input_select.battery_mode
        state: Export
    then:
      - service: switch.turn_off
        data: {}
        target:
          entity_id: switch.battery_ac_charging
      - service: switch.turn_on
        data: {}
        target:
          entity_id: switch.battery_dc_discharging
      - if:
          - condition: state
            entity_id: input_select.grid_export_tariff_type
            state: Flux
          - condition: time
            after: "16:00:00"
            before: "19:00:00"
        then:
          - service: number.set_value
            data:
              value: "{{ states('sensor.battery_level') | float * 1000 / 3 }}"
            target:
              entity_id: number.battery_discharge_power_limit
        alias: >-
          Pace the export if it is for the 4-7 Flux period, otherwise export at
          max speed
        else:
          - service: number.set_value
            data:
              value: "3600"
            target:
              entity_id: number.battery_discharge_power_limit
      - service: number.set_value
        data:
          value: "3600"
        target:
          entity_id: number.battery_charge_power_limit
    alias: Export
mode: queued
max: 10

1 Like

I notice that GivTCP developer has chosen to clone givenergy-modbus directly into his own project, and is developing from 10.1 base rather than using the givenergy-modbus modules. Patching your scripts with that directory structure might be worth considering, as I think the community uses givenergy-local and givtcp pretty interchangeably. Certainly looks that way from many (other) forum posts. Personally I like the standalone integration and appreciate your efforts. Also looks as if there are more modbus changes needed for the next firmware release for CRC checking.

1 Like

Just to confirm, I’m running the newest pre release firmware on a gen2 inverter (911) . That changes something in the CRC checking, and the 10.1 modbus module does not support it as is. So 909 is safe to upgrade to, but stop there, or you will break givenergy-local.

1 Like