jmccrohan / pysolarmanv5

A python module to interact with Solarman Data Logging Sticks
MIT License
116 stars 25 forks source link

DLS-L Ethernet Loggers #22

Open Memotech-Bill opened 1 year ago

Memotech-Bill commented 1 year ago

I have a LAN data logger, serial number 19XXXXXXX, firmware version ME-121001-V1.0.6(202011261020).

This does not have port 8899 open. Instead port 30003 is open. I have tried a register scan on that port, but just get a timeout on the first register.

Does anyone have any experience with getting data from port 30003?

solarjones commented 1 year ago

I have the same LAN logger too and scanned for open ports and confirm 30003 and 80 are open. However, you can configure Server B and specify which port it send out on eg 8899. This will leave the Solis main data logging out to Solis servers using 30003, and duplicate the stream of data out to server B IP and port of your choice.

Currently attempting to capture the server b stream which is TCP encapsulated MODBUS (I think!) using this pysolarmanv5 but struggling to run the python code under HA. Work in progress.

Memotech-Bill commented 1 year ago

I am not currently attempting any integration, just running Python from the command line and attempting to list some results to the screen.

It looks as though port 30003 may be plain ModBus TCP. I once managed to get umodbus.exceptions.IllegalDataAddressError. I am now just getting timeouts on receive.

I tried the Server B route. All I was receiving was the initial SolarManv5 handshake, and since as far as I can tell nobody has worked out the correct response, I was not able to get any further to receive useful data. Also, after leaving this running for a while the logger locked up, and it was necessary to unplug it to restore operation. Other people have also reported this.

The server B option does offer a choice of four protocols:

I have yet to work out whether the choice made here makes any difference.

Which protocol have you selected?

Memotech-Bill commented 1 year ago

Having allowed time for the logger to recover from attempting to access non-existent registers, port 30003 does appear to be ModBus TCP.

Taking some register definitions from https://github.com/NosIreland/solismon3/blob/master/config/registers.py, I obtain (labels added manually afterwards):

Register: 33022     Value: 00022 (0x0016) - Year
Register: 33023     Value: 00011 (0x000b) - Month
Register: 33024     Value: 00003 (0x0003) - Day
Register: 33025     Value: 00020 (0x0014) - Hour
Register: 33026     Value: 00051 (0x0033) - Minute
Register: 33027     Value: 00041 (0x0029) - Second
Register: 33028     Value: 00000 (0x0000) - Unused
Register: 33029     Value: 00000 (0x0000) - Total Generation 1
Register: 33030     Value: 00058 (0x003a) - Total Generation 2
Register: 33031     Value: 00000 (0x0000) - Generated this month 1
Register: 33032     Value: 00014 (0x000e) - Generated this month 2
Register: 33033     Value: 00000 (0x0000) - Generated last month 1
Register: 33034     Value: 00044 (0x002c) - Generated last month 2
Register: 33035     Value: 00022 (0x0016) - Generated today
Register: 33036     Value: 00076 (0x004c) - Generated yesterday
Register: 33037     Value: 00000 (0x0000) - Generated this year 1
Register: 33038     Value: 00058 (0x003a) - Generated this year 2
Register: 33039     Value: 00000 (0x0000) - Generated last year 1
Register: 33040     Value: 00000 (0x0000) - Generated last year 2

My code is a heavily hacked version of register_scan.py:

""" Scan Modbus registers to find valid registers"""
import umodbus.client.tcp
import socket
import sys

def main(addr):
    sock = socket.create_connection ((addr, 30003), timeout = 20)

    print("Scanning input registers")
    for x in range(33022, 33041):
        try:
            val = umodbus.client.tcp.send_message(
                umodbus.client.tcp.read_input_registers(1, x, 1), sock)[0]
            print(f"Register: {x:05}\t\tValue: {val:05} ({val:#06x})")
        except umodbus.exceptions.IllegalDataAddressError:
            pass
    sock.close ()

if __name__ == "__main__":
    if len (sys.argv) == 2:
        main(sys.argv[1])
    else:
        print ("Usage: register_scan.py <ip address>")
solarjones commented 1 year ago

Just checked and my LAN logger has identical firmware to yours. Are you running the python code from within HA? I can't seem to get it to execute successfully, never mind getting results back! I have tried via NodeRed and got some but not all data and it wasn't great. So I definitely think getting the data directly via Modbus/python is preferable, and encouraged with your above results.

If you look at the solarman solis_hybrid.yaml, it lists out the registers for all the interesting realtime data. I'll try once again to get the python environment working under HA.

jmccrohan commented 1 year ago

Hi @Memotech-Bill @solarjones,

Have you looked at issue #5? Your findings and those of the others on #5 confirms that (at least certain versions of) Ethernet loggers act as Modbus RTU to TCP gateways. Therefore pysolarmanv5 isn't required at all. Just plain Modbus TCP. :-)

Regards, Jon

Memotech-Bill commented 1 year ago

@jmccrohan, Thank you, yes I was aware that some people had found that port 8899 was plain Modbus on some versions of the logger. However I had found almost no reference to port 30003 so I had no idea what I was looking at. I thought that here was probably a good place to look for help. Apologies if that was not appropriate. Please feel free to close the issue.

@solarjones, I don't currently have Home Assistant. I am running my code from the command line on a Raspberry Pi. Thank you for the reference to solis_hybrid.ymal, I had not previously found this. The PDF file referenced from the ymal file is even more interesting.

solarjones commented 1 year ago

@Memotech-Bill Thanks for the code and details. I've ditched using Server B and Node Red. Managed to get the Python environment working in HA.

So will try your code out to get some real time data from the inverter into HA. Currently getting errors with the TCP connection being closed by the logger, sometimes it works, sometimes it doesn't.

Perhaps NodeRed with its built in Modbus might be an option. Will keep trying.

jmccrohan commented 1 year ago

@Memotech-Bill Thanks for the code and details. I've ditched using Server B and Node Red. Managed to get the Python environment working in HA.

So will try your code out to get some real time data from the inverter into HA. Currently getting errors with the TCP connection being closed by the logger, sometimes it works, sometimes it doesn't.

Perhaps NodeRed with its built in Modbus might be an option. Will keep trying.

Any reason why you can't just use HA's native Modbus integration? It supports Modbus TCP, so in theory it should work.

alienatedsec commented 1 year ago

@Memotech-Bill Try this integration for your data logger https://github.com/wills106/homeassistant-solax-modbus