Solax X3-Hybrid G4 Wifi Firmware Solax module fw version 3.003.02 Home Assistant Integration

Thank you @mf76130 . Looks like spot 19 and 20 are values I need to use.

Hi I have just got solax X3 G4 with wifi 3.0 module with version 3.015.02 installed in my home. It has separate wifi to connect to device locally via solax app.
Home assistant default solax integration works out of the box from the home default wifi and I don’t need any reverse proxy raspberry to get information from separate wifi. Why is that working so easily as I read that it would need reverse proxy solution. Should I disable updates to my wifi module somehow?

Edit: shared same question in original python repo: Question: why is it working without wifi proxy solax x3 hybrid g4 with wifi 3.0 ¡ Issue #173 ¡ squishykid/solax ¡ GitHub
Probably it’s a new feature introduced in newer firmwares :slight_smile:

I have successfully implemented this and I see data coming in. All sensors seem to have some data.
However when I look at solar production, my charts say that I have WAY too high yield.
2000 kWh in an hour while my solax app says I yielded 13.60 kWh in totaly today.
I also see negative values…
I didn’t customize anything from the first post, not sure how I would go about that either.
My output from the solax_rest_data sensor is the following where line 26 holds value 136 which seems to possibly be my yield?
The templates.yaml file also says I need to adjust customize.yaml but with what?
My type is 7 (X3-MIC/PRO)

sn: SXQCxxxxxxx
ver: 3.018.03
type: 7
Data:
  - 2353
  - 2344
  - 2349
  - 4
  - 5
  - 5
  - 0
  - 0
  - 1
  - 3158
  - 1980
  - 1
  - 2
  - 26
  - 25
  - 4999
  - 4999
  - 5000
  - 2
  - 45634
  - 1
  - 136
  - 0
  - 0
  - 0
  - 0
  - 0
  - 0
  - 0
  - 0
  - 0
  - 0
  - 0
  - 0
  - 0
  - 0
  - 0
  - 0
  - 0
  - 0
  - 8
  - 0
  - 0
  - 0
  - 0
  - 0
  - 8
  - 4000
  - 0
  - 32
  - 0
  - 0
  - 0
  - 0
  - 0
  - 0
  - 0
  - 0
  - 0
  - 0
  - 0
  - 0
  - 0
  - 0
  - 0
  - 0
  - 0
  - 0
  - 0
  - 0
  - 0
  - 0
  - 40
  - 0
  - 0
  - 0
  - 0
  - 0
  - 0
  - 0
  - 0
  - 0
  - 0
  - 0
  - 0
  - 0
  - 0
  - 0
  - 0
  - 0
  - 0
  - 0
  - 0
  - 0
  - 0
  - 0
  - 0
  - 0
  - 0
  - 0
Information:
  - 4
  - 7
  - MU402TH7023225
  - 8
  - 1.33
  - 1.02
  - 1.38
  - 1.02
  - 0
  - 1
friendly_name: solax_rest_data

might be more complicated for you, as you need to find the correct attributes and the correct calculation.
But there is a working Integration in Home Assistant already, which you can use and i personal prefer now using a modbus adapter and the “solax inverter modbus” integration

Hi could you please post all your latest working configfor the rest connection.
Thx

I did swich over to this Homeassistant SolaX modbus integration , but i have a backup:

### Solax REST command online sensor 
rest:
  - authentication: digest
    scan_interval: 5
    resource: http://192.168.0.2/                        #IP of solax module
    payload: "optType=ReadRealTimeData&pwd=SXEYMEEBDR"   #replace xxxxxxxxxx with password in whole file
    method: POST
    headers: 
      Content-Type: "application/x-www-form-urlencoded"
    sensor:
      - name: "solax_rest_data"
        json_attributes:
        - sn
        - ver
        - type
        - Data
        - Information
        value_template: 'OK'   #dummy value, not used; avoids the "State max length is 255 characters" error
        

  ###Solax
  - name: solax
    state: > 
            {% if state_attr('sensor.solax_rest_data', 'sn') == "SXEYMEEBDR"  %}{{ now() }}
            {% else %}{{ (states('sensor.solax')) }}{% endif %}
    attributes: 
      sn: >-
            {% if state_attr('sensor.solax_rest_data', 'sn') == "SXEYMEEBDR" %}{{ (state_attr('sensor.solax_rest_data', 'sn')) }}
            {% else %}{{ (state_attr('sensor.solax', 'sn')) }}{% endif %}
      ver: >-
          {% if state_attr('sensor.solax_rest_data', 'sn') == "SXEYMEEBDR" %}{{ (state_attr('sensor.solax_rest_data', 'ver')) }}
          {% else %}{{ (state_attr('sensor.solax', 'ver')) }}{% endif %}
      type: >-
          {% if state_attr('sensor.solax_rest_data', 'sn') == "SXEYMEEBDR" %}{{ (state_attr('sensor.solax_rest_data', 'type')) }}
          {% else %}{{ (state_attr('sensor.solax', 'type')) }}{% endif %}
      Data: >-
          {% if state_attr('sensor.solax_rest_data', 'sn') == "SXEYMEEBDR" %}{{ (state_attr('sensor.solax_rest_data', 'Data')) }}
          {% else %}{{ (state_attr('sensor.solax', 'Data')) }}{% endif %}
      Information: >-
          {% if state_attr('sensor.solax_rest_data', 'sn') == "SXEYMEEBDR" %}{{ (state_attr('sensor.solax_rest_data', 'Information')) }}
          {% else %}{{ (state_attr('sensor.solax', 'Information')) }}{% endif %}

###SOLAX Integration
###AC detailed information
  - name: "Solax L1 Voltage"
    state: "{{ state_attr('sensor.solax', 'Data')[0] | int(default=2300) / 10}}"
    unit_of_measurement: "V"
    device_class: "voltage"

  - name: "Solax L2 Voltage"
    state: "{{ state_attr('sensor.solax', 'Data')[1] | int(default=2300) / 10}}"
    unit_of_measurement: "V"
    device_class: "voltage"

  - name: "Solax L3 Voltage"
    state: "{{ state_attr('sensor.solax', 'Data')[2] | int(default=2300) / 10 }}"
    unit_of_measurement: "V"
    device_class: "voltage"

  - name: "Solax L1 Current"
    state: >
      {% if state_attr('sensor.solax', 'Data')[3] > 32767 %}{{ (state_attr('sensor.solax', 'Data')[3] - 65536) | int(default=0) / 10 }}
      {% else %}{{ state_attr('sensor.solax', 'Data')[3] | int(default=0) / 10 }}{% endif %}
    unit_of_measurement: "A"
    device_class: "current"

  - name: "Solax L2 Current"
    state: >
      {% if state_attr('sensor.solax', 'Data')[4] > 32767 %}{{ (state_attr('sensor.solax', 'Data')[4] - 65536) | int(default=0) / 10 }}
      {% else %}{{ state_attr('sensor.solax', 'Data')[4] | int(default=0) / 10 }}{% endif %}
    unit_of_measurement: "A"
    device_class: "current"

  - name: "Solax L3 Current"
    state: >
      {% if state_attr('sensor.solax', 'Data')[5] > 32767 %}{{ (state_attr('sensor.solax', 'Data')[5] - 65536) | int(default=0) / 10 }}
      {% else %}{{ state_attr('sensor.solax', 'Data')[5] | int(default=0) / 10 }}{% endif %}
    unit_of_measurement: "A"
    device_class: "current"

  - name: "Solax L1 Power"
    state: >
      {% if state_attr('sensor.solax', 'Data')[6] > 32767 %}{{ (state_attr('sensor.solax', 'Data')[6] - 65536) | int(default=0) }}
      {% else %}{{ state_attr('sensor.solax', 'Data')[6] | int(default=0) }}{% endif %}
    unit_of_measurement: "W"
    device_class: "power"

  - name: "Solax L2 Power"
    state: >
      {% if state_attr('sensor.solax', 'Data')[7] > 32767 %}{{ (state_attr('sensor.solax', 'Data')[7] - 65536) | int(default=0) }}
      {% else %}{{ state_attr('sensor.solax', 'Data')[7] | int(default=0) }}{% endif %}
    unit_of_measurement: "W"
    device_class: "power"

  - name: "Solax L3 Power"
    state: >
      {% if state_attr('sensor.solax', 'Data')[8] > 32767 %}{{ (state_attr('sensor.solax', 'Data')[8] - 65536) | int(default=0) }}
      {% else %}{{ state_attr('sensor.solax', 'Data')[8] | int(default=0) }}{% endif %}
    unit_of_measurement: "W"
    device_class: "power"

  - name: "Solax Total AC Power"
    state: >
      {% if state_attr('sensor.solax', 'Data')[9] > 32767 %}{{ (state_attr('sensor.solax', 'Data')[9] - 65536) | int(default=0) }}
      {% else %}{{ state_attr('sensor.solax', 'Data')[9] | int(default=0) }}{% endif %}
    unit_of_measurement: "W"
    device_class: "power"

  - name: "Solax L1 Frequency"
    state: "{{ state_attr('sensor.solax', 'Data')[16] | int(default=5000) / 100}}"
    unit_of_measurement: "Hz"
    device_class: "frequency"

  - name: "Solax L2 Frequency"
    state: "{{ state_attr('sensor.solax', 'Data')[17] | int(default=5000) / 100}}"
    unit_of_measurement: "Hz"
    device_class: "frequency"

  - name: "Solax L3 Frequency"
    state: "{{ state_attr('sensor.solax', 'Data')[18] | int(default=5000) / 100}}"
    unit_of_measurement: "Hz"
    device_class: "frequency"

### Solax Summary and statistic sensors ###
  - name: "Solax Feed-in Power"
    state: >
      {% if state_attr('sensor.solax', 'Data')[34] > 32767 %}{{ state_attr('sensor.solax', 'Data')[34] - 65536 }}
      {% else %}{{ state_attr('sensor.solax', 'Data')[34] }}{% endif %}
    unit_of_measurement: "W"
    device_class: "power"

  - name: "Solax Consumption"
    state: >
      {% if state_attr('sensor.solax', 'Data')[47] > 32767 %}{{ state_attr('sensor.solax', 'Data')[47] - 65536 }}
      {% else %}{{ state_attr('sensor.solax', 'Data')[47] }}{% endif %}
    unit_of_measurement: "W"
    device_class: "power"

  - name: "Solax Energy total"
    state: "{{ ((state_attr('sensor.solax', 'Data')[69] * 65536) + state_attr('sensor.solax', 'Data')[68]) | float / 10 }}"
    unit_of_measurement: "kWh"
    device_class: "energy"
    state_class: total_increasing

### Today's statistics ###
  - name: "Solax Grid out today"
    state: "{{ state_attr('sensor.solax', 'Data')[90] | float / 100 }}"
    unit_of_measurement: "kWh"
    device_class: "energy"

  - name: "Solax Grid in today"
    state: "{{ state_attr('sensor.solax', 'Data')[92] | float / 100 }}"
    unit_of_measurement: "kWh"
    device_class: "energy"

  - name: "Solax Battery discharge today"
    state: "{{ state_attr('sensor.solax', 'Data')[78] | float / 10 }}"
    unit_of_measurement: "kWh"
    device_class: "energy"

  - name: "Solax Battery charge today"
    state: "{{ state_attr('sensor.solax', 'Data')[79] | float / 10 }}"
    unit_of_measurement: "kWh"
    device_class: "energy"

  - name: "Solax Energy today"
    state: "{{ state_attr('sensor.solax', 'Data')[82] | float / 10 }}"
    unit_of_measurement: "kWh"
    device_class: "energy"

  - name: "Solax Energy incl battery today"
    state: "{{ state_attr('sensor.solax', 'Data')[70] | float / 10 }}"
    unit_of_measurement: "kWh"
    device_class: "energy"

### Total values for Energy panel - needs customization in customize.yaml ###
  - name: "Solax Solar energy total"
    state: "{{ ((state_attr('sensor.solax', 'Data')[81] * 65536) + state_attr('sensor.solax', 'Data')[80]) | float / 10 }}"
    unit_of_measurement: "kWh"
    device_class: "energy"
    state_class: total_increasing

  - name: "Solax Solar energy total"
    state: "{{ ((state_attr('sensor.solax', 'Data')[81] * 65536) + state_attr('sensor.solax', 'Data')[80]) | float / 10 }}"
    unit_of_measurement: "kWh"
    device_class: "energy"
    state_class: total_increasing

  - name: "Solax Grid out total"
    state: "{{ ((state_attr('sensor.solax', 'Data')[87] * 65536) + state_attr('sensor.solax', 'Data')[86]) | float / 100 }}"
    unit_of_measurement: "kWh"
    device_class: "energy"
    state_class: total_increasing

  - name: "Solax Grid in total"
    state: "{{ ((state_attr('sensor.solax', 'Data')[89] * 65536) + state_attr('sensor.solax', 'Data')[88]) | float / 100 }}"
    unit_of_measurement: "kWh"
    device_class: "energy"
    state_class: total_increasing

  - name: "Solax Grid in total-test"
    state: "{{ (state_attr('sensor.solax', 'Data')[89] * 65536)}}"
    unit_of_measurement: "kWh"
    device_class: "energy"
    state_class: total_increasing

  - name: "Solax Consumption total"
    state: "{{ state_attr('sensor.solax', 'Data')[88] | float / 100 }}"
    unit_of_measurement: "kWh"
    device_class: "energy"
    state_class: total_increasing

  - name: "Solax Battery discharge total"
    state: "{{ ((state_attr('sensor.solax', 'Data')[75] * 65536) + state_attr('sensor.solax', 'Data')[74]) | float / 10 }}"
    unit_of_measurement: "kWh"
    device_class: "energy"
    state_class: total_increasing

  - name: "Solax Battery charge total"
    state: "{{ ((state_attr('sensor.solax', 'Data')[77] * 65536) + state_attr('sensor.solax', 'Data')[76]) | float / 10 }}"
    unit_of_measurement: "kWh"
    device_class: "energy"
    state_class: total_increasing

### PV detailed information ###      
  - name: "Solax PV1 Voltage"
    state: "{{ state_attr('sensor.solax', 'Data')[10] | int(default=0) / 10}}"
    unit_of_measurement: "V"
    device_class: "voltage"

  - name: "Solax PV2 Voltage"
    state: "{{ state_attr('sensor.solax', 'Data')[11] | int(default=0) / 10}}"
    unit_of_measurement: "V"
    device_class: "voltage"
    
  - name: "Solax PV1 Current"
    state: "{{ state_attr('sensor.solax', 'Data')[12] | int(default=0) / 10 }}"
    unit_of_measurement: "A"
    device_class: "current"
    
  - name: "Solax PV2 Current"
    state: "{{ state_attr('sensor.solax', 'Data')[13] | int(default=0) / 10 }}"
    unit_of_measurement: "A"
    device_class: "current"

  - name: "Solax PV1 Power"
    state: "{{ state_attr('sensor.solax', 'Data')[14] | int(default=0) }}"
    unit_of_measurement: "W"
    device_class: "power"

  - name: "Solax PV2 Power"
    state: "{{ state_attr('sensor.solax', 'Data')[15] | int(default=0) }}"
    unit_of_measurement: "W"
    device_class: "power"

  - name: "Solax Total PV Power"
    state: "{{ (states('sensor.solax_pv1_power')|int + states('sensor.solax_pv2_power')|int) }}"
    unit_of_measurement: "W"
    device_class: "power"

### Battery detailed information ###      
  - name: "Solax Battery Voltage"
    state: "{{ state_attr('sensor.solax', 'Data')[39] | float / 100}}"
    unit_of_measurement: "V"
    device_class: "voltage"

  - name: "Solax Battery Current"
    state: >
      {% if state_attr('sensor.solax', 'Data')[40] > 32767 %}{{ (state_attr('sensor.solax', 'Data')[40] - 65536) / 100 }}
      {% else %}{{ state_attr('sensor.solax', 'Data')[40] / 100 }}{% endif %}
    unit_of_measurement: "A"
    device_class: "current"

  - name: "Solax Battery Power"
    state:  >
      {% if state_attr('sensor.solax', 'Data')[41] > 32767 %}{{ state_attr('sensor.solax', 'Data')[41] - 65536 }}
      {% else %}{{ state_attr('sensor.solax', 'Data')[41] }}{% endif %}
    unit_of_measurement: "W"
    device_class: "power"

  - name: "Solax Battery SoC"
    state: "{{ state_attr('sensor.solax', 'Data')[103] | int(default=0) }}"
    unit_of_measurement: "%"

  - name: "Solax Battery Remain Energy"
    state: "{{ state_attr('sensor.solax', 'Data')[106] | int(default=0) / 10 }}"
    unit_of_measurement: "kWh"
    device_class: "energy"

  - name: "Solax Battery Temperature"
    state: "{{ state_attr('sensor.solax', 'Data')[105] | int(default=0) }}"
    unit_of_measurement: "°C"
    device_class: "temperature"

###  - name: "Solax Battery BMS status"
###    state:  >
###      {% if state_attr('sensor.solax', 'Data')[45] | int == 1 %}OK
###      {% else %}Fail{% endif %}
###    unit_of_measurement: "%"

### Invertor modes, states ###
  - name: "Solax Battery Operation Mode"
    state: >
      {%   if state_attr('sensor.solax', 'Data')[168] == 0 %}Self Use Mode
      {% elif state_attr('sensor.solax', 'Data')[168] == 1 %}Force Time Use
      {% elif state_attr('sensor.solax', 'Data')[168] == 2 %}Back Up Mode
      {% elif state_attr('sensor.solax', 'Data')[168] == 3 %}Feed-in Priority
      {% else %}I dont know{% endif %}

  - name: "Solax Inverter Operation Mode"
    state: >
      {%   if state_attr('sensor.solax', 'Data')[19] ==  0 %}Waiting
      {% elif state_attr('sensor.solax', 'Data')[19] ==  1 %}Checking
      {% elif state_attr('sensor.solax', 'Data')[19] ==  2 %}Normal
      {% elif state_attr('sensor.solax', 'Data')[19] ==  3 %}Off
      {% elif state_attr('sensor.solax', 'Data')[19] ==  4 %}Permanent Fault
      {% elif state_attr('sensor.solax', 'Data')[19] ==  5 %}Updating
      {% elif state_attr('sensor.solax', 'Data')[19] ==  6 %}EPS Check
      {% elif state_attr('sensor.solax', 'Data')[19] ==  7 %}EPS Mode
      {% elif state_attr('sensor.solax', 'Data')[19] ==  8 %}Self Test
      {% elif state_attr('sensor.solax', 'Data')[19] ==  9 %}Idle
      {% elif state_attr('sensor.solax', 'Data')[19] == 10 %}Standby
      {% else %}I dont know{% endif %}

### Invertor and management module information ###
  - name: "Solax Module SN"
    state: "{{ state_attr('sensor.solax', 'sn') }}"

  - name: "Solax module fw version"
    state: "{{ state_attr('sensor.solax', 'ver') }}"

  - name: "Solax type"
    state: >  # Other Solax invertor type are described in web API manual
      {% if state_attr('sensor.solax', 'type') == 14 %}X3-Hybrid G4
      {% else %}Other{% endif %}

  - name: "Solax Inverter SN"
    state: "{{ state_attr('sensor.solax', 'Information')[2] }}"

  - name: "Solax Inverter Nominal Power"
    state: "{{ state_attr('sensor.solax', 'Information')[0] | float | round(1) }}"
    unit_of_measurement: "kW"

### Test parameters ###
  - name: "Solax Inverter Temperature inner ?"
    state: "{{ state_attr('sensor.solax', 'Data')[46] | int(default=0) }}"
    unit_of_measurement: "°C"
    device_class: "temperature"

#  - name: "Solax Inverter Temperature ?"
#    state: "{{ state_attr('sensor.solax', 'Data')[54] | int(default=0) }}"
#    unit_of_measurement: "°C"
#    device_class: "temperature"

Just starting with HA so not got my head round it all yet… more copy and hope :slight_smile:
I have a very similar setup and wanting to be able to program my Solax locally to control the charging side from HA.
I have installed this code having previously installed the Solax integration (but deleted and rebooted…)

When I add the cope to template.yaml and run I get several errors
“Property Name not allowed”
“Property state not allowed”
etc etc

Im assuming a syntax error somewhere at the top level but if im honest not yet sure what im looking at…
Can you help?

Yaml is very strict with spacing, so the code must be at the correct position, explained here: YAML Best Practices | RudderStack Docs.

And today its pretty easy to check your code, just post the code into chatgpt and the error and it will help you optimise it.

Besides all that, my code was working at the time i uploaded it, its possible that some syntax has been changed in Home Assistant since that, i am using the Modbus Integration for Solax now, which is much better than the one via the USB Stick.

Hello everyone,

I have a set of REST and template sensors in Home Assistant that monitor my Solax inverter. These sensors were working perfectly until I recently updated Home Assistant to version 2025.7.1 and continues in 2025.8.3

The REST sensor queries the inverter at http://192.168.1.48/ and the inverter always responds with valid JSON when I test it using curl:

curl -X POST -d "optType=ReadRealTimeData&pwd=XXXXXXXXX" http://192.168.X.X/

Sample response:

{"sn":"SXCCNPLNWM","ver":"3.003.02","type":15,"Data":[...],"Information":[...]}

Despite this, in Home Assistant sensor.solax now remains null, and the log repeatedly shows:

REST result could not be parsed as JSON

I am including the REST sensor in sensors.yaml like this:

- platform: rest
  name: solax_rest_data
  resource: http://192.168.X.X/
  method: POST
  headers:
    Content-Type: application/x-www-form-urlencoded
  payload: "optType=ReadRealTimeData&pwd=xxxxxxxxxxxx"
  value_template: "OK"
  json_attributes_path: "$"
  json_attributes:
    - sn
    - ver
    - type
    - Data
    - Information
  scan_interval: 5

I have many template sensors that depend on this REST sensor’s attributes, for example: state_attr('sensor.solax_rest_data', 'Data')[0].

I have tried moving the REST sensor between configuration.yaml and sensors.yaml, adjusting json_attributes_path, and changing scan_interval, but nothing seems to work.

Has anyone encountered a similar issue with Solax inverters after a Home Assistant update? How did you fix the JSON parsing or REST sensor integration so the template sensors could work again?

Thanks in advance!


i am not using this anymore, as i the rs485 modbus is much more reliable, so i added the rest sensor for testing and it still works, i just added the setup to the end of my configuration.
Do you get data into your rest sensor? You can check that easily in the developer tools:

Thats the config i used, looks complete different than your setup, i didn’t review if your syntax could be correct or not:

  ### Solax REST command online sensor ###
rest:
  - authentication: digest
    scan_interval: 5
    resource: http://192.168.0.2/                       # IP of solax module
    payload: "optType=ReadRealTimeData&pwd=MYPWD"  # replace xxxxxxxxxx with password in whole file
    method: POST
    headers: 
      Content-Type: "application/x-www-form-urlencoded"
    sensor:
      - name: "solax_rest_data"
        json_attributes:
        - sn
        - ver
        - type
        - Data
        - Information
        value_template: 'OK'  # dummy value, not used; avoids the "State max length is 255 characters" error

Thank you for de answer.
I check my configuration and it looks pretty similar to yours. I’ve just added the authentication line to mine.
No, I don’t receive the rest data anymore. As you can see the atributes are missing. When I go to the log a get this error:

Registrador: homeassistant.components.rest.util
Fuente: components/rest/util.py:37
integraciĂłn: RESTful (documentaciĂłn, problemas)
OcurriĂł por primera vez: 09:56:56 (56 ocurrencias)
Última vez registrado: 10:01:33

REST result could not be parsed as JSON

It seems like I don’t receive rest data anymore. It suddenly happened with the upgrade to version 2025.7.1.

I don’t get what the problem is…


SOLVED.
I deleted headers: Content-Type: “application/x-www-form-urlencoded”
and now it works