From f4fe9be40b3d162273026c53e561598fcfba8fcf Mon Sep 17 00:00:00 2001 From: Scott Petersen Date: Mon, 23 Mar 2015 11:55:16 -0700 Subject: [PATCH] Initial pass. --- alarmdecoder/decoder.py | 36 +++++++++++-------- alarmdecoder/devices.py | 70 ++++++++++++++++++------------------ alarmdecoder/messages.py | 8 +++-- alarmdecoder/util.py | 1 + alarmdecoder/zonetracking.py | 2 +- 5 files changed, 63 insertions(+), 54 deletions(-) diff --git a/alarmdecoder/decoder.py b/alarmdecoder/decoder.py index 5d12ba8..66ad156 100644 --- a/alarmdecoder/decoder.py +++ b/alarmdecoder/decoder.py @@ -9,6 +9,8 @@ Provides the main AlarmDecoder class. import time import re +from builtins import chr + from .event import event from .util import InvalidMessageError from .messages import Message, ExpanderMessage, RFMessage, LRRMessage @@ -51,15 +53,15 @@ class AlarmDecoder(object): on_write = event.Event("This event is called when data has been written to the device.\n\n**Callback definition:** *def callback(device, data)*") # Constants - KEY_F1 = unichr(1) + unichr(1) + unichr(1) + KEY_F1 = chr(1) + chr(1) + chr(1) """Represents panel function key #1""" - KEY_F2 = unichr(2) + unichr(2) + unichr(2) + KEY_F2 = chr(2) + chr(2) + chr(2) """Represents panel function key #2""" - KEY_F3 = unichr(3) + unichr(3) + unichr(3) + KEY_F3 = chr(3) + chr(3) + chr(3) """Represents panel function key #3""" - KEY_F4 = unichr(4) + unichr(4) + unichr(4) + KEY_F4 = chr(4) + chr(4) + chr(4) """Represents panel function key #4""" - KEY_PANIC = unichr(5) + unichr(5) + unichr(5) + KEY_PANIC = chr(5) + chr(5) + chr(5) """Represents a panic keypress""" BATTERY_TIMEOUT = 30 @@ -74,9 +76,9 @@ class AlarmDecoder(object): """The configuration bits set on the device.""" address_mask = 0xFFFFFFFF """The address mask configured on the device.""" - emulate_zone = [False for _ in range(5)] + emulate_zone = [False for _ in list(range(5))] """List containing the devices zone emulation status.""" - emulate_relay = [False for _ in range(4)] + emulate_relay = [False for _ in list(range(4))] """List containing the devices relay emulation status.""" emulate_lrr = False """The status of the devices LRR emulation.""" @@ -87,7 +89,7 @@ class AlarmDecoder(object): def __init__(self, device): """ - Constructor + Constructora :param device: The low-level device used for this `AlarmDecoder`_ interface. @@ -110,8 +112,8 @@ class AlarmDecoder(object): self.address = 18 self.configbits = 0xFF00 self.address_mask = 0x00000000 - self.emulate_zone = [False for x in range(5)] - self.emulate_relay = [False for x in range(4)] + self.emulate_zone = [False for x in list(range(5))] + self.emulate_relay = [False for x in list(range(4))] self.emulate_lrr = False self.deduplicate = False self.mode = ADEMCO @@ -211,13 +213,13 @@ class AlarmDecoder(object): """ if self._device: - self._device.write(str(data)) + self._device.write(data) def get_config(self): """ Retrieves the configuration from the device. Called automatically by :py:meth:`_on_open`. """ - self.send("C\r") + self.send(b"C\r") def save_config(self): """ @@ -236,7 +238,7 @@ class AlarmDecoder(object): ''.join(['Y' if r else 'N' for r in self.emulate_relay]))) config_entries.append(('LRR', 'Y' if self.emulate_lrr else 'N')) config_entries.append(('DEDUPLICATE', 'Y' if self.deduplicate else 'N')) - config_entries.append(('MODE', PANEL_TYPES.keys()[PANEL_TYPES.values().index(self.mode)])) + config_entries.append(('MODE', list(PANEL_TYPES)[list(PANEL_TYPES.values()).index(self.mode)])) config_string = '&'.join(['='.join(t) for t in config_entries]) @@ -301,6 +303,8 @@ class AlarmDecoder(object): :returns: :py:class:`~alarmdecoder.messages.Message` """ + data = str(data) + if data is not None: data = data.lstrip('\0') @@ -310,6 +314,8 @@ class AlarmDecoder(object): msg = None header = data[0:4] + #print('header', header, type(header), type(header[0])) + if header[0] != '!' or header == '!KPM': msg = self._handle_keypad_message(data) @@ -424,9 +430,9 @@ class AlarmDecoder(object): elif key == 'MASK': self.address_mask = int(val, 16) elif key == 'EXP': - self.emulate_zone = [val[z] == 'Y' for z in range(5)] + self.emulate_zone = [val[z] == 'Y' for z in list(range(5))] elif key == 'REL': - self.emulate_relay = [val[r] == 'Y' for r in range(4)] + self.emulate_relay = [val[r] == 'Y' for r in list(range(4))] elif key == 'LRR': self.emulate_lrr = (val == 'Y') elif key == 'DEDUPLICATE': diff --git a/alarmdecoder/devices.py b/alarmdecoder/devices.py index e3acd8b..3c10af8 100644 --- a/alarmdecoder/devices.py +++ b/alarmdecoder/devices.py @@ -61,7 +61,7 @@ class Device(object): Constructor """ self._id = '' - self._buffer = '' + self._buffer = b'' self._device = None self._running = False self._read_thread = None @@ -171,10 +171,10 @@ class Device(object): except SSL.WantReadError: pass - except CommError, err: + except CommError: self._device.close() - except Exception, err: + except Exception: self._device.close() self._running = False raise @@ -226,7 +226,7 @@ class USBDevice(Device): try: cls.__devices = Ftdi.find_all(query, nocache=True) - except (usb.core.USBError, FtdiError), err: + except (usb.core.USBError, FtdiError) as err: raise CommError('Error enumerating AD2USB devices: {0}'.format(str(err)), err) return cls.__devices @@ -433,10 +433,10 @@ class USBDevice(Device): self._id = self._serial_number - except (usb.core.USBError, FtdiError), err: + except (usb.core.USBError, FtdiError) as err: raise NoDeviceError('Error opening device: {0}'.format(str(err)), err) - except KeyError, err: + except KeyError as err: raise NoDeviceError('Unsupported device. ({0:04x}:{1:04x}) You probably need a newer version of pyftdi.'.format(err[0][0], err[0][1])) else: @@ -478,7 +478,7 @@ class USBDevice(Device): self.on_write(data=data) - except FtdiError, err: + except FtdiError as err: raise CommError('Error writing to device: {0}'.format(str(err)), err) def read(self): @@ -493,7 +493,7 @@ class USBDevice(Device): try: ret = self._device.read_data(1) - except (usb.core.USBError, FtdiError), err: + except (usb.core.USBError, FtdiError) as err: raise CommError('Error reading from device: {0}'.format(str(err)), err) return ret @@ -518,7 +518,7 @@ class USBDevice(Device): timeout_event.reading = True if purge_buffer: - self._buffer = '' + self._buffer = b'' got_line, ret = False, None @@ -530,11 +530,11 @@ class USBDevice(Device): while timeout_event.reading: buf = self._device.read_data(1) - if buf != '': + if buf != b'': self._buffer += buf - if buf == "\n": - self._buffer = self._buffer.rstrip("\r\n") + if buf == b"\n": + self._buffer = self._buffer.rstrip(b"\r\n") if len(self._buffer) > 0: got_line = True @@ -542,12 +542,12 @@ class USBDevice(Device): else: time.sleep(0.01) - except (usb.core.USBError, FtdiError), err: + except (usb.core.USBError, FtdiError) as err: raise CommError('Error reading from device: {0}'.format(str(err)), err) else: if got_line: - ret, self._buffer = self._buffer, '' + ret, self._buffer = self._buffer, b'' self.on_read(data=ret) @@ -653,7 +653,7 @@ class SerialDevice(Device): else: devices = serial.tools.list_ports.comports() - except serial.SerialException, err: + except serial.SerialException as err: raise CommError('Error enumerating serial devices: {0}'.format(str(err)), err) return devices @@ -724,7 +724,7 @@ class SerialDevice(Device): # all issues with it. self._device.baudrate = baudrate - except (serial.SerialException, ValueError, OSError), err: + except (serial.SerialException, ValueError, OSError) as err: raise NoDeviceError('Error opening device on {0}.'.format(self._port), err) else: @@ -764,7 +764,7 @@ class SerialDevice(Device): except serial.SerialTimeoutException: pass - except serial.SerialException, err: + except serial.SerialException as err: raise CommError('Error writing to device.', err) else: @@ -782,7 +782,7 @@ class SerialDevice(Device): try: ret = self._device.read(1) - except serial.SerialException, err: + except serial.SerialException as err: raise CommError('Error reading from device: {0}'.format(str(err)), err) return ret @@ -807,7 +807,7 @@ class SerialDevice(Device): timeout_event.reading = True if purge_buffer: - self._buffer = '' + self._buffer = b'' got_line, ret = False, None @@ -820,11 +820,11 @@ class SerialDevice(Device): buf = self._device.read(1) # NOTE: AD2SERIAL apparently sends down \xFF on boot. - if buf != '' and buf != "\xff": + if buf != b'' and buf != b"\xff": self._buffer += buf - if buf == "\n": - self._buffer = self._buffer.rstrip("\r\n") + if buf == b"\n": + self._buffer = self._buffer.rstrip(b"\r\n") if len(self._buffer) > 0: got_line = True @@ -832,12 +832,12 @@ class SerialDevice(Device): else: time.sleep(0.01) - except (OSError, serial.SerialException), err: + except (OSError, serial.SerialException) as err: raise CommError('Error reading from device: {0}'.format(str(err)), err) else: if got_line: - ret, self._buffer = self._buffer, '' + ret, self._buffer = self._buffer, b'' self.on_read(data=ret) @@ -1001,7 +1001,7 @@ class SocketDevice(Device): self._id = '{0}:{1}'.format(self._host, self._port) - except socket.error, err: + except socket.error as err: raise NoDeviceError('Error opening device at {0}:{1}'.format(self._host, self._port), err) else: @@ -1054,7 +1054,7 @@ class SocketDevice(Device): self.on_write(data=data) - except (SSL.Error, socket.error), err: + except (SSL.Error, socket.error) as err: raise CommError('Error writing to device.', err) return data_sent @@ -1071,7 +1071,7 @@ class SocketDevice(Device): try: data = self._device.recv(1) - except socket.error, err: + except socket.error as err: raise CommError('Error while reading from device: {0}'.format(str(err)), err) return data @@ -1096,7 +1096,7 @@ class SocketDevice(Device): timeout_event.reading = True if purge_buffer: - self._buffer = '' + self._buffer = b'' got_line, ret = False, None @@ -1108,11 +1108,11 @@ class SocketDevice(Device): while timeout_event.reading: buf = self._device.recv(1) - if buf != '': + if buf != b'': self._buffer += buf - if buf == "\n": - self._buffer = self._buffer.rstrip("\r\n") + if buf == b"\n": + self._buffer = self._buffer.rstrip(b"\r\n") if len(self._buffer) > 0: got_line = True @@ -1120,10 +1120,10 @@ class SocketDevice(Device): else: time.sleep(0.01) - except socket.error, err: + except socket.error as err: raise CommError('Error reading from device: {0}'.format(str(err)), err) - except SSL.SysCallError, err: + except SSL.SysCallError as err: errno, msg = err raise CommError('SSL error while reading from device: {0} ({1})'.format(msg, errno)) @@ -1132,7 +1132,7 @@ class SocketDevice(Device): else: if got_line: - ret, self._buffer = self._buffer, '' + ret, self._buffer = self._buffer, b'' self.on_read(data=ret) @@ -1177,7 +1177,7 @@ class SocketDevice(Device): self._device = SSL.Connection(ctx, self._device) - except SSL.Error, err: + except SSL.Error as err: raise CommError('Error setting up SSL connection.', err) def _verify_ssl_callback(self, connection, x509, errnum, errdepth, ok): diff --git a/alarmdecoder/messages.py b/alarmdecoder/messages.py index 6ed5d1f..25327ed 100644 --- a/alarmdecoder/messages.py +++ b/alarmdecoder/messages.py @@ -15,6 +15,8 @@ devices. import re import datetime +from reprlib import repr + from .util import InvalidMessageError from .panels import PANEL_TYPES, ADEMCO, DSC @@ -136,7 +138,7 @@ class Message(BaseMessage): :raises: :py:class:`~alarmdecoder.util.InvalidMessageError` """ - match = self._regex.match(data) + match = self._regex.match(str(data)) if match is None: raise InvalidMessageError('Received invalid message: {0}'.format(data)) @@ -163,7 +165,7 @@ class Message(BaseMessage): self.check_zone = is_bit_set(15) self.perimeter_only = is_bit_set(16) self.system_fault = is_bit_set(17) - if self.bitfield[18] in PANEL_TYPES.keys(): + if self.bitfield[18] in list(PANEL_TYPES): self.panel_type = PANEL_TYPES[self.bitfield[18]] # pos 20-21 - Unused. self.text = alpha.strip('"') @@ -292,7 +294,7 @@ class RFMessage(BaseMessage): """Low battery indication""" supervision = False """Supervision required indication""" - loop = [False for _ in range(4)] + loop = [False for _ in list(range(4))] """Loop indicators""" def __init__(self, data=None): diff --git a/alarmdecoder/util.py b/alarmdecoder/util.py index 23abf4a..cee0963 100644 --- a/alarmdecoder/util.py +++ b/alarmdecoder/util.py @@ -8,6 +8,7 @@ Provides utility classes for the `AlarmDecoder`_ (AD2) devices. import time import threading +from io import open class NoDeviceError(Exception): diff --git a/alarmdecoder/zonetracking.py b/alarmdecoder/zonetracking.py index 36334b0..e3adac6 100644 --- a/alarmdecoder/zonetracking.py +++ b/alarmdecoder/zonetracking.py @@ -294,7 +294,7 @@ class Zonetracker(object): """ zones = [] - for z in self._zones.keys(): + for z in list(self._zones): zones += [z] for z in zones: