Solax X1 Hybrid G4 Worked Example

I have a Solax X1 Hybrid G4 (Solar PV and Battery).

I could not get the Solax Integration working with the required proxy (issues described here: SolaX inverter Wifi Reverse Proxy setup), so I went down the REST API road.

There is lots of advice about on this forum (including Energy dashboard and Solax grid and battery integration, PV SolaX inverter cloud sensors via API). They are long threads that have evovled. So I’ve put this together as a complete worked example, to get it all working with the HA Energy integration, using Solax as the sole source of data.

The end result…

Here is how I did it…

Pre Requisite

You’ll need a Solax Cloud Account, and your API key details.

Create REST Sensor

First create the REST API sensors:

sensor:
  - platform: rest
    resource: https://www.solaxcloud.com/proxyApp/proxy/api/getRealtimeInfo.do?tokenId=XXX&sn=YYY
    name: "Solax"
    json_attributes_path: "$.result"
    json_attributes:
      - yieldtoday
      - yieldtotal
      - acpower
      - uploadTime
      - inverterStatus
      - feedinpower
      - feedinenergy
      - consumeenergy
      - soc
      - batPower
      - powerdc1
      - batStatus
    value_template: 'Active'  # dummy value, not used; avoids the "State max length is 255 characters" error

Replace XXX and YYY with the tokenId and SerialNumber found in the Solax Cloud respectively.

EDIT 12 Dec 2022

For other inverters / configurations you may need to edit the json_attributes list above, and make corresponding changes to the template below.
To see what your inverter returns point a web browser at the link below (replacing XXX and YYY):

https://www.solaxcloud.com/proxyApp/proxy/api/getRealtimeInfo.do?tokenId=XXX&sn=YYY

Create Template Sensors for Solax…

template:
  - sensor:
    - name: "Solax Yield Today"
      state: "{{ state_attr('sensor.solax', 'yieldtoday') }}"
      unit_of_measurement: "kWh"
      unique_id: solax_2
      icon: mdi:flash
      device_class: energy
      state_class: total_increasing

    - name: "Solax Yield Total"
      state: "{{ state_attr('sensor.solax', 'yieldtotal') }}"
      unit_of_measurement: "kWh"
      unique_id: solax_3
      icon: mdi:flash
      device_class: energy
      state_class: total_increasing

    - name: "Solax Inverter Power Total"
      unit_of_measurement: "W"
      state: "{{ state_attr('sensor.solax', 'acpower') }}"
      unique_id: solax_4
      icon: mdi:flash
      device_class: energy
      state_class: measurement

    - name: "Solax Upload Time"
      state: >
        {% set time = state_attr('sensor.solax', 'uploadTime') %}
        {{ as_timestamp(time) | timestamp_custom('%I:%M %p') }}
      unique_id: solax_5
      icon: mdi:clock

    - name: "Solax Battery Status"
      state: "{{ state_attr('sensor.solax', 'batStatus') }}"
      unique_id: solax_6
      icon: mdi:battery

    - name: "Solax Solar Panel"
      state: "{{ state_attr('sensor.solax', 'powerdc1') }}"
      unit_of_measurement: "W"
      device_class: energy
      state_class: measurement
      unique_id: solax_7
      icon: mdi:solar-power-variant

    - name: "Solax Battery Use"
      state: "{{ state_attr('sensor.solax', 'batPower') }}"
      unit_of_measurement: "W"
      device_class: energy
      state_class: measurement
      unique_id: solax_8
      icon: mdi:battery

    - name: "Solax Battery Use In"
      state: >
        {% set attr = state_attr('sensor.solax', 'batPower') %}
        {{ attr if is_number(attr) and (attr|float > 0) else 0 }}
      unit_of_measurement: "W"
      unique_id: solax_9
      icon: mdi:battery

    - name: "Solax Battery Use Out"
      state: >
        {% set attr = state_attr('sensor.solax', 'batPower') %}
        {{ (0 - attr) if is_number(attr) and (attr|float < 0) else 0 }}
      unit_of_measurement: "W"
      unique_id: solax_10
      icon: mdi:battery

    - name: "Solax Battery"
      state: "{{ state_attr('sensor.solax', 'soc') }}"
      unit_of_measurement: "%"
      device_class: battery
      state_class: measurement
      unique_id: solax_12
      icon: mdi:battery

    - name: "Solax Grid Power"
      state: >
        {% set attr = state_attr('sensor.solax', 'feedinpower') %}
        {{ (0 - attr) if is_number(attr) else 0 }}
      unit_of_measurement: "W"
      device_class: energy
      state_class: measurement
      unique_id: solax_13
      icon: mdi:transmission-tower

    - name: "Solax Grid Power in"
      state: >
        {% set attr = state_attr('sensor.solax', 'feedinpower') %}
        {{ (0 - attr) if is_number(attr) and (attr|float < 0) else 0 }}
      unit_of_measurement: "W"
      unique_id: solax_14
      icon: mdi:transmission-tower

    - name: "Solax Grid Power out"
      state: >
        {% set attr = state_attr('sensor.solax', 'feedinpower') %}
        {{ attr if is_number(attr) and (attr|float > 0) else 0 }}
      unit_of_measurement: "W"
      unique_id: solax_15
      icon: mdi:transmission-tower

    - name: "Solax Energy To Grid"
      state: "{{ state_attr('sensor.solax', 'feedinenergy') }}"
      unit_of_measurement: "kWh"
      unique_id: solax_16
      icon: mdi:transmission-tower
      device_class: energy
      state_class: total_increasing

    - name: "Solax Energy From Grid"
      state: "{{ state_attr('sensor.solax', 'consumeenergy') }}"
      unit_of_measurement: "kWh"
      unique_id: solax_19
      icon: mdi:transmission-tower
      device_class: energy
      state_class: total_increasing

    - name: "Solax Status"
      unique_id: solax_20
      icon: mdi:solar-power-variant
      state: >
          {% set attr = state_attr('sensor.solax', 'inverterStatus') %}
          {% if attr == '100' %}Wait
          {% elif attr == '101' %}Check
          {% elif attr == '102' %}Normal
          {% elif attr == '103' %}Fault
          {% elif attr == '104' %}Permanent Fault
          {% elif attr == '105' %}Update
          {% elif attr == '106' %}EPS Check
          {% elif attr == '107' %}EPS
          {% elif attr == '108' %}Self-test
          {% elif attr == '109' %}Idle
          {% elif attr == '110' %}Standby
          {% elif attr == '111' %}Pv Wake Up Bat
          {% elif attr == '112' %}Gen Check
          {% elif attr == '113' %}Gen Run
          {% else %}unknown{% endif %}

    - name: Total Home Use
      unique_id: home use
      state: >
          {% set battery = states('sensor.solax_battery_use') %}
          {% set grid = states('sensor.solax_grid_power') %}
          {% set solar = states('sensor.solar_panel_power') %}
          {% set total = 0 - battery|float if is_number(battery) else 0 %}
          {% set total = total + (solar|float if is_number(solar) else 0) %}
          {% set total = total + (grid|float if is_number(grid) else 0) %}
          {{ total }}
      state_class: measurement
      icon: 'mdi:flash'
      unit_of_measurement: W
      device_class: power

Notes:

  • The unique_id allows you to customise the Icon / Name in the HA Frontend.
  • I’ve added state_class in a few places from previous suggestions so that long term statistics are created.
  • The Total Home Use sesnor calculates my home total power consumption from all sources.

PowerCalc

I then used the PowerCalc integration to create energy sensors that can be used in the Energy integration. You’ll need to install this following its instructions (I used HACS).

sensor:
  - platform: powercalc
    entity_id: sensor.solax_solar_panel
    name: Solar Panel
    fixed:
      power: "{{states('sensor.solax_solar_panel')}}"

  - platform: powercalc
    entity_id: sensor.solax_battery_use_in
    name: Solar Battery In
    fixed:
      power: "{{states('sensor.solax_battery_use_in')}}"

  - platform: powercalc
    entity_id: sensor.solax_battery_use_out
    name: Solar Battery Out
    fixed:
      power: "{{states('sensor.solax_battery_use_out')}}"

  - platform: powercalc
    entity_id: sensor.measured_power
    name: Electric Consumption
    fixed:
      power: "{{states('sensor.measured_power')}}"

Utility Meter

I use Octopus Go for cheap overnight electricity to charge my battery, so I needed a Utility Meter to manage the peak/off peak tariff in the Energy Integration

utility_meter:
  daily_grid:
    source: sensor.solax_energy_from_grid
    name: From Grid
    cycle: daily
    tariffs:
      - peak
      - offpeak

This also needed an automation to set the tariff:

alias: Set Electric Tariff
description: "Set Electric Tariff for utility sensor"
trigger:
  - platform: time
    at: "00:30:00"
    variables:
      tariff: offpeak
  - platform: time
    at: "04:30:00"
    variables:
      tariff: peak
condition: []
action:
  - service: select.select_option
    target:
      entity_id: select.daily_grid
    data:
      option: "{{ tariff }}"
mode: single

Energy

To set up the HA energy dashboard, use the following sensors…

  • Grid Consumption: sensor.daily_grid_peak and sensor.daily_grid_offpeak
  • Return to Grid: sensor.solax_energy_to_grid
  • Solar Production: sensor.solar_panel_energy
  • Home Battery: sensor.solar_battery_in_energy and sensor.solar_battery_out_energy

NB: Once added to the dashboard, it will take an hour or two for data to become visible.

HA Frontend

I used the Power Flow Card integration to give a current snapshot of the output (screenshot above), in the same format as the HA Dashboard. You will need to install the Power Flow Card following its instructions (I used HACS).

type: vertical-stack
cards:
  - type: entities
    entities:
      - entity: sensor.solax_upload_time
        name: Last Update
      - entity: sensor.solax_status
        name: Inverter Status
  - type: custom:power-flow-card
    entities:
      battery:
        consumption: sensor.solax_battery_use_out
        production: sensor.solax_battery_use_in
      battery_charge: sensor.solax_battery
      grid:
        consumption: sensor.solax_grid_power_in
        production: sensor.solax_grid_power_out
      solar: sensor.solax_solar_panel
    watt_threshold: 1000

Notes

The value in Energy are an approximation, as the Solax reports data to the cloud once every five minutes, so any peaks / dips in use during the 5 minute slots are missed (e.g. boiling a kettle).
I have found in practice my daily figures agree with other data sources withing 5%.
The way round this is to use the local API intergration to get the data rather than REST API (once the issues issues are solved).

I hope you find this useful!
Suggested improvements welcome.

5 Likes

Thanks for taking the time to write down this example including all parts involved for the HA energy integration. I was able to set it up for my system in no time with this thread.

Maybe you could add the info to Create REST Sensor that the json attributes might need adjustments when another inverter is used.

Great work!

Thanks for the feedback - it was good to know it all worked, and I didn’t miss a step.

I’ve added a comment as recommended on the json_attributes.

Many thanks for this article. I’m also looking at switching to Octopus Go and charging the battery to full at night - could you share any info on how you are doing this? I guess calling the inverster twice a day to change its settings? Or only charging the battery at night and not through solar panels?

@kamilb, to use Octops Go, I have the Solax charging from the solar panels during the day, and grid at night. This is configured via the Solax App.

I’ve set “Self Use” mode, with charge from grid enabled, and “min Soc”, set to 10%, so I make full use of the battery.
Then in the “charge&discharge period”, I have “force charge” set to 00:30 to 04:30, and “allow discharge” set to 04:30 to 00:30.

The one variable I am experimenting with is under “self use”, the grid option, “charge battery to” percentage.
I currently (winter) have this at 80%, so there is room for some Solar top up. But on really cloudy days want this to be 100%. In summer I can see this would be lower (maybe 20% just to give some battery until the sun comes up.

I want to calculate this percentage, based on the HA Solar Predictor set up in the Energy dashboard. But I have yet to find a way to get HA to programmatically set this on the Solax. The Solax REST API is read only. Doing it manually via the Solax APP every day seems too much hassle.

1 Like

@ColinRobbins, much appreciated! I’ve been experimenting with the charge&discharge periods - now it makes more sense! Cheers! :slight_smile:
I believe you can programmatically change settings on your inverter via the SolaxCloud or even locally. When using SolaxCloud on your browser, you can view the content of the request using developer tools, then replicate that in HA.
A few more questions if you don’t mind:

  1. do you see your inverter obbey the “min SOC”/“charge battery to” limits? or is it off by a few % each time?
  2. do you also get your battery power output being under reported by about 100-150W, typically when solar panels don’t provide much output?
  3. are you on any of the Octopus Outgoing tarrifts?

BTW - I’ve managed to successfully connect to the inverter (H1 Hybrid G4) using my local network, and poll at a much higher rate (every 5s) - is that something of any interest to you?

@kamilb I would be very interested in how you have connected locally. I have set the proxy set us as per these instrustions, and got as far as getting data back via curl from 5.8.8.8.

  1. do you see your inverter obbey the “min SOC”/“charge battery to” limits? or is it off by a few % each time?

No, I’ve seen it vary. Seen my battery dip to 6% with the min SOC set to10%

  1. do you also get your battery power output being under reported by about 100-150W, typically when solar panels don’t provide much output?

I’ve seen the sum of Solar power plus Battery battery not equal to the reported Inverter output by 50-100w, but don’t have a view of where the “missing” power goes, or if it is an accuracy error.

  1. are you on any of the Octopus Outgoing tarrifts?

The Octopus Outgoing is not available with Octopus Go (see https://octopus.energy/outgoing/). I believe you can on have the SEG with Octopus Go - application in progress.

1 Like

I would be very wary of using the Pocket WiFi in AP Mode, I would recommend you have a read of these few posts to understand to consequences Universal Solar Inverter over Modbus RS485 / TCP custom_component (Growatt, Sofar, SolaX, Solis) - #715 by Lad1

You might want to contact SolaX to see if there is a firmware update. Sounds like you are on an older version.

Remember there are losses from converting from DC to AC etc and different voltage levels between PV, Battery and Grid.

I would be very wary of using the Pocket WiFi in AP Mode

My understanding is the AP Mode cannot be swithed off. If using Pocket WiFi you get both Internet access via your WiFi and a local access point. So by simply chosing to use the Pocket WiFi the risk exists.

So my choice is accept the risk, or not use the Pocket WiFi. If I choose to accept the risk, then using the local access point to get near real-time data, rather that cloud-delayed data, does not change the risk assessment - the risk still exists but has not been made worse. Thus I may as well enjoy the benefit.

Similar risks exist with other smart devices connected in the home, so I use segregated WiFi networks to minimise the risk.

1 Like

Thank you @ColinRobbins! Here is the write up on my local & cloud APIs: Solax X1 Hybrid G4 (local & cloud API) - hope you find it useful :slight_smile:

Thanks for this @kamilb, I was half way through figuring this out msyelf.
I’ll reply on your other thread, to keep it all in one place.

Hi ColinRobbins - I’m a totally newbie to HA and also to solar power. Just installed a 8kw panel array with a X3-Hybrid-G4 Solax Inverter (3-phase property) and 11.6kw Solax batteries. Moved onto Octopus early Jan 2023 and they installed a 3-phase SMETS2 meter in the first week. Also have an iboost installed in the hope of getting some hot water once we get more sun. I’m online with the Solax app and looking to learn more and integrate with HA later.

My first stumbling block is I want to do the same as you and use Octopus Go to charge my batteries up over night using off-peak electricity and low 12p pkw off-peak rate. As I do not have an electric vehicle (yet), they’re telling me that they can’t put me on this tariff as it’s exclusive to electric car owners. They’ve agreed that I could go on a higher price tariff with Economy 7 - off-peak price 18.61p. This seems discriminatory and unfair. As you’re using the tariff to charge your batteries, are you also charging an EV? Maybe I’m going about asking Octopus incorrectly? Any advice appreciated please

1 Like

Hi, yes I have an EV, so meet the Octopus requirement.

I believe the requirements is there, as Octopus need to stimulate changes in user behaviour to move demand overnight to make the economics work. The EV has a 62kwh battery they don’t want you to charge at 7.5kwh during the day.
With solar, you have already made the choice to switch usage / demand, so suggest Octopus don’t see a market opportunity to stimulate further change in demand by offering a lower “solar battery” tariff.
Also the grid demand to charge a solar battery is less, most charge about 2-3kWh, so the demand impact on the grid is lower, so impact of change less.

1 Like

Hi Colin,

Thanks for posting the local configuration!! I’ve got it all setup and working a treat!

I’m trying to configure Octopus Go on Self Use, like you have done, but I’m having zero success.

Would you mind sharing some screenshots of your inverters configuration?

Here are my settings, which I tried this morning, to force charge the battery for 30 minutes.

image

Would you have any idea where I’m going wrong?

Regards,
Tom

Settings look reasonable to me, and similar to mine.
I have “Allowed Discharge” set to 00:00 to 23:59 - happy for the battery to be used anytime.
Your “charge battery to” is “35%”, so I assume your battery level is below that.
On the screen before to go into settings, I assume you have “work mode” set to “self use”.

Thanks.

Work Mode is set to Self-Use. The battery had an SoC of 10% during the test.

I’ve adjusted the Allow Discharge to 00:00 - 23:59 as suggested and set the Force charge to 09:35 to 10:00 and I’ll see what happens.

Is your inverter firmware at 3.0001.02?

As if by magic, it worked as intended.

I wonder why it hasn’t worked the past three mornings with similar configuration? Maybe the order I click the save buttons in?? :rofl:

At least I know it can work now.

Thanks again!

Many thanks @ColinRobbins - that makes sense. I’ll still make savings on the Economy 7 tariff so likely I’ll trial that to how it works out in winter. EV is a target in the coming years too so will hopefully be able to benefit then

No overnight charge again, despite the settings being 01:30 to 06:25. I tried adjusting the settings to test it again, but kept getting a “Settings Failed” error.

I’ll try and configure the time periods directly on the inverter if I can.

Hello, I will go to test this at my environment. But I have 2 inverters and 2 punch of bateries, What should I add for that? Thank you