M-Bus - Meter-Bus
The M-Bus is serial line protocol popular within SCADA and metering deployments within Europe. The underlying norms are EN 13757-3 for application and EN 13757-2 for physical and data link layers. Since M-Bus is primarily serial protocol, which can be also bridged over TCP, there is single encoding scheme. Backing serial port might be of any type - RS232 (more common) or RS485.
Device discovery | Channel discovery | Read | Write | Subscribe |
---|---|---|---|---|
Yes |
Yes |
Yes |
No |
No |
While binding does not discover compatible interfaces out of the box. This is due to fact that any serial interface might be used as M-Bus interface. Binding does discover devices through bus scanning procedure, if conducted. It can also detect channels from received frames.
Device discovery
Each M-Bus device nowadays can be identified through primary or secondary address. The primary address is a serial bus identifier which is a number from 1 up to 250. Secondary scan procedure is much longer as it iterates over possible combinations of secondary address which is composed of 8 bytes.
The secondary address is constructed from several fields:
-
manufacturer - a three char manufacturer code.
-
device - device identifier, its serial number.
-
version - number which indicate hardware revision or model.
-
type - number which translates to pre-defined device types (oil meter, electricity meter, gas meter etc).
Based on above it is possible to construct a scanning mask which will limit address range. Once device is discovered it is being reported as a Thing which can be accepted through "inbox" functionality.
Thing and Channel discovery
As mentioned above - each meter which properly answers for primary or secondary address call is identified as a separate Thing. Once Thing is accepted through inbox functionality, additional configuration can be supplied.
Binding by default will create a new channel for each properly encoded data record within frame. The protocol defines several encoding schemes for data:
-
Empty data block
-
INT8
-
INT16
-
INT24
-
INT32
-
INT48
-
INT64
-
Real (32 bit)
-
BCD2
-
BCD4
-
BCD6
-
BCD8
-
BCD12
-
Date
-
String
Types are simplified at binding level to top-level primitive kinds - Long, Double, Date, String, BCD and None. From that point of view linked items do not need to worry about exact encoding of data record.
Readout principles
The readout specification rely on cyclic polling (refresh interval). In case of M-Bus all values (data records) are available at single poll attempt. This means that there is no support for refresh interval at channel level, because all channels are fetched at one call.
Polling based on Read-outs are grouped by refresh interval and, if possible, conducted in groups. Each refresh interval value will result in spinning of a separate polling task. For example, by defining If you define a Optimization of readouts is always specific to protocol. |
Write principles
There is no write support within this binding. There are no specific remarks for writing.
Channel definitions
Each channel is configured with div
and vib
parameters which uniquely identify each record within frame.
The dib
stands for Data Information Block and vib
represents Value Information Block.
Both blocks deliver together information of how its value should be interpreted.
The information which comes from these two places are:
DIB ships:
-
Storage - a present (0), or historical data value register.
-
Function
-
Instant value
-
Max value
-
Min value
-
Error value
-
-
Sub unit
-
Tariff
-
Storage number
VIB delivers:
-
Measurement kind
-
Multiplier
-
Measurement unit
All above information by default is placed in detected channel label / description, if available. It does not trigger any specific behavior when it comes to data acquisition.
Configuration example
Bridge co7io-mbus:openhab-serial:port2 "Serial Interface " [ serialPort="/dev/ttyS2", baudRate=2400, dataBits="DATABITS_5" ] { (1)
Thing device heatMeter1 "Kamstrup Multical" [ address=1, refreshInterval=60000 ] { (2)
Type number : power "Heat power" [ dib="AO", vib="10" ] (3)
Type number : flowRate "Flow rate" [ dib="AO", vib="11" ]
}
Thing device heatMeter2 "Techem ultra" [ address=2, refreshInterval=360000 ] {
Type number : power "Heat power" [ dib="1D", vib="F0" ]
Type number : flowRate "Flow rate" [ dib="3D", vib="FB" ]
}
}
1 | The serial bridge which points to serial port and transmission settings. |
2 | Device with defined primary address to poll. |
3 | Channel associated with device, it does rely on hex notation for DIB and VIB parameters. |
<?xml version="1.0" encoding="utf-8" ?>
<things xmlns="http://connectorio.com/xmlns/managed/things">
<bridge type="co7io-wmbus:serial-jrxtx" label="Radio interface">
<id>radio1</id>
<config>
<serialPort>/dev/ttyS3</serialPort>
<manufacturer>AMBER</manufacturer>
</config>
</bridge>
<thing type="co7io-wmbus:device" label="Kamstrup Multical">
<id>heatMeter1</id>
<bridge>co7io-wmbus:serial-jrxtx:radio1</bridge>
<config>
<serialNumber>01234</serialNumber>
<manufacturer>KAM</manufacturer>
<version>3</version>
<deviceType>HEAT_METER</deviceType>
</config>
<channel>
<id>co7io-wmbus:device:radio1:heatMeter1:power</id>
<type>co7io-wmbus:number</type>
<label>Heat power</label>
<config>
<dib>AO</dib>
<vib>10</vib>
</config>
</channel>
<channel>
<id>co7io-wmbus:device:radio1:heatMeter1:flowRate</id>
<type>co7io-wmbus:number</type>
<label>Flow rate</label>
<config>
<dib>AO</dib>
<vib>11</vib>
</config>
</channel>
</thing>
<thing type="co7io-wmbus:device" label="Techem ultra">
<id>heatMeter2</id>
<bridge>co7io-wmbus:serial-jrxtx:radio1</bridge>
<config>
<serialNumber>43210</serialNumber>
<manufacturer>TCH</manufacturer>
<version>23</version>
<deviceType>HEAT_METER</deviceType>
</config>
<channel>
<id>co7io-wmbus:device:radio1:heatMeter2:power</id>
<type>co7io-wmbus:number</type>
<label>Heat power</label>
<config>
<dib>1D</dib>
<vib>F0</vib>
</config>
</channel>
<channel>
<id>co7io-wmbus:device:radio1:heatMeter2:flowRate</id>
<type>co7io-wmbus:number</type>
<label>Flow rate</label>
<config>
<dib>3D</dib>
<vib>FB</vib>
</config>
</channel>
</thing>
</things>
---
things:
- kind: "Bridge"
UID: "co7io-mbus:openhab-serial:port2"
label: "Serial Interface "
configuration:
baudRate: 2400
serialPort: "/dev/ttyS2"
dataBits: "DATABITS_5"
things:
- id: "heatMeter1"
type: "co7io-mbus:device"
label: "Kamstrup Multical"
configuration:
refreshInterval: 60000
address: 1
channels:
- id: "power"
type: "number"
label: "Heat power"
configuration:
dib: "AO"
vib: "10"
- id: "flowRate"
type: "number"
label: "Flow rate"
configuration:
dib: "AO"
vib: "11"
- id: "heatMeter2"
type: "co7io-mbus:device"
label: "Techem ultra"
configuration:
refreshInterval: 360000
address: 2
channels:
- id: "power"
type: "number"
label: "Heat power"
configuration:
dib: "1D"
vib: "F0"
- id: "flowRate"
type: "number"
label: "Flow rate"
configuration:
dib: "3D"
vib: "FB"