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

panic: runtime error: index out of range [651] with length 648 #1

Closed
MitchSUEW opened this issue Jan 7, 2021 · 5 comments
Closed

Comments

@MitchSUEW
Copy link

MitchSUEW commented Jan 7, 2021

I tried to use your code with my Hager EHZ 363Z5 over TCP (modified the code a little). When using the following SML I get a "index out of range":

local/energyreader/sml/MessageBody.(*MessageBody).moveBytePointerToNextListEntry(0xc000132000)
sml/MessageBody/MessageBody.go:66 +0x9c
It says "found packet", but then the error occurs.

SML-String:
1B1B1B1B01010101760900000000255BED44620162007263010176010109000000000C73F9CC0B0648XXXXXX7527B010163953100760900000000255BED45620162007263070177010B06XXXXXXX527B070100620AFFFF726201650F4B602DF17977078181C78203FF01010101044841470177070100000009FF010101010B0648XXXXXX37527B0177070100010800FF628201621E52FF552354F20201770781F6AFACFAFACF621E52FF552354CAF2DE0177070100010802FF0101621E52FF5327100177070100020800FF628201621E52FF552BD5A0E10177070100020801FF0101621E52FF552BD579D10177070100020802FF0101621E52FF5327100177070100100700FF0101621B520053094C0177070100240700FF0101621B52FF53214601770701001F0700FF0101622152FE5301BE0177070100200700FF0101622352FE5356D30177070100380700FF0101621B52FF5316240177070100330700FF0101622152FE53011B0177070100340700FF0101622352FE53576A01770701004C0700FF0101621B52FF5324B40177070100470700FF0101622152FE5301B30177070100480700FF0101622352FE5355920177070100603200020101620952FF5301360177078181C78205FF010101018302BF093F6DE4D2CA3E3C2C04CCB9XXXXXXXXXX5192CDD4FF49296500DE1DAE8CF536160F9070AFD0FF0BE2FFC5834EAC0177070100603203030101622352006268017707010060320304010162235200630117017707010060320003010162095200520A017707010060320004010162095200522B017707010060320005010162095200520401010163812200760900000000255BED3E620162007263020171016338BA00001B1B1B1B1A019AD7

any idea?

@rennerDa
Copy link
Owner

rennerDa commented Jan 8, 2021

Hi Michael,

as I mentioned in the description, the Code was written for this smart meter -> https://emh-metering.com/produkte/haushaltszaehler-smart-meter/ehz-k/
Its not working with other smart meters, because the SML is very flexible and every smart meter sends the data more or less different.
I could not develop a more general working PoC because its hard to find a general SML-Specification.

You can try extracting the data manually like https://www.schatenseite.de/2016/05/30/smart-message-language-stromzahler-auslesen/ and compare them with the output of the code (add some debug messages).
If you have problems adjusting your SML-String with the code let me know. Maybe I can have a look saturday or sunday.

@MitchSUEW
Copy link
Author

Thanks, Daniel. First of all thanks for developing these awesome pieces of code. I'm a GO programming beginner so I was happy to find your stuff.
I've analyzed my SML stream and from the specs of my power meter I know there are three values in there:
energyCurrentID := []byte{0x01, 0x00, 0x10, 0x07, 0x00} (aktueller Stromverbrauch)
energyTotalRececeiveID := []byte{0x01, 0x00, 0x01, 0x08, 0x00} (vom Netzbetreiber gekaufter Strom)
energyTotalSentID := []byte{0x01, 0x00, 0x02, 0x08, 0x00} (eingespeister Strom von der Photovoltaikanlage).

I do find those three patterns within my SML-String and can also find the values for them. But as I said, I'm a GO beginner, so I'm not able to understand your code good enough to modify it. Especially the concepts behind your "...Strategy" modules.
Perhaps you can elaborate a bit on that an I'm able to debug on my own.
Thanks,
Michael

@rennerDa
Copy link
Owner

rennerDa commented Jan 11, 2021

First, I splitted your bytes to see the complete (or almost complete) SML-Message. I left some comments for a better understanding.

Before:
1B1B1B1B01010101760900000000255BED44620162007263010176010109000000000C73F9CC0B0648XXXXXX7527B010163953100760900000000255BED45620162007263070177010B06XXXXXXX527B070100620AFFFF726201650F4B602DF17977078181C78203FF01010101044841470177070100000009FF010101010B0648XXXXXX37527B0177070100010800FF628201621E52FF552354F20201770781F6AFACFAFACF621E52FF552354CAF2DE0177070100010802FF0101621E52FF5327100177070100020800FF628201621E52FF552BD5A0E10177070100020801FF0101621E52FF552BD579D10177070100020802FF0101621E52FF5327100177070100100700FF0101621B520053094C0177070100240700FF0101621B52FF53214601770701001F0700FF0101622152FE5301BE0177070100200700FF0101622352FE5356D30177070100380700FF0101621B52FF5316240177070100330700FF0101622152FE53011B0177070100340700FF0101622352FE53576A01770701004C0700FF0101621B52FF5324B40177070100470700FF0101622152FE5301B30177070100480700FF0101622352FE5355920177070100603200020101620952FF5301360177078181C78205FF010101018302BF093F6DE4D2CA3E3C2C04CCB9XXXXXXXXXX5192CDD4FF49296500DE1DAE8CF536160F9070AFD0FF0BE2FFC5834EAC0177070100603203030101622352006268017707010060320304010162235200630117017707010060320003010162095200520A017707010060320004010162095200522B017707010060320005010162095200520401010163812200760900000000255BED3E620162007263020171016338BA00001B1B1B1B1A019AD7

After:
1B1B1B1B
01010101
76 //List with 6 entries
	09 00000000255BED44 //transactionId
	6201 //groupNo
	6200 //abortOnError
	72 //messageBody List with 2 entries
		63 0101 //getOpenResponse
		76 //List with 6 entries
			01
			01
			09 000000000C73F9CC //reqFileId
			0B 0648XXXXXX7527B //serverId
			01
			01
	639531 //CRC checksum
	00 //end
----
76 //List with 6 entries
		09 00000000255BED45 //transactionId
		6201 //groupNo
		6200 //abortOnError
		72
			63 0701 //getListResponse
			77
				01
				0B 06XXXXXXX527B //serverId
				07 0100620AFFFF //reqFileId
				72 
					62 01 //choice: secIndex
					65 0F4B602DF179 //secIndex: (Uptime)
				77
					07 8181C78203FF //OBIS-CODE -> in this case -> manufacturer
					01 //status
					01 //valTime
					01 //unit
					01 //scaler
					04 484147 //value
					01 //valueSignature
				77
					07 0100000009FF //OBIS-CODE -> in this case -> device-dientification
					01
					01
					01
					01
					0B 0648XXXXXX37527B
					01
				77
					07 0100010800FF
					62 82
					01
					62 1E
					52 FF
					55 2354F202
					01
				77
					07 81F6AFACFAFA
					CF //seems to be wrong?
					62 1E
					52 FF
					55 2354CAF2
					DE //?
					01
				77
					07 0100010802FF
					01
					01
					62 1E
					52 FF
					53 2710
					01
				77
					07 0100020800FF
					62 82
					01
					62 1E
					52 FF
					55 2BD5A0E1
					01
				77
					07 0100020801FF
					01
					01
					62 1E
					52 FF
					55 2BD579D1
					01
				77
					07 0100020802FF
					01
					01
					62 1E
					52 FF
					53 2710
					01
				77
					07 0100100700FF
					01
					01
					62 1B
					52 00
					53 094C
					01
				77
					07 0100240700FF
					01
					01
					62 1B
					52 FF
					53 2146
					01
				77
					07 01001F0700FF
					01
					01
					62 21
					52 FE
					53 01BE
					01
				77
					07 0100200700FF
					01
					01
					62 23
					52 FE
					53 56D3
					01
				77
					07 0100380700FF
					01
					01
					62 1B
					52 FF
					53 1624
					01
				77
					07 0100330700FF
					01
					01
					62 21
					52 FE
					53 011B
					01
				77
					07 0100340700FF
					01
					01
					62 23
					52 FE
					53 576A01
				77
					07 01004C0700FF
					01
					01
					62 1B
					52 FF
					53 24B401
				77
					07 0100470700FF
					01
					01
					62 21
					52 FE
					53 01B301
				77
					07 0100480700FF
					01
					01
					62 23
					52 FE
					53 5592
					01
				77
					07 010060320002
					01
					01
					62 09
					52 FF
					53 0136
					01
				77
					07 8181C78205FF
					01
					01
					01
					01
					83 02 BF093F6DE4D2CA3E3C2C04CCB9XXXXXXXXXX5192CDD4FF49296500DE1DAE8CF536160F9070AFD0FF0BE2FFC5834EAC
					01
				77
					07 010060320303
					01
					01
					62 23
					52 00
					62 68
					01
				77
					07 010060320304
					01
					01
					62 23
					52 00
					63 0117
					01
				77
					07 010060320003
					01
					01
					62 09
					52 00
					52 0A
					01
				77
					07 010060320004
					01
					01
					62 09
					52 00
					52 2B
					01
				77
					07 010060320005
					01
					01
					62 09
					52 00
					52 04
					01
				01
				01
			63 8122
			00
	76
		09 00000000255BED3E
		62 01
		62 00
		72 63
		02 01
		...
		71016338BA
0000
1B1B1B1B
1A 019AD7

The first part is not relevant (at least not relevant for us). After ---- begins the fun.
Message.go only checks the beginning and the end and of the whole SML message.
MessageBody.go jumps on creation over the first message - Line 29 - 39. You can output the bytes after line 39 and check if the pointer is on the correct position. If not, check if the byte-jumps are correct (maybe your smart meter has other values in the first message).

I added the strategies to easily test, extend and create new "value readers". On creation of the MessageBody all strategies are initialized. If you need a new one, add it to the initializeStrategies method.

Now have a look at the ManufacturerValueStrategy.go.
In Responsible I check if this strategy is responsible for the current List-Block. In your SML message ->

77
	07 8181C78203FF //OBIS-CODE -> in this case -> manufacturer
	01 //status
	01 //valTime
	01 //unit
	01 //scaler
	04 484147 //value
	01 //valueSignature

Every strategy has a OBIS_T_ID variable. In ManufacturerValueStrategy.go for example ->
var OBIST_T_ID = []byte{0x81, 0x81, 0xc7, 0x82, 0x03, 0xff}
and this have to be equal to the List-Entry OBIS-Code.

So if you change the OBIS-Code of CurrentValueStrategy.go you should get the current value of your smart meter. Or you can easily add (or remove) strategies to read other values.

In MessageBody.go line 44 I extract one Block at a time, iterate over all strategies and check if one strategy can handle this Block, if not i move to the next block.
If a strategy fits, the strategy extracts the values (ManufacturerValueStrategy.go - ExtractStringValue or ExtractIntValue).
The ugly part is (I could not find a better way in go) MessageBody.go line 47 - 50. I had to use reflection to get the correct value and assign it to the correct variable. If you add new strategies you have to check here your strategies and assign the value to MessageBody.

I'm sorry, its late and some parts may be confusing. Ask if you have some questions.
You modified your SML-Message (which is absolutely necessary - I would suggest you to delete the SML-Message completely after we solved your problems) and therefor I cant test this message on my machine. If you need help adding some debug-messages let me know.

@rennerDa
Copy link
Owner

rennerDa commented Jan 11, 2021

You can test the code with your string-byte-example ->
decodedByteArray, err := hex.DecodeString(hexString)
so you don't have to read new values every time.

@rennerDa
Copy link
Owner

rennerDa commented May 7, 2021

Closed due to no activity. Feel free to write me if you want to continue the discussion :)

@rennerDa rennerDa closed this as completed May 7, 2021
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants