API integration for Solplanet inverter (AISWEI)

So im fine with this solution, but in my mind it’s not easier for beginners. You have to be fit in soldering and yaml codes. Also you need some stuff like an esp. I will give it a try because I have all the stuff at home. Thanks for the tip.

1 Like

True, you don’t really need to solder, I just chose to. I would recommend to use a simple 5V power supply for the esp. But I totally agree that if someone created a plug and play integration that would be easier for most people, although it might come with some others drawbacks.

I just checked the voltage of the Solplanet stick and it’s pretty inconsistent now at 7V so I’m not sure I would recommend executing my earlier reply, I’m going to change that message. (And add a step-down to my current setup :sweat_smile:)

Today I’ve tried a few things but I think there an issue with my translation of gpios for the esp32. Don’t you tried to use the original Wi-Fi dongle? There’s an esp32 build in. If we solder in the rs485 module, it’s the all in one solution.


Info: For all ones who have added the solplanet inverter to wifi or ethern, i recommend to stay with that.

IF YOU HAVENT ANY DONGLE, then the modbus solution may is something for you. Ive tried out everything, but i see no advantage to the Wifi integration.

May you have some advantage if you have any battery connected… but i havent.

heres the modbus file i’ve got from solplanet support, got it about 10 mins after my request, gratz for that…:

1 Like

I played around with the old Aiswei app android AISWEI app and captured additional endpoints that are in plain http and without credentials. all accessible via http://>you_invert_ip>:8484/…

  • getdev.cgi?device=3
    Exposes settings related to export power and power factor limits in JSON format. e.g.
"{
  ""mod"": 0,
  ""enb"": 0,
  ""exp_m"": 0,
  ""regulate"": 5,
  ""enb_PF"": 5,
  ""target_PF"": 0,
  ""abs"": 0,
  ""abs_offset"": 0,
  ""total_pac"": 203,
  ""total_fac"": 8000,
  ""meter_pac"": 0
}"
  • setting.cgi
    POST JSON to adjust PF and Export power limits e.g.:
{"device":3,"action":"setmeter","value":{"target":1000,"regulate":10,"enb_PF":5,"target_PF":0,"abs":0,"offset":2}}
  • fdbg.cgi
    Exposes lots of settings in MODBUS formatted coding. See modbus manual further up to get and idea.
    POST requests. e.g. to query the Active Power settings:
{"data":"030300c800010416"}

response

{"dat":"ok","data":"03030200010044"}

which basically means Active Power = on.

Don’t mess around blindly with the fdbg.cgi as you can hurt your installation and potentially fry your inverter.

Lot of stuff to investigate here!

1 Like

I managed to get a modbus connection running via the wi-fi dongle now.
Here’s how to reproduce it:

Add modbus connection in configuration.yaml:

modbus: !include modbus.yaml

Create modbus.yaml in the config dir and enter this (just one POC command for now to retrieve active power)

- name: modbus_solplanet
  type: rtuovertcp
  host: 127.0.0.1
  port: 502
  sensors:
    - name: Active Power
      unit_of_measurement: W
      slave: 3
      address: 1370
      input_type: input
      data_type: int32
      min_value: 0

Built a Node Red flow like below. It opens a tcp port 502 on the HA system and convert to and from hex string and JSON, basically behaving like a proxy translater service (just replace with your inverter IP in the http request:

[
    {
        "id": "094fa30b52f0902e",
        "type": "tab",
        "label": "Solplanet modbus via FDBG.CGI",
        "disabled": false,
        "info": "",
        "env": []
    },
    {
        "id": "8e966d69e2e7fffa",
        "type": "http request",
        "z": "094fa30b52f0902e",
        "name": "",
        "method": "POST",
        "ret": "obj",
        "paytoqs": "query",
        "url": "http://192.168.1.127:8484/fdbg.cgi",
        "tls": "",
        "persist": false,
        "proxy": "",
        "insecureHTTPParser": false,
        "authType": "",
        "senderr": false,
        "headers": [
            {
                "keyType": "Content-Type",
                "keyValue": "",
                "valueType": "application/json",
                "valueValue": ""
            }
        ],
        "x": 170,
        "y": 240,
        "wires": [
            [
                "fba4c181689f43f5"
            ]
        ],
        "info": "Call FDBG.CGI"
    },
    {
        "id": "f7175970bcfa5bc0",
        "type": "tcp in",
        "z": "094fa30b52f0902e",
        "name": "",
        "server": "server",
        "host": "",
        "port": "502",
        "datamode": "stream",
        "datatype": "buffer",
        "newline": "",
        "topic": "",
        "trim": false,
        "base64": false,
        "tls": "",
        "x": 130,
        "y": 100,
        "wires": [
            [
                "3af19067e5e83ce9",
                "fcb1504cb7d64448"
            ]
        ]
    },
    {
        "id": "082c048a0f2b256f",
        "type": "tcp out",
        "z": "094fa30b52f0902e",
        "name": "",
        "host": "",
        "port": "",
        "beserver": "reply",
        "base64": false,
        "end": false,
        "tls": "",
        "x": 150,
        "y": 360,
        "wires": []
    },
    {
        "id": "3af19067e5e83ce9",
        "type": "debug",
        "z": "094fa30b52f0902e",
        "name": "modbus input",
        "active": false,
        "tosidebar": true,
        "console": false,
        "tostatus": true,
        "complete": "true",
        "targetType": "full",
        "statusVal": "payload",
        "statusType": "auto",
        "x": 340,
        "y": 100,
        "wires": []
    },
    {
        "id": "fcb1504cb7d64448",
        "type": "function",
        "z": "094fa30b52f0902e",
        "name": "form JSON",
        "func": "var Hexstring = msg.payload.toString('hex');\nmsg.payload = {\n            \"data\": Hexstring\n}\nreturn msg;",
        "outputs": 1,
        "timeout": 0,
        "noerr": 0,
        "initialize": "",
        "finalize": "",
        "libs": [],
        "x": 150,
        "y": 180,
        "wires": [
            [
                "8e966d69e2e7fffa"
            ]
        ]
    },
    {
        "id": "fba4c181689f43f5",
        "type": "function",
        "z": "094fa30b52f0902e",
        "name": "form buffer",
        "func": "var Response = msg.payload;\nmsg.payload = Buffer.from(msg.payload.data, \"hex\");\nreturn msg;",
        "outputs": 1,
        "timeout": 0,
        "noerr": 0,
        "initialize": "",
        "finalize": "",
        "libs": [],
        "x": 170,
        "y": 300,
        "wires": [
            [
                "a6a8edf93eff2972",
                "082c048a0f2b256f"
            ]
        ]
    },
    {
        "id": "a6a8edf93eff2972",
        "type": "debug",
        "z": "094fa30b52f0902e",
        "name": "Inverter response",
        "active": false,
        "tosidebar": true,
        "console": false,
        "tostatus": false,
        "complete": "payload",
        "targetType": "msg",
        "statusVal": "",
        "statusType": "auto",
        "x": 370,
        "y": 300,
        "wires": []
    }
]

If all goes well, you now have an active power sensor.
From here it’s just a matter of adding more functions to the modbus.yaml file.
All the functions in the document shared by derkorte can be implemented wihtout any additional hardware.

1 Like

Hi Johan , I have a Solplanet ASW 6000 H - S2 hybrid and I´m trying to read/write the inverter over the API to configure the inverter (export 0 when price -) and read information like export energy the electrical network , house energy consumption, etc…

My inverter has 4 ports, but the COM port RS485 in my inverter is used for comunicate with the meter (master/inverter — slave/meterSDM230) . I need to connect to inverter(slave) with a master (to ask it with API). ¿Have yout advance about it?

I´m using the information from the last post from keld1 user to read/write the API:

Thank you very much about your work. I think that I have the value of export/import to/from grid.

// 20240802091729
// http://192.168.1.21:8484/**getdev.cgi?device=3**

{
  "mod": 2,
  "enb": 1,
  "exp_m": 0,
  "regulate": 5,
  "enb_PF": 5,
  "target_PF": 0,
  "total_pac": 1393,
  "total_fac": 6000,
  "meter_pac": 333, //**here is the VALUE**
  "sn": "EASTRONB3240XXXXXXXX",
  "manufactory": "EASTRON",
  "type": "1",
  "name": "SDM230",
  "model": 2,
  "abs": 0,
  "offset": 2
} 

It give me this value about the EASTRON SDM230 meter.
“+ VALUE” is energy kWh import from grid.
“- VALUE” is energy kWh export to the grid.

Do you know where (address) to extract this informaticon with a sensor modbus.yaml and Node Red? This is my next challenge :wink:

Working!

1 Like

Hi! I just got a solplanet t3 hybrid inverter. I used codes what are provided here, thanks for that. Problem is that I had Nordpool sensors already defined in configurration.yaml, so I have tried several ways to use multiple sensor so I stored solar.yaml and norpool.yaml in own sensors directory and importted them by:
(configuration.yaml)
sensor: !include_dir_merge_named sensors/
template: !include_dir_merge_named template/
in sensors directory I have :
Nordpool.yaml >>

platform: nordpool     # Country/region to get the energy prices for. 
region: "FI"

# Override HA local currency used to fetch the prices from the API.
currency: "EUR"

# Add Value Added Taxes (VAT)?
VAT: True

# Energy price rounding precision.
precision: 3

# Percentage of average price to set the low price attribute
# low_price = hour_price < average * low_price_cutoff
low_price_cutoff: 0.95

# Display price in cents in stead of (for example) Euros.
price_in_cents: true

# Price displayed for MWh, kWh or Wh
price_type: kWh

# Template to specify additional cost to be added to the tariff.
# The template price is in EUR, DKK, NOK or SEK (not in cents).
# For example: "{{ current_price * 0.19 + 0.023 | float}}" 
additional_costs: "{{0.0|float}}"

and

solar.yaml

  • platform: rest
    resource: http://myip:8484/getdevdata.cgi?device=2&sn=dongleserial
    scan_interval: “00:00:10”
    name: solplanet
    value_template: “OK”
    json_attributes:
    • flg # ???
    • tim # date/time
    • tmp # inverter temperature / 10
    • fac # frequency / 100
    • pac # actual power watt
    • sac # apparent power
    • qac # reactive power
    • eto # total produced / 10
    • etd # total producted daily / 10
    • hto # running time
    • pf # ???
    • wan # ???
    • err # ???
    • vac # voltage / 10
    • iac # current / 10
    • vpv # string voltage
    • ipv # string current
    • str
      dongle returns:
      {
      “flg”: 1,
      “tim”: “20240821092224”,
      “tmp”: 380,
      “fac”: 5002,
      “pac”: 3316,
      “sac”: 3316,
      “qac”: 1,
      “eto”: 425,
      “etd”: 47,
      “hto”: 36,
      “pf”: 100,
      “err”: 0,
      “vac”: [2349, 2326, 2356],
      “iac”: [48, 49, 49],
      “vpv”: [4898, 0, 3000],
      “ipv”: [686, 0, 64],
      “str”: ,
      “stu”: 1,
      “pac1”: 1126,
      “qac1”: 0,
      “pac2”: 1124,
      “qac2”: 0,
      “pac3”: 1139,
      “qac3”: 0
      }

template.yaml >>

sensor:

  • name: “solplanet_current_production”
    unique_id: solplanet_current_production
    state: “{{ state_attr(‘solplanet’, ‘pac’) | float }}”
    unit_of_measurement: “W”
    device_class: energy
    state_class: measurement
  • name: “solplanet_daily_production”
    unique_id: solplanet_daily_production
    state: “{{ state_attr(‘solplanet’, ‘etd’) | float / 10 }}”
    unit_of_measurement: “kWh”
    device_class: energy
    state_class: total_increasing
  • name: “solplanet_total_production”
    unique_id: solplanet_total_production
    state: “{{ state_attr(‘solplanet’, ‘eto’) | float / 10 }}”
    unit_of_measurement: “kWh”
    device_class: energy
    state_class: total_increasing
  • name: “solplanet_temperature”
    unique_id: solplanet_temperature
    state: “{{ state_attr(‘solplanet’, ‘tmp’) | float / 10 }}”
    unit_of_measurement: “°C”
    device_class: temperature
    state_class: measurement

no errors and restart ok and Norpool works fine, but solplanet sensors are still not available.

any ideas?

Hi, I found a solution for this by testing hard. Thanks for the examples…

Are you getting json with data when you put this into your browser?
http://192.168.1.15:8484/getdevdata.cgi?device=2&sn=SP00066032310236

If you do, try using this format:

rest:
  - authentication: basic
    resource: http://192.168.1.15:8484/getdevdata.cgi?device=2&sn=SP00066032310236
    scan_interval: "00:00:10"
    timeout: 20 # sec
    sensor:
      - name: solplanet
        value_template: "OK"
        json_attributes:
          - "flg"
          - "tim"
          - "tmp"
          - "fac"
          - "pac"
          - "sac"
          - "qac"
          - "eto"
          - "etd"
          - "hto"
          - "pf"
          - "wan"
          - "err"
          - "vac"
          - "iac"
          - "vpv"
          - "ipv"
          - "str"

for sensors:

template:
  - sensor:
      - name: "Solplanet Current Production"
        unique_id: solplanet_current_production
        state: "{{ state_attr('sensor.solplanet', 'pac') }}"
        unit_of_measurement: "W"
        device_class: power
        state_class: measurement
      [- etc...]

Keep in mind, that your main sensor’s entity_id is sensor.solplanet

As for attribute flg, the values are as follows:

Device State:
0 = Wait
1 = Normal
2 = Fault
4 = Checking

Hi, two weeks ago I started working at integration for solplanet inverters. You can check it here: GitHub - zbigniewmotyka/home-assistant-solplanet: An Home Assistant integration for Solplanet inverters

To add new device you only need to provide inverter ip address.

Right now it provides monitoring of energy production and I’m working on battery monitoring.

4 Likes

This is nice!

I’ve found out that the device actually provides new values every 10 seconds. Do you think you can drop the refresh timer?

I’m using those near-realtime values to calculate my current electricity usage, combined with energy injection/extraction readings from the power grid.

Sure, I will make this time configurable via UI, so everyone will be able to adjust it to own needs.

I’ve made changes in integration which allows to specify interval for reading data from inverter. By default its 60s. If you want to change this value for already added device you have to remove it and add it again.

Awesome @zmszaman !!

Would it be also possible to not just read some of the data, but also set some specific data?
I would like to manually set the SOC min and max level manually with such a plugin. Would that be possible?

Thanks

@Chavell3 Yes, it is possible. Few minutes ago I’ve released v0.4.0-beta1 version which contains select field to choose battery work mode.
It is also possible to prepare configuration fields for min and max level, as this data is sent to inverter when battery work mode is changed.

awesome. That sounds really great! I’ll check that out