Kamstrup Meter Protocol

26. feb 2012 kl. 17.19

Da vi sidst forlod emnet, havde jeg fået en Kamstrup 382J elmåler, men manglede protokollen for at kunne få andet en IEC1107 informationerne ud af den.

Det problem er løst nu: PyKamstrup er et lille python program der via en seriel-port og et optisk hovede (se tidligere blogindlæg for diagram) kan hente brugbare data ud af ihvertfald min elmåler.

Jeg har prøvet at spørge Kamstrup efter protokol dokumentationen et par gange, men det kommer der ikke noget ud af, selv ikke når man henviser til at Kamstrup selv i deres produktblade beskriver "KMP" protokollen som "the KMP (Kamstrup Meter. Protocol), which is [also] an open protocol."

Vink med Vognstang til Kamstrup:

Det er ikke en "åben protokol" når I ikke vil slippe dokumentationen.

Af hjemmestrikkede protokoller at være er det ikke den værste jeg har set, anvendelsen af CRC16 som checksum trækker opad, den klodsede frame- og escape-mekanisme tæller nedaf.

Jeg har ikke helt styr på hvordan/hvor godt Python virker under Windows, men i hvertfald alle nutidige UNIX dialekter burde kunne bruge ovenstående program.

At implementere protokollen på f.eks Arduino ligger lige til højrebenet.

Samme protokol anvendes tilsyneladende også af mange af Kamstrups andre måleindretninger, men der har man formodentlig andre variabel-numre med andre betydninger.

God Fornøjelse,

phk

PS: Output fra min elmåler:

Energy in (kWh) 6745 Energy out (kWh) 0 Energy in hi-res (kWh) 6745.4191 Energy out hi-res (kWh) 0.0 Voltage p1 (V) 229 Voltage p2 (V) 226 Voltage p3 (V) 232 Current p1 (A) 5.58 Current p2 (A) 1.69 Current p3 (A) 2.36 Power p1 (kW) 1.029 Power p2 (kW) 0.322 Power p3 (kW) 0.438

Poul-Henning Kamps billede
Poul-Henning Kamp
er selvstændig open source-softwareudvikler. Han skriver blandt andet om politik, hysteri, spin, monopoler, frihedskampe gør-det-selv-teknologi og humor.

Kommentarer (32)

Jeg har været igennem det samme for at kunne aflæse mine vand- og varmemålere fra Kamstrup. Har også forsøgt at få protokollen udleveret af Kamstrup, og fik at vide, at det kunne jeg måske godt, hvis mit forsyningsselskab ville tillade det. De svarede forsyningsselskabet aldrig på, så jeg begyndte at lave reverse engineering for at forstå protokollen.

Det letteste er register id'erne. De står i Kamstrup datablade for målerne - så intet problem dér.

Jeg har fundet et par ekstra detaljer, som du ikke har med i din implementation:

Byte 5 fra måleren er enhed jf. følgende:
units = {0: '', 1: 'Wh', 2: 'kWh', 3: 'MWh', 4: 'GWh', 5: 'j', 6: 'kj', 7: 'Mj', 8: 'Gj', 9: 'Cal', 10: 'kCal', 11: 'Mcal', 12: 'Gcal', 13: 'varh', 14: 'kvarh', 15: 'Mvarh', 16: 'Gvarh', 17: 'VAh', 18: 'kVAh', 19: 'MVAh', 20: 'GVAh', 21: 'kW', 22: 'kW', 23: 'MW', 24: 'GW', 25: 'kvar', 26: 'kvar', 27: 'Mvar', 28: 'Gvar', 29: 'VA', 30: 'kVA', 31: 'MVA', 32: 'GVA', 33: 'V', 34: 'A', 35: 'kV',36: 'kA', 37: 'C', 38: 'K', 39: 'l', 40: 'm3', 41: 'l/h', 42: 'm3/h', 43: 'm3xC', 44: 'ton', 45: 'ton/h', 46: 'h', 47: 'hh:mm:ss', 48: 'yy:mm:dd', 49: 'yyyy:mm:dd', 50: 'mm:dd', 51: '', 52: 'bar', 53: 'RTC', 54: 'ASCII', 55: 'm3 x 10', 56: 'ton x 10', 57: 'GJ x 10', 58: 'minutes', 59: 'Bitfield', 60: 's', 61: 'ms', 62: 'days', 63: 'RTC-Q', 64: 'Datetime'}

Byte 6: Antal bytes i data
Byte 7: Skaleringsfaktor:
exponent = b & 0x3F
if(b&0x40):
exponent = -exponent
factor = pow(10, exponent)
if (b&0x80==0x80):
factor=-factor

På Multical-målerne har jeg kørt med seriel parametre: 1200N82 - ved dog ikke om de kan køre hurtigere.

Til gengæld havde jeg ikke helt gennemskuet hvordan escape virkede. Men det kan jeg jo så få med nu :-)

  • 0
  • 0

Jeg er ligeledes igang med at interface til mine Kampstrup målere (min egen 382 bi-måler, mit forsyningsselskabs 601 varme og 61 vand -måler). Jeg har konstrueret et optisk læsehoved via en gammel 741 OpAmp og bortset fra noget echo/crosstalk (som jeg filtrerer i software, gør i også dét?) så fungerer det fint.

Ligeledes har jeg haft kontakt til Kamstrup, og udfordret dem på deres "open protocol" og "open source code" som de skriver i diverse materiale. Anyway, da jeg principielt nægter at acceptere nogen form for NDA, kom jeg ikke længere af den officielle vej. I skal dog næsten lige have denne skønne sætning med, omkring hvorfor protokollen er så hemmelig: "Årsagen hertil er, at vi løbende opdaterer KMP-protokollen og at vi derfor registrerer samtlige "brugere", sådan at vi senere kan rette henvendelse til disse firmaer om f.eks nye funktioner, implementering af nye målertyper osv.". Jeg tror hurtigt vi kan blive enige om at det er fis i en hornlygte, og at den sande grund nok er at Kamstrup forveksler sikkerhed med uigennemskuelighed (klassisk security though obscurity).

Og det giver måske også mening når man ser lidt nærmere på deres protokol, der er f.eks, kun 2^16 mulige passwords (til at kunne omprogrammere måleren) hvilket jeg har brugt til at finde passworded på min 382 måler med, via brute-force - det tager 1½ dag worst case at afprøve samtlige koder, med lidt under et forsøg pr. sekund.

Jeg havde også tænkt mig at dele information og kode med andre, der dog er i C# (Mono) da det er tilstrækkeligt lav-niveau (unsigned byte, serial support mv.) uden at være for besværligt. Grunden til jeg ikke har offentliggjort noget endnu, skyldes uklarhed over ricikoen ved at offentliggøre disse ting.

Det ville være suverent hvis vi kan stikke hovederne sammen og udveksle erfaringer. Et par issues. Hvorfor kalder i det CRC16, når der i virkeligheden er tale om en alm. 8-bit XOR/LRC?

            protected byte[] CalcChecksum(byte[] data)  
    {     
        byte checksum = (byte)0;  
        for (int i = 1; i < data.Length; i+=2)  
        {  
            checksum += (byte)FromKamstrupDouble(data, i);  
        }  
        checksum = (byte)((checksum ^ 0xFF) + 1);  
        return ToKamstrupDouble(checksum);  
    }

Og hvad er det for en mystisk ineffektiv protokol, hvor en Kamstrup byte bliver delt ud på 2 fysiske ASCII bytes der hver indeholder 0x30 - 0x46 og 0x40 hoppes over (speciel karakter)?

    private static byte ToKamstrupByte(int value)  
    {  
        if(value < 10)  
            return (byte)(0x30 + value);  
        return (byte)(0x40 + (value-9));  
    }  

    private static int FromKamstrupByte(byte value)  
    {  
        if(value < 0x3a)  
            return value - 0x30;  
        return value - 0x37;  
    }

Jeg skal lige have ryddet lidt op i koden, så smider jeg det på GitHub. Ser frem til hvad vi kan udrede sammen.

  • 0
  • 0

Så er Eriks information indarbejdet på github.

Casper, er vi sikre på at det er samme protokol den du roder med ?

Kamstrup angiver selv at de bruger CRC16 og derfra var det ret trivielt at finde hvilken CRC16 de brugte.

Mht til password: Har du prøvet default ? 12345

  • 0
  • 0

> Casper, er vi sikre på at det er samme protokol den du roder med ?

Nja jeg bliver da godt nok i tvivl. Jeg forbinder til min 382 med 1200N82, ingen handshake, og sender følgende som "Hello":

Talking through serial port /dev/ttyUSB1!
<- 0x40 0x46 0x45 0x30 0x30 0x30 0x32 @FE0002
-> 0x48 0x46 0x45 0x30 0x30 0x30 0x32 0x30 0x31 0x30 0x37 0x30 0x31 0x46 0x37 HFE0002010701F7

Første byte er reserveret til sign-on, resterende data bruger den lidt specielle encoding hvor Kamstrup deler en byte i en LSB og en MSB nibble, dvs. hvor 0x46 og 0x45 er lig 254 (16<<4 & 15), 0x30 og 0x30 er lig 0 (0<<4 & 0) og de to sidste bytes 0x30,0x32 er lig 2 (0<<4 & 2), som er en 8bit LRC af de underliggende data med første byte undtaget ((254 + 0)^0xff + 1). Måske er det min manglende forståelse af CRC16, jeg kan godt se at 2 bytes bliver brugt som checksum, men observerer kun 256 mutationer af disse hvilket der ikke er meget 16bit over.

  • 0
  • 0

> Talking through serial port /dev/ttyUSB1! <- 0x40 0x46 0x45 0x30 0x30 0x30 0x32 @FE0002 -> 0x48 0x46 0x45 0x30 0x30 0x30 0x32 0x30 0x31 0x30 0x37 0x30 0x31 0x46 0x37 HFE0002010701F7

Det ligner nærmest at nogen/noget hexdumper ting undervejs...

  • 0
  • 0

Det ligner nærmest at nogen/noget hexdumper ting undervejs...

Ja jeg tracer jo kommunikation, i et forsøg på at forstå og dokumentere hvad der sker. Anyway, eftersom kamstrup.py giver mig:

Energy in None None
Energy out None None
Energy in hi-res None None
Energy out hi-res None None
Voltage p1 None None
Voltage p2 None None
Voltage p3 None None
Current p1 None None
Current p2 None None
Current p3 None None
Power p1 None None
Power p2 None None
Power p3 None None

...må der næsten være tale om en anden (ældre) 382 måler.
Det KAN måske også skyldes echo/crosstalk? Måske jeg ikke kan få kamstrup.py til at funke, fordi mit optiske læsehoved læser hvad den selv skriver... dioderne på min 382 sidder begravet ca. 2 CM nede under et transparant stykke plastik, så jeg filtrerer denne echo/crosstalk fra i min software hvilket jo et nemt at gøre med en synkron protokol. Jeg må indrømme jeg er for nærig til at betale Kamstrup 1500kr for et læsehoved.

En IEC61107 forspørgsel afslører ikke hvilken generation jeg har:

KAM 685-382-OK-10
0.0(12345678)
1.20(0002308kWh)
1.20.1(0002307
kWh)
1.20.2(0000001kWh)
1.31(0050170
h)
1.26(0000000)
1.6(000000,5kW)
1.6
1(000000,5)!

...så det lader til at jeg måske har gang i en anden version af "KMP protokollen". Efter at have set de versioner af MeterTool Kamstrup har bikset sammen hardwired til én specifik måler, skulle det ikke undre mig.

  • 0
  • 0

Mange af de målere der er fjernaflæst bruger formaterne fra DS/EN 13757-3. Det meste af det stod tidligere i den 'gamle' DS/EN-1434-3 og kan sikker også findes i dokumenter fra M-bus User Group.

Dette er som i kan se europæiske standarder, som der er copyright på. Derfor kan jeg ikke udlevere det (og det Kamstrup nok heller ikke). Prøv evt. at se priserne på den slags dokumenter hos IEC eller ISO.

Det er helt rigtigt at meget af dette er "mindre struktureret". Der har ikke altid været en ordentlig systemarkitektur. Der har især tidligere været en masse mennesker der lavede 'smarte hack' når man skulle ha' plads til det i en 4-bit processor.

Koden for fabrikant navn er afledt af den tre bogstavs kode der bruges i IEC 1107 (som i øvrigt nu hedder IEC 62056-21). Teksten i standarden for dette er;
"The field "manufacturer" is coded unsigned binary with 2 bytes. This manufacturer ID is calculated from the ASCII code of EN 61107 manufacturer ID (three uppercase letters) with the following formula:
Man. ID = [ASCII(1st letter) – 64] • 32 • 32
+ [ASCII(2nd letter) – 64] • 32
+ [ASCII(3rd letter) – 64]

Forsyningsselskaber er generelt meget tilbageholdende med ændringer. Så længe den eksisterende standard virker, ønsker de ikke ændringer.

  • 0
  • 0

Jeg ved ikke om I har læst min lille intro på http://ing.dk/artikel/120890-hvilken-elmaa....

Et par kommentarer til ovenstående indlæg og Pyton-koden:
1. Man kan godt i hvert fald på nogle målere requeste flere end ét register i samme request
2. En liste over IEC fabrikant ID'er kan findes her:http://www.dlms.com/organization/flagmanuf...
3. Hvis man vil generalisere det hele lidt kan man med CID 0x01 (GetType) udlæse målermodellen. Ingen data ud over komandoen. 4 bytes svar:

[uint main hw type][uint8 sub hw type][uint16 sw revision]

53 00 Meter K382B / K382C
53 01 Meter K382Jx2, 3, 4, 5, 6, 7, 8, 9
55 00 Meter K382D / K382E
55 01 Meter K382JxB, C, D, F, G
56 00 Meter K162B / K162C
56 01 Meter K162Jx3, 6, 7
57 00 Meter K162D / K162E
57 01 Meter 162JxC, F, G
58 00 Meter K282B / K282C
58 01 Meter K282Jx2, 3, 4, 5, 6, 7, 8, 9
59 00 Meter K282D / K282E
59 01 Meter K282JxB, C, D, E, F, G

sw revision 0x0101 = A1, 0x0205 = B5 ...

  1. En lidt mere komplet register-liste for el-målere (per juli 2008):
    1 Active energy A14
    2 Active energy A23
    1031 Active energy A1234
    3 Reactive energy R12
    4 Reactive energy R34
    5 Reactive energy R1
    6 Reactive energy R4
    13 Active energy A14, test xxx.xxxx
    14 Active energy A23, test xxx.xxxx
    15 Reactive energy R12, test xxx.xxxx
    16 Reactive energy R34, test xxx.xxxx
    19 Active energy A14 Tariff 1
    23 Active energy A14 Tariff 2
    27 Active energy A14 Tariff 3
    31 Active energy A14 Tariff 4
    1059 Active energy A14 Tariff 5
    1060 Active energy A14 Tariff 6
    1061 Active energy A14 Tariff 7
    1062 Active energy A14 Tariff 8
    20 Active energy A23 Tariff 1
    24 Active energy A23 Tariff 2
    28 Active energy A23 Tariff 3
    32 Active energy A23 Tariff 4
    1063 Active energy A23 Tariff 5
    1064 Active energy A23 Tariff 6
    1065 Active energy A23 Tariff 7
    1066 Active energy A23 Tariff 8
    21 Reactive energy R12 Tariff 1
    25 Reactive energy R12 Tariff 2
    29 Reactive energy R12 Tariff 3
    33 Reactive energy R12 Tariff 4
    1067 Reactive energy R12 Tariff 5
    1068 Reactive energy R12 Tariff 6
    1069 Reactive energy R12 Tariff 7
    1070 Reactive energy R12 Tariff 8
    22 Reactive energy R34 Tariff 1
    26 Reactive energy R34 Tariff 2
    30 Reactive energy R34 Tariff 3
    34 Reactive energy R34 Tariff 4
    1071 Reactive energy R34 Tariff 5
    1072 Reactive energy R34 Tariff 6
    1073 Reactive energy R34 Tariff 7
    1074 Reactive energy R34 Tariff 8
    17 Resetable counter A14
    18 Resetable counter A23
    39 Max power P14
    40 Max power P23
    41 Max power Q12
    42 Max power Q34
    1023 Actual power P14
    1024 Actual power P23
    1025 Actual power Q12
    1026 Actual power Q34
    43 Accumulated max power P14
    44 Accumulated max power P23
    45 Accumulated max power Q12
    46 Accumulated max power Q34
    47 Number of debiting periods
    1049 Max power P14 RTC
    58 Pulse input
    1004 Hour counter
    1002 Clock
    1003 Date
    1047 RTC
    54 Configurations number 1
    55 Configurations number 2
    56 Configurations number 3
    1029 Configurations number 4
    1075 Configurations number 5
    57 Special Data 1
    1021 Special Data 2
    1010 Total meter number
    51 Meter number 1
    52 Meter number 2
    53 Meter number 3
    50 Meter status
    1001 Serial number
    1058 Type number
    2010 Active tariff
    1032 Operation mode
    1033 Max power P14 Tariff 1
    1050 Max power P14 Tariff 1 RTC
    1036 Max power P14 Tariff 2
    1051 Max power P14 Tariff 2 RTC
    1039 Power threshold value
    1040 Power threshold counter
    1045 RTC status
    1046 VCOPCO status
    1054 Voltage L1
    1055 Voltage L2
    1056 Voltage L3
    1076 Current L1
    1077 Current L2
    1078 Current L3
    1080 Actual power P14 L1
    1081 Actual power P14 L2
    1082 Actual power P14 L3
    1083 ROM checksum
    1005 Software revision
    1084 Voltage extremity
    1085 Voltage event
    1086 Logger status
    1087 Connection status
    1088 Connection feedback
    1102 Module port I/O configuration
  • 0
  • 0

Det lyder som om dit læsehoved er alt for følsomt.

Tak for tippet, jeg slap for crosstalk da jeg reducerede de ene modstand. Men jeg kan dog stadig ikke få kamstrup.py til at komme med noget konkret data, så jeg bliver nok nødt til at grave lidt mere i de forskellige måler typer/generationer... min er helt sikkert ikke en J generation (formeentligt en L eller en K).

  • 0
  • 0

Har du prøvet med andre seriel-parametre? phk's program kører 9600. Du skriver selv, at du bruger 1200N82.

Ja jeg har prøvet at gå ned til 1200, eftersom det ifølge Kamstrup's dokumentation kun er nyeste generation J der tillader 9600. De ældre generationer B, C, D, E, L og K, understøtter kun 1200.

  • 0
  • 0

Jeg synes mere det ligner en der samler pulser op fra gamle elmålere...

Hmm - der står da ellers:

"MGY skal først og
fremst være et alternativ der
man velger impulsbaserte
måleverdier fordi man ikke
ønsker å skifte ut (nye)
målere."

Men måske mine (manglende) norsk-kundskaber vindleder, så der menes "skifte ut [til] nye..." ?

Databladet er fra 2007.

  • 0
  • 0

Jeg har også selv overvejet at sætte en arduino på, men er ikke kommet længere end overvejelserne :-(.

Jeg snakkede med en installatør fra fjernvarmen, da jeg fik installeret ny måler med lækovervågning(Kamstrup 601, tror jeg ). Han påstod at det var problematisk at benytte sig af det optiske interface hvis man havde fjernaflæsning via f.eks GSM. De havde opgivet få til til at virke på en skole i området, der gerne selv ville følge med de deres forbrug. Jeg syntes nu det lyder lidt mystisk.

@Carsten: Kunne det måske være sådan noget der driller?

  • 0
  • 0

Da jeg spurgte Kamstrup om at få udleveret deres åbne protokol, sagde de, at forsyningsselskabet skulle give lov til at de udleverede protokollen, da kommunikationen kunne have indflydelse på opsætningen og driften af måleren. Jeg tolkede det som, at så længe jeg bare udlæser data, var der ikke noget problem (ud over at målerens batteri muligvis hurtigere bliver drænet). Men det er da ikke umuligt, at der er andre problemer.

  • 0
  • 0

Kunne det måske være sådan noget der driller?

Det tror jeg ikke, eftersom jeg p.t. kun arbejder med 382 målere (strømforbrug). Det optiske interface fører ifølge Kamstrup diagrammer, direkte ind i mikroprocessoren, og alt andet (MBus, wifi, GSM...) består så blot af konvertering til/fra KMP.

Jeg tolkede det som, at så længe jeg bare udlæser data, var der ikke noget problem (ud over at målerens batteri muligvis hurtigere bliver drænet).

For rent faktisk at ændre i måleren, skal du først autorisere dig. Tilsyneladende er mange målere aldrig blevet omprogrammeret fra default "12345", og det er måske derfor Kamstrup holder kortene tæt til kroppen.

  • 0
  • 0

Problemet er netop på mange målere (og måske også Kamstrups) at det er samme serielle kanal som det optiske øje og evt. indstiksmoduler til fjernaflæsningssystemer benytter - med det muligheder for sammenblanding af kommunikation som det kan medføre.

Mht. til sikkerhed tror jeg helt sikkert at Kamstrup og forsyningsselskaberne har røde øre. Mange default passwords, nem password brute force og ikke mindst ting man sjovt nok kan gøre uden brug af passwords (f.eks. at ændre målerens RTC - don't try this at home :-) )

  • 0
  • 0

Ingen af mine 382'ere (L og K modeller tror jeg det er) vil snakke på denne måde, men bruger åbentbart en ældre ASCII baseret protokol med simpel XOR checksum.

Er der andre der har held med at bruge PHK's Python kode på en ikke-J generation?

@PHK får du ikke et svar, hvis du sender 0x40 0x46 0x45 0x30 0x30 0x30 0x32 efterfulgt af 0x0D (LF) til din J-generations måler?

  • 0
  • 0

pywws burger jeg allerede til min Rosenberg måler, og dumper data til mit Synology NAS. Men der er ikke meget protokolværk der kan genbruges, hvilket jo er det svære... grafgenerering osv. kan man bare udlicitere til Google (http://code.google.com/apis/chart/).

Overvejer at prøve denne trådløse serielle enhed, så man bare kan knappe en lille dims på sine målere - men jeg ville skulle bruge 3, så søger p.t. efter en måde at multiplexe én på istedet:
http://77.162.55.232/usbscope/uart_index.html

  • 0
  • 0

Jeps, jeg tænkte heller ikke på protokollen, men mere på resten :O)

Den trådløse virker smart - det må du gerne holde mig opdateret med.

  • 0
  • 0

Hejsa

Jeg vil blot fortælle, at jeg med udgangspunkt i PyKamstrup har fået et par Arduino'er til at tale med både vores el- og fjernvarmemåler.

Den ene Arduino er koblet på vores elmåler (Kamstrup 382Jx3) vha. et hjemmebygget IR interface og afsender de opsamlede måledata via et ethernet-shield hvert minut til pachube.com.

Den anden Arduino har jeg bygget ind i en gammel Linksys WRT54GL router og koblet boardet til routerens interne serielport. Arduinoen trækker så - ligeledes ved hjælp af et IR interface - data ud af vor fjernvarmemåler (Kamstrup Multical 601), sender disse data serielt til Linksys'en, hvor et OpenWRT bash script derefter sender måledata til pachube.com.

Se evt. mere her: http://kildal.dk/?page_id=117

Begge målere "taler" KMP og mit lille projekt har kun kunnet lade sig gøre pga. det store forarbejde af Poul-Henning Kamp (PyKamstrup) samt den værdifulde information jeg har kunnet finde i denne tråd - så mange, mange tak for det!!

Jeg regner med at få renset lidt op i min Arduino kode, så den også kan havne på min webside herover.

Mvh Nicolai

  • 0
  • 0

Hej,

Synes det er super spaendende det i har gang i her. Jeg overvejer kraftigt at hoppe med i klubben.
Jeg ville bare naevne at en Raspberry Pi maaske kunne vaere et godt alternativ til at reimplementere protokollen paa en Arduino.

Pros:
- Har ethernet.
- Understoetter Python som standard.
- Er billig.
- Kan evt. logge til SD kort, drive hjemmeside etc. etc.

Cons:
- Ikke til at faa fat paa lige nu.

Laes mere:
http://www.raspberrypi.org/faqs
http://dk.rs-online.com/web/generalDisplay...

  • 0
  • 0