This forum uses cookies
This forum makes use of cookies to store your login information if you are registered, and your last visit if you are not. Cookies are small text documents stored on your computer; the cookies set by this forum can only be used on this website and pose no security risk. Cookies on this forum also track the specific topics you have read and when you last read them. Please confirm whether you accept or reject these cookies being set.

M-Bus (Meter-Bus) library and examples
#1
Packages
Already included in 2016.09.30 firmware

Library docs
http://openrb.com/docs/mbus.htm

Examples
Note:
as with any scripts which are using serial ports, make sure that only one script is running at any moment of time.

1. Scan the bus

If all short addresses are already programmed, you can scan the bus to find all connected meters. Scan function will return Lua table where key is meter's short address and value is the scan result. True means that the meter is working correctly, false means that probably several meters share the same short address which caused a collision during scan.
Code:
-- load mbus library
require('mbus')
-- use /dev/ttyUSB0 serial port with 2400 baud rate
mbus.init('/dev/ttyUSB0', 2400)
-- scan from range 0 to 5 (inclusive)
res = mbus.scan(0, 5)
-- save result to Logs tab
log(res)

2. Change short address of a meter

For small installations you can connect meters one by one and change short addresses for each meter via an event script mapped to a 1-byte unsigned object. Object value is the new short address to set. Script assumes that all new meters have a default short address of 0.
Code:
-- load mbus library
require('mbus')
-- use /dev/ttyUSB0 serial port with 2400 baud rate
mbus.init('/dev/ttyUSB0', 2400)
-- new address to write
addr = event.getvalue()
-- change short address from default 0 to new one
res, err = mbus.writeaddr(0, addr)

-- change ok
if res then
 alert('[mbus] changed short address to' .. addr)
-- change failed
else
 alert('[mbus] failed to change short address to ' .. addr .. ' ' .. tostring(err))
end

3. Reading meter data

You can read all single meter data via an event script mapped to a 1-byte unsigned object. Object value is the short address to read, make sure to wait before previous read completes or you will get collision errors.
Code:
-- load mbus library
require('mbus')
-- use /dev/ttyUSB0 serial port with 2400 baud rate
mbus.init('/dev/ttyUSB0', 2400)
-- new address to write
addr = event.getvalue()
-- read all data
res, err = mbus.getdata(addr)

-- read ok
if res then
 log(res)
-- read failed
else
 alert('[mbus] failed to read data from short address ' .. addr .. ' ' .. tostring(err))
end

The return value will look similar to this:
Code:
* table:
[data]
 * table:
  [0]
   * table:
    [timestamp]
     * string: 1470292199
    [unit]
     * string: Fabrication number
    [dif]
     * string: 14
    [value]
     * string: 0
    [vif]
     * string: 120
    [function]
     * string: Instantaneous value
    [storagenumber]
     * string: 0
  [1]
   * table:
    [timestamp]
     * string: 1470292199
    [unit]
     * string: Time Point (time & date)
    [dif]
     * string: 4
    [value]
     * string: 2016-08-04T07:27:00
    [vif]
     * string: 109
    [function]
     * string: Instantaneous value
    [storagenumber]
     * string: 0
  [2]
   * table:
    [timestamp]
     * string: 1470292199
    [unit]
     * string: Volume (m m^3)
    [dif]
     * string: 4
    [value]
     * string: 27
    [vif]
     * string: 19
    [function]
     * string: Instantaneous value
    [storagenumber]
     * string: 0
...
For this meter, current value resides at id 2, but it will be different for different meter models.

4. Gathering data from multiple meters

You can use this resident script to read values from meters and update object values as soon as meter value changes. Object datatype should be set to 4-byte unsigned integer when divisor is not set, otherwise it should be set to 4-byte floating point. Refer to the previous example on how to find the id value at which the current value resides.
Code:
-- config init
if not meters then
 require('mbus')

 -- time to wait between each meter read
 sleeptime = 10
 -- use /dev/ttyUSB0 serial port with 2400 baud rate
 mbus.init('/dev/ttyUSB0', 2400)
 -- base address for meter values, meter short address will be added to form the meters group address
 base = '2/1/'

 -- meter definition
 -- addr - short address
 -- id - number from data table where value resides
 -- div - optional divisor for convertion to the final value
 meters = {
   { addr = 1, id = 2, div = 1000 }, -- hot water meter, convert from m3 to liters
   { addr = 2, id = 2, div = 1000 }, -- cold water meter, convert from m3 to liters
   { addr = 3, id = 5 }, --  heating meter 1
   { addr = 4, id = 5 }, --  heating meter 2
 }

 -- reset meter values on first run
 for _, meter in ipairs(meters) do
   meter.value = 0
 end
end

-- read each meter
for _, meter in ipairs(meters) do
 res = mbus.getdata(meter.addr)

 -- read ok
 if type(res) == 'table' then
   data = res.data[ meter.id ]
   value = nil

   -- get current value
   if type(data) == 'table' then
     value = tonumber(data.value)
   end

   -- value is valid and different from previous read
   if value and meter.value ~= value then
     -- apply divisor if set
     div = meter.div
     dpt = div and dt.float32 or dt.uint32
     if div then
       value = value / div
     end

     -- update group address value
     grp.update(base .. tostring(meter.addr), value, dpt)
     meter.value = value
   end
 end

 -- wait for next read
 os.sleep(sleeptime)
end
Reply
#2
We used the following components for M-Bus integration into LogicMachine:

  • LogicMachine Reactor V3
[Image: LogicMachine-Reactor-V3.png]
  • USB to RS232 RS485 UART TTL Signal Converter DZ-074 
[Image: USB-to-RS232-RS485-UART-TTL-Signal-Conve...Z-074-.jpg]
  • Tecbase Mbus 10 RS232-MBus gateway
[Image: Techbase_Mbus10_RS232.png]
  • Maddalena 1.ETRMD.0340 M-bus water meter
[Image: Maddalena_Mbus_meter.png]


Here is how the whole setup looked like:

[Image: MBus_LogicMachine.jpg]
Reply
#3
Hi, this is great!

I had long awaited for this option. For better usability there is necessary to add secondary addressing / scanning option, as it is main mode in bigger networks. For example the Qundis/ Siemens metering  gateway WTT16  itself has primary m-bus address and meters inside the network is accessible thru secondary addressing.


Best regards
Reply
#4
Good morning, I am reading different meters by mbus communication, I have managed to read them following the tutorial by the port ('/ dev / RS232'). Would it be possible to read such data via Ethernet? I have a 4g router that has the possibility to read and transmit RS485 and RS232, it would be very useful to be able to install the router on the different counters and be able to read it all over Ethernet.
Reply
#5
Right now only serial connection is supported. TCP support can be added if needed. Do you want to use this solution to read meter data from different locations? Locally it's more cost-effective to connect all counters using MBUS and use a single gateway.
Reply
#6
(25.02.2021, 12:04)admin Wrote: Right now only serial connection is supported. TCP support can be added if needed. Do you want to use this solution to read meter data from different locations? Locally it's more cost-effective to connect all counters using MBUS and use a single gateway.

Thank you in advance.

We have counters in different locations that are not accessible to each other. Our idea is to put a gateway and a router in each building and read all the parameters with an lm5p-DR logic machine that we have installed in one of them.

I don't know if this is possible.
Reply
#7
We've never tested MBUS over TCP. It should work in theory but this needs to be implemented first and then tested.
Reply
#8
(25.02.2021, 13:44)admin Wrote: We've never tested MBUS over TCP. It should work in theory but this needs to be implemented first and then tested.

Forgive me, I'm new with the scripts, I understand them a little but I don't know how to develop them, could you tell me how I can move forward to implement this and then test it?
Reply
#9
This cannot be done via scripting at the moment. TCP support must be added to the MBUS library that LM has.
Reply


Forum Jump: