(04.08.2016, 06:50)admin Wrote: 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:
For this meter, current value resides at id 2, but it will be different for different meter models.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 ...
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
Here I'm again,
My first time will work with m-bus and I was able to read values from the meter
Quote:* table:I didn't know how to manage the script that will convert that data into objects!
["data"]
* table:
[0]
* table:
["timestamp"]
* string: 1659446656
["unit"]
* string: Actuality Duration (seconds)
["dif"]
* string: 9
["value"]
* string: 4
["vif"]
* string: 116
["function"]
* string: Instantaneous value
["storagenumber"]
* string: 0
[1]
* table:
["timestamp"]
* string: 1659446656
["unit"]
* string: Averaging Duration (seconds)
["dif"]
* string: 9
["value"]
* string: 4
["vif"]
* string: 112
["function"]
* string: Instantaneous value
["storagenumber"]
* string: 0
[2]
* table:
["timestamp"]
* string: 1659446656
["unit"]
* string: Energy (kWh)
["dif"]
* string: 12
["value"]
* string: 27342
["vif"]
* string: 6
["function"]
* string: Instantaneous value
["storagenumber"]
* string: 0
[3]
* table:
["timestamp"]
* string: 1659446656
["unit"]
* string: Volume (1e-2 m^3)
["dif"]
* string: 12
["value"]
* string: 156690
["vif"]
* string: 20
["function"]
* string: Instantaneous value
["storagenumber"]
* string: 0
[4]
* table:
["timestamp"]
* string: 1659446656
["unit"]
* string: Power (kW)
["dif"]
* string: 11
["value"]
* string: 0
["vif"]
* string: 46
["function"]
* string: Instantaneous value
["storagenumber"]
* string: 0
[5]
* table:
["timestamp"]
* string: 1659446656
["unit"]
* string: Volume flow ( m^3/h)
["dif"]
* string: 11
["value"]
* string: 0
["vif"]
* string: 62
["function"]
* string: Instantaneous value
["storagenumber"]
* string: 0
[6]
* table:
["timestamp"]
* string: 1659446656
["unit"]
* string: Flow temperature (deg C)
["dif"]
* string: 10
["value"]
* string: 23
["vif"]
* string: 91
["function"]
* string: Instantaneous value
["storagenumber"]
* string: 0
[7]
* table:
["timestamp"]
* string: 1659446656
["unit"]
* string: Return temperature (deg C)
["dif"]
* string: 10
["value"]
* string: 23
["vif"]
* string: 95
["function"]
* string: Instantaneous value
["storagenumber"]
* string: 0
[8]
* table:
["timestamp"]
* string: 1659446656
["unit"]
* string: Temperature Difference (1e-1 deg C)
["dif"]
* string: 10
["value"]
* string: 2
["vif"]
* string: 98
["function"]
* string: Instantaneous value
["storagenumber"]
* string: 0
[9]
* table:
["timestamp"]
* string: 1659446656
["unit"]
* string: Volume (1e-2 m^3)
["dif"]
* string: 76
["value"]
* string: 0
["vif"]
* string: 20
["function"]
* string: Instantaneous value
["storagenumber"]
* string: 1
[10]
* table:
["timestamp"]
* string: 1659446656
["unit"]
* string: Energy (kWh)
["dif"]
* string: 76
["value"]
* string: 0
["vif"]
* string: 6
["function"]
* string: Instantaneous value
["storagenumber"]
* string: 1
[11]
* table:
["timestamp"]
* string: 1659446656
["unit"]
* string: Fabrication number
["dif"]
* string: 12
["value"]
* string: 67095040
["vif"]
* string: 120
["function"]
* string: Instantaneous value
["storagenumber"]
* string: 0
[12]
* table:
["unit"]
* string: Averaging Duration (minutes)
["timestamp"]
* string: 1659446656
["dif"]
* string: 137
["device"]
* string: 0
["value"]
* string: 60
["tariff"]
* string: 1
["vif"]
* string: 113
["function"]
* string: Instantaneous value
["storagenumber"]
* string: 0
[13]
* table:
["unit"]
* string: Power (100 W)
["timestamp"]
* string: 1659446656
["dif"]
* string: 155
["device"]
* string: 0
["value"]
* string: 302
["tariff"]
* string: 1
["vif"]
* string: 45
["function"]
* string: Maximum value
["storagenumber"]
* string: 0
[14]
* table:
["unit"]
* string: Power (100 W)
["timestamp"]
* string: 1659446656
["dif"]
* string: 219
["device"]
* string: 0
["value"]
* string: 0
["tariff"]
* string: 1
["vif"]
* string: 45
["function"]
* string: Maximum value
["storagenumber"]
* string: 1
[15]
* table:
["unit"]
* string: Volume flow (m m^3/h)
["timestamp"]
* string: 1
Could you just give me an example of how to convert the [7] * table ? or what should I do to convert all the data into objects ?