PV Data from Solarman WiFi logger - with API

Hello everyone, I’m trying to obtain my token from solarman, but I am getting the following:
{
“code”: “2101018”,
“msg”: “auth appId not found”,
“success”: false,
“requestId”: “e24a8a34f10be85a”
}
I am sure I put the correct data in the input, does anyone have any idea what could be wrong? Thanks.

I have exact same response for curl run

I got it working now, I was not replacing AppID in URL, replacing it with my appID worked fine

1 Like

Finally got it working too, I believe I was making the same mistake, thanks for pointing it out Shriganesh!

I am using it as below

add this to configuration.yaml

	rest:
	  resource: https://api.solarmanpv.com/device/v1.0/currentData?appId=<YOU APP ID>&language=en&=
	  method: POST
	  scan_interval: 300 #Solarman only get data every 5 min.
	  headers:
		Authorization: bearer <YOUR ACCESS TOKEN>
		Content-Type: application/json
	  payload: '{  "deviceSn": "<YOUR DEVICE SERIAL NO>"}'
	  
	  sensor:
		- name : "Inverter Temprature"
		  value_template: >
			{%- for dict_item in value_json.dataList -%}
				{%- if dict_item.key == "INV_T0"-%} 
					{{dict_item.value}} 
				{%- endif -%}
			{%- endfor -%}
		  unit_of_measurement: °C

		- name : "Total AC Output Power (Active)"
		  value_template: >
			{%- for dict_item in value_json.dataList -%}
				{%- if dict_item.key == "APo_t1"-%} 
					{{dict_item.value}} 
				{%- endif -%}
			{%- endfor -%}
		  unit_of_measurement: W      

		- name : "Cumulative Production kWh"
		  value_template: >
			{%- for dict_item in value_json.dataList -%}
				{%- if dict_item.key == "Et_ge0"-%} 
					{{dict_item.value}} 
				{%- endif -%}
			{%- endfor -%}
		  unit_of_measurement: kWh

		- name : "Daily Production kWh"
		  value_template: >
			{%- for dict_item in value_json.dataList -%}
				{%- if dict_item.key == "Etdy_ge1"-%} 
					{{dict_item.value}} 
				{%- endif -%}
			{%- endfor -%}
		  unit_of_measurement: kWh        

		- name : "AC Voltage R/U/A"
		  value_template: >
			{%- for dict_item in value_json.dataList -%}
				{%- if dict_item.key == "AV1"-%} 
					{{dict_item.value}} 
				{%- endif -%}
			{%- endfor -%}
		  unit_of_measurement: V

		- name : "AC Current R/U/A"
		  value_template: >
			{%- for dict_item in value_json.dataList -%}
				{%- if dict_item.key == "AC1"-%} 
					{{dict_item.value}} 
				{%- endif -%}
			{%- endfor -%}
		  unit_of_measurement: A      

		- name : "DC Power PV1"
		  value_template: >
			{%- for dict_item in value_json.dataList -%}
				{%- if dict_item.key == "DP1"-%} 
					{{dict_item.value}} 
				{%- endif -%}
			{%- endfor -%}
		  unit_of_measurement: W

		- name : "DC Current PV1"
		  value_template: >
			{%- for dict_item in value_json.dataList -%}
				{%- if dict_item.key == "DC1"-%} 
					{{dict_item.value}} 
				{%- endif -%}
			{%- endfor -%}
		  unit_of_measurement: A

		- name : "DC Voltage PV1"
		  value_template: >
			{%- for dict_item in value_json.dataList -%}
				{%- if dict_item.key == "DV1"-%} 
					{{dict_item.value}} 
				{%- endif -%}
			{%- endfor -%}
		  unit_of_measurement: V   
1 Like

Hi did you manage? I am receiving soon Deye inverters too

Hello, no my Solarman logger actually gave the ghost the other day. thus I was forced to get a new logger i’ve opped for a Solar assistant logger which has the HA integration already build in.

this give me real time and historical logging to seconds rather than every fe minutes

https://solar-assistant.io/

Here is my config.yaml I’m using it with a Sofar ME3000SP Battery Inverter. I followed the instruction from here to get the Token and Json list of variables, very easy to follow: Collect Inverter data from Solarman API

rest:
  resource: https://api.solarmanpv.com/device/v1.0/currentData?appId=<Your_AppID_Here>&language=en&=
  method: POST
  scan_interval: 300 #Solarman only get data every 5 min.
  headers:
    Authorization: bearer <Your_Token_Here>
    Content-Type: application/json
  payload: '{  "deviceSn": "<Your_Device_Serial_Here>"}'
  
  
  sensor:
    - name : "Sofar Inverter Temprature"
      value_template: >
        {%- for dict_item in value_json.dataList -%}
          {%- if dict_item.key == "INV_T0"-%} 
            {{dict_item.value}} 
          {%- endif -%}
        {%- endfor -%}
      unit_of_measurement: '°C'

    - name : "Sofar Inverter Radiator Temp"
      value_template: >
        {%- for dict_item in value_json.dataList -%}
          {%- if dict_item.key == "T_RDT1"-%} 
            {{dict_item.value}} 
          {%- endif -%}
        {%- endfor -%}
      unit_of_measurement: '°C'
      
    - name : "Sofar Total AC Output Power (Active)"
      value_template: >
        {%- for dict_item in value_json.dataList -%}
          {%- if dict_item.key == "APo_t1"-%} 
            {{dict_item.value}} 
          {%- endif -%}
        {%- endfor -%}
      unit_of_measurement: 'W'      

    - name : "Sofar Cumulative Production kWh"
      value_template: >
        {%- for dict_item in value_json.dataList -%}
          {%- if dict_item.key == "Et_ge0"-%} 
            {{dict_item.value}} 
          {%- endif -%}
        {%- endfor -%}
      unit_of_measurement: 'kWh'

    - name : "Sofar Daily Production kWh"
      value_template: >
        {%- for dict_item in value_json.dataList -%}
          {%- if dict_item.key == "Etdy_ge1"-%} 
            {{dict_item.value}} 
          {%- endif -%}
        {%- endfor -%}
      unit_of_measurement: 'kWh'        

    - name : "Sofar AC Voltage R/U/A"
      value_template: >
        {%- for dict_item in value_json.dataList -%}
          {%- if dict_item.key == "AV1"-%} 
            {{dict_item.value}} 
          {%- endif -%}
        {%- endfor -%}
      unit_of_measurement: 'V'

    - name : "Sofar AC Current R/U/A"
      value_template: >
        {%- for dict_item in value_json.dataList -%}
            {%- if dict_item.key == "AC1"-%} 
              {{dict_item.value}} 
            {%- endif -%}
        {%- endfor -%}
      unit_of_measurement: 'A'      

    - name : "Sofar DC Input Power"
      value_template: >
        {%- for dict_item in value_json.dataList -%}
            {%- if dict_item.key == "DPi_t1"-%} 
              {{dict_item.value}} 
            {%- endif -%}
        {%- endfor -%}
      unit_of_measurement: 'W'

    - name : "Sofar Battery Status"
      value_template: >
        {%- for dict_item in value_json.dataList -%}
            {%- if dict_item.key == "B_ST1"-%} 
              {{dict_item.value}} 
            {%- endif -%}
        {%- endfor -%}
      unit_of_measurement: ''

    - name : "Sofar Battery Voltage"
      value_template: >
        {%- for dict_item in value_json.dataList -%}
            {%- if dict_item.key == "B_V1"-%} 
              {{dict_item.value}} 
            {%- endif -%}
        {%- endfor -%}
      unit_of_measurement: 'V'   
    
    - name : "Sofar Battery Current"
      value_template: >
        {%- for dict_item in value_json.dataList -%}
            {%- if dict_item.key == "B_C1"-%} 
              {{dict_item.value}} 
            {%- endif -%}
        {%- endfor -%}
      unit_of_measurement: 'A' 
      
    - name : "Sofar Battery Power"
      value_template: >
        {%- for dict_item in value_json.dataList -%}
            {%- if dict_item.key == "B_P1"-%} 
              {{dict_item.value}} 
            {%- endif -%}
        {%- endfor -%}
      unit_of_measurement: 'W' 
      
    - name : "Sofar Battery SoC"
      value_template: >
        {%- for dict_item in value_json.dataList -%}
            {%- if dict_item.key == "B_left_cap1"-%} 
              {{dict_item.value}} 
            {%- endif -%}
        {%- endfor -%}
      unit_of_measurement: '%'
      
    - name : "Sofar Inverter Status"
      value_template: >
        {%- for dict_item in value_json.dataList -%}
            {%- if dict_item.key == "INV_ST1"-%} 
              {{dict_item.value}} 
            {%- endif -%}
        {%- endfor -%}
      unit_of_measurement: ''
      

Hi there , have you got it right to integrate solarman to HA?

After last weekends Solarman Server “upgrades” I lost all my sensor data. I had to go back and re generate the bearer token following this thread and now all sensors are working again.

follow: Collect Inverter data from Solarman API

Hi @Benje26

This is what I extract from the Solarman API for my HA:
image

Thank you , i gave up on HA after it crashed and i haven’t run a backup, i was fedup and now waiting for hubitat, i dont have time to play with HA or learn it

Hello,

we have installed a PV system today which uses a LSW3 “WiFi” stick logger. Looking at the web UI of that logger I see a possibility to configure a 2nd server. I wonder has anybody here any idea how that could be made useful to point the logger at my own system either instead or in addition to the Solarman backend ?

Kind Regards
Jan

Thereby hangs a very long tale.

Solarman loggers are used by many inverters under brand names such as Solis/Ginlong etc. These devices push data via server ‘A’ to the cloud. Many include options for server ‘B’, and some also ‘C’.

The general consensus from many postings regarding Solarman loggers is that typically the second server (B) settings either cannot be set or can be set but do not work / do anything.
Try looking for the config_hide setting page which may have a B server setting that actually works

Solarman have gradually moved to more complex protocols (now V5 I think) that require handshakes from the receiving end to work, a bit more push-pull-push rather than a simple push. No correct handshake, no data. Very much depends on the firmware of your model.

If you can set server B (I have a very old LAN-only stick model where I can, WiFi and recent versions probably can’t) then you need something listening at the other end (set this up first as these sticks quickly time out and then lock up for hours).

Other options include using Modbus TCP directly on the stick. Probably port 8899 - these sticks host a web page at port 80 and, in many cases, a functioning Modbus over TCP repeater port at something like 8899. This is a ‘pull’ request rather than a ‘push’

For those of us lucky enough to have an old stick with server B option (push data) that works, since you asked, this is how it is typically done.

Of all the options for getting data out of an inverter with a Solarman logging stick (API call to cloud, scrape the stick status page, Modbus to stick, piggyback with stick to inverter) the ‘server B’ option appears to no longer work.

If you are interested, there are many postings of various attempts to get to / through / from these loggers via push / pull / poll and other techniques. See below for one such example.

https://github.com/XtheOne/Inverter-Data-Logger

Good luck!

Thank you very much for the wealth of information.

I have done a bit of looking around and came across a Node Red implementation https://github.com/serek4/node-red-sofar-ktl-x. It appears to be the case that Server B is indeed ignored, I had a look at config_hide.html and I was going to make a change there to try if that helps me. However, I was not aware that there might be a way to get Modbus to work over WiFi. If I understand correct this has been working on older loggers ? I give that a shot and see how far I can get.

Thanks again for all the information
Kind Regards
Jan

Edit Start
I have had a look again in the config_hide.html, I can see there is a “Internal Server” configuration for port 8899 bound to IP address 10.10.100.254. I assume thats the Modbus TCP service ? Unfortunately I can not change the IP address.
Edit End

I think the answer is Yes, and No…

Thank you for the link - I had not seen that one, and it is very informative. Another way of getting data by proxy between the logger and the cloud. Good solution (keep both, no extra hardware) if you can get it to work.

My direct experience is with an old (probably V2) LAN connection data logger. This has an older interface with connectable server ‘B’, as well as an internal (and settable) Modbus port. Both of which I have been able to use (push out data, connect Modbus over TCP). Incidentally, my stick pushes out a data block of 250 bytes, which does not compare with any of the more recent data block lengths at all. Since Solarman (Solis) updated their cloud offering a few months ago, my stick has connection issues and locks up after a few minutes, only coming back around every three hours. Clearly an issue with it not managing the (V5) heartbeat and keep alive messages.

I also have a newer version (V4?) stick which does not want to connect to the inverter, but has the later web pages, where the server ‘B’ does not work and neither does the config_hide stuff. As it won’t connect to the inverter I cannot use it let alone effectively test the settings. I also only have LAN sticks, which are quite different to the WiFi ones, although the later LAN stick assumes it is a WiFi model and wants SSIDs, even though it is a LAN stick and has no physical WiFi.

The latest protocol, V5, is becoming better documented. I also found this

https://pysolarmanv5.readthedocs.io/en/latest/index.html

As far as I can tell, Solarman have always used ‘Modbus over TCP’ in one form or another to connect to the cloud. Now (V5) use Modbus (over TCP) data packets, which are encapsulated into a proprietary message set (both message package and message sequences). The WiFi modules use chipsets that work to port 8899 by default, and older ‘open’ ports have been removed from the firmware settings.

I think the short answer is, yes you can get to the data via TCP connection, on port 8899. The IP address is a local (private) one, so probably should reflect the IP address of your stick. However, I suspect that a) this is encapsulated in the V5 protocol, and b) it appears it does not work with Solis S3-WIFI-ST. A guess is that some brandings (eg Solis) have complicated the setup even further!

All somewhat confusing, difficult to work out what is going on, what any particular stick actually is/does, and challenging to connect to. After months of working on this I have now given up on all my sticks, turned it off, and gone down a direct physical connection to the inverter RS485 port to connect directly with Modbus (over TCP via a serial-ethernet adaptor).

I wish you every success in your endeavours!

Hi again,

the WiFi Stick has a setting for the inverter make on the config_hide.html page. At the very bottom is a selection between Deye and Sofar, maybe you need to select a different make there with the newer stick you have ? The IP address is not from my local LAN, it shows as IP Address of the WiFi AP. It looks to me the AP is only used for the initial setup via the phone app. I did not have a chance yet to connect a device to it but I shall try that with a R-Pi next week. I have not yet been successful with the Node Red implementation, I cant seem to change the server IP address or at least nothing shows up on the Node Red debug output. I have to do some packet sniffing on the router to see if it actually send anything to my Node Red server, so far IDK if the issue is the Node Red implementation for this or if the Stick actually ignores anything I enter for the server. I think this will be a bit of a longer project. There was also a mentioning of simply parsing the output of status.html but that reveals only very little useful information.

I keep at it anyway.
Regards
Jan

PS. The firmware version on the WiFi Stick is LSW3_15_FFFF_1.0.78

Hello Ronald. Thanks for this but I get an error message when entering the curl command in step 2:
{
“code”: “2101006”,
“msg”: “invalid param”,
“success”: false,
“requestId”: “e25e55fec6exxxxx”
}

I have checked the different input without success. Any idea?

Hello, sorry for reviving an old Post.
I found this in my search to integrate my Sofar ME3000SP.
I have the API and also followed the instructions. Then I used your Config.yaml, but is does not read any data.

I see all the sofar entities but no values. I just can’t get it working.

Check out my post here, it runs you through exactly what you want as I have the Same Battery Inverter:

and here: