Solarman Integration by Stephan Joubert

Well according to the documentation you should have full support:

Supported models:

ME3000SP - Full support
HYD-xx00-ES - Full support

I made some notes to test the API at Solarman website, can you try and see if you get the output directly from the website, then at least you know the values are available for your MQTT server to extract in JSON format:

If Solarman stops working then try updating the token using below API by following these instructions :

My Information:

#How to refresh the Solarman Token Code if sensors stop getting data:
If the SOFAR sensor data stops working try to refresh the token by following these steps:

  1. Go to https://reqbin.com/curl and paste in the following curl:
curl --request POST \
  --url 'https://api.solarmanpv.com/account/v1.0/token?appId=20211xxxxxxxxxx&language=en&=' \
  --header 'Content-Type: application/json' \
  --data '{
	"appSecret": "8cb8f0fec435y654ea127eda0c7d9f406e",
	"email": "[email protected]",
	"password": "9d564hks8679534kghtd6da660b155cf15872fae88fc365a48683cac720cf18"
}'

NOTE: your Sofarman password has to be hashed using SHA256 Password: SHA256 - Online Tools

  1. The output should look like this:
{
    "code": null,
    "msg": null,
    "success": true,
    "requestId": "d94127a5000d00ad",
    "access_token": "eyJhbxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx",
    "token_type": "bearer",
    "refresh_token": "eyJhbxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx",
    "expires_in": "5183999",
    "scope": null,
    "uid": 762072
}
  1. copy the ACCESS TOKEN and then enter in to this replacing the previous token after “bearer”:
curl --request POST \
  --url 'https://api.solarmanpv.com/device/v1.0/currentData?appId=<appId>&language=en&=' \
  --header 'Authorization: bearer eyJhbxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx' \
  --header 'Content-Type: application/json' \
  --data '{
	"deviceSn": "SE1ESxxxxxxxxx"
}'

NOTE: Paste the ACCESS TOKEN in to the Home Assistant CURL .YAML file: /config/packages/systems/sofar_battery_inverter/solarman_sensors.yaml

  1. This should return values:

Data Recovery from Inverter:

{
    "code": null,
    "msg": null,
    "success": true,
    "requestId": "51fe94ec1aaf79a2",
    "deviceSn": "SE1ESxxxxxxxxxx",
    "deviceId": 2150xxxxxx,
    "deviceType": "INVERTER",
    "deviceState": 1,
    "dataList": [{
        "key": "SN1",
        "value": "SE1ESxxxxxxxxx",
        "unit": null,
        "name": "SN"
    }, {
        "key": "SS_CY1",
        "value": "9",
        "unit": null,
        "name": "Production Compliance Country"
    }, {
        "key": "HWv1",
        "value": "V100",
        "unit": null,
        "name": "Hardware Version"
    }, {
        "key": "SWmai_v1",
        "value": "V280",
        "unit": null,
        "name": "Software Master Version"
    }, {
        "key": "DSPv1",
        "value": "V280",
        "unit": null,
        "name": "DSP Version"
    }, {
        "key": "DSPv2",
        "value": "V280",
        "unit": null,
        "name": "Vice DSP Version"
    }, {
        "key": "DPi_t1",
        "value": "5100",
        "unit": "W",
        "name": "Total DC Input Power"
    }, {
        "key": "AV1",
        "value": "251.80",
        "unit": "V",
        "name": "AC Voltage R/U/A"
    }, {
        "key": "AV2",
        "value": "0.00",
        "unit": "V",
        "name": "AC Voltage S/V/B"
    }, {
        "key": "AV3",
        "value": "0.00",
        "unit": "V",
        "name": "AC Voltage T/W/C"
    }, {
        "key": "AC1",
        "value": "4.79",
        "unit": "A",
        "name": "AC Current R/U/A"
    }, {
        "key": "AC2",
        "value": "0.10",
        "unit": "A",
        "name": "AC Current S/V/B"
    }, {
        "key": "AC3",
        "value": "0.08",
        "unit": "A",
        "name": "AC Current T/W/C"
    }, {
        "key": "Et_ge0",
        "value": "431",
        "unit": "kWh",
        "name": "Cumulative Production (Active)"
    }, {
        "key": "Etdy_ge1",
        "value": "8.55",
        "unit": "kWh",
        "name": "Daily Production (Active)"
    }, {
        "key": "ST_PG1",
        "value": "Purchasing energy",
        "unit": null,
        "name": "Grid Status"
    }, {
        "key": "PG_F1",
        "value": "49.97",
        "unit": "Hz",
        "name": "Grid Frequency"
    }, {
        "key": "PG_Pt1",
        "value": "-10.00",
        "unit": "W",
        "name": "Total Grid Power"
    }, {
        "key": "t_gc1",
        "value": "174",
        "unit": "kWh",
        "name": "Cumulative Grid Feed-in"
    }, {
        "key": "Et_pu1",
        "value": "9",
        "unit": "kWh",
        "name": "Cumulative Energy Purchased"
    }, {
        "key": "t_gc_tdy1",
        "value": "0.14",
        "unit": "kWh",
        "name": "Daily Grid Feed-in"
    }, {
        "key": "Etdy_pu1",
        "value": "1.09",
        "unit": "kWh",
        "name": "Daily Energy Purchased"
    }, {
        "key": "PG_V1",
        "value": "251.80",
        "unit": "V",
        "name": "Grid Voltage R/U/A"
    }, {
        "key": "PG_V2",
        "value": "0.00",
        "unit": "V",
        "name": "Grid Voltage S/V/B"
    }, {
        "key": "PG_V3",
        "value": "0.00",
        "unit": "V",
        "name": "Grid Voltage T/W/C"
    }, {
        "key": "PG_C1",
        "value": "6.50",
        "unit": "A",
        "name": "Grid Current R/U/A"
    }, {
        "key": "PG_C2",
        "value": "0.00",
        "unit": "A",
        "name": "Grid Current S/V/B"
    }, {
        "key": "PG_C3",
        "value": "0.00",
        "unit": "A",
        "name": "Grid Current T/W/C"
    }, {
        "key": "BUS_V2",
        "value": "396.00",
        "unit": "V",
        "name": "Busbar Voltage"
    }, {
        "key": "E_Puse_t1",
        "value": "3470.00",
        "unit": "W",
        "name": "Total Consumption Power"
    }, {
        "key": "Et_use1",
        "value": "249",
        "unit": "kWh",
        "name": "Cumulative Consumption"
    }, {
        "key": "Etdy_use1",
        "value": "7.26",
        "unit": "kWh",
        "name": "Daily Consumption"
    }, {
        "key": "B_ST1",
        "value": "Charging",
        "unit": null,
        "name": "Battery Status"
    }, {
        "key": "B_V1",
        "value": "50.60",
        "unit": "V",
        "name": "Battery Voltage"
    }, {
        "key": "B_C1",
        "value": "31.29",
        "unit": "A",
        "name": "Battery Current"
    }, {
        "key": "B_P1",
        "value": "-1650.00",
        "unit": "W",
        "name": "Battery Power"
    }, {
        "key": "GE_C1",
        "value": "20.41",
        "unit": "A",
        "name": "Production Current"
    }, {
        "key": "Pcg_dcg1",
        "value": "1590.00",
        "unit": "W",
        "name": "Charging/Discharging Power"
    }, {
        "key": "P_INV1",
        "value": "1000.00",
        "unit": "W",
        "name": "Storage Inverter Power"
    }, {
        "key": "B_left_cap1",
        "value": "71",
        "unit": "%",
        "name": "SoC"
    }, {
        "key": "t_cd_cg_n1",
        "value": "15",
        "unit": null,
        "name": "Cumulative Charging/Discharging Time"
    }, {
        "key": "t_cg_n1",
        "value": "80",
        "unit": "kWh",
        "name": "Total Charging Energy"
    }, {
        "key": "t_dcg_n1",
        "value": "72",
        "unit": "kWh",
        "name": "Total Discharging Energy"
    }, {
        "key": "Etdy_cg1",
        "value": "4.09",
        "unit": "kWh",
        "name": "Daily Charging Energy"
    }, {
        "key": "Etdy_dcg1",
        "value": "2.26",
        "unit": "kWh",
        "name": "Daily Discharging Energy"
    }, {
        "key": "INV_T0",
        "value": "39",
        "unit": "℃",
        "name": "Temperature- Inverter"
    }, {
        "key": "B_T1",
        "value": "22.00",
        "unit": "℃",
        "name": "Temperature- Battery"
    }, {
        "key": "T_RDT1",
        "value": "33",
        "unit": "℃",
        "name": "Radiator Temperature"
    }, {
        "key": "SYSTIM1",
        "value": "  22-05-30 09:54:51",
        "unit": null,
        "name": "System Time"
    }, {
        "key": "V_eme_o1",
        "value": "251.10",
        "unit": "V",
        "name": "Emergency Output Voltage"
    }, {
        "key": "P_eme_o1",
        "value": "0.00",
        "unit": "W",
        "name": "Emergency Output Power"
    }, {
        "key": "Etdy_ge_hou1",
        "value": "3.15",
        "unit": "h",
        "name": "Daily Production Hour"
    }, {
        "key": "HR_Ege_t1",
        "value": "60",
        "unit": "h",
        "name": "Total Production Hour"
    }, {
        "key": "CD_TIM1",
        "value": "0.03",
        "unit": "s",
        "name": "Countdown Time"
    }, {
        "key": "Buck_C1",
        "value": "4.67",
        "unit": "A",
        "name": "Buck Current"
    }, {
        "key": "LLC_BUS_V1",
        "value": "331.70",
        "unit": "V",
        "name": "LLC Busbar Voltage"
    }, {
        "key": "C_Dcp1",
        "value": "0.01",
        "unit": null,
        "name": "DC Component-Current"
    }, {
        "key": "V_Dcp1",
        "value": "-69.00",
        "unit": null,
        "name": "DC Component-Voltage"
    }, {
        "key": "INV_ST1",
        "value": "Grid connected",
        "unit": null,
        "name": "Inverter status"
    }]
}
1 Like

Thank you,
as i said i already use the integration using Solarman API and it works fine but i would try to get datas directly from the data logger directly with local access

Hi Guys, that 65534 that you’re seeing is the equivalent of - 1 when represented as an unsigned integer - I’m not sure how you would fix it, but I think you can declare the datatype as a signed integer and the issue will be sorted.

2 Likes

Hi Everyone,

Looking to change the amount charged overnight via solar estimates.

I know you can bring in things around python scripts etc, I’m just wondering what’s the easiest method?

I am currently capturing tomorrows solar estimate and have sofar2mqtt up and running.

Thanks for your help.

I use Solcast for my Solar predictions. I have a ‘input_number’ helper set up for the “overnight charge powerwall max charge” and then here are my automation (the Chooses part) that I use to set the different SOC levels required. Obviously I have a power wall but the principle should still be the same. Then using your sofar2mqtt you can turn on charging and turn off once the corresponding Sofar Battery SOC matches the input_number.overnight_charge_powerwall_max_charge

choose:
  - conditions:
      - condition: numeric_state
        entity_id: sensor.solcast_forecast_tomorrow
        below: 8
    sequence:
      - service: input_number.set_value
        data:
          value: 100
        target:
          entity_id: input_number.overnight_powerwall_max_charge
  - conditions:
      - condition: numeric_state
        entity_id: sensor.solcast_forecast_tomorrow
        above: 8
        below: 12
        value_template: ""
    sequence:
      - service: input_number.set_value
        data:
          value: 80
        target:
          entity_id: input_number.overnight_powerwall_max_charge
  - conditions:
      - condition: numeric_state
        entity_id: sensor.solcast_forecast_tomorrow
        above: 12
        below: 14
    sequence:
      - service: input_number.set_value
        data:
          value: 70
        target:
          entity_id: input_number.overnight_powerwall_max_charge
  - conditions:
      - condition: numeric_state
        entity_id: sensor.solcast_forecast_tomorrow
        above: 14
        below: 18
    sequence:
      - service: input_number.set_value
        data:
          value: 60
        target:
          entity_id: input_number.overnight_powerwall_max_charge
  - conditions:
      - condition: numeric_state
        entity_id: sensor.solcast_forecast_tomorrow
        above: 18
    sequence:
      - service: input_number.set_value
        data:
          value: 50
        target:
          entity_id: input_number.overnight_powerwall_max_charge
  - conditions:
      - condition: numeric_state
        entity_id: sensor.solcast_forecast_tomorrow
        above: 18
    sequence:
      - service: input_number.set_value
        data:
          value: 35
        target:
          entity_id: input_number.overnight_powerwall_max_charge

A bit of a double post, but: PV Data from Solarman WiFi logger - with API - #78 by mhoogenbosch

Did you check if the token has changed? Follow my post here on how to do that:

Hi Chris, what does passive mode means in this context?

1 Like

It’s the setting that you must change in the SoFar inverter menu system to allow RS485 controlling of the inverter. See energy storage mode below.

1 Like

Hi Chris,
is there a reason you choose/prefered the cmcgerty/Sofar2mqqt approach over GitHub - wills106/homeassistant-solax-modbus: SolaX Power Modbus custom_component for Home Assistant (Supports some Ginlong Solis, Growatt, Sofar Solar & Qcells Q.Volt Hyb) ? or are they having very different goals?

if I understand it correctly you can change the settings like charge / discharge of battery from HA. So this way for example you can build logic in HA to trigger when battery should charge?

Hi Joost,

As you know with home assistant, there are always many ways of doing the same thing. I just went the way I did, invested money and time in building the module add setting everything up. It all works for me and I can control charging and discharging of the SoFar and Pylontech batteries in HA…so I’m happy.

Did you find a way to see what the inverter returns locally? I am also trying to catch the Sofar variables locally.

Thanks

I don’t know if anyone can give me a clue here, I am trying to build an estimate for how much power I have avialable based on the load on the system

So something like:
So Inverter Load - (Solar Production + Battery Storage)

The one thing I am struggling to figure out is which metric is the current battery capacity in watts, I see percentage but no watts. Am I missing something.

If anyone has solved for this, please share.

I don’t use Solarman (I opted for Solar Assistant, but in the end the fundamentals are the same), but you are confusing some terminology. Capacity relates to energy (kWh or then kJ). Power is a rate (kW or then kJ/s). Capacity would be like the distance you can cover. Power would then be your speed in this analogy.

If you don’t have energy sensors, you need to integrate the power sensor’s and then sum them, or calculate the net power and integrate that.

Use method left: Integration - Riemann sum integral - Home Assistant.

Otherwise, if what you’re trying to calculate is whether you can switch on the kettle or washing machine now, given your solar potential and battery (all of this in W or kW), then it’s probably more complicated if you want to include the battery. It’s fairly easy just to calculate the difference between your solar forecast and current solar PV power (this is what I do), but your battery will have a max rating (W) and total capacity (kWh), so technically you can hit it as hard as your battery can deliver in combination with your inverter’s rating. Thus, it becomes a question of need over ability.

The reason I only look at the PV, is because that’s the free energy. The battery really is just a big buffer on will either be topped up by solar for free or the grid. Since the grid costs money, I leave it out of the calculation. It’s also much simpler.

You can have a look at all my sensors and stuff. I just recently completed it, but it covers some of the things above.

I can add a screenshot of my dashboard later when I’m at my computer.

Thank Pieter, makes sense and exactly what I needed. Solarman is kak, I don’t know what shenegans they are pulling with the ESP chip in the damn thing, but it’s wifi connectivity is so bad, irrespective of what you do. I have tons of other ESP devices that have no issues. I should probably migrate to Solar Assistant or a Solarman unit with RJ45

I came up with a couple of sensors. I am a complete amateur, but thought I would share in case someone finds use.

Convert battery % to Watts, I just got this from the capacity I have - 20% which is the cut-off

  - platform: template
    sensors:
      solarman_battestwatts:
        friendly_name: "Available Battery SOC Watts Est"
        value_template: "{{ <YOUR AVAILABLE CAPACITY> | float * states('sensor.solarman_battery_soc') | float(0) / 100 }}"
        unit_of_measurement: 'W'

Estimated Battery Hours Left

  - platform: template
    sensors:
      solarman_battesthoursleft:
        friendly_name: "Battery Est Hours Left"
        value_template: "{{ (states('sensor.solarman_battestwatts') | float / states('sensor.solarman_total_load_power') | float)|round(2) }}"
        unit_of_measurement: 'Hrs'

Estimated battery flat time

  - platform: template
    sensors:
      solarman_battestflattime:
        friendly_name: "Battery Est Flat Time"
        value_template: "{{ (as_timestamp(now()) + 60 * 60 * states ('sensor.solarman_battesthoursleft') | float) | timestamp_custom('%I:%M %p') }}"

My use case for these is pretty particular. We have unreliable power and can lose grid for days, so I need to manage consumption during the evening to ensure we make it through to morning. I have been using these sensors in combination with Forecast.Solar and an enervue system to do this.

2 Likes

Having struggled with this ever since I had my Sofar inverters installed, I think I have finally cracked it so will post my findings in case they help someone else.

I have 2 inverters - one HYD6000-EP hybrid with batteries that connects to the grid, and a second small. one (I forget the model) to bring in power from another bank of panels.

I was originally using the Solarman API interface with sofar2mqtt, but it recently stopped working and I wanted to try to run everything locally without using the API.

Using the Solarman integration, I couldn’t work out how to get data to appear, until I realised that the modbus protocols for the HYD-6000-EP are different from the 6000-ES. Using the sofar_g3hyd.yaml definitions seems to work, rather than the 3-6k-es ones.

In the energy dashboard, I followed the instructions on the integration github page:

  • Total energy bought
  • Total energy sold
  • PV generation total (I added both inverters here to total them)
  • Total battery discharge
  • Total battery charge

Will see how it goes over the next few days - but at least I can see my battery charge again!

Hello all
So I’ve been using this integration happily for some time.
I have Deye Hybrid 8KW inverter and have deye_hybrid.yaml selected in the config

One piece of info that has been bothering me though is there are 2 sensors that do not show the proper values…

SmartLoad Status and Time of use.
These just show “LOOKUP” and not the actual value.

If I change the yaml files and remove the lookup table on these 2 sensors i can see values of 16 and 255 respectively

now this by no means correlates with the original 0/1 (off/on) values in the lookup table.

Is there a way I can get all the possible lookups for these values?

btw… If I turn on smart load the 16 actually changes to 17 :face_with_raised_eyebrow:

try this for hybrid 3000

so you create the custom_parameters.yaml on inverter_definitions folder. then configure the new device with ip, serial number and select custom_parameters.yaml file.

work fine with serial number 27xxx

1 Like

I recently acquired a Deye Inverter and am exploring possibilities to integrate it with Home Assistant.

In my pursuit of the same, I got a Solarman Stick with it. I am hopeful that the collective wisdom of this community could shed some light on a few inquiries I have.

Firstly, I am perfectly comfortable investing a bit more if it guarantees superior control over my inverter. Is it feasible to remotely control the inverter using the Solarman Stick?

Secondly, I’m interested in understanding the latency involved in updates via the Solarman Stick. Could anyone provide an estimate of the delay that I might expect?

Lastly, would it be more beneficial to consider a custom solution instead of using Solarman? I’m open to any suggestions that would enhance the functionality of my setup.

Thank you in advance for your time and any assistance you can provide. I greatly appreciate it!