Source code for pyad2usb.messages
"""
Message representations received from the panel through the AD2USB.
"""
import re
[docs]class Message(object):
"""
Represents a message from the alarm panel.
"""
def __init__(self, data=None):
"""
Constructor
"""
self.ready = False
self.armed_away = False
self.armed_home = False
self.backlight_on = False
self.programming_mode = False
self.beeps = -1
self.zone_bypassed = False
self.ac_power = False
self.chime_on = False
self.alarm_event_occurred = False
self.alarm_sounding = False
self.battery_low = False
self.entry_delay_off = False
self.fire_alarm = False
self.check_zone = False
self.perimeter_only = False
self.numeric_code = ""
self.text = ""
self.cursor_location = -1
self.data = ""
self.mask = ""
self.bitfield = ""
self.panel_data = ""
self._regex = re.compile('("(?:[^"]|"")*"|[^,]*),("(?:[^"]|"")*"|[^,]*),("(?:[^"]|"")*"|[^,]*),("(?:[^"]|"")*"|[^,]*)')
if data is not None:
self._parse_message(data)
def _parse_message(self, data):
"""
Parse the message from the device.
"""
m = self._regex.match(data)
if m is None:
raise util.InvalidMessageError('Received invalid message: {0}'.format(data))
self.bitfield, self.numeric_code, self.panel_data, alpha = m.group(1, 2, 3, 4)
self.mask = int(self.panel_data[3:3+8], 16)
self.data = data
self.ready = not self.bitfield[1:2] == "0"
self.armed_away = not self.bitfield[2:3] == "0"
self.armed_home = not self.bitfield[3:4] == "0"
self.backlight_on = not self.bitfield[4:5] == "0"
self.programming_mode = not self.bitfield[5:6] == "0"
self.beeps = int(self.bitfield[6:7], 16)
self.zone_bypassed = not self.bitfield[7:8] == "0"
self.ac_power = not self.bitfield[8:9] == "0"
self.chime_on = not self.bitfield[9:10] == "0"
self.alarm_event_occurred = not self.bitfield[10:11] == "0"
self.alarm_sounding = not self.bitfield[11:12] == "0"
self.battery_low = not self.bitfield[12:13] == "0"
self.entry_delay_off = not self.bitfield[13:14] == "0"
self.fire_alarm = not self.bitfield[14:15] == "0"
self.check_zone = not self.bitfield[15:16] == "0"
self.perimeter_only = not self.bitfield[16:17] == "0"
# bits 17-20 unused.
self.text = alpha.strip('"')
if int(self.panel_data[19:21], 16) & 0x01 > 0:
self.cursor_location = int(self.bitfield[21:23], 16) # Alpha character index that the cursor is on.
def __str__(self):
"""
String conversion operator.
"""
return 'msg > {0:0<9} [{1}{2}{3}] -- ({4}) {5}'.format(hex(self.mask), 1 if self.ready else 0, 1 if self.armed_away else 0, 1 if self.armed_home else 0, self.numeric_code, self.text)
[docs]class ExpanderMessage(object):
"""
Represents a message from a zone or relay expansion module.
"""
ZONE = 0
RELAY = 1
def __init__(self, data=None):
"""
Constructor
"""
self.type = None
self.address = None
self.channel = None
self.value = None
self.raw = None
if data is not None:
self._parse_message(data)
def __str__(self):
"""
String conversion operator.
"""
expander_type = 'UNKWN'
if self.type == ExpanderMessage.ZONE:
expander_type = 'ZONE'
elif self.type == ExpanderMessage.RELAY:
expander_type = 'RELAY'
return 'exp > [{0: <5}] {1}/{2} -- {3}'.format(expander_type, self.address, self.channel, self.value)
def _parse_message(self, data):
"""
Parse the raw message from the device.
"""
header, values = data.split(':')
address, channel, value = values.split(',')
self.raw = data
self.address = address
self.channel = channel
self.value = value
if header == '!EXP':
self.type = ExpanderMessage.ZONE
elif header == '!REL':
self.type = ExpanderMessage.RELAY
[docs]class RFMessage(object):
"""
Represents a message from an RF receiver.
"""
def __init__(self, data=None):
"""
Constructor
"""
self.raw = None
self.serial_number = None
self.value = None
if data is not None:
self._parse_message(data)
def __str__(self):
"""
String conversion operator.
"""
return 'rf > {0}: {1}'.format(self.serial_number, self.value)
def _parse_message(self, data):
"""
Parses the raw message from the device.
"""
self.raw = data
_, values = data.split(':')
self.serial_number, self.value = values.split(',')
[docs]class LRRMessage(object):
"""
Represent a message from a Long Range Radio.
"""
def __init__(self, data=None):
"""
Constructor
"""
self.raw = None
self._event_data = None
self._partition = None
self._event_type = None
if data is not None:
self._parse_message(data)
def __str__(self):
"""
String conversion operator.
"""
return 'lrr > {0} @ {1} -- {2}'.format()
def _parse_message(self, data):
"""
Parses the raw message from the device.
"""
self.raw = data
_, values = data.split(':')
self._event_data, self._partition, self._event_type = values.split(',')