M-Bus
This category contains functions specific to M-Bus devices.
api.mbusTransaction(msg, timeout, retry)
- Overview
- Arguments
- Return
- Example
Transmit "msg" and wait given "timeout" milliseconds for the answer. The transmission is retried "retry" times.
Turn on MBus using mbusState first.
- msg (string) - Message sent to MBus
- timeout (integer) - The maximum time in milliseconds to wait for answer from MBus device
- retry (integer) - Optional number of retransmissions, default number is 1
- status (integer) - Number of bytes received, zero on failure
- c (integer) - MBus c frame field
- a (integer) - MBus a frame field
- ci (integer) - MBus ci frame field
- answer (string) - MBus frame payload received from the bus
- raw (string) - Complete MBus frame with header
--Send MBus frame [0x10, 0x50, 0x30, 0x16] and wait 5s for the answer twice
msg = pack.pack('<b4', 0x10, 0x50, 0x30, 0x16)
status,c,a,ci,ans = api.mbusTransaction(msg, 5000, 2)
api.mbusSetup(baudrate, parity, stopBits, dataBits)
- Overview
- Arguments
- Example
Configures the MBus communication interface.
Turn on M-Bus using mbusState after setting up M-Bus parameters using this function.
- baudrate (integer) - Baudrate to use for communication (up to 921600 baud)
- parity (integer) - Parity, 0 for none, 1 for odd and 2 for even parity
- stopBits (integer) - Number of stop bits, 1 or 2 allowed
- dataBits (integer) - Number of data bits, 7 or 8 allowed
--setup M-Bus interface to 9600 Baud, 8E2
api.mbusSetup(9600, 2, 2, 8)
api.mbusState(state)
- Overview
- Arguments
- Return
- Example
Turns on the M-Bus circuitry.
Use api.mbusState(1) before api.mbusTransaction() and api.mbusState(0) after to reduce consumption. The consumption significantly raises if the circuitry is turned on for too long.
Do not use the api.mbusState(1) during LoRaWAN or NB-IoT message transmition.
- state (integer) - New state of MBus circuitry: 0 for off, 1 for on (apprx 30s power-up)
- UL (integer) - Returns approximate UL value when turing on
Valid only for new topology, otherwise there's no return value
api.mbusState(1) --turn on M-Bus
api.mbusScan(filter, timeout, mode)
- Overview
- Arguments
- Return
- Example
Scan for Mbus devices.
- filter (string)(optional) - filter by (no option selected = 0 = scan for everything):
- identification
- manufacturer
- ver
- medium
- timeout (integer)(optional) - by default set to 3000 ms
- mode (integer)(optional) - if true, scan in range 0-E instead of default 0-9 (true/false)
- var (hex)(table of variables) - table of variable (identification, manufacturer, ver, medium), look at the example to see how to index in table
- cnt (integer) - number of found devices
api.mbusSetup(2400,2,1,8)
api.mbusState(1) --turn on M-Bus
e,cnt = api.mbusScan("read") -- scan for everything(ID, man, ...) & use default timeout 3000 ms
for i = 1, cnt do
print(string.format("%08X", (e[i].identification)))
end
api.mbusState(0) --turn off M-Bus
api.mbusFilter(operation,filter,scan_filter)
- Overview
- Arguments
- Example #1
- Example #2
Function to create and manipulate internal table containing secondary addresses.
- operation (string) - use "purge", "populate", "show", "fetch" or "scan"
- filter (string) - M-Bus filter, array of ids
- scan_filter (string) - M-Bus scan filter, (id, manid, version, medium) groups array
This function is used for secondary addressing using 0xFD address internally. For more details check the example.
Example how to use api.mbusFilter for one secondary address
x=pack.pack("<I",0x22003287) -- store little endian unsigned integer value of 0x22003287 to "x" variable
api.mbusFilter("populate",x) -- insert the meter ID to mbusFilter
status,_,_,_,_,raw = api.mbusTransaction(0,3000,1) -- "mbusFilter" is a table to manage secondary addresses starting with index 0. Since ID "0x22003287" is first inserted value, the index of this ID is "0"
api.dumpArray(raw) -- print the content of variable raw
Example using while function to get complete mbus frame (if it's available)
--"i"=index in the table created by api.mbusFilter() (starting with 0)
status,_,_,_,_,raw = api.mbusTransaction(i,3000,1)
if status > 1 then
while status > 1 do
status,_,_,_,_,rawNext = api.mbusTransaction("",200,1)
if status > 1 then
raw = raw .. rawNext
else
break
end
end
end
api.dumpArray(raw)
api.mbusVifDifFilter(operation,scan_filter)
- Overview
- Arguments
- Example
Function filtering received M-Bus frame by given group of bytes (VIF/DIF)
- operation (string) - use "purge", "populate", "show", "activate", "activated"
- scan_filter (string) - MBUS VIF DIF filter string format (more details in the example)
baudrate = 2400 -- baudrate: up to 921600 baud
parity = 2 -- communication parity: 0 for none, 1 for odd and 2 for even parity
stopBits = 1 -- number of stop bits: 1 or 2
dataBits = 8 -- number of data bits: 7 or 8
-- b18 = bytes to pack in total
-- 0x02 = number of physical quantities/filters in this first group
-- 0x03 = number of following bytes
-- 0xFD, 0xDC, 0xFF = first applied filter in first group
-- 0xFD, 0xC9, 0xFF = second applied filter in first group
api.mbusVifDifFilter("populate",pack.pack("b18", 0x02, -- first group (index 0)
0x03, 0xFD, 0xDC, 0xFF, -- current
0x03, 0xFD, 0xC9, 0xFF, -- voltage
0x02, -- second group (index 1)
0x03, 0xFD, 0xDA, 0xFF, -- current
0x03, 0xFD, 0xC8, 0xFF)) -- voltage
api.mbusSetup(baudrate,parity,stopBits,dataBits)
api.mbusState(1)
api.delayms(2000)
-- choose only one index
api.mbusVifDifFilter("activate", 0) -- index 0
-- api.mbusVifDifFilter("activate", 1) -- index 1
b=pack.pack('<b5', 0x10, 0x7B, 0xFE, (0x7B+0xFE)%256, 0x16)
status,_,_,_,_,raw = api.mbusTransaction(b,3000,1)
api.mbusState(0)
print("From MBus Calorimeter: ")
api.dumpArray(raw)