Ginlong Solis solar inverter monitoring

Thank you everyone going to give a go, what’s been the problem is not being able to confirm a working example with someone who has the same firmware.

Apologies for delay in responding - as a new user I was temporarily restricted to 3 replies to the thread (already used)!

I have attatched a screenshot of the settings I am using in monitoring stick - I had previously found that having settings here with nothing at the other end “listening” regularly locked up the web interface on the monitoring stick!

I have written up the node red flow here

I recently got a Solis RHI-3K-48ES-5G inverter with batteries installed. Using the instructions above I tried to use my LAN datalogger to connect OpenHab to it. But I couldn’t get it to work. The binary format has changed again with my generation apparently, and then I messed up the configuration so the interface didn’t load anymore. So I decided to ditch the logger and use Modbus. I bought a cheap RS485 to USB converter (Joy-it Omvormer (USB/RS485) Raspberry Pi, Arduino [1x USB-A 2.0 stekker - 1x 2-dradenkabel] Zwart | Conrad.be) to hook it up.

The connector to the datalogger is a proprietary 4-pin connector, so the plan was to sacrifice my stick and Frankenstein it to the USB converter. However, once I opened it up it turned out I could simply detach the white connector from the PCB and be done with it:

So then I simply used 2 jumper cables to connect the yellow and blue cables to the A and B inputs on the USB stick. You don’t need the other two wires, these provide 5v power to the PCB. Edit: photo after the fact:

All this even fits inside the original datalogger case, so using a USB extension cord I now have quite a neat solution (my OpenHab-machine is near the inverter fortunately). I even think it is reversible as I didn’t cut any wires.

I then tried to use the Modbus-binding to read out the values, but I couldn’t get it to work. I ended up using the exec-binding with mbpoll (GitHub - epsilonrt/mbpoll: command line utility to communicate with ModBus slave (RTU or TCP)) I originally used to debug the connection. Not as elegant as I hoped, but it works and my data stays local. Still not sure why the Modbus-binding doesn’t work, but anyway…

Interesting solution. I must admit I thought that connecting directly to the RS485 looked like a good idea. I didn’t realise it used Modbus as a protocol. How did you know which registers to read?

I guess the only downside for some might be losing the ability to use the Ginlong app. Personally, despite my general aversion to using cloud services, I’ve tolerated this one on the basis that my OpenHAB integration doesn’t depend on it.

1 Like

I googled a lot to find the right registers, but most of the info I found wasn’t right for my inverter. In the end, I found this document (translated from Chinese apparently) which lists everything and is mostly correct: https://www.scss.tcd.ie/coghlan/Elios4you/RS485_MODBUS-Hybrid-BACoghlan-201811228-1854.pdf

I think one could replicate the entire functionality of the Ginlong-app in OpenHab, but without the 5-minute update delay. I’m only reading a few registers at the moment (current production/consumption, battery percentage, …). Not sure if I should read more the way I’m currently doing or try to get the Modbus-binding to work…

Thanks @jeroenv . Your post inspired me to have a bit more of a dig into this.

When I look at the config page on the wifi stick, I see this:
image

I am wondering if this is some sort of TCP server for the Modbus connection. I can establish a connection to the port (and the connection fails to all other ports, so I know it is connected) but I’m not getting any responses to various Modbus polls, not even error messages.

I have tried both Modbus TCP and Modbus RTU over TCP, which I think is more likely because the server would just need to strip the header and pass the RTU message. No luck with either yet but feels like it warrants a bit more playing.

Also, I found elsewhere that the Solis inverters are compliant with the SunSpec layout for registers. I’d need to test to see if that was true but if so, it would be useful because the OpenHAB Modbus binding already has a thing definition for that spec. Might be worth making your thing a modbus:inverter-single-phase rather than a modbus:poller and see if that yields anything.

1 Like

The other option for connecting remotely to a Modbus device is the Elfin EE11 (wired) or Elfin EW11 (WiFi). These devices are flexible serial port servers and can translate between TCP and a serial port (in the case of the Exx1, and RS485 one).

I use an EW10 to connect to the serial port on my EVSE by WiFI and it works well.

There is a sister series called Protoss PE11 and PW11 if you prefer a DIN rail version. There are other products from the same supplier that do the same job in different packages.

If possible, I’d like to keep the Ginlong Monitoring side and not have to add any more hardware but I might order an EE11 and see if I can get at least that working. If that works, I suspect the binding will need an additional option for Modbus RTU over TCP because at the moment it looks like pure Modbus TCP.

Thanks @barneyd! I already tried the SunSpec-thing, doesn’t work either. I searched the forum here with the errors I’m getting, even installed a new version of the Modbus binding. Still nothing. mbpoll on the same machine works flawlessly.

I’m not sure SunSpec is the way to go however. It doesn’t have a channel for the battery for example, so it doesn’t give me enough info.

I’ve also found out that the integer-registers are in big endian, which explains why some registers were not giving me the correct data. I don’t know much about modbus so I don’t really know what I’m doing ;-). But at least it means the PDF I linked seems to be correct.

BTW would it be possible to “splice” the connector so you could read the modbus-data and keep the logging stick? Still some modification of the hardware but you might be able to combine both.

Show us the settings you use for that.

You can only have one master on a modbus serial link.

I’m going to give this a bit more of a try.

My inverter is in the detached garage so I can’t cable it to my openHAB server. I’ve ordered on of these to connect over WiFi. It’s a sister product of the Elfin range, which are pretty good.

I also bought a plug that I’m hoping will mean I can connect to the inverter without having to borrow the connector from the WiFi stick. A bonus is that it includes the male half so I can get to the baseband Modbus that the stick is putting out to see if there’s any chance of using the stick to read the registers instead of an external device.

1 Like

So to read the register with the battery load percentage for example, I use:

mbpoll -a 1 -m rtu -d 8 -P none -b 9600 -t 3 -r 33139 /dev/ttyUSB1 -1 -q -B -0

This gives me this output:

-- Polling slave 1...
[33139]:        50

I configured a Modbus Serial Slave thing with the same values, a poller and a data thing. They all list as online, but an Item value is always NULL. I have seen these errors in openhab.log:

[WARN ] [rt.modbus.internal.ModbusManagerImpl] - Error getting a new connection for endpoint ModbusSerialSlaveEndpoint@164bc49b[portName=/dev/ttyUSB1]. Error was: java.lang.InterruptedException null
[WARN ] [rt.modbus.internal.ModbusManagerImpl] - Could not connect to endpoint ModbusSerialSlaveEndpoint@164bc49b[portName=/dev/ttyUSB1] -- aborting request ModbusReadRequestBlueprint@d8ba82b[slaveId=1,functionCode=READ_INPUT_REGISTERS,start=3005,length=17,maxTries=3] [operation ID 1dfbeee0-7952-4b53-8639-dcc94ec63c94]

I’ve searched the forums, so I have:

  • Added the device to the JVM parameters
  • Upgraded the nrjavaserial library
  • Upgraded the binding to v. 3.1
  • Tried a number of different settings

But no avail…

Binding can’t get at your serial port.
Note that if mbpoll has hold of the port, openHAB cannot.
If you have more than one Bridge Thing referencing the same port, make sure they all match in setting details.

Don’t keep them secret.

Hi @barneyd, did you get anywhere with this? I’m still running the mbpoll-script. I tried the modbus-binding again after upgrading to 3.1, but now I’m getting CRC-errors:

Error with read: org.openhab.core.io.transport.modbus.internal.ModbusSlaveIOExceptionImpl: Modbus IO Error with cause=ModbusIOException, EOF=false, message='I/O exception: IOException CRC Error in received frame. 0 bytes of payload () with invalid CRC of 01 83 ', cause2=null

So that still doesn’t work. I did get a call from my solar panel installer asking me to re-insert the logging stick so they can monitor the installation for errors, so I was wondering if you got it to work.

The plug I bought didn’t fit. I’ve put this on hold as I’m installing an AC coupler battery storage inverter, which has become the priority project.

On the Modbus binding there is an option for RTU encoding. Worth checking that is set correctly? You will get an invalid checksum error if the response from the inverter isn’t encoded as expected by the binding.

The other thing that can cause a checksum error is if another master is polling the same slave at the same time.

Can you tell us how did you go about it? I have always crc error when I attempted to read the registers.

Have you done writing to the inverter’s modbus port? I wonder if we can write to the holding register to control the power output of the inverter depending on the demand. Or any other controls that may be beneficial to us

Bridge modbus:tcp:solcelle [ host="192.168.1.47", port=502, id=1  ] {

    // read-write for coils. Reading 4 coils, with index 4, and 5.
    // These correspond to input register numbers 000005, and 000005
    //Bridge poller coils [ start=4, length=2, refresh=1000, type="coil" ] {
    //    // Note the zero based indexing: first coil is index 0.
    //    Thing data do4 [ readStart="4", readValueType="bit", writeStart="4", writeValueType="bit", writeType="coil" ]
    //    Thing data do5 [ readStart="5", readValueType="bit", writeStart="5", writeValueType="bit", writeType="coil" ]
    //}
    // read-only for input registers. Reading 2 registers, with index 1500, 1501, 1502, 1503.
    // These correspond to input register numbers 301501, 301502, 301503, 301504.
    Bridge poller input_3005 [ start=3005, length=38, refresh=10000, type="input" ]{
        Thing data input_3005 [ readStart="3005", readValueType="uint16", readTransform="JS(milli.js)"]
        Thing data input_3007 [ readStart="3007", readValueType="uint16", readTransform="JS(milli.js)"]
        Thing data input_3009 [ readStart="3009", readValueType="uint16"]
        Thing data input_3014 [ readStart="3014", readValueType="uint16", readTransform="JS(tidel.js)"]
        Thing data input_3017 [ readStart="3017", readValueType="uint16"]
        Thing data input_3019 [ readStart="3019", readValueType="uint16"]
        Thing data input_3021 [ readStart="3021", readValueType="uint16", readTransform="JS(tidel.js)"]
        Thing data input_3022 [ readStart="3022", readValueType="uint16", readTransform="JS(tidel.js)"]
        Thing data input_3035 [ readStart="3035", readValueType="uint16", readTransform="JS(tidel.js)"]
        Thing data input_3038 [ readStart="3038", readValueType="uint16", readTransform="JS(tidel.js)"]
        Thing data input_3041 [ readStart="3041", readValueType="uint16", readTransform="JS(tidel.js)"]
        Thing data input_3042 [ readStart="3042", readValueType="uint16", readTransform="JS(prosent.js)"]
    }

    //Bridge poller holding_1100 [ start=1100, length=5, refresh=10000, type="holding" ]{
    //    Thing data holding_1103 [ readStart="1103", readValueType="uint16", writeStart="1103", writeValueType="uint16", writeType="holding" ]
    //}
}
//Solcelleinverter
Number Inverter_Today_KW_once       "Produsert per dag [%.1f kWh]"                             (gPersist, gSolcelle)

Number Inverter_Realtime_ACW        "Produksjon nå AC[%.3f kW]"                                  (gPersist, gSolcelle)      ["Power"]       { channel="modbus:data:solcelle:input_3005:input_3005:number"}
Number Inverter_Realtime_DCW        "Produksjon nå DC [%.3f kW]"                                  (gPersist, gSolcelle)    { channel="modbus:data:solcelle:input_3005:input_3007:number"}
Number Inverter_AlltimeEnergy_KW    "Produsert totalt [%.0f kWh]"                              (gPersist, gSolcelle)        ["Energy"]      { channel="modbus:data:solcelle:input_3005:input_3009:number"}
Number Inverter_Today_KW            "Produsert i dag [%.1f kWh]"                               (gPersist, gSolcelle)        ["Energy"]      { channel="modbus:data:solcelle:input_3005:input_3014:number"}
Number Inverter_ThisYear_KW            "Produsert i år [%.1f kWh]"                               (gPersist, gSolcelle)    { channel="modbus:data:solcelle:input_3005:input_3017:number"}
Number Inverter_LastYear_KW            "Produsert i fjor [%.1f kWh]"                               (gPersist, gSolcelle)    { channel="modbus:data:solcelle:input_3005:input_3019:number"}
Number Inverter_Realtime_DCV        "Spenning DC [%.1f V]"                                     (gPersist, gSolcelle)    { channel="modbus:data:solcelle:input_3005:input_3021:number"}
Number Inverter_Realtime_DCI        "Strøm DC [%.1f A]"                                        (gPersist, gSolcelle)    { channel="modbus:data:solcelle:input_3005:input_3022:number"}
Number Inverter_Realtime_ACV        "Spenning AC [%.1f V]"                                     (gPersist, gSolcelle)        ["Voltage"]     { channel="modbus:data:solcelle:input_3005:input_3035:number"}
Number Inverter_Realtime_ACI        "Strøm AC [%.1f A]"                                        (gPersist, gSolcelle)        ["Current"]     { channel="modbus:data:solcelle:input_3005:input_3038:number"}
Number Inverter_Realtime_ACF        "Frekvens [%.2f Hz]"                                       (gPersist, gSolcelle)        ["Frequency"]   { channel="modbus:data:solcelle:input_3005:input_3042:number"}
Number Inverter_Temp                "Temperatur [%.1f C]"                                      (gPersist, gSolcelle)        ["Measurement", "Temperature"] { channel="modbus:data:solcelle:input_3005:input_3041:number"}

I haven’t tried it, but the PDF I linked to in this post lists all registers you can read from/write to.

How do you use modbus TCP with the solis inverter?