Page 1 of 3

District Heating / City Heating (Stadsverwarming) Mysensor IR sender/Receiver

Posted: Wednesday 30 March 2016 19:12
by Chakkie
Hi guys,

I've been looking for a while on internet to find a way to log the heating usage (District Heating) on my Kamstrup Multical 401. I have come across this thread viewtopic.php?f=31&t=5390&hilit=Stadsverwarming. This thread mentions the use of an IR convertor cable (25 euro see image below) and python script.


Image
Image

Since I've already been logging my energy and water usage using Mysensor pulse sensor, I though this might also work with the Kamstrup meter (Although I have not find any one on internet using Mysensor to log).

So I bought this IR Transmitter and receiver Image.

Uploaded the script found on this url http://frack.nl/wiki/Stadsverwarming to my arduino. Note that there is no Mysensors components in this script. I only use serial monitor of the ArduinoIDE to test if this works.

Code: Select all

#include <SoftwareSerial.h>
 
const int LEDPIN   = 5;
const int DIODEPIN = A1;
 
SoftwareSerial mySerial(DIODEPIN, LEDPIN); // RX, TX
 
long d;
 
void setup() {
  pinMode(LEDPIN, OUTPUT);
  pinMode(DIODEPIN, INPUT);
  digitalWrite(DIODEPIN, LOW);
  Serial.begin(9600);
  d = millis() + 5000;
}
 
char ch;
boolean rx;
 
void rx300() {
  boolean done=false;
  mySerial.begin(300);
  mySerial.println("/?!");
  while (!done) {
    if (mySerial.available()) {
      ch = mySerial.read() & 0x7F;
      if (ch == 2) rx = true;
      else if (ch == 3) {
         rx = false;
         done = true;
      }
      else if (rx == true) 
        Serial.print(ch);
        //Serial.write(ch);
    }
  }
}
 
void rx1200(char k, long* val, char n) {
  boolean done=false;
  char str[12];
  char i=0, j=0;
  String req = "/#";
  req += k;
  mySerial.begin(300);
  mySerial.println(req);
  mySerial.begin(1200);
  while (n>0) {
    if (mySerial.available()) {
      ch = mySerial.read() & 0x7F;
      if (ch != 0x7F) {
        if (ch == 13) ch == 32;
        //Serial.print(ch);
        if (ch == 32) {
           str[j] = 0;
           *val = atol(str);
           j = 0;
           val++;
           i++;
           n--;
        } else str[j++] = ch;
      }
    }
  }
}
 
void loop() {
  long vala[10];
  if (d < millis()) {
    rx300();
    rx1200('1', vala, 10);
    Serial.print("energy [GJ]: ");
    Serial.println(vala[0]/100.0);
    Serial.print("water [m3]: ");
    Serial.println(vala[1]/100.0);
    Serial.print("hourcounter [j]: ");
    Serial.println(vala[2]);
    Serial.print("Tin [.C]: ");
    Serial.println(vala[3]/100.0);
    Serial.print("Tout [.C]: ");
    Serial.println(vala[4]/100.0);
    Serial.print("deltaT [.C]: ");
    Serial.println(vala[5]/100.0);
    Serial.print("power [kW]: ");
    Serial.println(vala[6]/10.0);
    Serial.print("flow [l/h]: ");
    Serial.println(vala[7]);
    Serial.print("peak power/flow [?]: ");
    Serial.println(vala[8]);
    Serial.print("info: ");
    Serial.println(vala[9]);
    while(1);
  }
}
I have set the baudrate to 300 and 1200. Unfortunately I did not get any feedback from the Kamstrup meter. I was wondering if anyone know if this IR transmitter will acturally communicate with the Kamstrup meter. Or am I really stuck with the IR converter cable.

Thanks everyone.


Controller: Domoticz
Server: Raspberry Pi

Re: District Heating / City Heating (Stadsverwarming) Mysensor IR sender/Receiver

Posted: Friday 10 June 2016 8:55
by flederflick
Hi Chakkie,

I was wondering if you were making any progress with the mysensor version of the IR convertor cable?

I was also checking if their was a different way to integrate my kamstrup meter into my mysensor network.

Best regards/Groeten,

flederflick

Re: District Heating / City Heating (Stadsverwarming) Mysensor IR sender/Receiver

Posted: Friday 10 June 2016 17:26
by Chakkie
flederflick wrote:Hi Chakkie,

I was wondering if you were making any progress with the mysensor version of the IR convertor cable?

I was also checking if their was a different way to integrate my kamstrup meter into my mysensor network.

Best regards/Groeten,

flederflick
No not yet. Please see this post https://forum.mysensors.org/topic/3525/ ... r-receiver

I've got tips from people how to create a reader for the Kamstrup meter. But it seems that there are no communication between the reader and the meter.

May be the communication interface module in the Kamstrup meter is missing. Or the arduino reader I created does not work

Re: District Heating / City Heating (Stadsverwarming) Mysensor IR sender/Receiver

Posted: Sunday 11 September 2016 20:14
by Hesmink
Hi,

I use the same IR Transmitter/Receiver for my Kamstrup Multical 602 to read heat usage and hot water usage.
I noticed there are two ways to talk to the Multical using this IR dongle, and only one of them is working for me.
For me, using the Kamstrup Meter Protocol (KMP) works.

I have a Python script available that works for me, and is currently reading the heat usage (and hot water usage) and sending it to Domoticz using JSON, for usage with a dummy sensor. The IR dongle is plugged in the RPI.
The original of the script is here: https://github.com/bsdphk/PyKamstrup

I modified it to retrieve 1 value, and send it to Domoticz.
You have to supply comport, the register ID you want you retrieve from the meter and the IDX code of the virtual sensor you want to modify.

My crontab reads:
0 1 * * * /home/pi/domoticz/scripts/pyKamstrup_single.py /dev/ttyUSB2 84 44
1 1 * * * /home/pi/domoticz/scripts/pyKamstrup_single.py /dev/ttyUSB2 60 43

Register ID 60 = Energy register 1: Heat energy
Register ID 84 = Input register VA (used to measure hot water usage)
pyKamstrup_single.zip
(2.42 KiB) Downloaded 323 times

Re: District Heating / City Heating (Stadsverwarming) Mysensor IR sender/Receiver

Posted: Wednesday 26 October 2016 10:03
by markiemajax
Hello Hesmink,

What do i change in the script?

Only the ip of my pi or do i need to change other settings?

I do not get a reading.

Greatings,
Mark (NED)

Re: District Heating / City Heating (Stadsverwarming) Mysensor IR sender/Receiver

Posted: Wednesday 26 October 2016 12:30
by Hesmink
Hi,

Normally, you should only have to enter the correct IP in the scripts, and suply the correct com port, idx en command on the command line.
To see if the sensor returns anything change the last two lines

requestPost = urllib2.Request( "http://127.0.0.1:8080/json.htm?type=com ... evice&idx=" + str(index) + "&svalue=" + str(value) )
resultPost = json.load(urllib2.urlopen(requestPost))

to

print( int(value) )

and run in from the command line. This will print the read value from the Kamstrup.

Some things to check:
- Is the sensor correctly identified by the operating system?
- Are you using the correct com port for your sensor?
- Is the sensor correctly aligned on the meter? The right way up? It's infrared, so you should position it carefully.

Also, I read that sometimes the IR port is disabled. And also, sometimes a simpler protocol is used that obviously wasn't the case for me.

Re: District Heating / City Heating (Stadsverwarming) Mysensor IR sender/Receiver

Posted: Thursday 10 November 2016 21:31
by markiemajax
Hello,

I get the error:

root@raspberrypi:/home/pi/domoticz/scripts/python# sudo ./pyKamstrup_single.py
Traceback (most recent call last):
File "./pyKamstrup_single.py", line 233, in <module>
comport = sys.argv[1]
IndexError: list index out of range


What can be wrong??

Mark

Re: District Heating / City Heating (Stadsverwarming) Mysensor IR sender/Receiver

Posted: Thursday 10 November 2016 22:04
by Hesmink
You need to enter parameters, like: /dev/ttyUSB2 84 253
First paramater is the connected USB port, second the command (register id), third, the idx of the domoticz dummy sensor.

Re: District Heating / City Heating (Stadsverwarming) Mysensor IR sender/Receiver

Posted: Thursday 10 November 2016 22:15
by markiemajax
I added the parameters in crontab-e.

1 1 * * * /home/pi/domoticz/scripts/pyKamstrup_single.py /dev/ttyACM0 60 262

Re: District Heating / City Heating (Stadsverwarming) Mysensor IR sender/Receiver

Posted: Thursday 10 November 2016 22:23
by Hesmink
I would change the script temporarily as I stated above (using the print( int(value) )), and check the output of /home/pi/domoticz/scripts/pyKamstrup_single.py /dev/ttyACM0 60 262
This should give the current readout. Then you know it works.

Re: District Heating / City Heating (Stadsverwarming) Mysensor IR sender/Receiver

Posted: Thursday 09 February 2017 15:55
by Jendemen
Hesmink,
I am struggling for a while now to read values from the Kamstrup, but so far no success.
I send data and receive the same data back in the logfile. Other baudrates give me errors.
Now I am thinking that the Kamstrup (I have the one with no additional modules installed) cannot communicate due to the lack of an additional module. The typenr of my meter shows 67C0252F1285.
C = 2 wire communication
0 = no module
25 = Radio + pulse inputs (internal antenna)
So I think my Kamstrup communicates via radio and is not able to communicate via the IR channel.
Can anyone possibly confirm that this is the case? If so, has anyone ideas if it is possible to use this radio signal?
Thanks, Jan.

Re: District Heating / City Heating (Stadsverwarming) Mysensor IR sender/Receiver

Posted: Thursday 09 February 2017 19:53
by Chakkie
I came across the same problem you have. I could not get the IR port working and since then I have not tried it again.

If I understand correctly, the Kamstrup meter has two way of data communication. Either using Infrared or the optional module (which are the M-Bus, modem or RF signal). The forth digit '0' you indicated on the part number inidicate your meter has no communication module (which are M-Bus, modem, RS232 interface or radio) installed. The IR port should always be there and functional.
MULTICAL® 401 has two ports for data communication.
The optical eye on the front panel complies with
EN 61107 standard and facilitates reading of consumption
data, data logger and on-line serial PC connection
when configuring the energy meter.
A split multiplug is placed beneath the top cover. The
top part of this plug is used to verify the meter. The
lower part is used when connecting communication
modules with M-Bus, modem, RS232 interface or radio.

Re: District Heating / City Heating (Stadsverwarming) Mysensor IR sender/Receiver

Posted: Thursday 09 February 2017 22:41
by Hesmink
Jendemen wrote:Hesmink,
I am struggling for a while now to read values from the Kamstrup, but so far no success.
I send data and receive the same data back in the logfile. Other baudrates give me errors.
Now I am thinking that the Kamstrup (I have the one with no additional modules installed) cannot communicate due to the lack of an additional module. The typenr of my meter shows 67C0252F1285.
C = 2 wire communication
0 = no module
25 = Radio + pulse inputs (internal antenna)
So I think my Kamstrup communicates via radio and is not able to communicate via the IR channel.
Can anyone possibly confirm that this is the case? If so, has anyone ideas if it is possible to use this radio signal?
Thanks, Jan.
Did you try both types of communication (Kamstrup Meter Protocol and the simple method)?
Is the dongle aligned correctly and the right way up?

Mine uses the KMP protocol, and until I found this out, the meter returned absolutely nothing.

Re: District Heating / City Heating (Stadsverwarming) Mysensor IR sender/Receiver

Posted: Wednesday 15 February 2017 21:38
by Jendemen
Hi Hesmink,

I only tried KMP, and yes, the dongle is alligned fine.
What other communication protocol do you mean and can you possibly give me a hint of howto?

Many thanks in advance, Jan

Re: District Heating / City Heating (Stadsverwarming) Mysensor IR sender/Receiver

Posted: Wednesday 15 February 2017 21:45
by Jendemen
I have the predecessor of the 602, the Kamstrup 601 by the way...

Re: District Heating / City Heating (Stadsverwarming) Mysensor IR sender/Receiver

Posted: Wednesday 15 February 2017 22:18
by Hesmink
Jendemen wrote:Hi Hesmink,

I only tried KMP, and yes, the dongle is alligned fine.
What other communication protocol do you mean and can you possibly give me a hint of howto?

Many thanks in advance, Jan
I think it's this script: http://www.smartmeterdashboard.nl/downl ... ects=0&d=1

The protocol is very simple, just send a certain string to get the results you want.

Re: District Heating / City Heating (Stadsverwarming) Mysensor IR sender/Receiver

Posted: Sunday 07 October 2018 21:45
by strategy
Hi all,

I know this topic is a bit aged already.
Anyway as I spent almost my whole day with the Kamstrup 602 I want to share my results with you.
Thanks a lot for collecting the information and especially for the script. This was a big help to me.

I was in the same situation like Jendeman. I tried almost everything but could not get any information out of my heat meter.
Then i tried do remove it to have a look at the back. Unfortunatly this was not possible. So i moved it to the old position.
And with the next try I got data for the first time...
Then some minutes later: Again no data...

Finally - after another 2 hours I figured out:

You have to press the play button on the Kamstrup 602. This activates the IR interface for a certain time and you will get the data.

I could reproduce this and it worked every time. I'll now test if the interface stays active if I send continous requests for data...

By the way I found a document describing all registers within the KAMPSTRUP. The fields are named in german but anyway it maybe interesting for you as well:

http://datenblatt.stark-elektronik.de/M ... _Daten.pdf
Starting at page 105.

Thanks to all of you,
strategy

Re: District Heating / City Heating (Stadsverwarming) Mysensor IR sender/Receiver

Posted: Tuesday 06 November 2018 17:08
by remko2000
I've bought also a IR IR Transmitter and receiver from HAL9.dk. I've a Kamstrup Multical601.
This is my script:

Code: Select all

#!/usr/bin/python
#
# ----------------------------------------------------------------------------
# "THE BEER-WARE LICENSE" (Revision 42):
# <[email protected]> wrote this file.  As long as you retain this notice you
# can do whatever you want with this stuff. If we meet some day, and you think
# this stuff is worth it, you can buy me a beer in return.   Poul-Henning Kamp
# ----------------------------------------------------------------------------
#
# Modified for Domotics and single request.
#
# Usage: __file__ <ComPort> <KMP_Command_Decimal> <Domoticz_IDX>
#



from __future__ import print_function

# You need pySerial 
import serial
import math
import sys
import json
import urllib2


kamstrup_601_var = {
    0x003C: "Verwarming verbruik",
    0x0054: "Warm waterverbruik",
}

#######################################################################
# Units, provided by Erik Jensen

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'
}

#######################################################################
# Kamstrup uses the "true" CCITT CRC-16
#

def crc_1021(message):
        poly = 0x1021
        reg = 0x0000
        for byte in message:
                mask = 0x80
                while(mask > 0):
                        reg<<=1
                        if byte & mask:
                                reg |= 1
                        mask>>=1
                        if reg & 0x10000:
                                reg &= 0xffff
                                reg ^= poly
        return reg

#######################################################################
# Byte values which must be escaped before transmission
#

escapes = {
    0x06: True,
    0x0d: True,
    0x1b: True,
    0x40: True,
    0x80: True,
}

#######################################################################
# And here we go....
#
class kamstrup(object):

    def __init__(self, serial_port):
        self.debug_fd = open("/tmp/_kamstrup", "a")
        self.debug_fd.write("\n\nStart\n")
        self.debug_id = None

        self.ser = serial.Serial(
            port = serial_port,
            baudrate = 1200,
            timeout = 2.0)

    def debug(self, dir, b):
        for i in b:
            if dir != self.debug_id:
                if self.debug_id != None:
                    self.debug_fd.write("\n")
                self.debug_fd.write(dir + "\t")
                self.debug_id = dir
            self.debug_fd.write(" %02x " % i)
        self.debug_fd.flush()

    def debug_msg(self, msg):
        if self.debug_id != None:
            self.debug_fd.write("\n")
        self.debug_id = "Msg"
        self.debug_fd.write("Msg\t" + msg)
        self.debug_fd.flush()

    def wr(self, b):
        b = bytearray(b)
        self.debug("Wr", b);
        self.ser.write(b)

    def rd(self):
        a = self.ser.read(1)
        if len(a) == 0:
            self.debug_msg("Rx Timeout")
            return None
        b = bytearray(a)[0]
        self.debug("Rd", bytearray((b,)));
        return b

    def send(self, pfx, msg):
        b = bytearray(msg)

        b.append(0)
        b.append(0)
        c = crc_1021(b)
        b[-2] = c >> 8
        b[-1] = c & 0xff

        c = bytearray()
        c.append(pfx)
        for i in b:
            if i in escapes:
                c.append(0x1b)
                c.append(i ^ 0xff)
            else:
                c.append(i)
        c.append(0x0d)
        self.wr(c)

    def recv(self):
        b = bytearray()
        while True:
            d = self.rd()
            if d == None:
                return None
            if d == 0x40:
                b = bytearray()
            b.append(d)
            if d == 0x0d:
                break
        c = bytearray()
        i = 1;
        while i < len(b) - 1:
            if b[i] == 0x1b:
                v = b[i + 1] ^ 0xff
                if v not in escapes:
                    self.debug_msg(
                        "Missing Escape %02x" % v)
                c.append(v)
                i += 2
            else:
                c.append(b[i])
                i += 1
        if crc_1021(c):
            self.debug_msg("CRC error")
        return c[:-2]

    def readvar(self, nbr):
        # I wouldn't be surprised if you can ask for more than
        # one variable at the time, given that the length is
        # encoded in the response.  Havn't tried.

        self.send(0x80, (0x3f, 0x10, 0x01, nbr >> 8, nbr & 0xff))

        b = self.recv()
        if b == None:
            return (None, None)

        if b[0] != 0x3f or b[1] != 0x10:
            return (None, None)

        if b[2] != nbr >> 8 or b[3] != nbr & 0xff:
            return (None, None)

        if b[4] in units:
            u = units[b[4]]
        else:
            u = None

        # Decode the mantissa
        x = 0
        for i in range(0,b[5]):
            x <<= 8
            x |= b[i + 7]

        # Decode the exponent
        i = b[6] & 0x3f
        if b[6] & 0x40:
            i = -i
        i = math.pow(10,i)
        if b[6] & 0x80:
            i = -i
        x *= i

        if False:
            # Debug print
            s = ""
            for i in b[:4]:
                s += " %02x" % i
            s += " |"
            for i in b[4:7]:
                s += " %02x" % i
            s += " |"
            for i in b[7:]:
                s += " %02x" % i

            print(s, "=", x, units[b[4]])

        return (x, u)
            

if __name__ == "__main__":

    import time

    comport = sys.argv[1]
    command = int( sys.argv[2], 0)
    index = int( sys.argv[3], 0)

    foo = kamstrup( comport )

    value,unit = foo.readvar( command )

    # We're sending an integer value to Domoticz, so with two digits, muliply by 100
    # Use Domiticz setting to devide by 100 again.
    value = int(value * 1000)

    print( int(value) )

I add in crontab:
1 1 * * * /home/pi/domoticz/scripts/pyKamstrup_single.py /dev/ttyUSB1 60 21

My IDX in domoticz is 21

When I: sudo python /home/pi/domoticz/scripts/pyKamstrup_single.py

I get error:
Traceback (most recent call last):
File "/home/pi/domoticz/scripts/pyKamstrup_single.py", line 233, in <module>
comport = sys.argv[1]
IndexError: list index out of range
What do I miss?

Re: District Heating / City Heating (Stadsverwarming) Mysensor IR sender/Receiver

Posted: Wednesday 07 November 2018 23:14
by freijn
You are missing the "/dev/ttyUSB1 60 21" in the second call.
So

sudo python /home/pi/domoticz/scripts/pyKamstrup_single.py /dev/ttyUSB1 60 21

Re: District Heating / City Heating (Stadsverwarming) Mysensor IR sender/Receiver

Posted: Friday 09 November 2018 10:13
by remko2000
ah you are right. My mistake. When I use:
sudo python /home/pi/domoticz/scripts/pyKamstrup_single.py /dev/ttyUSB1 60 21

I get:
Traceback (most recent call last):
File "/home/pi/domoticz/scripts/pyKamstrup_single.py", line 243, in <module>
value = int(value * 1000)
TypeError: unsupported operand type(s) for *: 'NoneType' and 'int'