66.2. Example of I/O management via LUA Script

Abilis permits to pilot Input and Output also making phone calls. For that we use a LUA script joined to DISA resource that allows to open Gate#1 connected to Digital Output 1 verifying the calling number.

[Note]Note

This advanced configuration normally is realized by Second Level Abilis support. Following are reported only the resource configurations and a short logical description

1 - The Abilis verify to receive a call for the called number 0213456789 from the calling numbers recognized in list CallingOK, in this case is sent a call to DISA Service with called Number 91.

[13:47:55] ABILIS_CPX: d ctir pr:3

Last change: 01/02/2015 14:20:26 CET

---+-----+-----------------+---------+--------------------+--------------------
PR |[DESCR]
   |TYPE |POI/SR   [SR]    |POO/DS   |CDI                 |CDO
ACT|NEXT       |LAST       |EEC |T301|CGI                 |CGO
EDT|SP   |SC   |DJ   |MJ   |FMDJ|FMMJ|SDI                 |SDO
   |SPOUT|SCOUT|DJOUT|MJOUT|LCS |LCST|SGI                 |SGO
   |                       |BCO      |RGI                 |RGO
   |FMRLY|FAXSP|MODSP|FMLVL|ECM |UDT |IG  |OG  |SG        |DL  |DH
|CODERS
   |CODERSOUT
   |TI1 .. TI5
-------------------------------------------------------------------------------
3   CtoD  *                 CtiDisa   0213456789           91
NO          ANY         NO   Dft  'CallingOK'          *
64000 Sys   *     *     Sys  Sys  *                    *
-------------------------------------------------------------------------------

2- The DISA resource, configured like below, receive the call with called number 91. The DISA SERVICE:entryphone refuse the call but recognized the number that is motorized by LUA Script.

[13:47:16] ABILIS_CPX: d p ctidisa

RES:CtiDisa -------------------------------------------------------------------
Run    DESCR:Direct_Inward_System_Access
       LOG:NO          ACT:YES        sesnum:10       RESTRICTED-CALLING:NO
       PROVIDE-SG:YES  CALL-ABORT:**  CALL-REPEAT:**  PIN-START:*  PIN-END:#
       NPOO-CT:SYS     CTIP-TYPE:NET-PRIVATE          BUSY-NOCHAN:YES
WDIR:C:\APP\DISA\

[13:47:19] ABILIS_CPX: d ctidisa user

Total number of users:1

-------------------------------------------------------------------------------
USER:Anonymous
  PIN:     #                |MAX-CALLS: NOMAX |PERMIT: SERVICE
SERVICE: AUTO             |CB:        NO    |DENY:   #
  CGI:   -
-------------------------------------------------------------------------------

[13:47:22] ABILIS_CPX: d ctidisa service:entryphone

Total number of services:2

-------------------------------------------------------------------------------
SERVICE:entryphone        DESCR:
  MODE:        APP                    |INTRO-STATE:   CREQ  |INTRO:
  MAX-CALLS:   NOMAX                  |CONN-DELAY:    6     |WELCOME:
  BC:          Speech                 |DIAL-TOUT:     30    |INITDIAL:
  CB-CGO:      #                                            |BYE:      #
  CDI:         9*
  CGI:         #
-------------------------------------------------------------------------------

3- The script ephone-cd.lua verify the last digit of called number and pilot the corresponding Digital Output. In this example the called number is 91 then the driven Digital Output is D-OUT: 1

[13:46:52] ABILIS_CPX: d p script

RES:Script --------------------------------------------------------------------
Run    DESCR:Scripting_service
       LOG:NO        ACT:YES    bg-sesnum:4    fg-sesnum:4
wdir:C:\APP\SCRIPT\
       - Background scripts ---------------------------------------------------
       id:0  startup:YES  file:ephone-cd.lua
       id:1  startup:NO   file:
       id:2  startup:NO   file:
       id:3  startup:NO   file:

[Tip]Tip

To manage the Lua script by web interface follow the chapter Section 57.11, “LUA scripts”

4- To open GATE#1 connected to D-OUT:1 Mfio is configured to generate a Pulse of 250 ms

[13:46:44] ABILIS_CPX: d p mfio

RES:MfIo ----------------------------------------------------------------------
Run    DESCR:Abilis_Multi_Function_IO_Interface
       LOG:NO        ACT:YES
       -------+-------------------- Digital Input lines -----------------------
       D-IN:  | [DESCR:]
       -------+----------------------------------------------------------------
       -------+-------------------- Digital Output lines ----------------------
       D-OUT: | [DESCR:]
              | MODE:    PULSE-T:    PULSE-GAP:
-------+----------------------------------------------------------------
       1      | GATE#1
              | PULSE    250          1000
       2      | GATE#2
              | PULSE    250          1000
       3      | PULSE    90000        1000
       ------------------------------------------------------------------------   

LUA Script ephone-cd.lua :

------------------------------------------------------------
--- ephone-cd.lua Script
--
-- This script waits for incoming call and makes a 250 ms
-- pulse on the selected digital output line depending on
-- the called number.
--
-- @author Tomas Klinkovsky <tklink@antek.it>
------------------------------------------------------------

local abilis = require "abilis"

------------------------------------------------------------

-- call state
local CLOSED = 0
local CALLING = 1
local ALERTING = 2
local ACTIVE = 3
local CLOSING = 4
local LISTENING = 5
-- play state
--local SILENT = 0,
--local PLAYING = 1,

------------------------------------------------------------

-- Name of this script, show in log
local SCRIPTNAME = "ephone-cd.lua"
-- Name of DISA/APP service
local DISASERVICE = "entryphone"
-- GPIO resource type
local GPIORESTYPE = "MFIO"
-- GPIO resource instance
local GPIORESINST = 1
-- GPIO pulse duration
local PULSEDURATION = 0.25
-- Poll period in seconds
local POLLPERIOD = 0.5

------------------------------------------------------------
--- Display log message
-- The message is preceded with an automatically generated
-- timestamp.
-- @parammsg Message to be logged
--
local function log(msg)
	local dt = os.date("%Y-%m-%d %X")
	local sep = " "
	print(dt .. sep .. msg)
end

------------------------------------------------------------
--- Handle of selected GPIO device
--
local GPIOHANDLE = abilis.gio.get_device_handle(GPIORESTYPE, GPIORESINST)

------------------------------------------------------------
--- Generate 250 ms pulse on selected GPIO line
-- @param line Digital output line number
--
local function pulse_line(line)
	abilis.gio.set_digital_output(GPIOHANDLE, line, 1)
	abilis.cpx.sleep(PULSEDURATION)
	abilis.gio.set_digital_output(GPIOHANDLE, line, 0)
end

------------------------------------------------------------
--- Wait for incoming call in DISA/APP
-- @param handle DISA/APP handle
--
local function wait_for_incoming_call(handle)
	assert(handle > 0)

	while true do
		local state = abilis.disa.get_state(handle)
		if state == CLOSED then
			return false
		elseif state ~= LISTENING then
			return true
		else
			abilis.cpx.sleep(POLLPERIOD)
		end
	end
end

------------------------------------------------------------
--- Map last digit of called number to GPIO line
--
local MAP = {
	["1"] = 1,
	["2"] = 2,
	["3"] = 3,
	["4"] = 4,
}

------------------------------------------------------------
--- Convert called number to GPIO line (or nil).
-- @param number Called phone number
-- @return GPIO line number
--
local function get_line_for_number(number)
	if number ~= nil then
		local last_digit = number:sub(-1)
		return MAP[last_digit]
	else
		return nil
	end
end

------------------------------------------------------------
--- Convert value to string.
-- Nil is converted to empty string, other values are
-- returned unchanged.
-- @param x String or nil
-- @return String
local function tostr(x)
	if x ~= nil then
		return x
	else
		return ""
	end
end

------------------------------------------------------------
--- Handle incoming call.
-- Wait for incoming call, obtain called number, find the
-- corresponding GPIO line, and generate pulse there.
-- @param handle DISA/APP handle
--
local function handle_incoming_call(handle)
	assert(handle > 0)

	if wait_for_incoming_call(handle) then
		local cg, cd = abilis.disa.get_info(handle)
		log("incoming call CG:" .. tostr(cg) .. " CD:" .. tostr(cd))
		local line = get_line_for_number(cd)
		if line ~= nil then
			log("generating pulse on line " .. line)
			pulse_line(line)
		else
	 	log("unsupported called number")
		end
	end
	log("closing call")
	abilis.disa.close(handle)
end

------------------------------------------------------------
--- Handle incoming calls.
-- Listen on selected DISA/APP service, and process
-- incoming call. And again, forever.
--
local function handle_incoming_calls()
	while true do
		log("waiting for incoming call")
		local handle = abilis.disa.listen(DISASERVICE)
		if handle ~= nil then
			handle_incoming_call(handle)
		else
			log("listen function failed")
			break
		end
	end
end

------------------------------------------------------------
--- Create session object, and handle incoming calls from
-- DISA/APP.
--
local function main()
	log(SCRIPTNAME .. " script started")
	handle_incoming_calls()
	log(SCRIPTNAME .. " script ended")
end

-- Execute the main function
main()

-- vim: tabstop=2 shiftwidth=2 noexpandtabfileformat=dos
--