Comments (5)
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.
from gosml.
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
from gosml.
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.
from gosml.
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.
from gosml.
Closed due to no activity. Feel free to write me if you want to continue the discussion :)
from gosml.
Related Issues (1)
Recommend Projects
-
React
A declarative, efficient, and flexible JavaScript library for building user interfaces.
-
Vue.js
🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
-
Typescript
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
-
TensorFlow
An Open Source Machine Learning Framework for Everyone
-
Django
The Web framework for perfectionists with deadlines.
-
Laravel
A PHP framework for web artisans
-
D3
Bring data to life with SVG, Canvas and HTML. 📊📈🎉
-
Recommend Topics
-
javascript
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
-
web
Some thing interesting about web. New door for the world.
-
server
A server is a program made to process requests and deliver data to clients.
-
Machine learning
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
-
Visualization
Some thing interesting about visualization, use data art
-
Game
Some thing interesting about game, make everyone happy.
Recommend Org
-
Facebook
We are working to build community through open source technology. NB: members must have two-factor auth.
-
Microsoft
Open source projects and samples from Microsoft.
-
Google
Google ❤️ Open Source for everyone.
-
Alibaba
Alibaba Open Source for everyone
-
D3
Data-Driven Documents codes.
-
Tencent
China tencent open source team.
from gosml.