Browse Source

Simplification and compliance (mostly) with pep8.

pyserial_fix
Scott 11 years ago
parent
commit
f1a71def32
10 changed files with 39 additions and 18 deletions
  1. +7
    -8
      alarmdecoder/decoder.py
  2. +12
    -7
      alarmdecoder/devices.py
  3. +1
    -0
      alarmdecoder/event/event.py
  4. +5
    -1
      alarmdecoder/messages.py
  5. +1
    -0
      alarmdecoder/tests/test_ad2.py
  6. +2
    -0
      alarmdecoder/tests/test_devices.py
  7. +1
    -0
      alarmdecoder/tests/test_messages.py
  8. +2
    -1
      alarmdecoder/tests/test_zonetracking.py
  9. +5
    -0
      alarmdecoder/util.py
  10. +3
    -1
      alarmdecoder/zonetracking.py

+ 7
- 8
alarmdecoder/decoder.py View File

@@ -12,6 +12,7 @@ from .util import CommError, NoDeviceError
from .messages import Message, ExpanderMessage, RFMessage, LRRMessage from .messages import Message, ExpanderMessage, RFMessage, LRRMessage
from .zonetracking import Zonetracker from .zonetracking import Zonetracker



class AlarmDecoder(object): class AlarmDecoder(object):
""" """
High-level wrapper around Alarm Decoder (AD2) devices. High-level wrapper around Alarm Decoder (AD2) devices.
@@ -237,8 +238,8 @@ class AlarmDecoder(object):
raise InvalidMessageError() raise InvalidMessageError()


msg = None msg = None

header = data[0:4] header = data[0:4]

if header[0] != '!' or header == '!KPE': if header[0] != '!' or header == '!KPE':
msg = Message(data) msg = Message(data)


@@ -295,7 +296,7 @@ class AlarmDecoder(object):
self.on_panic(status=True) self.on_panic(status=True)


elif msg.event_type == 'CANCEL': elif msg.event_type == 'CANCEL':
if self._panic_status == True:
if self._panic_status is True:
self._panic_status = False self._panic_status = False
self.on_panic(status=False) self.on_panic(status=False)


@@ -321,11 +322,9 @@ class AlarmDecoder(object):
elif k == 'MASK': elif k == 'MASK':
self.address_mask = int(v, 16) self.address_mask = int(v, 16)
elif k == 'EXP': elif k == 'EXP':
for z in range(5):
self.emulate_zone[z] = (v[z] == 'Y')
self.emulate_zone = [v[z] == 'Y' for z in range(5)]
elif k == 'REL': elif k == 'REL':
for r in range(4):
self.emulate_relay[r] = (v[r] == 'Y')
self.emulate_relay = [v[r] == 'Y' for r in range(4)]
elif k == 'LRR': elif k == 'LRR':
self.emulate_lrr = (v == 'Y') self.emulate_lrr = (v == 'Y')
elif k == 'DEDUPLICATE': elif k == 'DEDUPLICATE':
@@ -371,14 +370,14 @@ class AlarmDecoder(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] + AlarmDecoder.BATTERY_TIMEOUT:
if message.battery_low is True or time.time() > self._battery_status[1] + AlarmDecoder.BATTERY_TIMEOUT:
self._battery_status = (message.battery_low, time.time()) self._battery_status = (message.battery_low, time.time())
self.on_low_battery(status=self._battery_status) self.on_low_battery(status=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] + AlarmDecoder.FIRE_TIMEOUT:
if message.fire_alarm is True or time.time() > self._fire_status[1] + AlarmDecoder.FIRE_TIMEOUT:
self._fire_status = (message.fire_alarm, time.time()) self._fire_status = (message.fire_alarm, time.time())
self.on_fire(status=self._fire_status) self.on_fire(status=self._fire_status)




+ 12
- 7
alarmdecoder/devices.py View File

@@ -4,10 +4,12 @@ Contains different types of devices belonging to the Alarm Decoder (AD2) family.
.. moduleauthor:: Scott Petersen <scott@nutech.com> .. moduleauthor:: Scott Petersen <scott@nutech.com>
""" """


import usb.core, usb.util
import usb.core
import usb.util
import time import time
import threading import threading
import serial, serial.tools.list_ports
import serial
import serial.tools.list_ports
import socket import socket


from OpenSSL import SSL, crypto from OpenSSL import SSL, crypto
@@ -16,6 +18,7 @@ from pyftdi.pyftdi.usbtools import *
from .util import CommError, TimeoutError, NoDeviceError from .util import CommError, TimeoutError, NoDeviceError
from .event import event from .event import event



class Device(object): class Device(object):
""" """
Generic parent device to all Alarm Decoder (AD2) products. Generic parent device to all Alarm Decoder (AD2) products.
@@ -143,6 +146,7 @@ class Device(object):


time.sleep(0.01) time.sleep(0.01)



class USBDevice(Device): class USBDevice(Device):
""" """
AD2USB device exposed with PyFTDI's interface. AD2USB device exposed with PyFTDI's interface.
@@ -334,11 +338,11 @@ class USBDevice(Device):
# Open the device and start up the thread. # Open the device and start up the thread.
try: try:
self._device.open(self._vendor_id, self._device.open(self._vendor_id,
self._product_id,
self._endpoint,
self._device_number,
self._serial_number,
self._description)
self._product_id,
self._endpoint,
self._device_number,
self._serial_number,
self._description)


self._device.set_baudrate(baudrate) self._device.set_baudrate(baudrate)


@@ -763,6 +767,7 @@ class SerialDevice(Device):


return ret return ret



class SocketDevice(Device): class SocketDevice(Device):
""" """
Device that supports communication with an Alarm Decoder (AD2) that is Device that supports communication with an Alarm Decoder (AD2) that is


+ 1
- 0
alarmdecoder/event/event.py View File

@@ -9,6 +9,7 @@
# * Added type check in fire() # * Added type check in fire()
# * Removed earg from fire() and added support for args/kwargs. # * Removed earg from fire() and added support for args/kwargs.



class Event(object): class Event(object):


def __init__(self, doc=None): def __init__(self, doc=None):


+ 5
- 1
alarmdecoder/messages.py View File

@@ -9,6 +9,7 @@ import re


from .util import InvalidMessageError from .util import InvalidMessageError



class BaseMessage(object): class BaseMessage(object):
""" """
Base class for messages. Base class for messages.
@@ -29,6 +30,7 @@ class BaseMessage(object):
""" """
return self.raw return self.raw



class Message(BaseMessage): class Message(BaseMessage):
""" """
Represents a message from the alarm panel. Represents a message from the alarm panel.
@@ -141,6 +143,7 @@ class Message(BaseMessage):
if int(self.panel_data[19:21], 16) & 0x01 > 0: 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. self.cursor_location = int(self.bitfield[21:23], 16) # Alpha character index that the cursor is on.



class ExpanderMessage(BaseMessage): class ExpanderMessage(BaseMessage):
""" """
Represents a message from a zone or relay expansion module. Represents a message from a zone or relay expansion module.
@@ -151,7 +154,6 @@ class ExpanderMessage(BaseMessage):
RELAY = 1 RELAY = 1
"""Flag indicating that the expander message relates to a Relay Expander.""" """Flag indicating that the expander message relates to a Relay Expander."""



type = None type = None
"""Expander message type: ExpanderMessage.ZONE or ExpanderMessage.RELAY""" """Expander message type: ExpanderMessage.ZONE or ExpanderMessage.RELAY"""
address = -1 address = -1
@@ -205,6 +207,7 @@ class ExpanderMessage(BaseMessage):
else: else:
raise InvalidMessageError('Unknown expander message header: {0}'.format(data)) raise InvalidMessageError('Unknown expander message header: {0}'.format(data))



class RFMessage(BaseMessage): class RFMessage(BaseMessage):
""" """
Represents a message from an RF receiver. Represents a message from an RF receiver.
@@ -267,6 +270,7 @@ class RFMessage(BaseMessage):
except ValueError: except ValueError:
raise InvalidMessageError('Received invalid message: {0}'.format(data)) raise InvalidMessageError('Received invalid message: {0}'.format(data))



class LRRMessage(BaseMessage): class LRRMessage(BaseMessage):
""" """
Represent a message from a Long Range Radio. Represent a message from a Long Range Radio.


+ 1
- 0
alarmdecoder/tests/test_ad2.py View File

@@ -9,6 +9,7 @@ from ..messages import Message, RFMessage, LRRMessage, ExpanderMessage
from ..event.event import Event, EventHandler from ..event.event import Event, EventHandler
from ..zonetracking import Zonetracker from ..zonetracking import Zonetracker



class TestAlarmDecoder(TestCase): class TestAlarmDecoder(TestCase):
def setUp(self): def setUp(self):
self._panicked = False self._panicked = False


+ 2
- 0
alarmdecoder/tests/test_devices.py View File

@@ -164,6 +164,7 @@ class TestUSBDevice(TestCase):
with self.assertRaises(CommError): with self.assertRaises(CommError):
self._device.read_line() self._device.read_line()



class TestSerialDevice(TestCase): class TestSerialDevice(TestCase):
def setUp(self): def setUp(self):
self._device = SerialDevice() self._device = SerialDevice()
@@ -250,6 +251,7 @@ class TestSerialDevice(TestCase):
with self.assertRaises(CommError): with self.assertRaises(CommError):
self._device.read_line() self._device.read_line()



class TestSocketDevice(TestCase): class TestSocketDevice(TestCase):
def setUp(self): def setUp(self):
self._device = SocketDevice() self._device = SocketDevice()


+ 1
- 0
alarmdecoder/tests/test_messages.py View File

@@ -3,6 +3,7 @@ from unittest import TestCase
from ..messages import Message, ExpanderMessage, RFMessage, LRRMessage from ..messages import Message, ExpanderMessage, RFMessage, LRRMessage
from ..util import InvalidMessageError from ..util import InvalidMessageError



class TestMessages(TestCase): class TestMessages(TestCase):
def setUp(self): def setUp(self):
pass pass


+ 2
- 1
alarmdecoder/tests/test_zonetracking.py View File

@@ -4,6 +4,7 @@ from mock import Mock, MagicMock
from ..messages import Message, ExpanderMessage from ..messages import Message, ExpanderMessage
from ..zonetracking import Zonetracker, Zone from ..zonetracking import Zonetracker, Zone



class TestZonetracking(TestCase): class TestZonetracking(TestCase):
def setUp(self): def setUp(self):
self._zonetracker = Zonetracker() self._zonetracker = Zonetracker()
@@ -135,7 +136,7 @@ class TestZonetracking(TestCase):
self._zonetracker.update(msg) self._zonetracker.update(msg)


self.assertIn(4, self._zonetracker._zones_faulted) self.assertIn(4, self._zonetracker._zones_faulted)
self._zonetracker._zones[4].timestamp -= 35 # forcefully expire the zone
self._zonetracker._zones[4].timestamp -= 35 # forcefully expire the zone


# generic message to force an update. # generic message to force an update.
msg = Message('[0000000000000000----],000,[f707000600e5800c0c020000]," "') msg = Message('[0000000000000000----],000,[f707000600e5800c0c020000]," "')


+ 5
- 0
alarmdecoder/util.py View File

@@ -7,30 +7,35 @@ Provides utility classes for the Alarm Decoder (AD2) devices.
import time import time
import threading import threading



class NoDeviceError(Exception): class NoDeviceError(Exception):
""" """
No devices found. No devices found.
""" """
pass pass



class CommError(Exception): class CommError(Exception):
""" """
There was an error communicating with the device. There was an error communicating with the device.
""" """
pass pass



class TimeoutError(Exception): class TimeoutError(Exception):
""" """
There was a timeout while trying to communicate with the device. There was a timeout while trying to communicate with the device.
""" """
pass pass



class InvalidMessageError(Exception): class InvalidMessageError(Exception):
""" """
The format of the panel message was invalid. The format of the panel message was invalid.
""" """
pass pass



class Firmware(object): class Firmware(object):
""" """
Represents firmware for the Alarm Decoder devices. Represents firmware for the Alarm Decoder devices.


+ 3
- 1
alarmdecoder/zonetracking.py View File

@@ -10,6 +10,7 @@ import time
from .event import event from .event import event
from .messages import ExpanderMessage from .messages import ExpanderMessage



class Zone(object): class Zone(object):
""" """
Representation of a panel zone. Representation of a panel zone.
@@ -22,7 +23,7 @@ class Zone(object):
CHECK = 2 # Wire fault CHECK = 2 # Wire fault
"""Status indicating that there is a wiring issue with the zone.""" """Status indicating that there is a wiring issue with the zone."""


STATUS = { CLEAR: 'CLEAR', FAULT: 'FAULT', CHECK: 'CHECK' }
STATUS = {CLEAR: 'CLEAR', FAULT: 'FAULT', CHECK: 'CHECK'}


def __init__(self, zone=0, name='', status=CLEAR): def __init__(self, zone=0, name='', status=CLEAR):
""" """
@@ -52,6 +53,7 @@ class Zone(object):
""" """
return 'Zone({0}, {1}, ts {2})'.format(self.zone, Zone.STATUS[self.status], self.timestamp) return 'Zone({0}, {1}, ts {2})'.format(self.zone, Zone.STATUS[self.status], self.timestamp)



class Zonetracker(object): class Zonetracker(object):
""" """
Handles tracking of zone and their statuses. Handles tracking of zone and their statuses.


Loading…
Cancel
Save