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 that you accept these cookies being set.

Paradox EVO192 integration
#3
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.  Cool
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..
Reply


Messages In This Thread
Paradox EVO192 integration - by edgars - 13.11.2019, 09:00
RE: Paradox EVO192 integration - by fleeceable - 18.07.2020, 14:37
RE: Paradox EVO192 integration - by gtsamis - 25.03.2022, 02:02
RE: Paradox EVO192 integration - by mishoboss - 01.12.2020, 21:05
RE: Paradox EVO192 integration - by mishoboss - 26.06.2021, 05:27
RE: Paradox EVO192 integration - by Angeles - 27.10.2021, 11:41
RE: Paradox EVO192 integration - by admin - 22.02.2022, 12:09
RE: Paradox EVO192 integration - by admin - 22.02.2022, 15:16
RE: Paradox EVO192 integration - by JMemphix - 10.10.2022, 00:10
RE: Paradox EVO192 integration - by mishoboss - 22.04.2024, 08:47
RE: Paradox EVO192 integration - by Daniel - 22.04.2024, 08:54

Forum Jump: