Browse Source

Reworked Message fields.

pyserial_fix
Scott Petersen 11 years ago
parent
commit
247bc829b8
1 changed files with 110 additions and 136 deletions
  1. +110
    -136
      pyad2usb/ad2usb.py

+ 110
- 136
pyad2usb/ad2usb.py View File

@@ -231,24 +231,23 @@ class AD2USB(object):
elif header == '!RFX':
msg = RFMessage(data)

if msg:
self.on_message(msg)
return msg

def _update_internal_states(self, message):
if message.ac != self._power_status:
self._power_status, old_status = message.ac, self._power_status
if message.ac_power != self._power_status:
self._power_status, old_status = message.ac_power, self._power_status

if old_status is not None:
self.on_power_changed(self._power_status)

if message.alarm_bell != self._alarm_status:
self._alarm_status, old_status = message.alarm_bell, self._alarm_status
if message.alarm_sounding != self._alarm_status:
self._alarm_status, old_status = message.alarm_sounding, self._alarm_status

if old_status is not None:
self.on_alarm(self._alarm_status)

if message.bypass != self._bypass_status:
self._bypass_status, old_status = message.bypass, self._bypass_status
if message.zone_bypassed != self._bypass_status:
self._bypass_status, old_status = message.zone_bypassed, self._bypass_status

if old_status is not None:
self.on_bypass(self._bypass_status)
@@ -269,12 +268,12 @@ class AD2USB(object):
"""
Internal handler for reading from the device.
"""
self.on_read(args)

msg = self._handle_message(args)
if msg:
self.on_message(msg)

self.on_read(args)

def _on_write(self, sender, args):
"""
Internal handler for writing to the device.
@@ -290,28 +289,24 @@ class Message(object):
"""
Constructor
"""
self._ignore_packet = False
self._ready = False
self._armed_away = False
self._armed_home = False
self._backlight = False
self._backlight_on = False
self._programming_mode = False
self._beeps = -1
self._bypass = False
self._ac = False
self._chime_mode = False
self._zone_bypassed = False
self._ac_power = False
self._chime_on = False
self._alarm_event_occurred = False
self._alarm_bell = False
self._numeric = ""
self._alarm_sounding = False
self._numeric_code = ""
self._text = ""
self._cursor = -1
self._raw = ""
self._cursor_location = -1
self._data = ""
self._mask = ""

self._msg_bitfields = ""
self._msg_zone = ""
self._msg_binary = ""
self._msg_alpha = ""
self._bitfield = ""
self._panel_data = ""

self._regex = re.compile('("(?:[^"]|"")*"|[^,]*),("(?:[^"]|"")*"|[^,]*),("(?:[^"]|"")*"|[^,]*),("(?:[^"]|"")*"|[^,]*)')

@@ -320,86 +315,38 @@ class Message(object):

def _parse_message(self, data):
"""
Parse the raw message from the device.
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._msg_bitfields, self._msg_zone, self._msg_binary, self._msg_alpha = m.group(1, 2, 3, 4)
self.mask = int(self._msg_binary[3:3+8], 16)

self.raw = data
self.ready = not self._msg_bitfields[1:2] == "0"
self.armed_away = not self._msg_bitfields[2:3] == "0"
self.armed_home = not self._msg_bitfields[3:4] == "0"
self.backlight = not self._msg_bitfields[4:5] == "0"
self.programming_mode = not self._msg_bitfields[5:6] == "0"
self.beeps = int(self._msg_bitfields[6:7], 16)
self.bypass = not self._msg_bitfields[7:8] == "0"
self.ac = not self._msg_bitfields[8:9] == "0"
self.chime_mode = not self._msg_bitfields[9:10] == "0"
self.alarm_event_occurred = not self._msg_bitfields[10:11] == "0"
self.alarm_bell = not self._msg_bitfields[11:12] == "0"
self.numeric = self._msg_zone
self.text = self._msg_alpha.strip('"')

if int(self._msg_binary[19:21], 16) & 0x01 > 0:
self.cursor = int(self._msg_bitfields[21:23], 16)

#print "Message:\r\n" \
# "\tmask: {0}\r\n" \
# "\tready: {1}\r\n" \
# "\tarmed_away: {2}\r\n" \
# "\tarmed_home: {3}\r\n" \
# "\tbacklight: {4}\r\n" \
# "\tprogramming_mode: {5}\r\n" \
# "\tbeeps: {6}\r\n" \
# "\tbypass: {7}\r\n" \
# "\tac: {8}\r\n" \
# "\tchime_mode: {9}\r\n" \
# "\talarm_event_occurred: {10}\r\n" \
# "\talarm_bell: {11}\r\n" \
# "\tcursor: {12}\r\n" \
# "\tnumeric: {13}\r\n" \
# "\ttext: {14}\r\n".format(
# self.mask,
# self.ready,
# self.armed_away,
# self.armed_home,
# self.backlight,
# self.programming_mode,
# self.beeps,
# self.bypass,
# self.ac,
# self.chime_mode,
# self.alarm_event_occurred,
# self.alarm_bell,
# self.cursor,
# self.numeric,
# self.text
# )
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._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, self.text)

@property
def ignore_packet(self):
"""
Indicates whether or not this message should be ignored.
"""
return self._ignore_packet

@ignore_packet.setter
def ignore_packet(self, value):
"""
Sets the value indicating whether or not this packet should be ignored.
"""
self._ignore_packet = value
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)

@property
def ready(self):
@@ -444,18 +391,18 @@ class Message(object):
self._armed_home = value

@property
def backlight(self):
def backlight_on(self):
"""
Indicates whether or not the panel backlight is on.
"""
return self._backlight
return self._backlight_on

@backlight.setter
def backlight(self, value):
@backlight_on.setter
def backlight_on(self, value):
"""
Sets the value indicating whether or not the panel backlight is on.
"""
self._backlight = value
self._backlight_on = value

@property
def programming_mode(self):
@@ -486,46 +433,46 @@ class Message(object):
self._beeps = value

@property
def bypass(self):
def zone_bypassed(self):
"""
Indicates whether or not zones have been bypassed.
"""
return self._bypass
return self._zone_bypassed

@bypass.setter
def bypass(self, value):
@zone_bypassed.setter
def zone_bypassed(self, value):
"""
Sets the value indicating whether or not zones have been bypassed.
"""
self._bypass = value
self._zone_bypassed = value

@property
def ac(self):
def ac_power(self):
"""
Indicates whether or not the system is on AC power.
"""
return self._ac
return self._ac_power

@ac.setter
def ac(self, value):
@ac_power.setter
def ac_power(self, value):
"""
Sets the value indicating whether or not the system is on AC power.
"""
self._ac = value
self._ac_power = value

@property
def chime_mode(self):
def chime_on(self):
"""
Indicates whether or not panel chimes are enabled.
"""
return self._chime_mode
return self._chime_on

@chime_mode.setter
def chime_mode(self, value):
@chime_on.setter
def chime_on(self, value):
"""
Sets the value indicating whether or not the panel chimes are enabled.
"""
self._chime_mode = value
self._chime_on = value

@property
def alarm_event_occurred(self):
@@ -542,32 +489,32 @@ class Message(object):
self._alarm_event_occurred = value

@property
def alarm_bell(self):
def alarm_sounding(self):
"""
Indicates whether or not an alarm is currently sounding.
"""
return self._alarm_bell
return self._alarm_sounding

@alarm_bell.setter
def alarm_bell(self, value):
@alarm_sounding.setter
def alarm_sounding(self, value):
"""
Sets the value indicating whether or not an alarm is currently sounding.
"""
self._alarm_bell = value
self._alarm_sounding = value

@property
def numeric(self):
def numeric_code(self):
"""
Numeric indicator of associated with message. For example: If zone #3 is faulted, this value is 003.
"""
return self._numeric
return self._numeric_code

@numeric.setter
def numeric(self, value):
@numeric_code.setter
def numeric_code(self, value):
"""
Sets the numeric indicator associated with this message.
"""
self._numeric = value
self._numeric_code = value

@property
def text(self):
@@ -584,32 +531,32 @@ class Message(object):
self._text = value

@property
def cursor(self):
def cursor_location(self):
"""
Indicates which text position has the cursor underneath it.
"""
return self._cursor
return self._cursor_location

@cursor.setter
def cursor(self, value):
@cursor_location.setter
def cursor_location(self, value):
"""
Sets the value indicating which text position has the cursor underneath it.
"""
self._cursor = value
self._cursor_location = value

@property
def raw(self):
def data(self):
"""
Raw representation of the message data from the panel.
Raw representation of the message from the panel.
"""
return self._raw
return self._data

@raw.setter
def raw(self, value):
@data.setter
def data(self, value):
"""
Sets the raw representation of the message data from the panel.
Sets the raw representation of the message from the panel.
"""
self._raw = value
self._data = value

@property
def mask(self):
@@ -625,11 +572,38 @@ class Message(object):
"""
self._mask = value

@property
def bitfield(self):
"""
The bit field associated with this message.
"""
return self._bitfield

@bitfield.setter
def bitfield(self, value):
"""
Sets the bit field associated with this message.
"""
self._bitfield = value

@property
def panel_data(self):
"""
The binary field associated with this message.
"""
return self._panel_data

@panel_data.setter
def panel_data(self, value):
"""
Sets the binary field associated with this message.
"""
self._panel_data = value

class ExpanderMessage(object):
"""
Represents a message from a zone or relay expansion module.
"""

ZONE = 0
RELAY = 1



Loading…
Cancel
Save