@@ -65,9 +65,9 @@ class Overseer(object): | |||
device = cls.__devices[0] | |||
vendor, product, sernum, ifcount, description = device | |||
device = devices.USBDevice(serial=sernum, description=description) | |||
device = devices.USBDevice((sernum, ifcount - 1)) | |||
return AD2USB(device) | |||
return AD2(device) | |||
def __init__(self, attached_event=None, detached_event=None): | |||
""" | |||
@@ -169,7 +169,7 @@ class Overseer(object): | |||
time.sleep(0.25) | |||
class AD2USB(object): | |||
class AD2(object): | |||
""" | |||
High-level wrapper around AD2USB/AD2SERIAL devices. | |||
""" | |||
@@ -329,6 +329,7 @@ class AD2USB(object): | |||
:param simulate_wire_problem: Whether or not to simulate a wire fault. | |||
:type simulate_wire_problem: bool | |||
""" | |||
# Allow ourselves to also be passed an address/channel combination | |||
# for zone expanders. | |||
# | |||
@@ -418,7 +419,6 @@ class AD2USB(object): | |||
""" | |||
msg = messages.LRRMessage(data) | |||
args = (msg.partition, msg.event_type, msg.event_data) | |||
if msg.event_type == 'ALARM_PANIC': | |||
self._panic_status = True | |||
self.on_panic(True) | |||
@@ -500,14 +500,14 @@ class AD2USB(object): | |||
if message.battery_low == self._battery_status[0]: | |||
self._battery_status = (self._battery_status[0], time.time()) | |||
else: | |||
if message.battery_low == True or time.time() > self._battery_status[1] + AD2USB.BATTERY_TIMEOUT: | |||
if message.battery_low == True or time.time() > self._battery_status[1] + AD2.BATTERY_TIMEOUT: | |||
self._battery_status = (message.battery_low, time.time()) | |||
self.on_low_battery(self._battery_status) | |||
if message.fire_alarm == self._fire_status[0]: | |||
self._fire_status = (self._fire_status[0], time.time()) | |||
else: | |||
if message.fire_alarm == True or time.time() > self._fire_status[1] + AD2USB.FIRE_TIMEOUT: | |||
if message.fire_alarm == True or time.time() > self._fire_status[1] + AD2.FIRE_TIMEOUT: | |||
self._fire_status = (message.fire_alarm, time.time()) | |||
self.on_fire(self._fire_status) | |||
@@ -166,17 +166,17 @@ class USBDevice(Device): | |||
:returns: the interface used to connect to the device. | |||
""" | |||
return (self._device_number, self._endpoint) | |||
return (self._serial_number, self._endpoint) | |||
@interface.setter | |||
def interface(self, value): | |||
""" | |||
Sets the interface used to connect to the device. | |||
:param value: Tuple containing the device number and endpoint number to use. | |||
:param value: Tuple containing the serial number and endpoint number to use. | |||
:type value: tuple | |||
""" | |||
self._device_number = value[0] | |||
self._serial_number = value[0] | |||
self._endpoint = value[1] | |||
@property | |||
@@ -218,7 +218,7 @@ class USBDevice(Device): | |||
""" | |||
self._description = value | |||
def __init__(self, interface=(0, 0)): | |||
def __init__(self, interface=(None, 0)): | |||
""" | |||
Constructor | |||
@@ -228,11 +228,11 @@ class USBDevice(Device): | |||
Device.__init__(self) | |||
self._device = Ftdi() | |||
self._device_number = interface[0] | |||
self._serial_number = interface[0] | |||
self._endpoint = interface[1] | |||
self._vendor_id = USBDevice.FTDI_VENDOR_ID | |||
self._product_id = USBDevice.FTDI_PRODUCT_ID | |||
self._serial_number = None | |||
self._device_number = None | |||
self._description = None | |||
def open(self, baudrate=BAUDRATE, no_reader_thread=False): | |||
@@ -369,7 +369,8 @@ class USBDevice(Device): | |||
self._buffer = self._buffer[:-1] | |||
except (usb.core.USBError, FtdiError), err: | |||
timer.cancel() | |||
if timer: | |||
timer.cancel() | |||
raise util.CommError('Error reading from device: {0}'.format(str(err)), err) | |||
@@ -587,7 +588,8 @@ class SerialDevice(Device): | |||
self._buffer = self._buffer[:-1] | |||
except (OSError, serial.SerialException), err: | |||
timer.cancel() | |||
if timer: | |||
timer.cancel() | |||
raise util.CommError('Error reading from device: {0}'.format(str(err)), err) | |||
@@ -862,7 +864,8 @@ class SocketDevice(Device): | |||
self._buffer = self._buffer[:-1] | |||
except socket.error, err: | |||
timer.cancel() | |||
if timer: | |||
timer.cancel() | |||
raise util.CommError('Error reading from device: {0}'.format(str(err)), err) | |||
@@ -5,6 +5,7 @@ Message representations received from the panel through the AD2USB. | |||
""" | |||
import re | |||
from . import util | |||
class BaseMessage(object): | |||
""" | |||
@@ -145,13 +146,17 @@ class ExpanderMessage(BaseMessage): | |||
:param data: The message data | |||
:type data: str | |||
""" | |||
header, values = data.split(':') | |||
address, channel, value = values.split(',') | |||
try: | |||
header, values = data.split(':') | |||
address, channel, value = values.split(',') | |||
self.raw = data | |||
self.address = int(address) | |||
self.channel = int(channel) | |||
self.value = int(value) | |||
self.raw = data | |||
self.address = int(address) | |||
self.channel = int(channel) | |||
self.value = int(value) | |||
except ValueError: | |||
raise util.InvalidMessageError('Received invalid message: {0}'.format(data)) | |||
if header == '!EXP': | |||
self.type = ExpanderMessage.ZONE | |||
@@ -193,22 +198,27 @@ class RFMessage(BaseMessage): | |||
:param data: The message data. | |||
:type data: str | |||
""" | |||
self.raw = data | |||
try: | |||
self.raw = data | |||
_, values = data.split(':') | |||
self.serial_number, self.value = values.split(',') | |||
self.value = int(self.value, 16) | |||
_, values = data.split(':') | |||
self.serial_number, self.value = values.split(',') | |||
self.value = int(self.value, 16) | |||
is_bit_set = lambda b: self.value & (1 << b) > 0 | |||
is_bit_set = lambda b: self.value & (1 << b) > 0 | |||
# Bit 1 = unknown | |||
self.battery = is_bit_set(2) | |||
self.supervision = is_bit_set(3) | |||
# Bit 8 = unknown | |||
self.loop[0] = is_bit_set(5) | |||
self.loop[1] = is_bit_set(6) | |||
self.loop[2] = is_bit_set(7) | |||
self.loop[3] = is_bit_set(8) | |||
except ValueError: | |||
raise util.InvalidMessageError('Received invalid message: {0}'.format(data)) | |||
# Bit 1 = unknown | |||
self.battery = is_bit_set(2) | |||
self.supervision = is_bit_set(3) | |||
# Bit 8 = unknown | |||
self.loop[0] = is_bit_set(5) | |||
self.loop[1] = is_bit_set(6) | |||
self.loop[2] = is_bit_set(7) | |||
self.loop[3] = is_bit_set(8) | |||
class LRRMessage(BaseMessage): | |||
""" | |||
@@ -243,7 +253,11 @@ class LRRMessage(BaseMessage): | |||
:param data: The message data. | |||
:type data: str | |||
""" | |||
self.raw = data | |||
try: | |||
self.raw = data | |||
_, values = data.split(':') | |||
self.event_data, self.partition, self.event_type = values.split(',') | |||
_, values = data.split(':') | |||
self.event_data, self.partition, self.event_type = values.split(',') | |||
except ValueError: | |||
raise util.InvalidMessageError('Received invalid message: {0}'.format(data)) |