jbuehl / solaredge

SolarEdge inverter logging data capture
GNU General Public License v3.0
289 stars 60 forks source link

error message #4

Closed wimsan closed 8 years ago

wimsan commented 9 years ago

I'm trying to get this working on my synology NAS. I get an error :+1: debug: True debugFiles: True debugData: True headers: True delim: , dataBase: dbHostName: userName: password: append: a inFileName: stdin invFileName: optFileName: jsonFileName: reading stdin solaredge inputSeq 0 seDataLen 14951 solaredge inputSeq 1 seDataLen 0 solaredge inputSeq 2 seDataLen 0 solaredge inputSeq 3 seDataLen 342 solaredge seHdr a9 fe 03a9 7f190ff7 fffffffe 0500 solaredge seType 0010 seId 7F190FF7 seDeviceLen 124 Traceback (most recent call last): File "/root/solaredge/seconvert2.py", line 454, in seConvert() File "/root/solaredge/seconvert2.py", line 197, in seConvert seHeader(inRec+inFile.read(2)) File "/root/solaredge/seconvert2.py", line 238, in seHeader seInvData = readData(inFile, invInFmt, seDeviceLen) File "/root/solaredge/seconvert2.py", line 262, in readData return list(struct.unpack(inFmt, inFile.read(seDeviceLen))) struct.error: unpack requires a string argument of length 104

I have no idea why this goes wrong. My inverter is a SE3000 that sends it's data to domoticz on ip address 192,168.1.51 port 22222

please advise wimsan

jbuehl commented 9 years ago

It looks like your inverter is sending 124 bytes of data and the program expects there to be only 104 bytes so it is crashing. I don't know what this extra data is. I will change the program so it doesn't fail when this happens.

wimsan commented 9 years ago

would it be of any help of I provided teh pcap file(s)?

jbuehl commented 9 years ago

I just made a change to seconvert2.py to ignore any data that is past the expected size. Hopefully this will allow the program to run for you. Apparently your inverter is sending additional data that mine isn't but I have no way of knowing what this data is.

wimsan commented 9 years ago

Thanks for changing seconvert2.py. I don't get the error message anymore but I think the format my inverter uses is different than yours because I do get some data for the inverter but no data at all for the optimizers. My inverter was installed in april this year so it's rather new and I read somewhere that solaredge have changed the format. Is there any wat other than with solaredge to find out the details of teh new format?

jbuehl commented 9 years ago

You could try running seconvert2 with the -vvv option which will cause it to print a lot of debug information that you could use to see what is different. I was able to figure out as much of the format as I did by dumping out the pcap file and comparing values to numbers that I was seeing on the inverter display. I never tried asking SolarEdge for the information, but that might work.

wimsan commented 9 years ago

I ran seconvert2 with -vvv option but it did not provide much moer information. It seems that it doesn't recognize seType 0080 which appears to be optimizer data based on the seId. I tried updating seconvert2 to read seType 0080 but then i get yet another different error. Unfortunately my programming skills are not sufficient to figure it all out.

jbuehl commented 9 years ago

I just updated seconvert2.py with an additional debug level. Now if you run it with the -vvvv option it will log all of the data it reads in hex format. This is very verbose, but it should show you what data is in the 0080 records. I also added an option -l to send messages to sysout instead of the system log, which may be more convenient for debugging.

wimsan commented 9 years ago

Thank you. I tried it and allthough it provides much more insight I'wondering if there is an easy way to show the decimal values of the various floats; that would make debugging even easier for me.

jbuehl commented 9 years ago

The trick is knowing which bytes are floats and which ones are integers. Can you post the output of one of the 0080 records?

wimsan commented 9 years ago

solaredge inputSeq 50 seDataLen 426 solaredge rawdata: 55 fe 24 04 f7 0f 19 7f fe ff ff ff 00 05 solaredge seHdr 55 fe 0424 7f190ff7 fffffffe 0500 solaredge rawdata: 10 00 f7 0f 99 7f 7c 00 solaredge seType 0010 seId 7F190FF7 seDeviceLen 124 solaredge rawdata: ef 12 d3 55 e2 e9 00 00 2c 01 00 00 ca 3d f1 41 eb 24 fd 44 2e b2 7c 41 00 3c 6b 43 ae 47 35 3f c9 fd 47 42 ff ff 7f ff ff ff 7f ff 00 f8 ad 43 ff ff 7f ff 38 ae c5 49 62 10 d8 3b ff ff 7f ff 01 00 80 3f 04 00 00 00 00 80 bb 45 00 00 c8 42 00 00 f9 bc ff ff 7f ff ff ff 7f ff 00 80 0f 43 00 80 21 43 00 00 94 c2 00 00 c8 42 00 00 c8 42 ff ff 7f ff c7 b5 18 00 00 00 00 00 writing 2015-08-18,13:11:43,7F190FF7,59874,300,30.155170,2025.153687,15.793501,235.234375,0.708125,49.997837,347.937500,1619399.000000,6000.000000,143.500000 solaredge rawdata: 80 00 0d 10 0f 20 0d 00 solaredge seType 0080 seId 200F100D seDeviceLen 13 solaredge rawdata: 0a 13 d3 55 68 2a dc f0 22 04 cf 01 09 80 00 5e 20 0f 20 0d 00 0f 13 d3 55 71 2a dc e8 f2 03 c7 01 09 80 00 77 17 0f 20 0d 00 16 13 d3 55 80 2a d8 c8 63 04 1e 02 09 80 00 0a 10 0f 20 0d 00 17 13 d3 55 81 2a e1 f4 c3 04 30 02 09 80 00 04 09 0f 20 0d 00 1c 13 d3 55 87 2a da d8 a3 04 24 02 09 80 00 a1 0c 0f 20 0d 00 2e 13 d3 55 96 2a de ec b3 04 2d 02 09 80 00 eb 0c 0f 20 0d 00 40 13 d3 55 a8 2a e0 e4 e3 04 28 02 09 80 00 f4 10 0f 20 0d 00 4c 13 d3 55 b4 2a e3 e4 03 05 2d 02 09 80 00 0b 10 0f 20 0d 00 a1 13 d3 55 06 2b e7 e0 b3 07 31 02 09 80 00 18 10 0f 20 0d 00 b3 13 d3 55 18 2b ec e0 b3 07 2f 02 09 80 00 16 10 0f 20 0d 00 b8 13 d3 55 1a 2b ea fc 52 06 b9 01 09 80 00 eb 0c 0f 20 0d 00 de 13 d3 55 45 2b e8 e0 f3 08 2b 02 09 80 00 a1 0c 0f 20 0d 00 e6 13 d3 55 4d 2b e2 dc 13 09 31 02 09 80 00 77 17 0f 20 0d 00 07 14 d3 55 71 2b e4 c4 73 09 23 02 09 solaredge rawdata: fc 03 00 00 00 00 00 00 solaredge seType 03fc seId 0 seDeviceLen 0 solaredge rawdata: 12 34 56 79 00 00 ff ff 24 04 fe ff ff ff f7 0f 19 7f 80 00 32 b9 00 00 00 00 00 00 12 34 56 79 00 00 ff ff 25 04 f7 0f 19 7f fe ff ff ff 00 05 b2 69 12 34 56 79 00 00 ff ff 25 04 fe ff ff ff f7 0f 19 7f 80 00 36 45 00 00 00 00 00 00 00 00 00 00 00 00 12 34 56 79 00 00 ff ff 26 04 f7 0f 19 7f fe ff ff ff 00 05 bd 2d 12 34 56 79 00 00 ff ff 26 04 fe ff ff ff f7 0f 19 7f 80 00 39 01 00 00 00 00 00 00 12 34 56 79 80 01 7f fe 27 04 f7 0f 19 7f fe ff ff ff 00 05 10 00 f7 0f 99 7f 7c 00 1b 14 d3 55 0e eb 00 00 2c 01 00 00 d7 de ef 41 5e 62 ff 44 b4 5c 8f 41 00 4c 6b 43 ae 47 b5 3f 59 0a 48 42 ff ff 7f ff ff ff 7f ff 00 58 ae 43 ff ff 7f ff b8 ae c5 49 89 41 e0 3b ff ff 7f ff 01 00 80 3f 04 00 00 00 00 80 bb 45 00 00 c8 42 00 00 cf bc ff ff 7f ff ff ff 7f ff 00 00 9d 43 00 c0 a1 43 00 00 a3 solaredge rawdata: c2 00 00 c8 42 00 00 c8 solaredge seType 00c2 seId 42C800 seDeviceLen 51200 solaredge rawdata: 42 ff ff 7f ff d7 b5 18 00 00 00 00 00 80 00 0d 10 0f 20 0d 00 2e 14 d3 55 89 2b e9 fc 82 08 d5 01 09 80 00 16 10 0f 20 0d 00 44 14 d3 55 a5 2b ea ec e2 07 bc 01 09 80 00 18 10 0f 20 0d 00 4e 14 d3 55 b2 2b ed ec 53 0a 34 02 09 80 00 5e 20 0f 20 0d 00 70 14 d3 55 d0 2b f0 f4 32 08 ce 01 09 80 00 24 19 0f 20 0d 00 8e 14 d3 55 f7 2b e9 d8 d3 0a 38 02 09 80 00 0b 10 0f 20 0d 00 90 14 d3 55 f3 2b e8 e8 c3 0a 38 02 09 80 00 f4 10 0f 20 0d 00 a2 14 d3 55 07 2c ea dc 13 0b 37 02 09 80 00 0a 10 0f 20 0d 00 b1 14 d3 55 19 2c ed e0 73 0b 3b 02 09 80 00 04 09 0f 20 0d 00 ed 14 d3 55 56 2c eb d4 43 0c 31 02 09 80 00 16 10 0f 20 0d 00 0a 15 d3 55 6a 2c eb 0c c3 0a c2 01 09 80 00 0b 10 0f 20 0d 00 11 15 d3 55 74 2c ec dc 93 0d 3d 02 09 80 00 04 09 0f 20 0d 00 13 15 d3 55 7c solaredge rawdata: 2c ee solaredge seCksum 2cee seDataLen -50943 solaredge rawdata: d0 23 0d 33 solaredge rawdata: 02 solaredge rawdata: 09 solaredge rawdata: 20 solaredge rawdata: 81 solaredge rawdata: 12 solaredge rawdata: 34 solaredge rawdata: 56 solaredge rawdata: 79 solaredge rawdata: 00 00

200F100D is the serial number of one of my optimizers

jbuehl commented 9 years ago

I can see data for 14 optimizers in the raw data, each with 13 bytes of data. It looks like the first 4 bytes may be a timestamp, but it is difficult to guess what the rest of the data represents without being able to compare it to something. I don't want to push changes to this repository without being able to test them first. Please send an email to joe.buehl@buehltech.com and we can continue this discussion offline.

mwhiemstra commented 9 years ago

I have re-written the data of the last packet a bit: 80 00 0a 10 0f 20 0d 00 b1 14 d3 55 19 2c ed e0 73 0b 3b 02 09 80 00 04 09 0f 20 0d 00 ed 14 d3 55 56 2c eb d4 43 0c 31 02 09 80 00 16 10 0f 20 0d 00 0a 15 d3 55 6a 2c eb 0c c3 0a c2 01 09 80 00 0b 10 0f 20 0d 00 11 15 d3 55 74 2c ec dc 93 0d 3d 02 09 80 00 04 09 0f 20 0d 00 13 15 d3 55 7c

This is what I have found: 00 0d 20 0f 10 0a = the optimizer ID 55 d3 14 b1 = the time stamp as already mentioned by jbuehl

And then 9 bytes, exactly as my SE3000 produces. I have spend quite some time to decode thes bytes but no success. If any of you have a suggestion, please pass it on.

jbuehl commented 9 years ago

Actually, 20 0f 10 0a is the optimizer ID and 0d 00 is the length of the data that follows (13 bytes), but the mystery is still how to interpret the last 9 bytes.

I have spent some time formatting these bytes in various types such as 16 bit integers and 32 bit floats, but the values are never reasonable. In order for the optimizers to function, they must report their input and output voltages so this data has to be in there somewhere.

If someone is able to compare the optimizer data reported on the inverter screen or taken from the SolarEdge monitoring website with the captured data, this would be very helpful.

mwhiemstra commented 9 years ago

Thanks for your response.

Learned one more bit: 0D00 being the lenght of the data I had not noticed that yet.

I have done the same and did not find anything sensible either. I have tried full precision float for the inverter data and that works fine. Consequently I have tried half precison float and straigh hex decoding. No success. My theory is that the power value is calculated from the voltage and current values. This matches exactly with the values I see in my SolarEdge portal. So I would expect to find the two voltages, the current and energy values out of the data.

Let see if anybody responds to this post.

jpnp commented 9 years ago

My SE2200 produces similar packets of type 0x0080:

 80 00 cb 54 18 20 0d 00 cc 56 0e 56 41 31 aa e5 55 1b 1e 03 0d

I have had most luck decoding them when I consider the bytes in reverse order:

0d 03 1e 1b 55 e5 aa 31 41 56 0e 56 cc
Tt Ee ee Cc cO o# pp Uu uu Dd dd dd dd 

# = oo|Pp

The data seem to be the same as in the 0x0000 type, but represented in a more compact form (maybe in order to save network bandwidth for solaredge? or just to represent the bit format the inverter receives data from the optimisers?).

My best determination is:

T (8 bit) = temperature? E (16 bit) = Energy since optimiser power on in 1/4 Wh C (12 bit) = Panel current in 1/160 Amp O (10 bit) = Output voltage in 1/8 Volt P (10 bit) = Panel voltage in 1/8 Volt U (16 bit) = Optimiser uptime in seconds D = DateTime seconds since epoch

This decoding matches the data on the inverter panel and the inverter data from type 0x0010 entries very closely.

Thus my entry above represents an optimiser which has been up 12609 seconds (3hr30mins), generating 199.5 Wh of energy, and is currently receiving 53.25v at 2.73125A from the panel and outputting 47.125v to the string.

Similarly @wimsan's entry from above:

 80 00 0b 10 0f 20 0d 00 11 15 d3 55 74 2c ec dc 93 0d 3d 02 09

09 02 3d 0d 93 dc ec 2c 74 55 d3 15 11
Tt Ee ee Cc cO o# pp Uu uu Dd dd dd dd

shows an uptime of 11380s generating 143.25 Wh, receiving 29.5v at 1.35A, and outputting 30.875v.

My only confusion is the final byte which seems to represent temperature (it rises and falls through the day in the right sort of pattern), but for me is only showing a range of 0x04 - 0x13, which doesn't represent a reasonable temperature swing over the day to much precision. Maybe I have some of the bits assigned wrongly and there are some low order temperature buts hidden elsewhere.

jbuehl commented 9 years ago

Excellent information @jpnp. I suspected that the data was in integer format and not floating, but I had no way to correlate the values.

If the values in the last byte seem to follow the temperature cycle during the day, then that is what it likely represents. I don't know that the temperature data would have to be very precise for this purpose. The temperature of the optimizers will vary from a low which matches the ambient air temperature in the morning when the sun rises, to a high that is considerably hotter than the air temperature during the hottest part of the day. I have seen temperatures as high as 154F (68C) when the air temperature is 100F (38C).

jpnp commented 9 years ago

Well air temperature here basically never reaches 100°F ;-)

Yesterday it varied between about 7°C and 19°C during the period that the panels were generating. It does seems odd to represent a range that will certainly be more than that with just 16 values (my log varied between 0x04 and 0x13).

Representing panel current to 160th of an Amp maybe seems a little out of balance with the other values. I wouldn't be surprised if some of the bits in the 3rd nibble I've labled 'c' are actually low order bits for the temperature rather than current. It would make for an odd looking encoding though.

mwhiemstra commented 9 years ago

Excellent job jpnp! The decoding matches exactly with my data on the SolaEdge portal.

COMMENT_1; I have spoken to early: energy, uptime and temperature are correct but the current and voltages deviate now at the end of the day. Current stays at 4 to 6 A and the output voltage goes to 100 to 50V; that is not true.... COMMENT_2: the Python 'bin' function skipped a few msb zero's for lower values, giving the strange results; all is fine now.

I saw a temperature range from 5 to 17 degrees Celsius in the packets and that matches with the ambient temperature here. Just wonder what happens when we get below zero?

jbuehl commented 9 years ago

I think they may be using a temperature sensor chip that reports the value as a 2s complement integer which would cover values from -128 to +127. We will find out when your weather gets colder.

jpnp commented 8 years ago

I've done a little further investigation of the temperature values. I don't believe that it encodes °C directly as it's been reading down to 04 for me this last week, and our temperature hasn't got that low.

A couple of days ago I attached a 1-wire DS18B20 thermometer to a raspberry pi with the sensor in the gap below my panels. This should give a reasonable approximation of the temperature at the optimiser (especially in the last few days which have been cloudy and generating low power). My readings suggest that the factor is in the range 1.5-1.8.

I've gone with 1.6 which is a good fit to the readings and would correspond to a 12bit value in 1/10 °C which has been truncated at 8bits to fit into one byte of the message.

jbuehl commented 8 years ago

Measuring the temperature with another device is a good idea. The temperature sensor chips I have seen all measure in fractions of 2 (e.g. .50, .25, .125, etc) but I suppose a sensor that reports in increments of .10 is possible. It would be interesting to take one of these optimizers apart and see which components are inside.