WienerNetze meter reading

19 posts / 0 new
Last post
tofuSCHNITZEL
WienerNetze meter reading

Hi!

I received a smartmeter from the local powercompany and recenently they allowed me to enable the (IR) userinterface to read out data.

The problem is that they are not very forthcoming with information regarding this interface so I'm not 100% sure how to implement the readout of the meter.

Here are the facts and what I know so far:

Hardware:
ISKRA (Iskraemeco) AM550
It has an optical interface (IR LEDs)
I have a USB to Serial to IR LED interface Cable

Infos:
This is the only information I received from the powercompany:
– Protocoll: IEC 62056 – 21
– optical interface (IR)
– DLMS IDIS CII

Additional Info I could gather from the webinterface where you can enable the customerinterface:
"Information is sent every second over the IR Interface"
and also a 32 char HEX encyption key

If I use e.g. Hterm with "9600 Data 8 Stop 1 Parity None" I see that every second I receive data over the IR-Serial Adaper. (sending the DLMS handshake does nothing)

I would like to create a python script (with the help of the gurux-dlms library) to gather and decode/decrypt the data to read the meter values.

Could you please give me some directions because it seems this meter does not use the regular way of handshake etc but instead just sends bursts of (encrypted)data.

Thanks a lot!

Kurumi
Kurumi's picture

Hi,

I believe that your meter is sending push messages and you can use that encryption key to decrypt received push message.

It might be possible that you are not allowed to make a connection to the meter. You can only receive push messages. This is for security reasons.

If you can post one push message in hex here, I can check that received data is correct.

BR,

Mikko

________________________________________
Mikko Kurunsaari
Gurux Ltd
http://www.gurux.fi

tofuSCHNITZEL

Hi Mikko,

this is one of the push messages in hex:

7EA067CF022313FBF1E6E700DB0849534B697456F2C34F20001E7C7084747ABDE06AFD9D573972A26FB7E03E19D13366C43B72A212BA089F79B3EC074F474E1EA9C86E445EC8156D8C0EC33B9953FA58200768FDCCD633933B4453BF53C990C241E538C3320D01E27E

Image: 
Kurumi
Kurumi's picture

Hi,

Below is source code. Update keys that you have received from the power company and you should see received data in XML.

BR,

Mikko

from gurux_dlms.GXByteBuffer import GXByteBuffer
from gurux_dlms.GXDLMSTranslator import GXDLMSTranslator
from gurux_dlms.GXReplyData import GXReplyData
from gurux_dlms.secure.GXDLMSSecureClient import GXDLMSSecureClient
from gurux_dlms.TranslatorOutputType import TranslatorOutputType

reply = GXReplyData()
notify = GXReplyData()
data = "7EA067CF022313FBF1E6E700DB0849534B697456F2C34F20001E7C7084747ABDE06AFD9D573972A26FB7E03E19D13366C43B72A212BA089F79B3EC074F474E1EA9C86E445EC8156D8C0EC33B9953FA58200768FDCCD633933B4453BF53C990C241E538C3320D01E27E"
cl = GXDLMSSecureClient(True, 0, 145)
cl.ciphering.authenticationKey = cl.ciphering.blockCipherKey = GXByteBuffer.hexToBytes("UPDATE CORRECT KEY")
if cl.getData(GXByteBuffer.hexToBytes(data), reply, notify):
if len(notify.data) != 0:
#Handle notify.
if not notify.isMoreData():
#Show received push message as XML.
t = GXDLMSTranslator()
cml = t.dataToXml(notify.data)
notify.clear()

________________________________________
Mikko Kurunsaari
Gurux Ltd
http://www.gurux.fi

Kurumi
Kurumi's picture

Hi,

I forget to say that update to the latest version from gurux-dlms. We fixed a few issues.

BR,

Mikko

________________________________________
Mikko Kurunsaari
Gurux Ltd
http://www.gurux.fi

tofuSCHNITZEL

Hi Mikko,

wow, thank you very much!
I have been playing aroung with the c sharp library all morning because I thought that there is no secureclient in python (the documentation said so) - but with python it will be way easier.

I've entered my encryption key but using gurux-dlms 1.0.19 "cl.getData(GXByteBuffer.hexToBytes(data), reply, notify)" always returns false

I received only one key (32 characters) - is it the case that it is auth and block cipher key? or do we split it in half?

do I maybe need to do something with the hex string? (prepending 0x only gives invalid hex string)

Kurumi
Kurumi's picture

Hi,

Secure client in python is newer functionality. Doc is updated at some point. :-)
Remove 0x from a hex string. Key size is 16 bytes. Are there 32 chars in hex string?

getData returns false because there is no reply. len(notify.data) is not zero if there is notify message.
It's possible that sometimes there is a reply and notify in received data. This might happen when we communicate over the air. Usually, that is not happening when we are using TCP/IP or serial port connection.

BR,
Mikko

________________________________________
Mikko Kurunsaari
Gurux Ltd
http://www.gurux.fi

Kurumi
Kurumi's picture

Hi,

Change this:
if cl.getData(GXByteBuffer.hexToBytes(data), reply, notify):
to
if not cl.getData(GXByteBuffer.hexToBytes(data), reply, notify):

BR,

Mikko

________________________________________
Mikko Kurunsaari
Gurux Ltd
http://www.gurux.fi

tofuSCHNITZEL

Yes its 32chars long so it is 16 bytes.
I get the following error now:

Traceback (most recent call last):
File ".\testdecode.py", line 19, in <module>
cml = t.dataToXml(notify.data)
File "C:\Users\TobiasPerschon\AppData\Local\Programs\Python\Python35-32\lib\site-packages\gurux_dlms\GXDLMSTranslator.py", line 1674, in dataToXml
_GXCommon.getData(data, di)
File "C:\Users\TobiasPerschon\AppData\Local\Programs\Python\Python35-32\lib\site-packages\gurux_dlms\internal\_GXCommon.py", line 289, in getData
value = cls.getDouble(data, info)
File "C:\Users\TobiasPerschon\AppData\Local\Programs\Python\Python35-32\lib\site-packages\gurux_dlms\internal\_GXCommon.py", line 591, in getDouble
cls.setData(tmp, DataType.FLOAT64, value)
File "C:\Users\TobiasPerschon\AppData\Local\Programs\Python\Python35-32\lib\site-packages\gurux_dlms\internal\_GXCommon.py", line 1249, in setData
buff.setDouble(value)
File "C:\Users\TobiasPerschon\AppData\Local\Programs\Python\Python35-32\lib\site-packages\gurux_dlms\GXByteBuffer.py", line 280, in setDouble
self.setDouble(value, self.size)
File "C:\Users\TobiasPerschon\AppData\Local\Programs\Python\Python35-32\lib\site-packages\gurux_dlms\GXByteBuffer.py", line 283, in setDouble
self.set(struct.pack("d", value))
struct.error: required argument is not a float

Kurumi
Kurumi's picture

Hi,

Can you post notify.data hex string? I'll check this.

BR,

Mikko

________________________________________
Mikko Kurunsaari
Gurux Ltd
http://www.gurux.fi

tofuSCHNITZEL

05 18 E0 D2 20 A2 15 5A 83 C8 85 03 7D EF 76 0B D8 67 D5 21 5F 32 4A BB D4 AE 15 77 6A 1F 04 59 DE E8 0F AB 5D F1 D1 97 49 03 95 9A 58 8A 73 CD D9 B0 FC 4E A3 86 37 DC 7F 26 F5 76 F6 6E AB 1F 91 D2 5F 2E DE 2A 8A EA 29 55

Kurumi
Kurumi's picture

Hi,

Data is invalid. Usually it means that key is not correct. Python version is quite new. We'll test this.

BR,
Mikko

________________________________________
Mikko Kurunsaari
Gurux Ltd
http://www.gurux.fi

steve_cz

Hi!

Is there an example how this is done using c and arduino?
That would be great to hear for one of my projects ;-)

Regards
Steve

Kurumi
Kurumi's picture

Hi Steve,

You can do this with ANSI C. There is a client example that can do this, but there is no XML support. You need to save received data by yourself.

BR,
Mikko

________________________________________
Mikko Kurunsaari
Gurux Ltd
http://www.gurux.fi

steve_cz

thank you for the info mikko!

I try to develop a converter from smart meter to homematic system. I use an arduino with serial connected IR reader for the meter and Asksin++ library.
The hardest part is decryption but maybe i can use your lib depending on how much space it needs on the arduino.

Currently i can receive the smart meter push message but it seems to be wrong. Maybe there is something missing between E6 E7 and DB?

7E A0 67 CF 02 23 13 FB F1 E6 E7 DB 08 49 53 4B 69 74 92 ED 66 4F 20 02 B2 FD FE 7C 38 36 B7 17 25 49 D0 A3 A8 99 D3 8F F1 37 21 DA A0 BB 58 96 EF 55 E2 84 8C 15 58 BF 71 5C 7E 53 7E F3 9D 49 53 C2 94 68 F4 B5 B4 01 B0 6E 10 BE 31 89 AD 59 08 55 A5 36 96 FA 7B 7D 76 A4 93 CC AD 8D 98 E2 98 84 7E

I have a 32 character key, but when i put it in your DLMS Translator nothing happens.
Do you have an idea why?

Regards Stefan

Kurumi
Kurumi's picture

Hi Stefan,

There are bytes missing from the message. There should be 105 bytes and now there are only 99.
What IR reader you are using?

DLMS is a large protocol and there are a lots of features that you don't need if you are only receiving push messages. If you remove all non-needed features you might get this work in Arduino.

You don't receive any output because the data is invalid. Check why you are not receiving the correct data.

Set 32 char keys to block cipher and authentication keys and it will start to work when your data is correct.

BR,
Mikko

________________________________________
Mikko Kurunsaari
Gurux Ltd
http://www.gurux.fi

pocki

Hi. Same question here.
A sample data packet from my AM550:

7e a0 67 cf 02 23 13 fb f1 e6 e7 00 db 08 49 53 4b 69 74 6c 83 b4 4f 20 00 03 b1 d9 16 c2 0d ea cb d1 33 48 b0 7a 7b 3a 85 0a c5 c1 ce 55 a7 0e a5 7a 15 c2 84 c6 ba 47 32 6e 2a 59 8f 32 76 b7 a4 a1 5c 03 93 c4 49 2c a8 3a 56 0b 3b 53 5d 15 8a 22 05 5f 89 a1 11 7c aa 91 89 5f cf 63 c5 05 b4 20 7b 16 a9 a3 f6 79 7e

From octet 1 til 27 ("b1" in above example) it is same in all messages.
Octet 28 ("d9") increases by 1 every message or second (I get 1 message each second, so hard to tell if it's sequence or seconds)
From octet 29 ("16 c2...") until last but one the content changes each packet.

I have the 32char/256bit key from Webportal.
What enc-algo is used?
How to build the IV?
What part of that message is the encrypted part?
Where to fill "00"?

BR

Kurumi
Kurumi's picture

Hi,

Set 32 char key to block cipher and authentication key and you can get XML output.
Used encryption debends from the meter. You can get more information from here:
http://www.gurux.fi/Gurux.DLMS.Secure
Your meter is using AES-GCM-128.

BR,
Mikko

________________________________________
Mikko Kurunsaari
Gurux Ltd
http://www.gurux.fi

pocki

Thanks for your hint. In Gurix-DLMS-Translator I have set:

Ciphering -> Security=Encryption, BlockCipherKey and AuthKey=may 32char hex key.

With this The translations results in:

1: 7E A0 67 CF 02 23 13 FB F1 E6 E7 00 DB 08 49 53 4B 69 74 6C 83 B4 4F 20 00 03 B1 D9 16 C2 0D EA CB D1 33 48 B0 7A 7B 3A 85 0A C5 C1 CE 55 A7 0E A5 7A 15 C2 84 C6 BA 47 32 6E 2A 59 8F 32 76 B7 A4 A1 5C 03 93 C4 49 2C A8 3A 56 0B 3B 53 5D 15 8A 22 05 5F 89 A1 11 7C AA 91 89 5F CF 63 C5 05 B4 20 7B 16 A9 A3 F6 79 7E
<HDLC len="66" >
<TargetAddress Value="67" />
<SourceAddress Value="91" />
<!-- Notification frame. -->
<FrameType Value="13" />
<PDU>
<!--
IDIS system title:
Manufacturer Code: ISK
Function type: Disconnector extension, Load Management extension, Multi Utility extension
Serial number: 74220468
-->
<GeneralGloCiphering>
<SystemTitle Value="49534B69746C83B4" />
<CipheredService Value="200003B1D916C20DEACBD13348B07A7B3A850AC5C1CE55A70EA57A15C284C6BA47326E2A598F3276B7A4A15C0393C4492CA83A560B3B535D158A22055F89A1117CAA91895FCF63C505B4207B16A9A3" />
</GeneralGloCiphering>
</PDU>
</HDLC>

So first: it is not decrypted.
And second: the "CipheredService Value" appers to be to be one octet too short. I caputred 40+ packets and all have the same length. So I feel this is not an IRDA/hw-interfacing issue, but rather a data issue?

You think this is due to a firmware version issue?
The meter shows:
1.0.0.2.0 (Core FW) = 302002
1.5.0.2.0 (APL FWLR) = 302008

Another interesting thing: byte 5 of ciphered-block (here: "d9") increments by 1 each packet. For that reason this byte is unlikeley part of the cipheredblock. I can't imagine that an imcremeted value like "second" will also appear as an incrementing byte after encryption.

Here an example 9 packets in sequence, where as octed 28 increments from "d9" to "e1":

7e a0 67 cf 02 23 13 fb f1 e6 e7 00 db 08 49 53 4b 69 74 6c 83 b4 4f 20 00 03 b1 d9 16 c2 0d ea cb d1 33 48 b0 7a 7b 3a 85 0a c5 c1 ce 55 a7 0e a5 7a 15 c2 84 c6 ba 47 32 6e 2a 59 8f 32 76 b7 a4 a1 5c 03 93 c4 49 2c a8 3a 56 0b 3b 53 5d 15 8a 22 05 5f 89 a1 11 7c aa 91 89 5f cf 63 c5 05 b4 20 7b 16 a9 a3 f6 79 7e

7e a0 67 cf 02 23 13 fb f1 e6 e7 00 db 08 49 53 4b 69 74 6c 83 b4 4f 20 00 03 b1 da c0 b0 52 5d a1 3d 5d 20 f3 ff c5 34 fd 60 87 d7 e3 31 22 70 eb 06 b1 82 86 b3 32 bb e2 c5 c5 fe dc ed c4 0a 3f b3 f8 0c ae 04 92 d1 3d 08 9f 64 f6 18 26 75 dd cb 22 c0 06 e3 fa e8 a5 dc b4 83 17 d5 7b 57 39 6c e1 a2 26 6f ae 53 7e

7e a0 67 cf 02 23 13 fb f1 e6 e7 00 db 08 49 53 4b 69 74 6c 83 b4 4f 20 00 03 b1 db 45 e7 e7 68 91 fb de 03 9d f9 36 87 20 16 7f 1a fa b0 a9 d3 68 df 2c ff 94 b7 ed aa 44 81 17 03 9e f5 d8 d4 0b 55 89 63 49 16 3a 38 f5 4d a3 77 17 17 71 b6 d8 0d ac a0 44 30 e5 e4 b1 0e 88 cf 20 f9 ba 31 ed 7a 8c 23 7d db f4 28 7e

7e a0 67 cf 02 23 13 fb f1 e6 e7 00 db 08 49 53 4b 69 74 6c 83 b4 4f 20 00 03 b1 dc 7d d7 62 23 c6 0e 62 87 eb 53 84 1d 22 e2 03 f0 a0 e8 64 2e b6 8e 4e 2a 31 d9 7a 37 24 1f e8 c8 13 be cc 1d cc 15 b5 2b be db b6 fe 41 f1 17 17 ce e0 aa c9 20 ff 91 c0 ba cc 41 14 ea b9 d2 d3 f7 98 85 f0 a2 3f 02 b5 3b d1 7e 51 7e

7e a0 67 cf 02 23 13 fb f1 e6 e7 00 db 08 49 53 4b 69 74 6c 83 b4 4f 20 00 03 b1 dd 06 0c fa 1b c3 3d 65 6a 1f 16 b6 51 e5 56 6d 23 d6 e5 0d fa a9 80 b1 18 a8 a4 9c c7 7c 44 df dd 57 4f e0 72 ce 14 db 07 e1 86 c9 b8 19 ac 56 e8 61 54 ff 8a 13 65 c9 c6 9e 91 81 bd f5 35 35 aa 4b 73 e0 b2 e9 29 f3 79 5d 0e f9 57 7e

7e a0 67 cf 02 23 13 fb f1 e6 e7 00 db 08 49 53 4b 69 74 6c 83 b4 4f 20 00 03 b1 de 4d a9 86 79 07 a6 e0 2a 48 67 c2 e3 bf a6 6f 22 2f 95 b2 61 e7 af 98 08 47 ce 8b 6e 4f 65 db 6a 29 d0 93 ed d1 3c cd 41 22 f4 84 d1 e3 42 e9 1e 39 70 e6 c1 8a ac 9b 4a 97 95 2a e7 6f 76 68 cc b7 f1 3d c9 e2 65 39 ad c9 ef e2 bd 7e

7e a0 67 cf 02 23 13 fb f1 e6 e7 00 db 08 49 53 4b 69 74 6c 83 b4 4f 20 00 03 b1 df a8 59 ab 1a 55 be 95 a4 50 f2 c2 18 71 72 0f 92 f1 d2 d4 93 2e 5d ca 26 b3 0f c4 ea 8d 15 f3 d2 1b 02 da 37 5f d2 12 f8 ae 6b 5e 4a e1 6f 43 80 27 11 8f c5 a2 aa b3 2d 5e de d5 62 b3 93 cf fe 21 db 89 40 0e 5f 72 1a 2c 7c 7e 25 7e

7e a0 67 cf 02 23 13 fb f1 e6 e7 00 db 08 49 53 4b 69 74 6c 83 b4 4f 20 00 03 b1 e0 c4 9c 7d e4 47 89 f4 87 e9 59 5a 2a 9c e6 b3 be 0c ff 8a 3f 89 fa e3 08 28 9a 8c 1e ec f2 de 9b a1 64 7a f5 28 39 40 61 3c 04 ad 38 1e 90 00 76 75 31 92 ee 83 e6 25 22 66 8c 50 96 ee 8a 1b ff 8e 90 f8 4f 92 2b ff 56 b2 c1 9f 45 7e

7e a0 67 cf 02 23 13 fb f1 e6 e7 00 db 08 49 53 4b 69 74 6c 83 b4 4f 20 00 03 b1 e1 8c c9 c0 b5 18 6b 62 1c d1 6d 02 0b b9 14 5a 79 01 17 59 20 68 38 d2 15 83 7b af f7 eb 96 67 8f 9a 1f d5 00 ba 67 07 82 71 a7 4d 66 af 80 12 97 4e 43 7d d3 ec 13 e3 db c3 ac 8a 0d dc 75 b9 d1 b5 e0 fa c9 ec 5d dc a7 9f 37 0e 02 7e