Game Development with Corona SDK and Lua - Lua Workshop 2014
An005 Lua BACNET Client Operations
-
Upload
robson-fernandes -
Category
Documents
-
view
262 -
download
4
Transcript of An005 Lua BACNET Client Operations
-
8/10/2019 An005 Lua BACNET Client Operations
1/8
SmartStruxure Lite
Solution
Application NotesAN005 - Lua BACnet Client Operations
Get Control. Get Efficient. Get Value TM
-
8/10/2019 An005 Lua BACNET Client Operations
2/8
AN005 - Lua BACnet Client OperationsApplication Notes AN005 2
Schneider Electric- Small Building Systems Tel. Americas: North Andover, MA 1-800-225 -0962 Tel. Europe: Malm, Sweden +46 40 38 68 50 Tel. Asia Pacific: Hong Kong +852 2565 0621 Product Name AN005 - Lua BACnet Client Operations - 02 www.schneider-electric.com/buildings October 2013 ct
2
0 1 3 S c
h n e
i d e r
E l e c
t r i c
. A l l r i g
h t s r e s e r v e
d .
A l l b r a n
d n a m e s ,
t r a d
e m a r k s ,
a n
d r e g
i s t e r e
d t r a
d e m a r k s a r e
t h e p r o p e r
t y o
f
t h e
i r r e s p e c
t i v e o
w n e r s .
I n f o r m a
t i o n c o n
t a i n e
d w
i t h i n t h i s d o c u m e n t
i s s u
b j e c
t t o c
h a n g e w
i t h o u
t n o
t i c e .
Introduction and ContextWhen integrating SmartStruxure Lite Managers with third-party devices, sometimes aBACnet client functionality can be useful. This application note gives an overview of the fourbasic Lua functions to access remote BACnet points.
Note that all SmartStruxure Lite Managers have full BACnet server capabilities, howeverthe BACnet client functionality is currently only available through Lua. Also, with the currentbasic client capabilities, the maximum number of devices supported on a single BACnetnetwork is 1000.
NOTE: If using BACnet client tools in version 2.6.x or later, it is necessary to modify yourscript to prevent BACnet communication from starting 90 seconds after the controllerinitialization.
This can be done by encapsulating your script logic within the fo llowing loop:
if scl.sysclock() > 90 then
Case 1: Four Lines The three basic BACnet commands that can be performed are who-is, read and wri terequests for speci points. A fourth function is available to obtain the resulting value of aread request.
The below shows a simple four-line script that does a who-is , reads a value, displays thevalue, does a write.
bacnet.whois(500, 500)
bacnet.read(500, AV1)
print(bacnet.value())
bacnet.write(500, AV1, 32)
-
8/10/2019 An005 Lua BACNET Client Operations
3/8
AN005 - Lua BACnet Client OperationsApplication Notes AN005 3
Schneider Electric- Small Building Systems Tel. Americas: North Andover, MA 1-800-225 -0962 Tel. Europe: Malm, Sweden +46 40 38 68 50 Tel. Asia Pacific: Hong Kong +852 2565 0621 Product Name AN005 - Lua BACnet Client Operations - 02 www.schneider-electric.com/buildings October 2013 ct
2
0 1 3 S c
h n e
i d e r
E l e c
t r i c
. A l l r i g
h t s r e s e r v e
d .
A l l b r a n
d n a m e s ,
t r a d
e m a r k s ,
a n
d r e g
i s t e r e
d t r a
d e m a r k s a r e
t h e p r o p e r
t y o
f
t h e
i r r e s p e c
t i v e o
w n e r s .
I n f o r m a
t i o n c o n
t a i n e
d w
i t h i n t h i s d o c u m e n t
i s s u
b j e c
t t o c
h a n g e w
i t h o u
t n o
t i c e .
Step 2: Step-by-Step Process The below shows a more thorough step-by-step example on how to access a remote BACnetdevice point in Lua.
if scl.sysclock() > 90 then
if whois ~= true then
bacnet.whois(500, 500) -- Step one: who is? (device or range)
whois = true -- Next run: skip to step two
elseif fetch ~= 0 then
fetch = bacnet.read(500, AV1) -- Step two: read! (specic point)
else
value, stamp = bacnet.value() -- Step three: check value and time
if old_stamp ~= stamp then -- If time differs: value has changed!
old_stamp = stamp -- Keep track of time stamp
print(DEV500.AV1:, value) -- Optional: display the changed value
ME.AV2_Present_Value.value = value -- Optional: keep value locally
end
fetch = false -- Next run: go back to step two (to read again)
end
end
-
8/10/2019 An005 Lua BACNET Client Operations
4/8
AN005 - Lua BACnet Client OperationsApplication Notes AN005 4
Schneider Electric- Small Building Systems Tel. Americas: North Andover, MA 1-800-225 -0962 Tel. Europe: Malm, Sweden +46 40 38 68 50 Tel. Asia Pacific: Hong Kong +852 2565 0621 Product Name AN005 - Lua BACnet Client Operations - 02 www.schneider-electric.com/buildings October 2013 ct
2
0 1 3 S c
h n e
i d e r
E l e c
t r i c
. A l l r i g
h t s r e s e r v e
d .
A l l b r a n
d n a m e s ,
t r a d
e m a r k s ,
a n
d r e g
i s t e r e
d t r a
d e m a r k s a r e
t h e p r o p e r
t y o
f
t h e
i r r e s p e c
t i v e o
w n e r s .
I n f o r m a
t i o n c o n
t a i n e
d w
i t h i n t h i s d o c u m e n t
i s s u
b j e c
t t o c
h a n g e w
i t h o u
t n o
t i c e .
Case 3: More OptionsFor a simpler way to change the remote BACnet point specications, another example isprovided below. This Lua uses two top variables to specify the remote device instance andthe object name.
if scl.sysclock() > 90 then
dev_inst = 500 -- Device instanceobj_name = AV1 -- Object type and number
if whois ~= true then
bacnet.whois(dev_inst, dev_inst) -- Step one: who is? (device or range)
whois = true -- Next run: skip to step two
elseif fetch ~= 0 then
fetch = bacnet.read(dev_inst, obj_name) -- Step two: read! (specic point)
else
value, stamp = bacnet.value() -- Step three: check value and time
if old_stamp ~= stamp then -- If time differs: value has changed!old_stamp = stamp -- Keep track of time stamp
-- Optional: display the changed value
print(DEV .. dev_inst .. . .. obj_name .. :, value)
ME.AV2_Present_Value.value = value -- Optional: keep value locally
bacnet.write(dev_inst, obj_name, value + 1) -- Optional: increase value by +1
end
fetch = false -- Next run: go back to step two (to read again)
end
endSimply changing the dev_inst and obj_name variables will sufce in using the script in real-lifesituations.
Note that as an additional step, the above script example is also writing to the remote object. This means that every time the script is executed (e.g. every few seconds), the remotevalue will be incremented and read back again. As a result, the last optional lines should beadjusted for the specic needs of the integrator.
-
8/10/2019 An005 Lua BACNET Client Operations
5/8
AN005 - Lua BACnet Client OperationsApplication Notes AN005 5
Schneider Electric- Small Building Systems Tel. Americas: North Andover, MA 1-800-225 -0962 Tel. Europe: Malm, Sweden +46 40 38 68 50 Tel. Asia Pacific: Hong Kong +852 2565 0621 Product Name AN005 - Lua BACnet Client Operations - 02 www.schneider-electric.com/buildings October 2013 ct
2
0 1 3 S c
h n e
i d e r
E l e c
t r i c
. A l l r i g
h t s r e s e r v e
d .
A l l b r a n
d n a m e s ,
t r a d
e m a r k s ,
a n
d r e g
i s t e r e
d t r a
d e m a r k s a r e
t h e p r o p e r
t y o
f
t h e
i r r e s p e c
t i v e o
w n e r s .
I n f o r m a
t i o n c o n
t a i n e
d w
i t h i n t h i s d o c u m e n t
i s s u
b j e c
t t o c
h a n g e w
i t h o u
t n o
t i c e .
Case 4: Reading Multiple Devices and CharactersWhen many BACnet remote points need to be read, the below lus function can be used.
This Lua loops through a list of device instances and object names.
if scl.sysclock() > 90 then
obj_list = { -- Local and remote objects list
AV21 = {600, AV1},
AV22 = {700, AV2},
AV23 = {800, AV3}}
if whois ~= true then
bacnet.whois(600, 800) -- Step one: who is? (devices range)
whois = true -- Next run: skip to step two
elseif fetch ~= 0 then
obj_link, obj_info = next(obj_list, obj_link) -- Find next objects pair
if obj_link == nil then -- Loop around on last pair
obj_link, obj_info = next(obj_list, obj_link)
end
dev_inst = obj_info[1]
obj_name = obj_info[2]
fetch = bacnet.read(dev_inst, obj_name) -- Step two: read request!
if fetch ~= 0 then -- On error: print message
print(BACnet read failure on DEV .. dev_inst .. . .. obj_name)
else
old_value, old_stamp = bacnet.value() -- Reset the timeout
end
else
value, stamp = bacnet.value() -- Step three: check value and time
if old_stamp ~= stamp then -- If time differs: value has changed!
ME[obj_link .. _Present_Value].value = value -- Update value
print(string.sub(os.date(), 10, 17), ME. .. obj_link,
DEV .. dev_inst .. . .. obj_name, value) -- Display value
elseif scl.sysclock() - old_stamp > 3 then -- Timeout after 3 seconds
print(BACnet read timeout on DEV .. dev_inst .. . .. obj_name)
end
fetch = false -- Next run: read next object in list
end
end
Simply adjusting the obj_list table content should sufce in using the script in real-lifesituations. This specic example fetches three remote points (DEV600.AV1, DEV600.AV2,and DEV600.AV3) from three different remote BACnet devices. It then stores the resultsinto local analog values (ME.AV21, ME.AV22, and ME.AV23).
Note the resulting update period for those variables is twice the PG script period,multiplied by the number of remote objects actively fetched. In this case, since the script
is running every second, and because three objects are read, the resulting typical objectupdate period is every 6 seconds (1 2 3).
-
8/10/2019 An005 Lua BACNET Client Operations
6/8
AN005 - Lua BACnet Client OperationsApplication Notes AN005 6
Schneider Electric- Small Building Systems Tel. Americas: North Andover, MA 1-800-225 -0962 Tel. Europe: Malm, Sweden +46 40 38 68 50 Tel. Asia Pacific: Hong Kong +852 2565 0621 Product Name AN005 - Lua BACnet Client Operations - 02 www.schneider-electric.com/buildings October 2013 ct
2
0 1 3 S c
h n e
i d e r
E l e c
t r i c
. A l l r i g
h t s r e s e r v e
d .
A l l b r a n
d n a m e s ,
t r a d
e m a r k s ,
a n
d r e g
i s t e r e
d t r a
d e m a r k s a r e
t h e p r o p e r
t y o
f
t h e
i r r e s p e c
t i v e o
w n e r s .
I n f o r m a
t i o n c o n
t a i n e
d w
i t h i n t h i s d o c u m e n t
i s s u
b j e c
t t o c
h a n g e w
i t h o u
t n o
t i c e .
Case 5: Full Read and Write ScriptIn a situation where some points need to be updated more often than others, an extratime condition can be used to only perform read operations when required. On top of theread interval, the below example script adds the ability to specify which objects should bewritten when their value changes.
-- *** Variables Initialization ***
if scl.sysclock() > 90 then
if var_init == nil then
var_init = true
-- Local and remote objects list, in the format:
-- LocalObject = {RemoteDevice, RemoteObject, ReadSecs, Write, KeptValue, KeptSecs}
obj_list = {
AV21 = {600, AV1, 10 , false, 0, 0}, -- Read DEV600.AV1 every 10s into AV21
AV22 = {700, AV2, 10 , false, 0, 0}, -- Read DEV700.AV2 every 10s into AV22
AV23 = {800, AV3, 30 , true, 0, 0}} - - Read every 10s, write if AV23 changes
-- This is just a quick function to print with a timestamp:
function display(...) print(os.date():sub(10, 17), ...) end
end
-- *** Program Execution ***
if whois ~= true then
bacnet.whois(600, 800) -- Step one: who is? (devices range)
whois = true -- Next run: skip to step two
ecount = 0 -- Reset the error count
display(Sending who-is...)
elseif fetch ~= 0 then
repeat
obj_link, obj_info = next(obj_list, obj_link) -- Find next pair
if obj_link == nil then -- Loop around
obj_link, obj_info = next(obj_list, obj_link)
end
obj_item = ME[obj_link .. _Present_Value] -- Keep object pointer
-- Read condition, when time interval has elapsed:
obj_read = (scl.sysclock() - obj_item.time > obj_info[3])
-
8/10/2019 An005 Lua BACNET Client Operations
7/8
AN005 - Lua BACnet Client OperationsApplication Notes AN005 7
Schneider Electric- Small Building Systems Tel. Americas: North Andover, MA 1-800-225 -0962 Tel. Europe: Malm, Sweden +46 40 38 68 50 Tel. Asia Pacific: Hong Kong +852 2565 0621 Product Name AN005 - Lua BACnet Client Operations - 02 www.schneider-electric.com/buildings October 2013 ct
2
0 1 3 S c
h n e
i d e r
E l e c
t r i c
. A l l r i g
h t s r e s e r v e
d .
A l l b r a n
d n a m e s ,
t r a d
e m a r k s ,
a n
d r e g
i s t e r e
d t r a
d e m a r k s a r e
t h e p r o p e r
t y o
f
t h e
i r r e s p e c
t i v e o
w n e r s .
I n f o r m a
t i o n c o n
t a i n e
d w
i t h i n t h i s d o c u m e n t
i s s u
b j e c
t t o c
h a n g e w
i t h o u
t n o
t i c e .
-- Write conditions:
obj_write = (obj_info[4] -- When writeable, and:
and ((obj_info[5] ~= obj_item.value) -- Either value changed
or (obj_info[6] ~= obj_item.time))) -- Or timestamp changed
until obj_read or obj_write -- Loop until read or write has been found...
-- Step two: read or write request!if obj_write then
display(ME. .. obj_link .. DEV .. obj_info[1]
.. . .. obj_info[2] .. write: .. obj_item.value)
bacnet.write(obj_info[1], obj_info[2], obj_item.value) -- Write value
obj_info[5] = obj_item.value -- Keep last object value
obj_info[6] = obj_item.time -- Keep last object time
else
fetch = bacnet.read(obj_info[1], obj_info[2]) -- Read at time interval
if fetch ~= 0 then -- On error: print messagedisplay(BACnet read failure on DEV .. obj_info[1] .. . .. obj_info[2])
else
old_value, old_stamp = bacnet.value() -- Reset the timeout
end
end
else
value, stamp = bacnet.value() -- Step three: check value and time
if old_stamp ~= stamp then -- If time differs: value has changed!
obj_item.value = value -- Update valueobj_info[5] = obj_item.value -- Keep last object value
obj_info[6] = obj_item.time -- Keep last object time
display(ME. .. obj_link .. DEV .. obj_info[1]
.. . .. obj_info[2] .. read: .. value)
ecount = 0 -- Reset the error count
elseif scl.sysclock() - old_stamp > 3 then -- Timeout after 3 seconds
display(BACnet read timeout on DEV .. obj_info[1] .. . .. obj_info[2])
-- Send another who-is? after 3 read errors:
ecount = ecount + 1if ecount >= 3 then
whois = false
end
end
fetch = false -- Next run: read next object in list
end
end
-
8/10/2019 An005 Lua BACNET Client Operations
8/8
AN005 - Lua BACnet Client OperationsApplication Notes AN005 8
Schneider Electric- Small Building Systems Tel. Americas: North Andover, MA 1-800-225 -0962 Tel. Europe: Malm, Sweden +46 40 38 68 50 Tel. Asia Pacific: Hong Kong +852 2565 0621 Product Name AN005 - Lua BACnet Client Operations - 02 www.schneider-electric.com/buildings October 2013 ct
2
0 1 3 S c
h n e
i d e r
E l e c
t r i c
. A l l r i g
h t s r e s e r v e
d .
A l l b r a n
d n a m e s ,
t r a d
e m a r k s ,
a n
d r e g
i s t e r e
d t r a
d e m a r k s a r e
t h e p r o p e r
t y o
f
t h e
i r r e s p e c
t i v e o
w n e r s .
I n f o r m a
t i o n c o n
t a i n e
d w
i t h i n t h i s d o c u m e n t
i s s u
b j e c
t t o c
h a n g e w
i t h o u
t n o
t i c e .
Simply adjusting the obj_list table content should sufce in using that script in real-lifesituations. The above example fetches three remote points (DEV600.AV1, DEV600.AV2,and DEV600.AV3) from three different remote BACnet devices. It then stores the results intolocal analog values (ME.AV21, ME.AV22, and ME.AV23). It performs the read requests at thespecied ReadSecs interval for each object (10 seconds, 10 seconds, and 30
seconds).
This script a lso writes back, when specied, the object value when it changes, (in the aboveexample), only if the third line of the if obj_list table has its Write parameter set to true, whichwill write ME.AV23, if changed, into DEV600.AV3). It then performs a BACnet write operationto the remote device, effectively sending out the new value.
Note if the BACnet connectivity is completely lost, an error count gets incremented to triggeranother who-is request periodically (after every 3 failures) to effectively re-acquire the devicesonce the connectivity is restored.