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