Utile h+ is a middleware that aims to integrate IP-PBX platforms with Property Management Systems (PMS). This guide describes the configurations needed on the PBXact server for the integration to be established.
Services that will get implemented
Features supported in PBXact:
Class of service (calls permissions whether checked-in or checked-out)
Room Status (room cleaned status ; for hotel cleaning employees to register in the PMS that the room has been cleaned)
Minibar (minibar IVR for easy ordering)
Alarm management (wake-up calls)
Billing (billing for external calls dialed)
Previous Considerations in the PBXact server
SAMBA file sharing software must be installed for being able to exchange information between utile h+ and PBXact.
Within the configuration of the extensions in PBXact, the variable HABITACION must be defined, with the room number.
Trunks for placing external calls must have the parameter "Outbound CallerID" properly set with the DID of that trunk, complying with what the Carrier expects. You may have to set it with the format:
"Hotel Name" <#######>
(where: ####### is the Hotel's DID)Each and every hotel room extension must be created with a single same SIP channel driver, either PJSIP (default for utile h+ integration) or CHAN_SIP, for all the rooms.
We'll be configuring points 1 & 2 next.
Integration Scheme
Directories Structure
For the information exchange between PBXact and utile h+ , a directory will be used within the PBXact system, for example, /opt/CHAR . This directory has to be visible from within the Windows computer where utile h+ is installed.
That is why, the SAMBA Server need to be installed:
yum install samba |
Once installed, place the following minimum settings in its configuration file ( /etc/samba/smb.conf ):
[global] server string = PBXact Server-CHAR %h obey pam restrictions = Yes follow symlinks = yes wide links = yes unix extensions = no security = user map to guest = Bad User passdb backend = tdbsam pam password change = Yes passwd program = /usr/bin/passwd %u passwd chat = *Enter\snew\s*\spassword:* %n\n *Retype\snew\s*\spassword:* %n\n *password\supdated\ssuccessfully* . unix password sync = Yes log file = /var/log/samba/log.%m max log size = 1000 dns proxy = No panic action = /usr/share/samba/panic-action %d load printers = no [ASTCHAR] comment = PBXact communications directory - CHAR path = /opt/CHAR/ force user = asterisk printable = no read only = No create mask = 0777 directory mask = 0777 guest ok = Yes locking = No volume = ASTCHAR |
Once the SAMBA configuration has been set, it is necessary to create the following directory structure inside the /opt/CHAR path:
Directory
/opt/CHAR/checking → Directory where the AGI files of each room will be found
Directory
/opt/CHAR/despertador → Symbolic link to /var/spool/asterisk/outgoing for the Alarm Service
Directory
/opt/CHAR/tarificacion → Symbolic link to /var/log/asterisk/cdr-csv
File
/opt/CHAR/codigos.txt → Employees codes so that they can get validated when calling to register the room as clean and also for registering in the log files which employee cleaned the room
mkdir /opt/CHAR mkdir /opt/CHAR/checking mkdir /opt/CHAR/tarificacion ------ (example) ------ echo 72638 >> /opt/CHAR/codigos.txt ------ (example) ------ ln -s /var/spool/asterisk/outgoing /opt/CHAR/despertador ln -s /var/log/asterisk/cdr-csv /opt/CHAR/tarificacion |
NOTE: remember to assign the correct owner and give appropriate permissions, just execute the following:
chmod -R 777 /opt/CHAR chmod -R 777 /var/log/asterisk chown -R asterisk.asterisk /opt/CHAR |
You will also have to copy the default agi:
cp /var/lib/asterisk/agi-bin/* /opt/CHAR/checking/ |
Restart the SAMBA service to apply the changes made before on its configuration file:
service smb restart |
Enable it to autorun every time the server boot, as well:
systemctl enable smb |
The following minimum contexts can be defined within the asterisk file: /etc/asterisk/extensions_custom.conf where we specify certain configuration parameters for the room extensions:
[habitaciones] → Outgoing Context for room extensions.
[hab-libre] → Outgoing Context when the room is empty.
[hab-ocupada] → Outgoing Context when the room is occupied.
[servicios] → Context where the hotel services are located.
[extensiones] → Outgoing Context for internal calls from room to room.
[internacionales] → Outgoing Context for external calls outside the hotel (so that they get billed).
[roomservice] → Outgoing Context for cleaning service status (so that the cleaning person can register once the room has been cleaned).
[minibar] → Outgoing Context for calls to minibar service.
[despertador] → Incoming Context for the wake-up calls.
We'll configure them next, within the following sections:
Checked-in / Checked-out Status
This service is used when a room is occupied (Checked-In) or empty (Checked-Out).
So, it is necessary to control the type of outbound calls to be allowed in each of these states. To do it, in the directory /opt/CHAR/checking the utile h+ application will modify the AGI Script that will select the Context where it should look for the number to call.
All room extensions must belong to the "habitaciones" context and have defined a variable with the Room Number (HABITACION), as follows:
[101]
type=friend
secret=clave
defaultuser=101
canreinvite=no
nat=no
context=habitaciones
setvar=HABITACION=101
As indicated, the last two lines (context and setvar) are the ones allowing the integration of PBXact with utile h+ . For these lines to be properly added to the room extensions, the /etc/asterisk/pjsip.endpoint_custom_post.conf (or /etc/asterisk/sip_custom_post.conf if the hotel room extensions rather use the CHAN_SIP channel driver) file should be edited as follows (example):
[101](+) context=habitaciones set_var=HABITACION=101 [102](+) context=habitaciones set_var=HABITACION=102 . . . |
NOTE: for CHAN_SIP extensions, the correct nomenclature is setvar (and not set_var which is for PJSIP extensions)
And so forth for all hotel room extensions.
The [habitaciones] context, point in asterisk's dialplan from where the room extensions will start at for each placed call, should be as follows (place these lines in the /etc/asterisk/extensions_custom.conf file):
[habitaciones] exten=>_X.,1,NoOP(-- Llamada desde la habitacion ${HABITACION}) exten=>_X.,n,Set(CDR(userfield)=${HABITACION}) exten=>_X.,n,AGI(/opt/CHAR/checking/checkinout${HABITACION}.php) exten=>_X.,n,Goto(${CONTEXTO},${EXTEN},1) exten=>_*.,1,NoOP(-- Llamada desde la habitacion ${HABITACION}) exten=>_*.,n,Set(CDR(userfield)=${HABITACION}) exten=>_*.,n,AGI(/opt/CHAR/checking/checkinout${HABITACION}.php) exten=>_*.,n,Goto(${CONTEXTO},${EXTEN},1) |
Once configured, room extensions will be able to call hotel services or any number, depending on the result of the executed AGI script executed, as it will set a call with the context [hab-ocupada] or with the context [hab-libre], which may be configured as follows:
[hab-libre] → It should only allow to place hotel services calls and calls to other room extensions, configured as follows (place these lines in the
/etc/asterisk/extensions_custom.conf file):
[hab-libre] include=>roomservice exten=>i,1,NoOP(-- Llamada no permitida --) exten=>i,n,Playback(invalid) exten=>i,n,Hangup() |
[hab-ocupada] → It should allow to make any call, configured as follows (place these lines in the
/etc/asterisk/extensions_custom.conf file):
[hab-ocupada] include=>servicios include=>extensiones ;include=>nacionales ;include=>moviles include=>internacionales ;include=>especiales exten=>i,1,NoOP(-- Llamada no permitida --) exten=>i,n,Playback(invalid) exten=>i,n,Hangup() |
To be able to dial to other rooms and to place external calls, the contexts [extensiones] and [internacionales] have to be added to the /etc/asterisk/extensions_custom.conf file as well respectively:
[extensiones] exten => _ZXX,1,NoOP(-- Llamada a otra habitación ---) same => n,Dial(PJSIP/${EXTEN}) same => n,Hangup |
NOTE 1: ZXX will allow for the dialing of any extension from 100 to 999 (see DIAL PATTERN INFO), if the hotel room extensions follow rather a different pattern (perhaps four digits numbers), this has to be adjusted accordingly.
NOTE 2: PJSIP/${EXTEN} may need to be changed to SIP/${EXTEN} if the hotel room extensions were rather created using the CHAN_SIP channel driver.
[internacionales] exten => _X.,1,NoOP(-- Contexto extensiones --- Llamada Internacional ---) same => n,Goto(from-internal,${EXTEN},1) same => n,Hangup |
NOTE: AGIs are generated by utile h+ directly.
Room Cleaned Status
This service will be used by the hotel’s employee to indicate if the room is clean or dirty. To do so, utile h+ will read the information from the file “/opt/CHAR/roomservice.log”.
To access the service, it is necessary to add a code in the service context, as follows (place these lines in the /etc/asterisk/extensions_custom.conf file):
[servicios] exten=>*01,1,NoOP(-- Servicio de Habitaciones --) exten=>*01,n,Goto(roomservice,s,1) |
With this configuration, we will be able to access the roomservice context, where the service calls will be configured. To configure this, at least 1 audio file is recommended to be generated (see System Recordings Module User Guide):
room-cleaning-service.gsm → “Room Cleaning Service. Press 0 if the room is clean, or press 1 if it is not clean”.
The file “/opt/CHAR/codigos.txt” will be used to validate the code entered by the employee and be able to log it for the PMS (date, time, employee cleaning which room). The following context can be used (place these lines in the /etc/asterisk/extensions_custom.conf file):
[roomservice] exten=>s,1,NoOP(servicio de habitacion) exten=>s,n,Answer() exten=>s,n,Playback(room-service) exten=>s,n,Authenticate(/opt/CHAR/codigos.txt,a) exten=>s,n(opcion),Read(ESTADO,custom/room-cleaning-service,1,,2,15) exten=>s,n,GotoIF($[ ${ESTADO} == 0 || ${ESTADO} == 1 ]?registro) exten=>s,n,Goto(opcion) exten=>s,n(registro),System(echo "RS ${STRFTIME(,,%d/%m/%Y %H:%M)} ${HABITACION} ${ESTADO} ${CDR(accountcode)}" >> /opt/CHAR/roomservice.log) exten=>s,n,Playback(thanks-for-using) exten=>s,n,Playback(room-service) exten=>s,n,Hangup() |
NOTE: the format for each one of the lines that will get stored in the log to be transferred to the PMS (roomservice.log) is the following:
Room Service Identifier (RS), Date and Hour of the input, Room Number, Room Status (0 - clean, 1 - dirty), Employee Code
Minibar Service
This service is used to indicate the minibar charges. To do it, utile h+ will read the information from the file /opt/CHAR/roomservice.log
To access to the service it is necessary to add a code in the [servicios] context, as follows (place the bold lines in the /etc/asterisk/extensions_custom.conf file under the previous lines already added to the [servicios] context):
[servicios]
exten=>*01,1,NoOP(-- Servicio de Habitaciones --)
exten=>*01,n,Goto(roomservice,s,1)
exten=>*02,1,NoOP(-- Servicio de MiniBAR --)
exten=>*02,n,Goto(minibar,s,1)
With this configuration we will be able to access to the minibar context where its service will be configured. It is recommended to generate at least 7 audio files for it:
minibar.gsm → "Welcome to the Minibar service"
intro_cantidad.gsm → "Introduce the quantity"
intro_articulo,gsm → "Introduce the aritcle code"
cantidad.gsm → "Quantity introduced…"
articulo.gsm → "Article introduced…"
menuarticulo.gsm → "Press 1 to confirm and continue, press 2 to cancel, press 3 to confirm and finish and * to access to the article list."
listacodigos → "Whenever you want to stop hearing the article list, press a key. The article list is the following: ..."
The following context can be used (place these lines in the /etc/asterisk/extensions_custom.conf file):
[minibar] exten=>s,1,NoOP(--Servicio de Minibar--) exten=>s,n,Answer() exten=>s,n,Playback(custom/minibar) exten=>s,n(intro),READ(CANTIDAD,custom/intro_cantidad,1,,1,15) exten=>s,n,GotoIF($[ "${CANTIDAD}" == "" ]?intro) exten=>s,n,READ(ARTICULO,custom/intro_articulo,1,,1,15) exten=>s,n,GotoIF($[ "${ARTICULO}" == "" ]?intro) exten=>s,n,Playback(custom/cantidad) exten=>s,n,SayNumber(${CANTIDAD}) exten=>s,n,Playback(custom/articulo) exten=>s,n,SayNumber(${ARTICULO}) exten=>s,n(confirmar),READ(OPCION,custom/menuarticulo,1,,1,15) exten=>s,n,GotoIF($[ ${OPCION} == 1]?1,1) exten=>s,n,GotoIF($[ ${OPCION} == 2]?2,1) exten=>s,n,GotoIF($[ ${OPCION} == 3]?3,1) exten=>s,n,GotoIF($[ "${OPCION}" == "*" ]?*,1) exten=>s,n,Goto(confirmar) exten=>1,1,NoOP(--Confirmar y seguir--) exten=>1,n,System(echo "MB ${STRFTIME(,,%d/%m/%Y %H:%M)} ${HABITACION} ${CANTIDAD} ${ARTICULO} ${CDR(accountcode)}" >> /opt/CHAR/roomservice.log) exten=>1,n,Goto(s,intro) exten=>2,1,NoOP(--Anular la entrada--) exten=>2,n,Goto(s,intro) exten=>3,1,NoOP(--Confirmar y salir--) exten=>3,n,System(echo "MB ${STRFTIME(,,%d/%m/%Y %H:%M)} ${HABITACION} ${CANTIDAD} ${ARTICULO} ${CDR(accountcode)}" >> /opt/CHAR/roomservice.log) exten=>3,n,Playback(thanks-for-using) exten=>3,n,Playback(custom/minibar) exten=>3,n,Hangup() exten=>*,1,NoOP(--Acceder a la lista de articulos--) exten=>*,n,Read(VOLVER,custom/listacodigos,1,,1,15) exten=>*,n,Goto(s,intro) |
Alarm Clock Service (Wake-up calls)
This service is used when the guest ask to be woke up to a certain hour in the morming. It is based in the Call files of Asterisk that it will be generated by utile h+ and saved in the directory /opt/CHAR/despertador . That is not more than a symbolic link with /var/spool/asterisk/outgoing.
The context for the wake up service is the “despertador” context and it can be as follows (place these lines in the /etc/asterisk/extensions_custom.conf file):
[despertador] exten=>s,1,NoOP(--Servicio de Despertador--) exten=>s,n,Answer() exten=>s,n,Playback(wakeup-call) exten=>s,n,Playback(current-time-is) exten=>s,n,SayUnixTime(,,IMp) exten=>s,n,Wait(1) exten=>s,n,Playback(thanks-for-using) exten=>s,n,Playback(wakeup-call) exten=>s,n,Hangup() |
NOTE: it may be necessary to modify the template file for generating the wake-up calls according to the SIP channel driver the hotel room extensions were created with (CHAN_SIP or PJSIP). This is done by editing the reminder_template.call file inside the Windows computer running the utile h+ software, specifically located at: C:\CHARWIN\asterisk\hlink\reminder_template.call Simply change in the first line from PJSIP to SIP if the hotel room extensions use the CHAN_SIP channel driver and not the PJSIP driver:
Channel: PJSIP/%EXTENSION% → Channel: SIP/%EXTENSION%
Allow calls from administrative extensions (Reception and others) to rooms
Add the following lines at the end of the /etc/asterisk/extensions_custom.conf file
[from-internal-custom] include => extensiones |
Billing
Every external call placed from a room extension is accounted and transferred accordingly to utile h+ which in turn sends the information to the PMS. For this integration, the following has to be included in the /etc/asterisk/cdr.conf file:
[csv] usegmtime=yes loguniqueid=yes loguserfield=yes accountlogs=yes |
The final step is to make sure the Asterisk changes get applied, just execute:
fwconsole restart |
APPENDIX A
Optional bash Scripts for batch automations
Populating the SIP custom_post.conf file
For automatically populating the /etc/asterisk/pjsip.endpoint_custom_post.conf (or /etc/asterisk/sip_custom_post.conf if the hotel room extensions rather use the CHAN_SIP channel driver and not PJSIP) file, the optional bash script
could be used:Simply run it from any Linux PC or Server (it could be run from the PBXact itself) as follows:
Make the script file executable:
chmod +x populate_custom_post_file_for_utileh.shExecute it:
sh populate_custom_post_file_for_utileh.sh
The script will ask on screen (Linux console) for the total quantity of rooms and then for the actual number of the first room, based on this information it generates a file called "custom_post.conf" which then must be placed with the correct name (either pjsip.endpoint_custom_post.conf or sip_custom_post.conf), depending if using PJSIP or CHAN_SIP for the created Rooms extensions, and of course placed under the correct path ( /etc/asterisk/ ) with the correct owner and permissions (see APPENDIX B below).
Note: the script does not consider, for example, cases in which the rooms do not always reach 99 in every hundred (example: from room 120 skips to room 201, from 220 to 301, etc.); modifying it could achieve this behavior, or, perhaps faster/easier, simply consider those "empty spaces of rooms" when entering the total quantity of rooms during the script's execution, and then proceed to manually delete, in the generated resulting file, the lines for those rooms (extensions) that don't really exist.
First-time generation of the checkinout###.php files
The first time a Room's status is set as either Checked-In or Checked-Out via utile h+ (or via the PMS itself), utile h+ generates a corresponding checkinout###.php file and places it inside the PBX under /opt/CHAR/checking/ as mentioned before; if considered, the optional bash script
together along with the could be used to automatically generate those checkinout###.php files for every Room at once:Place both files in the PBX, under: /opt/CHAR/checking/
Give execute permissions to the script:
chmod +x /opt/CHAR/checking/generate_chekinout_files_for_utileh.shChange the owner of both files to asterisk:
chown asterisk: /opt/CHAR/checking/checkinout_BASE_FILE.php /opt/CHAR/checking/generate_chekinout_files_for_utileh.shExecute the script as asterisk user:
sudo -u asterisk sh /opt/CHAR/checking/generate_chekinout_files_for_utileh.sh
The script will ask on screen (Linux console) for the total quantity of rooms and then for the actual number of the first room, based on this information it generates all checkinout###.php files.
Note1: the script does not consider, for example, cases in which the rooms do not always reach 99 in every hundred (example: from room 120 skips to room 201, from 220 to 301, etc.); modifying it could achieve this behavior, or, perhaps faster/easier, simply consider those "empty spaces of rooms" when entering the total quantity of rooms during the script's execution, and then, if so desired, proceed to manually delete the files for those rooms (extensions) that don't really exist.
Note2: all generated files will have the context "hab-libre", to change this to "hab-ocupada" the corresponding room status change must be made in utile h+ (or the PMS).
Delete voicemail files after Room's status has changed to checked-out
To automatically delete every voicemail file of all the Rooms that have changed to checked-out status, the optional bash script
could be used:Place the script on the PBX, under: /opt/
Make it executable:
chmod +x /opt/delete_vm_files.shEdit the crontab (crontab -e) and add the cronjob line that will make the script run periodically. Examples:
a) If wanting for the script to run every day at 13h30: 30 13 * * * /usr/bin/sh /opt/delete_vm_files.sh
b) If wanting for the script to run every 10 minutes: */10 * * * * /usr/bin/sh /opt/delete_vm_files.sh
The script will also delete any possible customized voicemail greetings files reproduced to callers before they can leave a voicemail message, if such customized voicemail greetings files are to be used in the Hotel, rather use the bash script
instead.Note that if no customized voicemail greetings files exist, the PBX will simply just reproduce to callers, before they can leave a voicemail message, the voicemail announcement that comes already predetermined with the system.
APPENDIX B
Sample .conf files
Here are sample configuration (.conf) files from the integration described above, instead of adding/editing the files mentioned above right from within the PBXact server. You may consider downloading these following files and uploading them in the PBXact server under their correct paths (make sure to adjust the owner and permissions of these files accordingly after having manually uploaded them):
(root 644) /etc/samba/ :
(asterisk 777) /opt/CHAR/ :
(asterisk 664) /etc/asterisk/ : or /etc/asterisk/ :
(asterisk 664) /etc/asterisk/ :
(asterisk 664) /etc/asterisk/ :
Sangoma Professional Services are able to provide PBXact configuration support and it is limited to the PBXact configuration. utile h+ is without any warranty from Sangoma as this is a third party integration. End users are responsible for obtaining their own utile h+ support.