AD2.pm

AD2

SYNOPSIS

---Example Code and Usage---

DESCRIPTION

Module for interfacing with the AD2 line of products. Monitors known events and maintains the state of the Ademco system in memory. Module also sends instructions to the panel as requested.

CONFIGURATION

Older versions of this library relied almost exclusively on ini parameters. This revised library provides extensive support for using an mht file to define AD2 objects and only requires setting ini parameters for the initial AD2 Interface configuration. [Feb 5, 2014]

At minimum, you must define the Interface. In addition, this library provides for the ability to define separate objects for each zone and relay. This allows for the display of these zones as separate items in the MH interface and allows users to interact directly with these objects using the basic Generic_Item functions such as tie_event.

Finally, this library permits the definition of Partitions. Partitions are available on all Ademco panels, but they are likely foreign to most users as more than one Partition is rarely used. In short, Partitions allow for what appears to be multiple distinct alarm systems to share a single alarm board. Each zone and alarm panel is assigned to a Partition. For example, a business may use partition 1 for the front office and partition 2 for the warehouse, this allows warehouse personel to arm/disarm the warehouse but not the front office while providing a single point of contact for the alarm monitoring company.

Within MisterHouse, the Partition is used primarily as a stand in for the alarm panel. The Partition object is used to arm/disarm the panel as well as to check on the agregate state of all of the zones.

Interface Configuration

There is a small difference in configuring the AD2 Interface for direct connections (Serial or USB) or IP Connections (Ser2Sock).

AD2-Prefix

This library envisions that a user may connect multiple AD2 Interfaces to MisterHouse. In order to distinguish between each interface, each interface must use a unique prefix. This prefix must take the following form:

   AD2[_digits]

Wherein the _digits suffix is optional. Each of the following prefixes would define a separate Interface:

   AD2
   AD2_1
   AD2_11

Direct Connections (USB or Serial)

INI file:

   AD2_serial_port=/dev/ttyAMA0

Wherein the format for the parameter name is:

   AD2-Prefix_serial_port

IP Connections (Ser2Sock)

INI file:

   AD2_server_ip=192.168.11.17
   AD2_server_port=10000

Wherein the format for the parameter name is:

   AD2-Prefix_server_ip
   AD2-Prefix_server_port

Defining the Interface Object (All Connection Types)

In addition to the above configuration, you must also define the interface object. The object can be defined in either an mht file or user code.

In mht file:

   AD2_INTERFACE, AD2_Interface, AD2

Wherein the format for the definition is:

   AD2_INTERFACE, Object Name, AD2-Prefix

In user code:

   $AD2 = new AD2(AD2);

Wherein the format for the definition is:

   $AD2 = new AD2(AD2-Prefix);

Partition Configuration

See AD2_Partition

Zone Configuration

See AD2_Item

NOTES

Hardwired zones are difficult for us to deal with. Due to their nature, the AD2 board only receives Alphanumberic fault messages for these zones and never receives ready messages. Due to the way these Alphanumeric fault messages cycle around, the resetting of a hardwired zone from fault to ready may take a bit longer then expected. Additionally, in certain circumstances a hardwired zone will be reset from fault to ready improperly, it will be tripped back to fault a few seconds later. The only way to avoid these annoyances is to map your hardwired zones to fake relays. See the discussion of Relay Mappings in the AD2_Item documentation below.

TODO

- Add support for control of emulated zones on the AD2 device. Would allow MisterHouse to "communicate" with the alarm panel. Perhaps to trigger an alarm if certain conditions are met.

INHERITS

Generic_Item

METHODS

new()

Instantiates a new object.

restore_string()

This is called by mh on exit to save the cached states of the zones to persistant data.

NOTE: It would probably be easier/better to simply have the child objects each store their own state using the built-in MH methods. However, this would require users to define the child objects and would break the original code design.

get_object_by_instance($instance)

Takes a scalar instance name, AD2-Prefix, and returns the object associated with that name.

read_parms()

Causes MH to read the ini parameters and load them into the local configuration hash. This is necessary in order to join together ini and mht defined features.

init()

Used to initialize the serial port.

serial_startup()

Called by the MH main script as a result of defining a serial port.

server_startup()

Called by the MH main script as a result of defining a server port.

check_for_data()

Called at the start of every loop. This checks either the serial or server port for new data. If data is found, the data is broken down into individual messages and sent to GetStatusType to be parsed. The message is then compared to the previous data received if this is a duplicate message it is logged and ignored. If this is a new message it is sent to CheckCmd.

CheckCmd()

This routine takes the parsed message and performs the necessary actions that result.

GetStatusType()

This routine parses a message passed in the form of a string and returns a hash filled with the resulting message data.

ChangeZoneState($zone, $new_status, $log)

This routine changes the defined zone to the state that was passed. Will also update any child objects that exist as well as other necessary routines

$zone = Zone number to start at

$new_status = The status to which the zones should be changed too.

$log = If true will log its actions

zone_bypassed($zone, $bypass)

Sets or gets the bypass state of a zone. The state of mapped zones is always accurately reported. Non-mapped hardwired zones have no state when they are bypassed, we cannot determine their fault status. As such, the state of non-mapped hardwired zones will be "bypass" when they are bypassed.

The state of child objects is similar with the exception that the state of mapped zones will be appended with " - bypass" if they are currently bypassed.

This routine will always accurately return the bypass state of a zone. The funtion will return true if bypassed or false if not. To set the bypass state simply pass it as $bypass.

DefineCmdMsg()

Creates the Hash of available commands.

This undoubtedly still needs work.

debug_log()

Used to log messages to the specific AD2 log file.

This can likely be eliminated once testing is complete and replaced with the new debug routine in Generic_Item.

is_zone_mapped($zone)

Takes a zone number as a parameter and returns true if it is mapped to a relay, wireless, or expander.

cmd()

Older method used to send commands to the Interface.

Has potential security flaws. It certainly allows for a brute force attack to identify the Master Code. Potentially other flaws too.

set()

Used to send commands to the interface.

set_receive()

Used internally to update the state of the object inside MisterHouse.

status_zone($zone)

Takes a zone number and returns its status.

If an object exists for this zone you can also use:

$object->state;

zone_now($zone)

Takes a zone number and returns its status if the zone status was set on this loop.

If an object exists for this zone you can also use:

$object->state_now;

zone_name($zone)

Takes a zone number and returns its name.

The name is not used very much, likely was more necessary before zones were made into individual objects.

zone_partition($zone)

Takes a zone number and returns the partition that it is a member of.

partition_now($part)

Takes a partition number and returns its status if its status was set on this loop.

If an object exists for this partition you can also use:

$object->state_now;

partition_msg($part)

Takes a partition number and returns the last alphanumeric message that was sent by this partition.

partition_name($part)

Takes a partition number and returns its name.

The name is not used very much, likely was more necessary before partitions were made into individual objects.

status_partition($part)

Takes a partition number and returns its status.

If an object exists for this partition you can also use:

$object->state;

cmd_list()

Returns the list of available commands.

register()

Used to associate child objects with the interface.

get_child_object_name($zone)

Takes a zone number and returns the name of the child object associated with it.

AD2_Item

SYNOPSIS

User code:

    $front_door = new AD2_Item('door','AD2', 5, 1);
    $upstairs_motion = new AD2_Item('motion','AD2', 6, 1);
    $generic_zone = new AD2_Item('','AD2', 7, 1);

See new() for a more detailed description of the arguments.

In mht file:

        AD2_DOOR_ITEM, back_door, AD2, 4, 1, HARDWIRED
        AD2_DOOR_ITEM, front_door, AD2, 5, 1, EXP=0101
        AD2_MOTION_ITEM, upstairs_motion, AD2, 6, 1, REL=1301
        AD2_GENERIC_ITEM, generic_zone, AD2, 7, 1, RFX=0014936.4.k

Wherein the format for the definition is:

   AD2_DOOR_ITEM, Object Name, AD2-Prefix, Zone Number, Partition Number, Expander/Relay/Wireless Address

The type of items can be DOOR (open/close) MOTION (motion/still) and GENERIC (fault/ready).

HARDWIRED/EXPANDER/RELAY/WIRELESS ADDRESS

The last item is the Expander, Relay, or Wireless address if it applicable. For hardwired zones this last item should be HARDWIRED.

EXPANSION BOARDS

For zones wired to an expansion board, the prefix EXP= should be used. The address is the expansion board id (2 digits, 0 padded if required) concatenated with the expansion input number (2 digits, 0 padded if required) such as 0101 or 1304.

RELAY MAPPINGS

The state of hardwired zones can only be obtained from the alphanumeric messages that scroll by on the panel screens. If multiple zones are tripped, it may take a few seconds for the status of a hardwired zone to be updated. Moreover, the status of a hardwired zone cannot be obtained while the system is armed because no alphanumeric messages are displayed while armed.

To overcome these limitations, depending on your alarm panel model, you can map a hardwired zone to a relay. In essence, if a zone that is mapped to a relay the alarm panel will close the relay whenever the zone is faulted and open the relay when the zone is ready. Luckily, this relay can be a virtual device. The messages sent by the alarm panel to open/close a virtual relay are sent immediatly and are not affected by the state of the alarm.

To setup relay mappings, consult your alarm panel's instruction manual for programing a relay board and mapping zones to it. Some alarm panels have limited capabilities when it comes to relays. Specifically, you want to refer to section of your manual that discusses *80 programming.

For hardwired zones mapped to a relay board, the prefix REL= should be used. The address is the relay board id (2 digits, 0 padded if required) concatenated with the relay output number (2 digits, 0 padded if required) such as 0101 or 1304.

WIRELESS DEVICES

For wireless zones, the prefix RFX= should be used. The address is the wireless ID (7 digits) followed by a period, the loop number, followed by a period, and the wireless device type. All of this without any spaces. The loop number need only be specified if it is not 1. Generally, the loop number for most devices is 1. Similarly, the device type need only be specified if the wireless device is a keypad, in which case the type is the letter k. The following are valid wireless addresses:

        RFX=0014936.4.k
        RFX=0101538
        RFX=5848878.1.k

DESCRIPTION

Provides support for creating MH-Style child objects for each zone. These allow zones to behave like Generic_Items. For example, Generic_Item subroutines such as tie_event and get_idle_time can be used with these devices.

To use these, you must first create the appropriate AD2 Interface object.

INHERITS

Generic_Item

METHODS

new($type,$interface,$zone,$partition,$expander,$relay,$wireless)

Instantiates a new object.

$type = May be either 'door', 'motion', or ''. This just defines the states for the object. door = open/closed, motion = motion/still, '' = fault/ready

$interface = The AD2-Prefix of the interface that this zone is found on

$zone = The zone number of this zone

$partition = The partition number of this zone, usually 1

Zone Mapping

$expander = If not null, the expander address that the zone is mapped to.

$relay = If not null, the relay address that the zone is mapped to.

$wireless = If not null, the wireless address that the zone is mapped to in the form of [RF_ID].[LOOP].[TYPE].

The wireless address is the wireless ID (7 digits) followed by a period, the loop number, followed by a period, and the wireless device type. All of this without any spaces. The loop number need only be specified if it is not 1. Generally, the loop number for most devices is 1. Similarly, the device type need only be specified if the wireless device is a keypad, in which case the type is the letter k.

set()

Sets the object's state.

get_child_item_type()

Returns the item type, either 'motion' or 'door'.

Extraneous Methods

The following methods seem to me to be unnecessary in light of the functions available in Generic_Item.

get_last_close_time()

Returns the time the object was closed.

get_last_open_time()

Returns the time the object was opened.

get_last_still_time()

Returns the time the object was still.

get_last_motion_time()

Returns the time the object was motion.

AD2_Partition

SYNOPSIS

User code:

    $partition_1 = new AD2_Partition('AD2', 1, 31);

See new() for a more detailed description of the arguments.

In mht file:

        AD2_PARTITION, partition_1, AD2, 1, 31

Wherein the format is

        AD2_PARTITION, Object Name, AD2-Prefix, Partition Number, Address

The address is the address of a panel that is assigned to this partition. Multiple panels may be assigned to a partition, only one address is required. If your system is a non-addressable system, 31 should be used as the address.

DESCRIPTION

Provides support for creating MH-Style child objects for each partition.

For an explanation of what a partition is, please see the Description section of AD2.

The Partition is used primarily as a stand in for the alarm panel. The Partition object is used to arm/disarm the panel as well as to check on the agregate state of all of the zones that are within this partition.

The partition object can be set to:

      Disarm            - Disarm the system
      ArmAway           - Arm the entire system with an exit delay
      ArmStay           - Arm the perimeter with an exit delay
      ArmAwayMax        - Arm entire system with NO delay
      Test              - Places the system into the test mode
      Bypass            - Bypass or exclude specific zones from arming
      ArmStayInstant    - Arm the perimeter with NO delay
      Code              - Used to program alarm including codes
      Chime             - Turns the the audible fault notification on/off
      ToggleVoice       - Turns on/off the audible voice if available

All of the above commands require an alarm code except for the ToggleVoice command.

Use of Alarm Code

You have two options for entering your alarm code. First, you can preprogram your alarm code into you ini file using the following parameter:

        AD2_user_master_code=1234

Where, AD2 is your AD2-Prefix. If you elect to use this system, the above commands can be run by anyone with access to your MisterHouse installation. You will not be required to enter your alarm code again. This includes the ability to disarm the system. Obviously, only elect this design if you are comfortable with the security of your MisterHouse installation.

Note: In the future, it may be possible to use a secondary code that allows for the arming of the system, but not disarming. This would slightly decrease the security risk, but would still create a "harassment" risk in that if your MisterHouse installation is hacked, your alarm could easily be triggered.

Second if you do not place your alarm code in your ini file, you must then set your alarm code before setting any of the above states. For example:

        $partition_1->set("1234");
        $partition_1->set("Disarm");

These commands must be sent within 4-5 seconds of each other.

INHERITS

Generic_Item

METHODS

new($interface, $partition, $address)

Instantiates a new object.

$interface = The AD2-Prefix of the interface that this zone is found on

$partition = The partition number, usually 1

$address = The address of a panel that is assigned to this partition. For non-addressable systems this should be set to 31.

While there may be multiple panels on a partition, and as a result multiple addresses, only ONE address is needed in $address.

AD2_Output

SYNOPSIS

User code:

    $desk_lamp = new AD2_Output('AD2', 01);

See new() for a more detailed description of the arguments.

In mht file:

        AD2_OUTPUT, desk_lamp, AD2, 01

Wherein the format for the definition is:

   AD2_OUTPUT, Object Name, AD2-Prefix, Output Number

DESCRIPTION

Provides support for creating MH-Style child objects for each output device. These allow output devices to behave like Generic_Items. For example, Generic_Item subroutines such as tie_event and get_idle_time can be used with these devices.

To use these, you must first create the appropriate AD2 Interface object.

An output device is generally a relay, but it could be an X10 device, connected to the alarm panel. The alarm panel can control the state of this relay. See the *80 programming menu for your alarm panel for more details.

Note: These relays are not to be confused with the emulated relays that are used to track the state of hardwired zones in some instances.

Alarm Code

See the note above above in the partition description regarding the use of the alarm code.

If you elect not to store you alarm code in you ini file, you will need to set the code first and then call start/stop. For Example:

   $desk_lamp->set("1234");
   $desk_lamp->set("Start");

INHERITS

Generic_Item

METHODS

new($interface,$output)
set()

Sets the object's state.

INI PARAMETERS

NOTES

AUTHOR

Kirk Friedenberger <kfriedenberger@gmail.com>, Wayne Gatlin <wayne@razorcla.ws> H Plato <hplato@gmail.com>, Kevin Robert Keegan

SEE ALSO

LICENSE

This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version.

This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details.

You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.

 AD2.pm