Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add Version 5 protocol support #3

Open
XtheOne opened this issue Oct 1, 2017 · 133 comments
Open

Add Version 5 protocol support #3

XtheOne opened this issue Oct 1, 2017 · 133 comments
Assignees

Comments

@XtheOne
Copy link
Owner

XtheOne commented Oct 1, 2017

Implement support for V5 protocol as used in new embedded ethernet loggers.
Needs documentation from Omnik and or iGEN / Solarman.

This is requested.
Also a firmware update file is requested.

@XtheOne
Copy link
Owner Author

XtheOne commented Oct 12, 2017

Development done in branch: "Experimental_Frame_Version_5_support"

@abc1000
Copy link

abc1000 commented Oct 13, 2017

Tried 00-ff for the first bit, some works for 70%..
But with these empty, i'v got also a error..
frame_hdr = ''
command = ''

@XtheOne
Copy link
Owner Author

XtheOne commented Oct 13, 2017

frame_hdr = byte(headCode) + short(dataFieldLength) + short(contrlCode) + short(serialNumber)
Change only contrlCode and serialNumber (which is a frame sequential number)
if you change command length then change dataFieldLength to match the nr of bytes.

@XtheOne
Copy link
Owner Author

XtheOne commented Oct 30, 2017

As there is still no more help from Omnik or SolarMan about the V5 frame data needed to trigger the logger we are a bit stuck at the moment.
Will now wait for updates for the Android Apps or firmware from/for the ethernet module as none of the apps now gets data from the new logger in local mode.
It seems that the firmware still is buggy as it frequently locks up so hopefully an update will come.

@PhyxionNL
Copy link
Contributor

Added a PR, thanks for this script 👍

@XtheOne
Copy link
Owner Author

XtheOne commented Nov 20, 2017

The reply is only 99 bytes, have to check the docs what frame type this is.

@PhyxionNL
Copy link
Contributor

FYI, the main_fwver and slave_fwver both still fail in InverterMsg with this logger. Most likely because 101 and 121 don't exist due to 99 bytes.

@XtheOne
Copy link
Owner Author

XtheOne commented Dec 13, 2017

Yes, cannot get data past EOF. Still need to fix this.
No time too many work to do before end of this year :-(

@XtheOne
Copy link
Owner Author

XtheOne commented Dec 13, 2017

Still NO help from Omnik or Solarman dev...

@coraminformatica
Copy link

Hello, I need also the V5 support.
How can I help you?
I tried your frame reader for V5 but I get right only the serial number.
I can't decode e_total, e_today or other important values.

Regards

@XtheOne
Copy link
Owner Author

XtheOne commented Mar 16, 2018

Still........ Nothing from Omnik. :-(

Repository owner deleted a comment from PhyxionNL Mar 19, 2018
Repository owner deleted a comment from Raamkonijn Mar 19, 2018
@stenjo
Copy link

stenjo commented Apr 11, 2018

I'm really interested in this. Have a data logger stick from Ginlong where they obviously are using frame format V5 as the inverter is logging new sets of data like total energy yesterday, this month and last month. Think I have debugged where to find the main firmware version and yesterdays data, but my energy reading does not match what my app claims to be the current production level.
Any way I can contribute?

@XtheOne
Copy link
Owner Author

XtheOne commented Apr 16, 2018

I would really need some trace data.
I still did not find what magic string would trigger the logger.
In the mean time I am working on a listen server which waits for a logger message and then processes the message. You can then add a server in the logger pointing to the python server IP/port

@stenjo
Copy link

stenjo commented May 2, 2018

Solis Three phase communication protocal.pdf
Got hold of this document. Will that cover Version 5 of the protocol?
Looks to be Version 7...

@XtheOne
Copy link
Owner Author

XtheOne commented May 2, 2018

The Wi-Fi data logger communicates to the inverter trough RS485, the protocol is MODBUS.
The IP network frames are in iGEN own format. And V4 format has been in use for a long time but V5 was recently introduced. I first found it on the new wired ethernet logger module from Omnik.
I hope that they will implement it in the android app soon.
I know the sent frame format, but the V5 frame which has to be sent to the logger to trigger it is still unknown.
You can monitor the frames with logger data which are sent to the public server with wireshark on your network.

@XtheOne
Copy link
Owner Author

XtheOne commented Oct 16, 2018

I might get an ethernet logger myself later this year.
No replies from Omnik or iGEN until now.

@nielsvn92
Copy link

Not sure if you're still working on this, but I tried your experimental branch in attempt to get my inverter working with your script, and I actually do get a response now. I didn't get that on the master branch.

This is the error I'm getting:
2019-01-10 17:42:13,020 INFO Loggers found on the network: ['192.168.1.xxx', '640xxxxxx']. 2019-01-10 17:42:13,020 INFO Connecting to logger with IP: 192.168.1.xxx and SN 640xxxxxx 2019-01-10 17:42:13,021 INFO connecting to 192.168.1.xxx port 8899 2019-01-10 17:42:19,127 DEBUG RAW sent Packet (len=15): a5:02:00:10:45:00:00:7b:8a:26:26:01:00:a9:15 E{&& 2019-01-10 17:42:19,164 DEBUG RAW received Packet (len=38): a5:19:00:10:15:00:18:7b:8a:26:26:01:01:29:da:0f:00:e1:98:00:00:c1:9b:27:5c:2b:45:52:52:3d:2d:31:0d:0a:0d:0a:f0:15 {&&)'\+ERR=-1 2019-01-10 17:42:19,164 DEBUG DATA len=640.0: Traceback (most recent call last): File "LiveStats.py", line 17, in <module> inverter_exporter.run() File "/<path>/Inverter-Data-Logger/InverterExport.py", line 137, in run if (msg.msg)[:9] == 'DATA SEND': File "/<path>/Inverter-Data-Logger/InverterMsg.py", line 88, in msg return self.__get_string(self.Frame_offset + 0, self.len + self.Frame_offset + 0) File "/<path>/Inverter-Data-Logger/InverterMsg.py", line 28, in __get_string return self.raw_msg[begin:end] TypeError: slice indices must be integers or None or have an __index__ method

I have an Omnik 3K TL3, and the Wi-Fi data logger has firmware version H4.01.51MW.2.01W1.0.64(2018-01-251-D).
I too am not able to configure any other remote server.

@ppiwowar
Copy link

nielsvn92, I am glad to know someone with the same wifi firmware version ( H4.01.51MW.2.01W1.0.64(2018-01-251-D) ) got ANY answer at last. It must be a kind of error-frame as I see
+ERR=-1
asscii sequence at the end of your received packet ....
Maybe your inverter is not connected or sent packet is still invalid.
I will check myself in few hours ...
XtheOne, your advice, please.

@ppiwowar
Copy link

After experimenting with our omnik/wifi we get the same error result. I think we have a problem with calling packet frame.

@XtheOne
Copy link
Owner Author

XtheOne commented Jan 14, 2019

The problem is that I do not have a new WiFi module or able to get a firmware update from Omnik.
I asked them several times for a firmware file.
This started with the new Ethernet module which had the first buggy implementation of the V5 protocol from iGEN. This interface crashes on the magic packet so we stopped there.
It looks that this new WiFi firmware also has V5 but is responding to the magic frame.
I will look what data it returns.
It is also strange that entering more than the default server is not possible anymore.
This is why the server script was made to also support in decoding the V5 frame layout.
Until now I only got some information of the frame layout from the android app. but the implementation there is incomplete and won't work.

@XtheOne
Copy link
Owner Author

XtheOne commented Jan 14, 2019

ERR=-1 probably shows that the V5 magic frame is not correct.
What does scanloggers returns?

@ppiwowar
Copy link

We did not use scanloggers.py. LiveStats.py with setting in the config file:
gateways = auto
did not discover any logger automatically. Only setting logger manually in the config file:
gateways = 192.168.1.160,638xxxxxx
found the logger and returned the frame. We will check with scan loggers.py too.
Could you please specify, what is the 'android app' you use so we could check it here. Standard Omnik app in the manual mode does not give the access to electricity parameters of inverter. It gives a possibility to change some config parameters ....
General question: Has Omnik may limited access to the inverter by third party software so the portal is the only option?

@XtheOne
Copy link
Owner Author

XtheOne commented Jan 14, 2019

iGEN is the company which creates the logger. they upgraded the V4 protocol to V5 last year.
The app on android I use is from Omnik and the one from iGEN which is newer and has some parts about V5 but incomplete.
Until now no luck on getting a firmware update file for the newer loggers...
Or any documentation.
I hoped that someone could enter my IP in their logger so I would get some frames to analyse.

@nielsvn92
Copy link

What we are able to do is setting the internal server of port 8899 to client mode, and insert any IP/port as server. I've tried it before, but it seems there is no data coming out. If I remember correctly there was only the following TCP flow:

  • Handshake
  • Directly FIN, FIN-ACK (I believe from both sides, will have to double check)

So no data.

If you want, I could move my logger to another subnet and grant you access to the inverter WiFi module via a VPN @XtheOne? Or would physical access be required?
When I had the gateway set to auto, it could detect my logger btw with the correct SN.

Is there anything else we can try for you?

@ppiwowar
Copy link

I have already tried setting the internal server of port 8899 to client mode before. Linux or Node-Red have got connected but no data coming in - exactly as with your trial...
The only thing comes to my mind is sniffing .... ? Or else could I possibly downgrade WiFi card firmware ? Risky, as it might not talk to the inverter any more ....

@silvanverschuur
Copy link

@jessiesolar

This is the output of the python3 server.py command:

2021-04-19 19:09:01,009 - solis_service - INFO - Starting server on 192.168.1.51:10000
2021-04-19 19:10:00,631 - solis_service - DEBUG - Received heartbeat message from ('192.168.1.18', 1196)
2021-04-19 19:10:01,717 - solis_service - DEBUG - Received data message from ('192.168.1.18', 36257)
2021-04-19 19:10:01,718 - solis_service - DEBUG - data message: {'inverter_serial_number': 'NLBN50201894N017', 'inverter_temperature': <Quantity(23.4, 'centigrade')>, 'dc_voltage_pv1': <Quantity(262.4, 'volt')>, 'dc_current': <Quantity(1.1, 'ampere')>, 'ac_current_t_w_c': <Quantity(0.0, 'ampere')>, 'ac_voltage_t_w_c': <Quantity(0.0, 'volt')>, 'ac_output_frequency': <Quantity(50.02, 'hertz')>, 'daily_active_generation': <Quantity(16.76, 'kilowatt_hour')>, 'total_dc_input_power': <Quantity(3225138.0, 'watt')>, 'total_active_generation': <Quantity(0.0, 'kilowatt_hour')>, 'generation_yesterday': <Quantity(1335.8, 'kilowatt_hour')>, 'power_grid_total_apparent_power': <Quantity(0.0, 'volt_ampere')>}
2021-04-19 19:10:12,648 - solis_service - DEBUG - Received data message from ('192.168.1.18', 17344)
2021-04-19 19:10:12,649 - solis_service - DEBUG - data message: {'inverter_serial_number': 'NLBN50201894N017', 'inverter_temperature': <Quantity(23.4, 'centigrade')>, 'dc_voltage_pv1': <Quantity(262.4, 'volt')>, 'dc_current': <Quantity(1.1, 'ampere')>, 'ac_current_t_w_c': <Quantity(0.0, 'ampere')>, 'ac_voltage_t_w_c': <Quantity(0.0, 'volt')>, 'ac_output_frequency': <Quantity(50.02, 'hertz')>, 'daily_active_generation': <Quantity(16.76, 'kilowatt_hour')>, 'total_dc_input_power': <Quantity(3225138.0, 'watt')>, 'total_active_generation': <Quantity(0.0, 'kilowatt_hour')>, 'generation_yesterday': <Quantity(1335.8, 'kilowatt_hour')>, 'power_grid_total_apparent_power': <Quantity(0.0, 'volt_ampere')>}
2021-04-19 19:10:23,656 - solis_service - DEBUG - Received data message from ('192.168.1.18', 3682)
2021-04-19 19:10:23,657 - solis_service - DEBUG - data message: {'inverter_serial_number': 'NLBN50201894N017', 'inverter_temperature': <Quantity(23.4, 'centigrade')>, 'dc_voltage_pv1': <Quantity(262.4, 'volt')>, 'dc_current': <Quantity(1.1, 'ampere')>, 'ac_current_t_w_c': <Quantity(0.0, 'ampere')>, 'ac_voltage_t_w_c': <Quantity(0.0, 'volt')>, 'ac_output_frequency': <Quantity(50.02, 'hertz')>, 'daily_active_generation': <Quantity(16.76, 'kilowatt_hour')>, 'total_dc_input_power': <Quantity(3225138.0, 'watt')>, 'total_active_generation': <Quantity(0.0, 'kilowatt_hour')>, 'generation_yesterday': <Quantity(1335.8, 'kilowatt_hour')>, 'power_grid_total_apparent_power': <Quantity(0.0, 'volt_ampere')>}

As you can see the inverter sends the same message 3 times with an interval of about 10 seconds. After these messages it remains silent. I have captured some of the data between the inverter and the cloud service (using the intercept script). I'm wondering if the suffix is always the same.

This is a part of the intercept output:

serving on ('192.168.1.51', 10000)
{"timestamp": "2021-04-13T18:45:05.802607", "target": ["47.88.8.200", 10000], "data": "pVYAEEEAAYojXCUC92f/AhQAAAAAAAAABTx4AWQBSDQuMDEuNTFNVy4yLjAxVzEuMC42NCgyMDE4LTAxLTI1MS1EKQAAALxU+fcsqTE5Mi4xNjguMS4xOAAAAAAAAAECATIV", "length": 99}
{"timestamp": "2021-04-13T18:45:05.987256", "target": ["192.168.1.18", 18888], "data": "pQoAEBEqAYojXCUCAZHKdWCqqgAACxU=", "length": 23}
{"timestamp": "2021-04-13T18:45:07.062630", "target": ["47.88.8.200", 10000], "data": "pdcAEEIqAoojXCUBAgH4Z/8CFQAAAJlidl0BALosAABOTEJONTAyMDE4OTROMDI57QCeCl4KMwAJADwAAAAAACYJAAAAAIgTmAUAAAUIAAAY6wAAQTUAAAEAAAAAAAAAAAAAAAAAAAAAAFY1LjI3QnVpbGQyNjEAAAAAAAAAVjUuNDNCdWlsZDE4MgAAAAAAAAAwLjAwQnVpbGQwMDAAAAAAAAAAADAuMDBCdWlsZDAwMAAAAAAAAAAAMC4wMEJ1aWxkMDAwAAAAAAAAAAAwLjAwQnVpbGQwMDAAAAAAAAAAABIV", "length": 228}
{"timestamp": "2021-04-13T18:45:07.207958", "target": ["192.168.1.18", 14511], "data": "pQoAEBIrAoojXCUBAZPKdWCqqgAADxU=", "length": 23}
{"timestamp": "2021-04-13T18:45:09.112543", "target": ["47.88.8.200", 10000], "data": "pRwAEEgrA4ojXCUB+Wf/AhYAAACbYnZdAQEM82f/AgAAAAAAAAAAgRU=", "length": 41}
{"timestamp": "2021-04-13T18:45:09.257586", "target": ["192.168.1.18", 5715], "data": "pQoAEBgsA4ojXCUBAZXKdWCqqgAAGRU=", "length": 23}
{"timestamp": "2021-04-13T18:45:11.375479", "target": ["47.88.8.200", 10000], "data": "pTwAEEgsBIojXCUB+2f/AhgAAACbYnZdAQUsmdFtW0g0LjAxLjUxTVcuMi4wMVcxLjAuNjQoMjAxOC0wMS0yNTEtRCkAAAAyFQ==", "length": 73}
{"timestamp": "2021-04-13T18:45:11.527394", "target": ["192.168.1.18", 5759], "data": "pQoAEBgtBIojXCUBAZfKdWCqqgAAHRU=", "length": 23}
{"timestamp": "2021-04-13T18:45:21.795128", "target": ["47.88.8.200", 10000], "data": "pQEAEEctBYojXCUAuBU=", "length": 14}
{"timestamp": "2021-04-13T18:45:21.941758", "target": ["192.168.1.18", 36488], "data": "pQoAEBcuBYojXCUAAaHKdWCqqgAAJxU=", "length": 23}
{"timestamp": "2021-04-13T18:47:27.352197", "target": ["47.88.8.200", 10000], "data": "pQEAEEcuBoojXCUAuhU=", "length": 14}
{"timestamp": "2021-04-13T18:47:27.352566", "target": ["192.168.1.18", 38516], "data": "", "length": 0}
{"timestamp": "2021-04-13T18:49:49.270415", "target": ["47.88.8.200", 10000], "data": "pQEAEEcuB4ojXCUAuxU=", "length": 14}
{"timestamp": "2021-04-13T18:49:49.270748", "target": ["192.168.1.18", 28424], "data": "", "length": 0}
{"timestamp": "2021-04-13T18:50:24.844280", "target": ["47.88.8.200", 10000], "data": "pdcAEEIuCIojXCUBAgE0af8CUwEAAJpidl0BALssAABOTEJONTAyMDE4OTROMDI56AB6CloKMgAJADoAAAAAABwJAAAAAIQTYwUAABAIAAAZ6wAAQTUAAAEAAAAAAAAAAAAAAAAAAAAAAFY1LjI3QnVpbGQyNjEAAAAAAAAAVjUuNDNCdWlsZDE4MgAAAAAAAAAwLjAwQnVpbGQwMDAAAAAAAAAAADAuMDBCdWlsZDAwMAAAAAAAAAAAMC4wMEJ1aWxkMDAwAAAAAAAAAAAwLjAwQnVpbGQwMDAAAAAAAAAAADQV", "length": 228}
{"timestamp": "2021-04-13T18:50:24.844545", "target": ["192.168.1.18", 7009], "data": "", "length": 0}
{"timestamp": "2021-04-13T18:50:35.838414", "target": ["47.88.8.200", 10000], "data": "pdcAEEIuCYojXCUBAgE+af8CXgEAAJpidl0BALssAABOTEJONTAyMDE4OTROMDI56AB6CloKMgAJADoAAAAAABwJAAAAAIQTYwUAABAIAAAZ6wAAQTUAAAEAAAAAAAAAAAAAAAAAAAAAAFY1LjI3QnVpbGQyNjEAAAAAAAAAVjUuNDNCdWlsZDE4MgAAAAAAAAAwLjAwQnVpbGQwMDAAAAAAAAAAADAuMDBCdWlsZDAwMAAAAAAAAAAAMC4wMEJ1aWxkMDAwAAAAAAAAAAAwLjAwQnVpbGQwMDAAAAAAAAAAAEoV", "length": 228}
{"timestamp": "2021-04-13T18:50:35.979614", "target": ["192.168.1.18", 18665], "data": "pQoAEBIvCYojXCUBAdvLdWCqqgAAYxU=", "length": 23}

@jessiesolar
Copy link

Does the output completely stop for at least 30 minutes? In my case, a fresh 228 byte message arrives every 5-10 minutes; so if it takes longer than 15 minutes, something seems indeed wrong.

I must admit I am not sure about that 41 byte message and the 14 byte messages. The 14 byte messages I see as well, and I also see sometimes 60 byte messages; but I ignore all these, and that seems to work fine.

One other improvement I did was to disable acknowledgements on that config_hide.html page - that got rid of a resends, as it seems the response that the solis-service provides is not a proper acknowledgement. I now see a fresh 228 byte message about every 5-10 minutes.

I also added following at the end of async def handle_inverter_message(persist, reader, writer):, to make messages other than the expected 99 and 228 byte messages visible:

    else:
        writer.close()
        logger.debug(f'Invalid data message len: {len(message)}')
        logger.debug(f'Invalid data message: {message}')

@silvanverschuur
Copy link

@jessiesolar Thanks for your help! I have disabled the acknowledgements and now it's working.

@NibblyPig
Copy link

Been playing with this and it is what I would call a gigantic pain in the bottom.

Even proxying the chinese server with my ginlong wifi stick, it doesn't behave properly. Sometimes it connects and sends no data. Sometimes it ignores the heartbeat acknowledgement messages. And it almost always stops on 3 messages. Occasionally it sends other-sized packets like 41 bytes or 60 bytes.

As a result even though my code works and if I wanted I can emulate the server responses correctly, the thing is so unreliable and stops working so often that it can't feasibly be used to log any data.

What I would give for a simple json API... if anyone has any ideas on why it's so temperamental, would be appreciated.

As a side note my config_hide page doesn't seem to have any option for disabling acknowledgements as mentioned above.

@silvanverschuur
Copy link

@NibblyPig Did you try to disable acknowledgements? I had the same issue (stopping after 3 messages) and disabling acknowledgements fixed my problem.

@NibblyPig
Copy link

@silvanverschuur Unfortunately I don't seem to have an option for that. Perhaps because I'm using the wifi stick rather than the LAN stick? Or it could be my firmware, however I couldn't find any information about upgrading/downgrading.

Here is a screenshot of my config hide page

Inverter Firmware version (main)003E
Inverter Firmware version (slave)0025
Inverter model00AD
Wifi stick MW_08_512_0501_1.82

I'm sending the acknowledgements directly from the server, or I can emulate them myself as I figured out from someone else's page how to recreate them. But it sometimes stops responding despite sending them. Resetting the stick fixes it for a short while, like 20 messages or so will send between acks but then it stops again.

@silviudc
Copy link

Anyone got this to work consistently with a wifi logger, serial number starting with 072? model EN2-8M and MW_08_512_0501_1.82

@jlopez77
Copy link

jlopez77 commented Jul 13, 2021

Implement support for V5 protocol as used in new embedded ethernet loggers.
Needs documentation from Omnik and or iGEN / Solarman.

This is requested.
Also a firmware update file is requested.

I might have a bit of information about the V5 protocol...
Can we try something?

--- To get data from the logger ---
Connect to TCP port 8899 on the WiFi-Kit IP.

Then sent the following DATA (16 bytes) to trigger the logger.
HEX: A5 (V5 headCode)
HEX: 02 (dataFieldLength)
HEX: 10 45 (contrlCode)
HEX: e8 e4 71 5f (reversed hex notation of the logger s/n)
HEX: e8 e4 71 5f (reversed hex notation of the logger s/n)
HEX: 01 00 (command)
HEX: 2d (checksum)
HEX: 15 (V5 endCode)

I've read all the msgs in the post. I see that most of this information was already decoded.

  public SendInstruction(String paramString, BusinessField paramBusinessField) {
    setStart("A5");
    setControlCode("1045");
    setSerial("0000");
    setDeviceSN(paramString);
    SendDataField sendDataField = new SendDataField();
    sendDataField.setBusinessField(paramBusinessField);
    setDataField(sendDataField);
    setDataLength((String)null);
    setChecksum((String)null);
    setEnd("15");
  }

This is the java function used in the APK to communicate with the inverter...

public String toString() {
    StringBuilder stringBuilder = new StringBuilder();
    stringBuilder.append(this.start);
    stringBuilder.append(this.dataLength);
    stringBuilder.append(this.controlCode);
    stringBuilder.append(this.serial);
    stringBuilder.append(this.deviceSN);
    stringBuilder.append(this.dataField);
    stringBuilder.append(this.checksum);
    stringBuilder.append(this.end);
    return stringBuilder.toString().toUpperCase();
  }

And this is the right order of the fields...

@jlopez77
Copy link

If someone is interested

https://github.com/jlopez77/DeyeInverter

I've written a version to read Deye Inverters with serial 17XXXXX

@gordonforbes
Copy link

If someone is interested

https://github.com/jlopez77/DeyeInverter

I've written a version to read Deye Inverters with serial 17XXXXX

This is really great, Updated the config file and removed the comment from the print-command and it work perfectly first time. Thank you very much, you saved me a whole lotta trouble.

@jlopez77
Copy link

jlopez77 commented Aug 25, 2021 via email

@MichaluxPL
Copy link

MichaluxPL commented Sep 18, 2021

If someone is interested

https://github.com/jlopez77/DeyeInverter

I've written a version to read Deye Inverters with serial 17XXXXX

@jlopez77
Do You have any information what should I change in Your solution to get data from Sofar Solar Inverter ? Currently, using Your solution, I can see it comunicates with interver through logger, but logger sends only short packets without the required data.

Michal

@jlopez77
Copy link

jlopez77 commented Sep 18, 2021

If someone is interested
https://github.com/jlopez77/DeyeInverter
I've written a version to read Deye Inverters with serial 17XXXXX

@jlopez77
Do You have any information what should I change in Your solution to get data from Sofar Solar Inverter ? Currently, using Your solution, I can see it comunicates with interver through logger, but logger sends only short packets without the required data.

Michal

Sadly I dont have one of this to check. Probably my script is not querying the right addresses also, It cannot decode the answers.

@MichaluxPL
Copy link

If someone is interested
https://github.com/jlopez77/DeyeInverter
I've written a version to read Deye Inverters with serial 17XXXXX

@jlopez77
Do You have any information what should I change in Your solution to get data from Sofar Solar Inverter ? Currently, using Your solution, I can see it comunicates with interver through logger, but logger sends only short packets without the required data.
Michal

Sadly I dont have one of this to check. Probably my script is not querying the right addresses also, It cannot decode the answers.
It's not about querying wrong adresses. The response simply it too short to contain the actuall data. So probably it requires a different query data to be sent.

Michal

@jlopez77
Copy link

jlopez77 commented Sep 18, 2021 via email

@MichaluxPL
Copy link

Could You please tell me which part of the request data is the address we ask for ?
I've tested several control codes, but the only one that make the logger respond is 1045.

Michal

@MichaluxPL
Copy link

Actually, I've managed to figure it out on my own :) Now I have a working solution for Sofar KTL-X intverter family.
Thanks jlopez77 for a great work !

@mindakas
Copy link

Actually, I've managed to figure it out on my own :) Now I have a working solution for Sofar KTL-X intverter family.
Thanks jlopez77 for a great work !

Michal, could you share your findings? Have you managed to connect to Sofar inverter via WiFi kit?

@MichaluxPL
Copy link

MichaluxPL commented Sep 19, 2021

Actually, I've managed to figure it out on my own :) Now I have a working solution for Sofar KTL-X intverter family.
Thanks jlopez77 for a great work !

Michal, could you share your findings? Have you managed to connect to Sofar inverter via WiFi kit?

I'll make a project on github shortly to share the solution.
Yes it allows to gather Sofar inverter data through WiFi dongle (WLS-3).

@jlopez77
Copy link

jlopez77 commented Sep 20, 2021 via email

@MichaluxPL
Copy link

OK, so the new project (based on @jlopez77 fantastic work) is here: https://github.com/MichaluxPL/Sofar_LSW3
In addition to Sofar registers mapping, I've made some other changes in the code to make some results look better or use dictionaries from mapping file.
One thing: I'm not sure if two byte values (Total production and Total generation time) are derived correctly (when first byte value <> 0) - have to think about this :)
Enjoy :)

@jmccrohan
Copy link

FYI

I've written a Python module to interact with Solarman v5 data loggers. The library exposes a Modbus type interface and encapsulates the Modbus RTU frames in the V5 protocol.

https://github.com/jmccrohan/pysolarmanv5/

Might be of use to someone here.

@iv765
Copy link

iv765 commented Aug 20, 2022

Thx to the community

For Bosswerk(Deye) MI600
SN=22* FW=V0.2.0.1 V0.1.1.4 V1.2.1.2

this works for me:

def parse_inverter_message(message):
return {
"Timestamp": datetime.now().timestamp(),
"Today(44)": unpack_from("<H", message, 44)[0], # Or? unpack_from("<I", message, 44)[0]
"Total(48)": unpack_from("<H", message, 48)[0], # Or? unpack_from("<I", message, 48)[0]
"Frequency(68)": unpack_from("<H", message, 68)[0],
"Production(70)": unpack_from("<H", message, 70)[0],
"Voltage(56)": unpack_from("<H", message, 56)[0],
"Temperature(74)": unpack_from("<H", message, 74)[0],
}

BR

@iMarvinS
Copy link

Thx to the community

For Bosswerk(Deye) MI600 SN=22* FW=V0.2.0.1 V0.1.1.4 V1.2.1.2

this works for me:

def parse_inverter_message(message): return { "Timestamp": datetime.now().timestamp(), "Today(44)": unpack_from("<H", message, 44)[0], # Or? unpack_from("<I", message, 44)[0] "Total(48)": unpack_from("<H", message, 48)[0], # Or? unpack_from("<I", message, 48)[0] "Frequency(68)": unpack_from("<H", message, 68)[0], "Production(70)": unpack_from("<H", message, 70)[0], "Voltage(56)": unpack_from("<H", message, 56)[0], "Temperature(74)": unpack_from("<H", message, 74)[0], }

BR

Could you please go a little bit more into detail how you got it working?
I own exactly the same Inverter with the the same FW Version but simply replacing the parse_inverter_message function with your version and intercepting the Inverter's traffic did not work.

@ppiwowar
Copy link

Implement support for V5 protocol as used in new embedded ethernet loggers.
Needs documentation from Omnik and or iGEN / Solarman.
This is requested.
Also a firmware update file is requested.

I might have a bit of information about the V5 protocol... Can we try something?

--- To get data from the logger --- Connect to TCP port 8899 on the WiFi-Kit IP.

Then sent the following DATA (16 bytes) to trigger the logger. HEX: A5 (V5 headCode) HEX: 02 (dataFieldLength) HEX: 10 45 (contrlCode) HEX: e8 e4 71 5f (reversed hex notation of the logger s/n) HEX: e8 e4 71 5f (reversed hex notation of the logger s/n) HEX: 01 00 (command) HEX: 2d (checksum) HEX: 15 (V5 endCode)

I've read all the msgs in the post. I see that most of this information was already decoded.

  public SendInstruction(String paramString, BusinessField paramBusinessField) {
    setStart("A5");
    setControlCode("1045");
    setSerial("0000");
    setDeviceSN(paramString);
    SendDataField sendDataField = new SendDataField();
    sendDataField.setBusinessField(paramBusinessField);
    setDataField(sendDataField);
    setDataLength((String)null);
    setChecksum((String)null);
    setEnd("15");
  }

This is the java function used in the APK to communicate with the inverter...

public String toString() {
    StringBuilder stringBuilder = new StringBuilder();
    stringBuilder.append(this.start);
    stringBuilder.append(this.dataLength);
    stringBuilder.append(this.controlCode);
    stringBuilder.append(this.serial);
    stringBuilder.append(this.deviceSN);
    stringBuilder.append(this.dataField);
    stringBuilder.append(this.checksum);
    stringBuilder.append(this.end);
    return stringBuilder.toString().toUpperCase();
  }

And this is the right order of the fields...

jlopez77, I am not sure I understand how the below sequence:

--- To get data from the logger ---
Connect to TCP port 8899 on the WiFi-Kit IP.

Then sent the following DATA (16 bytes) to trigger the logger.
HEX: A5 (V5 headCode)
HEX: 02 (dataFieldLength)
HEX: 10 45 (contrlCode)
HEX: e8 e4 71 5f (reversed hex notation of the logger s/n)
HEX: e8 e4 71 5f (reversed hex notation of the logger s/n)
HEX: 01 00 (command)
HEX: 2d (checksum)
HEX: 15 (V5 endCode)

is compatible with SolarmanV5 protocol?
https://pysolarmanv5.readthedocs.io/en/latest/solarmanv5_protocol.html

BTW: Your code https://github.com/jlopez77/DeyeInverter is compatible with SolarmanV5.

Which one is right ?
Regards, Paweł

@iv765
Copy link

iv765 commented Aug 24, 2022

For Bosswerk(Deye) MI600 SN=22* FW=V0.2.0.1 V0.1.1.4 V1.2.1.2
this works for me (writing to /dev/shm/pv.json):

intercept.zip

@iv765
Copy link

iv765 commented Aug 25, 2022

@iMarvinS

Do you confirm?

    "Voltage1(96)":                         0.1 * unpack_from("<H", message, 96)[0], # seems to be Voltage Module1
    "Ampere1(98)":                          0.1 * unpack_from("<H", message, 98)[0], # seems to be Ampere Module1
    "Voltage2(100)":                        0.1 * unpack_from("<H", message, 100)[0], # seems to be Voltage Module2
    "Ampere2(102)":                         0.1 * unpack_from("<H", message, 102)[0], # seems to be Ampere Module2

BTW:
Response Time might by lazy, keep calm( >10m)

Bosswerk(Deye) MI600 SN=22* FW=V0.2.0.1 V0.1.1.4 V1.2.1.2

BR

@iMarvinS
Copy link

@iv765 It worked out perfectly, thank you very much! I

@iv765
Copy link

iv765 commented Aug 26, 2022

Cloudless (App does not work)
Bosswerk(Deye) MI300/MI600/SUN600G3-EU-230 SN=22* FW=V0.2.0.1 V0.1.1.4 V1.2.1.2
inverter.zip
Experimental !!!

@psunny28
Copy link

psunny28 commented Jun 7, 2024

Can some one help decode the bytes

data_packet1 = b'\xa5\x82\x00\x10A\x00\x01\x8cn\x91\xd1\x02\xa8\xc0\x06\x00:\x00\x00\x00\x00\x00\x00\x00\x05<x\x011\x03LSW5BLE_17_DD01_1.23\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00@*\x8f?\xa2\x1c192.168.0.80\x00\x00\x00\x00\x03\x00\x01\x01\xdd\x07\x00\xffV1.1.00.0B\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xffF\x15'
data_packet2 = b'\xa5\x82\x00\x10A\x00\x02\x8cn\x91\xd1\x02\xc7\xc0\x06\x00Y\x00\x00\x00\x00\x00\x00\x00\x05<x\x014\x03LSW5BLE_17_DD01_1.23\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00@*\x8f?\xa2\x1c192.168.0.80\x00\x00\x00\x00\x03\x00\x01\x01\xdd\x07\x00\xffV1.1.00.0B\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xff\x88\x15'
data_packet3 = b'\xa5\x82\x00\x10A\x00\x03\x8cn\x91\xd1\x02\xe6\xc0\x06\x00x\x00\x00\x00\x00\x00\x00\x00\x05<x\x011\x03LSW5BLE_17_DD01_1.23\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00@*\x8f?\xa2\x1c192.168.0.80\x00\x00\x00\x00\x03\x00\x01\x01\xdd\x07\x00\xffV1.1.00.0B\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xff\xc4\x15'

This would be a great help

also help me understand the decoding

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests