Energy concepts Germany solar storage Ampere.Storage.Pro

Hello guys,

I have a new solar installation with battery, inverter and all. Its from Energie Konzepte Deutschland. They system is called Ampere.Storage.Pro. It looks a lot like SAJ Series HS2.

I have not yet found an integration, but was able to reverse engineer the REST API. I was able to extract 44 different values. Kudos to this site which helped me a lot.

I have a set of Restful sensors to collect all the information form the REST API.

I am currently struggling to use the variables in the energy dashboard. I am happy to provide input for people able to create an integration. I wanted to use the sensors in the energy dashboard. I would love to get some help to get this resolved.

Lets start with the battery. I have the following two entities defined:

- platform: rest
  resource: http://10.0.30.130/rest/items/sajhybrid_battery_94_HSR2103J2323E18072_battery_totalDischargeEnergy
  # 2.13 kWh
  name: solar_battery_totalDischargeEnergy
  value_template: '{{ value_json.state | regex_replace("([^\d.-]+)","") | float }}'
  unit_of_measurement: "kWh"
  device_class: energy
  state_class: measurement
- platform: rest
  resource: http://10.0.30.130/rest/items/sajhybrid_battery_94_HSR2103J2323E18072_battery_totalChargeEnergy
  # 0.28 kWh
  name: solar_battery_totalChargeEnergy
  value_template: '{{ value_json.state | regex_replace("([^\d.-]+)","") | float }}'
  unit_of_measurement: "kWh"
  device_class: energy
  state_class: measurement

Both entites can be selected now in the battery section of the energy dashboard, however some error are shown in the dashboard. The “last reset is missing”.

I am done for now, need some sleep. HOwever, I would love to get some help to be able to create all the sensors for the energy dashboard.

These are the parameter I can extract:

battery_mode, 0
battery_modeConverter, OFF
battery_power, 22 W
battery_stateOfCharge, 20.00 %
battery_temperature, 13.0 °C
battery_totalChargeEnergy, 0.32 kWh
battery_totalDischargeEnergy, 2.15 kWh
# The following are linux timestamps in UTC plus a current value.
harmonized_power_in, 1708550445000|28.0 W
harmonized_power_out, 1708550445000|0.0 W
harmonized_work_in, 1708550400000|0.0 Ws
harmonized_work_out, 1708550400000|0.0 Ws
harmonized_mppt_dc_power, 1708550445000|0.0 W
harmonized_mppt_dc_work, 1708550400000|0.0 Ws
harmonized_power_in, 1708550445000|28.0 W
harmonized_power_out, 1708550445000|0.0 W
harmonized_work_in, 1708550400000|7155.0 Ws
harmonized_work_out, 1708550400000|0.0 Ws
inverter_activePower, -28.0 W
inverter_activePowerRaw, 70 W
inverter_apparentPower, 306 W
inverter_energyIn, 168035.0 Ws
inverter_energyOut, 7787450.0 Ws
inverter_pvEnergy, NULL
inverter_pvPower, 0 W
inverter_pvPowerMPPT, 0 W
inverter_selfConsumptionPower, 713 W
limitable_getActualProductionPower_P_active, -28.0 W
harmonized_power_in, 1708550445000|725.5 W
harmonized_power_out, 1708550445000|0.0 W
harmonized_work_in, 1708550400000|257647.5 Ws
harmonized_work_out, 1708550400000|0.0 Ws
metering_getConsumption_P_active, 717.0 W
metering_getProduction_P_active, 717.0 W
powermeter_phase_r_export, 0.32 kWh
powermeter_phase_r_import, 0.51 kWh
powermeter_phase_s_export, 0.00 kWh
powermeter_phase_s_import, 1.57 kWh
powermeter_phase_t_export, 0.04 kWh
powermeter_phase_t_import, 1.05 kWh
powermeter_real_power_1, 152 W
powermeter_real_power_2, 325 W
powermeter_real_power_3, 240 W
powermeter_realPower, 717.0 W
powermeter_totalExport, 147280.0 Ws
powermeter_totalImport, 10433527.5 Ws

These additional ones are there as well in the API, but yet with NULL values.

harmonized_power_buffered_from_grid, NULL
harmonized_power_buffered_from_producers, NULL
harmonized_power_buffered, NULL
harmonized_power_consumed_from_grid, NULL
harmonized_power_consumed_from_producers, NULL
harmonized_power_consumed_from_storage, NULL
harmonized_power_consumed, NULL
harmonized_power_in, NULL
harmonized_power_out_from_producers, NULL
harmonized_power_out_from_storage, NULL
harmonized_power_out, NULL
harmonized_power_produced, NULL
harmonized_power_released, NULL
harmonized_power_self_consumed, NULL
harmonized_power_self_supplied, NULL
harmonized_work_buffered_from_grid_total, NULL
harmonized_work_buffered_from_grid, NULL
harmonized_work_buffered_from_producers_total, NULL
harmonized_work_buffered_from_producers, NULL
harmonized_work_buffered_total, NULL
harmonized_work_buffered, NULL
harmonized_work_consumed_from_grid_total, NULL
harmonized_work_consumed_from_grid, NULL
harmonized_work_consumed_from_producers_total, NULL
harmonized_work_consumed_from_producers, NULL
harmonized_work_consumed_from_storage_total, NULL
harmonized_work_consumed_from_storage, NULL
harmonized_work_consumed_total, NULL
harmonized_work_consumed, NULL
harmonized_work_in_total, NULL
harmonized_work_in, NULL
harmonized_work_out_from_producers_total, NULL
harmonized_work_out_from_producers, NULL
harmonized_work_out_from_storage_total, NULL
harmonized_work_out_from_storage, NULL
harmonized_work_out_total, NULL
harmonized_work_out, NULL
harmonized_work_produced_total, NULL
harmonized_work_produced, NULL
harmonized_work_released_total, NULL
harmonized_work_released, NULL
harmonized_work_self_consumed_total, NULL
harmonized_work_self_consumed, NULL
harmonized_work_self_supplied_total, NULL
harmonized_work_self_supplied, NULL
harmonized_power_out, NULL
harmonized_work_out_total, NULL
harmonized_work_out, NULL
1 Like

Hi,
I read out the values that seemed interesting to me as follows (I hope the order of the data in the field is always the same…):

rest:
  - resource: "http://EVX01-200003403.home/rest/items"
    scan_interval: 300
    sensor:
      - name: "Battery Temperature"
        value_template: "{{ value_json[14].state[:-2] | float | round  }}"
        unit_of_measurement: "°C"
      - name: "Battery Power"
        value_template: "{{ value_json[44].state[:-1] | float | round }}"
        unit_of_measurement: "W"
      - name: "Self Consumption Power"
        value_template: "{{ value_json[73].state[:-1] | float | round }}"
        unit_of_measurement: "W"
      - name: "Battery Mode"
        value_template: "{{ value_json[74].state | int }}"
        unit_of_measurement: "[-1;0;1]"
      - name: "PV Power"
        value_template: "{{ value_json[76].state[:-1] | float | round }}"
        unit_of_measurement: "W"
      - name: "Battery SoC"
        value_template: "{{ value_json[82].state[:-1] | float | round }}"
        unit_of_measurement: "%"
      - name: "PowerOut"
        value_template: "{{ value_json[9].state[14:-1] | float | round }}"
        unit_of_measurement: "W"
      - name: "PowerIn"
        value_template: "{{ value_json[67].state[14:-1] | float | round }}"
        unit_of_measurement: "W"
      - name: "Total Import Energy"
        value_template: "{{ value_json[48].state[:-2] | float | multiply(0.00000027777) | round }}"
        unit_of_measurement: "kWh"
      - name: "Total Export Energy"
        value_template: "{{ value_json[88].state[:-2] | float | multiply(0.00000027777) | round }}"
        unit_of_measurement: "kWh"
      - name: "Total Inverter Energy"
        value_template: "{{ value_json[68].state[:-2] | float | multiply(0.00000027777) | round }}"        
        unit_of_measurement: "kWh"

Hello everyone,
this thread and the GitHub discussion helped me immensely to get all the sensor data working in Home Assistant that I needed for the Energy Dashboard as well as a live view with the current wattages. This is the Code of my configuration.ymal
If someone that reads this that does not know how to edit it Youtube Video .
In the code below you need to change every IP adress to the adress of your Smartbox, make sure it is a fixed adress in your Router.
You also need to change the serial number of the battery
94_HSR2103J2320E16060 to your serial that is found at

http://IPofYourSmartbox/rest/items in one of the first lines

Every Unit is converted to W or kwh, the originals are sometimes in WS with maybe a 1,0354E+7 notation. I am uncertain when this E notation appears and if it may break the code when it is not there or switches to a different format.
Please excuse my rather lengthy sensor names. You can change them if you want. Finally a small rant to the EKD support, they refused to release any documentation of this API. The 4 People in support that I talked to couldn’t help or wouldn’t.

# Loads default set of integrations. Do not remove.
default_config:

# Load frontend themes from the themes folder
frontend:
  themes: !include_dir_merge_named themes

sensor:
    #Total battery Discharge in kwh
  - platform: rest
    resource: http://192.168.178.86/rest/items/sajhybrid_battery_94_HSR2103J2320E16060_battery_totalDischargeEnergy
    name: PV_battery_totalDischargeEnergy
    value_template: '{{ value_json.state | regex_replace("([^\d.-]+)","") | float }}'
    unit_of_measurement: "kWh"
    device_class: energy
    state_class: total_increasing
    scan_interval: 15

    #Total Battery Charge in kwh
  - platform: rest
    resource: http://192.168.178.86/rest/items/sajhybrid_battery_94_HSR2103J2320E16060_battery_totalChargeEnergy
    name: PV_battery_totalChargeEnergy
    value_template: '{{ value_json.state | regex_replace("([^\d.-]+)","") | float }}'
    unit_of_measurement: "kWh"
    device_class: energy
    state_class: total_increasing
    scan_interval: 15
    
    #Batttery charge/Discharge in W with negatives inverted for right Dashboard functionality
  - platform: rest
    resource: http://192.168.178.86/rest/items/sajhybrid_battery_94_HSR2103J2320E16060_battery_power
    name: PV_curernt_battery_power
    value_template: '{{ (value_json.state.split(" ")[0] | float) * -1 }}'
    unit_of_measurement: "W"
    device_class: energy
    state_class: measurement
    scan_interval: 15
    
    # Powermeterhouse in W
  - platform: rest
    resource: http://192.168.178.86/rest/items/sajhybrid_powermeter_94_HSR2103J2320E16060_powermeter_realPower
    name: PV_grid_current_powermeter_realPower
    value_template: '{{ value_json.state | regex_replace("([^\d.]+)","") | float }}'
    unit_of_measurement: "W"
    device_class: energy
    state_class: measurement
    scan_interval: 15
    
    #Solar power in W
  - platform: rest
    resource: http://192.168.178.86/rest/items/sajhybrid_inverter_94_HSR2103J2320E16060_inverter_pvPower
    name: PV_solar_current_inverter_pvPower
    value_template: '{{ value_json.state | regex_replace("([^\d.]+)","") | float }}'
    unit_of_measurement: "W"
    device_class: energy
    state_class: measurement
    scan_interval: 15
    
    # State Of Charge Battery in %
  - platform: rest
    resource: http://192.168.178.86/rest/items/sajhybrid_battery_94_HSR2103J2320E16060_battery_stateOfCharge
    name: PV_battery_stateOfCharge
    value_template: '{{ value_json.state | regex_replace("([^\d.]+)","") | float }}'
    unit_of_measurement: "W"
    device_class: energy
    state_class: measurement
    scan_interval: 15
    
    # Total Engergy out of the inverter I use this as total Solar Power produced but I'm not shure if this also includes energy out of the Battery
  - platform: rest
    resource: http://192.168.178.86/rest/items/sajhybrid_inverter_94_HSR2103J2320E16060_inverter_energyOut
    name: PV_solar_total_inverter_energyOut
    value_template: "{{(value_json.state.split(' ')[0] | float) * (0.00000027777)  }}"
    unit_of_measurement: "kWh"
    device_class: energy
    state_class: total_increasing
    scan_interval: 15
    
    
    
    
    # Powerneter Import Export
  - platform: rest
    resource: http://192.168.178.86/rest/items/sajhybrid_powermeter_94_HSR2103J2320E16060_powermeter_totalExport
    name: PV_grid_out_totalExport
    value_template: "{{(value_json.state.split(' ')[0] | float) * (0.00000027777)  }}"
    unit_of_measurement: "kWh"
    device_class: energy
    state_class: total_increasing
    scan_interval: 15

    
  - platform: rest
    resource: http://192.168.178.86/rest/items/sajhybrid_powermeter_94_HSR2103J2320E16060_powermeter_totalImport
    name: PV_grid_in_totalImport
    value_template: "{{ value_json.state[:-2] | float | multiply(0.00000027777)  }}"
    unit_of_measurement: "kWh"
    device_class: energy
    state_class: total_increasing
    scan_interval: 15
  
automation: !include automations.yaml
script: !include scripts.yaml
scene: !include scenes.yaml

1 Like

It will break. However there is an easy fix.

{{ “1e9” | regex_replace(“([^\d.e-]+)”, “”) | float }}

Hi,
instead of “total_inverter_energyOut” I use “inverter_pvPower” which seem to be the current wattage for me. This value gets summed up to KWh whcih I in turn use for the energy dashboard:

    #Solar power in W
  - platform: rest
    resource: http://192.168.10.11/rest/items/sajhybrid_inverter_94_HSR2103J2325E20061_inverter_pvPower
    name: PV_solar_current_inverter_pvPower
    value_template: '{{ value_json.state | regex_replace("([^\d.]+)","") | float }}'
    unit_of_measurement: "W"
    device_class: energy
    state_class: measurement
    scan_interval: 15

  - platform: integration
    source: sensor.PV_solar_current_inverter_pvPower
    name: PV_total_pvPower
    unit_prefix: k
    method: trapezoidal
    round: 2

Now my question: Did any of you manage to control the inverter and use the battery loading via grid feature?
I find the EKD solution not very intelligent. I would like something like this:
if price is low, battery below 30% and no sun for the next 8 hours, then load.
What do you think?

Isnt this something you can enable in the Ampere.IQ App? I have not tried it yet, bc my tibber contract starts only in May.

Yes, you can and I used it a bit. But it does not fullfill my expectations. You can charge up to a specific SoC depending on price. But if you get power from sun and the battery reached that SoC, it is not charged anymore, the energy goes to the grid. That’s why I wanted to implement a more flexible and weather dependend algorithm.

Reminder: This is an English Language only forum.

Ok, thanks for that hint. So I restart the discussion in English again.

Ulrich wrote something like that he managed to charge his battery via grid using modbus register 0x3644 with some value. I do not get the idea of that. So what registers need to be set with what values to charge the battery via grid?

More information in this repro

3 Likes

@melksem , sorry this is a misunderstanding. The adress 0x3644 is for the emergency power capacity. At this level the battery stops to discharge in normal “on_grid_mode”. During wintertime I would like to set this to i.e. 50%, because there is normaly not enough power comming from the solar panels to refill from 20% to a much higher level. I was thinking about an automatism, but have no idea.

Charging the battery from the grid should be possible, but I don’t have a solution for that. Currently this is not interesting for me, because I do not have a provider with dynamic tariffs. The GitHub solution mentioned by @Dawidh does currently not provide “Charging from grid”.

Thanks for clarifying that. Atm I am not able to even integrate the box using modbus. I tried the GitHub version as well as the one mentioned here: SAJ Solar inverter - #205 by stanus74
But no sensor is showing up nor do I get any useful info from the logs.
Despite that, I am able to read the box using a ModBus testing tool. So I have no clue, what I am doing wrong.

Thank you very much! GitLab sensor config (yaml)works great with my Amper Storage Pro with Modbus!

I followed the readme, and was able to create a dashboard based on the configured sensors.
(For the ones with problems, you need to create the folder ‚integrations‘ manually.)

But one Template I missed for the current house energy consumption. So I tried to calculate it via Template: inverter power - total active power - battery power.

- sensor:
    # House power consumption = inverter power - total active power - battery power 
      - name: House Active Power
        unique_id: house_active_power_consumption
        unit_of_measurement: W
        device_class: power
        state_class: measurement
        availability: >-
          {{ 
          not is_state('sensor.pv1_power', 'unavailable') 
          and not is_state('sensor.pv2_power', 'unavailable') 
          and not is_state('sensor.total_active_power', 'unavailable') 
          and not is_state('sensor.ampere_battery_power', 'unavailable') 
          }}
        state: "{{ (states('sensor.pv1_power') | int + states('sensor.pv2_power') | int + states('sensor.total_active_power') | int + states('sensor.ampere_battery_power') | int ) | int }}"

But it is not working. In the Dashboard the value is „unknown“, Strage is, that I get values, when I replace sensor. ampere_battery_power with another sensor, so it seems to have something to do with the battery_power sensor itself . But wenn i use it in a Widget/Card I See plausible values for battery_power.

But I do Not See any difference to the total_active_power Sensor configuration, which is working, when I use it in the Template formula.

Does someone have an idea how to correct the template or why I can Not use Sensor battery_power in the formula?

Thank you
Christian

1 Like

Hello,
I solved it and proposed following additional templates, that the Ampere Storage Pro can be added also in Energy Dashboard (via Riemann Sum Integral).

- sensor:
    # House power consumption = inverter - total active power - battery loading
      - name: House Active Power
        unique_id: house_active_power_consumption
        unit_of_measurement: W
        device_class: power
        state_class: measurement
        availability: >-
          {{ 
          not is_state('sensor.pv1_power', 'unavailable') 
          and not is_state('sensor.pv2_power', 'unavailable') 
          and not is_state('sensor.total_active_power', 'unavailable') 
          and not is_state('sensor.ampere_battery_power', 'unavailable') 
          }}
   #     state: "{{ (states('sensor.battery_power') | int) }}"
        state: "{{ (states('sensor.pv1_power') | int + states('sensor.pv2_power') | int + states('sensor.total_active_power') | int + states('sensor.battery_power') | int ) | int }}"


#Thanks to the forum were I find similar grid templates (the last two) in a post from „creis Christian“:
#https://community.home-assistant.io/t/solved-help-getting-a-value-from-negative-to-positive-in-template-1/411076

  - sensor:
      - name: Grid Power In
        unit_of_measurement: W
        state_class: measurement
        device_class: power
        state: >
          {% if states('sensor.total_active_power') | float(0) >= 0 %}
            {% set gridin = states('sensor.total_active_power') | float(0) %}
          {% else %}
            {% set gridin = 0 %}
          {% endif %}
          {{ gridin }}
        attributes:
          last_reset: '1970-01-01T00:00:00+00:00'

  - sensor:
      - name: Grid Power Out
        unit_of_measurement: W
        state_class: measurement
        device_class: power
        state: >
          {% if states('sensor.total_active_power') | float(0) <= 0 %}
            {% set gridout = states('sensor.total_active_power') | float(0) | abs %}
          {% else %}
            {% set gridout = 0 %}
          {% endif %}
          {{ gridout }}
        attributes:
          last_reset: '1970-01-01T00:00:00+00:00'

1 Like

Very nice and thanks for the tip with the integrations folder.

I only have to your code to my rest_ampere_storage_pro.yaml right? or can you dm me your config.
Thanks!

hey all,

thanks to your guidance I came up with a sensor YAML that (at least for me) solves all the issues previously encountered. It pulls all values from the REST interface of the Ampere.IQ Smartbox.
In the hope that it could be helpful to others as well: GitHub - daduke/Ampere.IQ-HA: Home Assistant sensor for Ampere Pro PV

best,
-d

2 Likes

You’ve set the time to get the data to 15 seconds. Are there any reasons against to set it to a shortet period? E.g. 5 seconds?

well I had to pick something… I’m sure you can go lower.