18.07.2020, 14:37
(This post was last modified: 16.04.2024, 18:58 by fleeceable.)
Another update to get integration done about 1 minute.
Now my script reads out all arealabels and zone labels (You don't need to know anything about EVO program). Also creates automatically group objects. I tested it couple days ago in my new project and really, integration takes about 1-2 minutes.
What you probably need to do is edit zone labels to more understandable form (paradox allows enter only 16 characters for area and zone name).
Program needs one main group address range (example 10/x/x)
Group address structure is like this:
All what you need to change is in resident script (group addresses).
Resident script (EVO192 communication, sleep interval 0):
User library (guardAreaLabels):
User library (guardAreaStatus):
User library (guardZoneLabels):
User library (guardZoneStatus):
After you request area and zone names, give it some time to scan and create group objects. Mine needed about 15-20 seconds (1 area, 50 zones)...
All objects what are created automatically they have also object comment "Automatically created object - Security Area X", "Automatically created object - Zone XX" etc..
Now my script reads out all arealabels and zone labels (You don't need to know anything about EVO program). Also creates automatically group objects. I tested it couple days ago in my new project and really, integration takes about 1-2 minutes.
What you probably need to do is edit zone labels to more understandable form (paradox allows enter only 16 characters for area and zone name).
Program needs one main group address range (example 10/x/x)
Group address structure is like this:
Code:
security_main_ga = '10/' --'3-level' = main/middle/sub. Make sure that 10/0/0 - 10/7/X group addresses are not used. System creates objects automatically.
10/0/1 - Area 1 security status [0-DISARMED, 1-ARMED, 2-FORCE ARMED, 3-STAY ARMED, 4-INSTANT ARMED]
...
10/0/8 - Area 8 security status
10/0/11 - Area 1 exit delay
...
10/0/18 - Area 8 exit delay
10/0/21 - Area 1 entry delay
...
10/0/28 - Area 8 entry delay
10/0/31 - Area 1 alarm status
...
10/0/38 - Area 8 alarm status
10/0/41 - Area 1 trouble
...
10/0/48 - Area 8 trouble
10/0/51 - Area 1 not ready
...
10/0/58 - Area 8 not ready
10/1/1 - Area 1 control [1-ARM, 2-FORCE ARM, 3-STAY ARM, 4-INSTANT ARM, 5-DISARM]
...
10/1/8 - Area 8 control
10/2/1 - Zone 1 status
...
10/2/xxx - Zone xxx status
All what you need to change is in resident script (group addresses).
Resident script (EVO192 communication, sleep interval 0):
Code:
require('user.guardZoneStatus')
require('user.guardAreaStatus')
require('user.guardAreaLabels')
require('user.guardZoneLabels')
command_enum = {
[1] = 'A',
[2] = 'F',
[3] = 'S',
[4] = 'I',
}
if not port then
require('serial')
port = serial.open('/dev/RS232', { baudrate = 9600, parity = 'none', databits = '8', stopbits = '1'})
port:flush()
line = ''
end
security_main_ga = '10/' --'3-level' = main/middle/sub. Make sure that 10/0/0 - 10/7/X group addresses are not used. System creates objects automatically.
security_code = '1234'
request_area_status_ga = '32/5/0' --Create scheduled script for this one. Write true every minute.
request_zone_labels_ga = '32/5/3' --You need to change this to true only one time or if security zones are changed.
--This also activates group address generation.
--Make sure that zone label is not "Zone 001, Zone 002 etc because these zone names gonna be ignored.
request_area_labels_ga = '32/5/4' --You need to change this to true only one time or if security areas are changed.
--This also activates group address generation.
--Make sure that area label is not "Area 001, Area 002 etc because these area names gonna be ignored.
request_zone_name_count = 50 --how many zones will be scanned to get zone labels.
active_areas = 1 --How many areas are polled periodically. Starts on first area.
char = port:read(1, 1)
--log(char)
if char then
if char == '\r' then
line = line:trim()
log(line)
event = string.sub(line,1,2)
-- log(event)
if event == 'G0' then
eventnr = tonumber(string.sub(line,6,-5))
area = tonumber(string.sub(line,10,-1))
eventngr = tonumber(string.sub(line,2,4))
guardzonefunction(eventngr,eventnr,area,security_main_ga)
elseif event == 'RA' then
area = tonumber(string.sub(line,3,5))
securitystatus_1 = string.sub(line,6,6)
areastatus_1 = string.sub(line,7,7)
areastatus_2 = string.sub(line,8,8)
areastatus_3 = string.sub(line,9,9)
areastatus_4 = string.sub(line,10,10)
areastatus_5 = string.sub(line,11,11)
areastatus_6 = string.sub(line,12,12)
guardareafunction(area,securitystatus_1,areastatus_1,areastatus_2,areastatus_3,areastatus_4,areastatus_5,areastatus_6,security_main_ga )
elseif event == 'AL' then
area = tonumber(string.sub(line,3,5))
name = string.sub(line,6,16)
guardarealabelfunction(area, name,security_main_ga)
elseif event == 'ZL' then
zone = tonumber(string.sub(line,3,5))
name = string.sub(line,6,16)
guardzonelabelfunction(zone, name,security_main_ga)
end
line = ''
else
line = line .. char
end
else
request = grp.getvalue(request_area_status_ga) --scheduled script changes object to true every minute
if request then
for i = 1, active_areas, 1 do
port:write('RA00'.. i .. '\r') --send area1 status request command
os.sleep(0.2)
if i==active_areas then
grp.update(request_area_status_ga, false)
end
end
end
request_area_names = grp.getvalue(request_area_labels_ga)
if request_area_names then
for i = 1, 8, 1 do
port:write('AL00'..tostring(i)..'\r')
os.sleep(0.2)
end
grp.update(request_area_labels_ga, false)
end
request_zone_names = grp.getvalue(request_zone_labels_ga)
if request_zone_names then
for i = 1, request_zone_name_count, 1 do
if i<10 then
port:write('ZL00'..tostring(i)..'\r')
os.sleep(0.2)
else
port:write('ZL0'..tostring(i)..'\r')
os.sleep(0.2)
end
end
grp.update(request_zone_labels_ga, false)
end
for i = 1, active_areas, 1 do
exist = grp.alias(security_main_ga .. '1/' .. i)
if exist ~= nil then
AreaControl = grp.getvalue(security_main_ga .. '1/' .. i) --1-Arm; 2-Force arm; 3-Stay arm; 4-Instant arm; 5-Disarm
if AreaControl ~=0 then
if AreaControl ~= 5 then
port:write('AA00' .. i .. command_enum[AreaControl] .. security_code ..'\r')
grp.update(security_main_ga .. '1/' .. i, 0)
else
port:write('AD00' .. i .. security_code ..'\r')
grp.update(security_main_ga .. '1/' .. i, 0)
end
end
end
end
end
User library (guardAreaLabels):
Code:
function guardarealabelfunction(areanumber, areaname, security_main_ga)
if areaname ~= ('Area ' .. tonumber(areanumber)) then
for i = 1, 7, 1 do
if i==1 then
exist = grp.alias(security_main_ga .. '0/' .. tonumber(areanumber))
if exist == nil then
address = grp.create({
datatype = dt.uint8,
address = security_main_ga .. '0/' .. tonumber(areanumber),
name = areaname .. ' security status',
comment = 'Automatically created object - Security Area '.. tonumber(areanumber),
units = '',
tags = { },
})
end
elseif i==2 then
exist = grp.alias(security_main_ga .. '0/' .. tonumber(areanumber)+10)
if exist == nil then
address = grp.create({
datatype = dt.bool,
address = security_main_ga .. '0/' .. tonumber(areanumber)+10,
name = areaname .. ' exit delay',
comment = 'Automatically created object - Security Area '.. tonumber(areanumber) .. ' exit delay',
units = '',
tags = { },
})
end
elseif i==3 then
exist = grp.alias(security_main_ga .. '0/' .. tonumber(areanumber)+20)
if exist == nil then
address = grp.create({
datatype = dt.bool,
address = security_main_ga .. '0/' .. tonumber(areanumber)+20,
name = areaname .. ' entry delay',
comment = 'Automatically created object - Security Area '.. tonumber(areanumber) .. ' entry delay',
units = '',
tags = { },
})
end
elseif i==4 then
exist = grp.alias(security_main_ga .. '0/' .. tonumber(areanumber)+30)
if exist == nil then
address = grp.create({
datatype = dt.bool,
address = security_main_ga .. '0/' .. tonumber(areanumber)+30,
name = areaname .. ' alarm status',
comment = 'Automatically created object - Security Area '.. tonumber(areanumber) .. ' alarm status',
units = '',
tags = { },
})
end
elseif i==5 then
exist = grp.alias(security_main_ga .. '0/' .. tonumber(areanumber)+40)
if exist == nil then
address = grp.create({
datatype = dt.bool,
address = security_main_ga .. '0/' .. tonumber(areanumber)+40,
name = areaname .. ' trouble',
comment = 'Automatically created object - Security Area '.. tonumber(areanumber) .. ' trouble',
units = '',
tags = { },
})
end
elseif i==6 then
exist = grp.alias(security_main_ga .. '0/' .. tonumber(areanumber)+50)
if exist == nil then
address = grp.create({
datatype = dt.bool,
address = security_main_ga .. '0/' .. tonumber(areanumber)+50,
name = areaname .. ' not ready',
comment = 'Automatically created object - Security Area '.. tonumber(areanumber) .. ' not ready',
units = '',
tags = { },
})
end
elseif i==7 then
exist = grp.alias(security_main_ga .. '1/' .. tonumber(areanumber))
if exist == nil then
address = grp.create({
datatype = dt.uint8,
address = security_main_ga .. '1/' .. tonumber(areanumber),
name = 'Control ' .. areaname,
comment = 'Automatically created object - Control Security Area '.. tonumber(areanumber),
units = '',
tags = { },
})
end
end
end
end
end
User library (guardAreaStatus):
Code:
function guardareafunction(areanumber, areastatus, areastatus1, areastatus2, areastatus3, areastatus4, areastatus5, areastatus6, security_main_ga ) --what must be process RA001DOONOOO; RA - Request area; 001 - Area number; D - Disarmed/Armed/Force armed/Stay armed/Instant armed; O - Zone in memory/Ok; O - Troube/Ok; N - Not ready/Ok; O - In programming/Ok; O - In alarm/Ok; O - Strobe/Ok
if areastatus == 'D' then
grp.write(security_main_ga .. '0/' .. areanumber , 0)
elseif areastatus == 'A' then
grp.update(security_main_ga .. '0/' .. areanumber , 1)
elseif areastatus == 'F' then
grp.update(security_main_ga .. '0/' .. areanumber , 2)
elseif areastatus == 'S' then
grp.update(security_main_ga .. '0/' .. areanumber , 3)
elseif areastatus == 'I' then
grp.update(security_main_ga .. '0/' .. areanumber , 4)
end
if areastatus2 == 'T' then
grp.update(security_main_ga .. '0/' .. areanumber+40 , true)
elseif areastatus2 == 'O' then
grp.update(security_main_ga .. '0/' .. areanumber+40 , false)
end
if areastatus3 == 'N' then
grp.update(security_main_ga .. '0/' .. areanumber+50 , true)
elseif areastatus3 == 'O' then
grp.update(security_main_ga .. '0/' .. areanumber+50 , false)
end
if areastatus5 == 'A' then
grp.update(security_main_ga .. '0/' .. areanumber+30 , true)
elseif areastatus5 == 'O' then
grp.update(security_main_ga .. '0/' .. areanumber+30 , false)
end
end
User library (guardZoneLabels):
Code:
function guardzonelabelfunction(zonenumber, zonename, security_main_ga)
exist = grp.alias(security_main_ga .. '2/'.. tonumber(zonenumber))
if exist == nil then
if zonenumber<10 then
if zonename ~= ('Zone 00' .. tonumber(zonenumber)) then
address = grp.create({
datatype = dt.bool,
address = security_main_ga .. '2/'.. tonumber(zonenumber),
name = zonename,
comment = 'Automatically created object - Zone '.. tonumber(zonenumber),
units = '',
tags = { },
})
end
elseif zonenumber>=10 and zonenumber<100 then
if zonename ~= ('Zone 0' .. tonumber(zonenumber)) then
address = grp.create({
datatype = dt.bool,
address = security_main_ga .. '2/'.. tonumber(zonenumber),
name = zonename,
comment = 'Automatically created object - Zone '.. tonumber(zonenumber),
units = '',
tags = { },
})
end
elseif zonenumber>=100 then
if zonename ~= ('Zone ' .. tonumber(zonenumber)) then
address = grp.create({
datatype = dt.bool,
address = security_main_ga .. '2/'.. tonumber(zonenumber),
name = zonename,
comment = 'Automatically created object - Zone '.. tonumber(zonenumber),
units = '',
tags = { },
})
end
end
end
end
User library (guardZoneStatus):
Code:
function guardzonefunction( eventgroup,eventnumber,areanumber,security_main_ga)
if eventgroup == 0 or eventgroup == 1 then
if eventgroup == 0 then
grp.update(security_main_ga .. '2/'..eventnumber, false)
elseif eventgroup == 1 then
grp.update(security_main_ga .. '2/'..eventnumber, true)
end
elseif eventgroup == 5 then -- disarm
grp.update(security_main_ga .. '0/' .. areanumber , 0)
grp.update(security_main_ga .. '0/' .. areanumber+10,false) --reset exit delay
grp.update(security_main_ga .. '0/' .. areanumber+20 , false) --reset entry delay
elseif eventgroup == 13 then -- disarm
grp.update(security_main_ga .. '0/' .. areanumber , 0)
grp.update(security_main_ga .. '0/' .. areanumber+10,false) --reset exit delay
grp.update(security_main_ga .. '0/' .. areanumber+20 , false) --reset entry delay
elseif eventgroup == 64 then --
if eventnumber == 0 then
grp.write(security_main_ga .. '0/' .. areanumber , 1)
grp.update(security_main_ga .. '0/' .. areanumber+10,false) --reset exit delay
grp.update(security_main_ga .. '0/' .. areanumber+20 , false) --reset entry delay
elseif eventnumber == 1 then
grp.write(security_main_ga .. '0/' .. areanumber , 2)
grp.update(security_main_ga .. '0/' .. areanumber+10,false) --reset exit delay
grp.update(security_main_ga .. '0/' .. areanumber+20 , false) --reset entry delay
elseif eventnumber == 2 then
grp.write(security_main_ga .. '0/' .. areanumber , 3)
grp.update(security_main_ga .. '0/' .. areanumber+10,false) --reset exit delay
grp.update(security_main_ga .. '0/' .. areanumber+20 , false) --reset entry delay
elseif eventnumber == 3 then
grp.write(security_main_ga .. '0/' .. areanumber , 4)
grp.update(security_main_ga .. '0/' .. areanumber+10,false) --reset exit delay
grp.update(security_main_ga .. '0/' .. areanumber+20 , false) --reset entry delay
elseif eventnumber == 4 or eventnumber == 5 or eventnumber == 6 or eventnumber == 7 then
grp.update(security_main_ga .. '0/' .. areanumber+30 , true)
end
elseif eventgroup == 65 then
if eventnumber == 1 then
grp.update(security_main_ga .. '0/' .. areanumber+10 , true)
elseif eventnumber == 2 then
grp.update(security_main_ga .. '0/' .. areanumber+20 , true)
elseif eventnumber == 0 then
grp.update(security_main_ga .. '0/' .. areanumber+10 , false)
grp.update(security_main_ga .. '0/' .. areanumber+20 , false)
end
end
end
After you request area and zone names, give it some time to scan and create group objects. Mine needed about 15-20 seconds (1 area, 50 zones)...
All objects what are created automatically they have also object comment "Automatically created object - Security Area X", "Automatically created object - Zone XX" etc..