From bf73c6821f6a41772e08117eebc4a84454f3f2b4 Mon Sep 17 00:00:00 2001 From: Scott Petersen Date: Thu, 13 Jun 2013 13:28:09 -0700 Subject: [PATCH] Working timeout version of the tracker. --- pyad2usb/ad2usb.py | 37 +++++++++++++++++++++++++++++++++++++ test.py | 26 ++++++++++++++++++++++++++ 2 files changed, 63 insertions(+) diff --git a/pyad2usb/ad2usb.py b/pyad2usb/ad2usb.py index 04706e5..5798ee8 100644 --- a/pyad2usb/ad2usb.py +++ b/pyad2usb/ad2usb.py @@ -6,6 +6,7 @@ import time import threading import re import logging +from collections import OrderedDict from .event import event from . import devices from . import util @@ -158,6 +159,8 @@ class AD2USB(object): on_bypass = event.Event('Called when a zone is bypassed.') on_boot = event.Event('Called when the device finishes bootings.') on_config_received = event.Event('Called when the device receives its configuration.') + on_fault = event.Event('Called when the device detects a zone fault.') + on_restore = event.Event('Called when the device detects that a fault is restored.') # Mid-level Events on_message = event.Event('Called when a message has been received from the device.') @@ -174,6 +177,8 @@ class AD2USB(object): F3 = unichr(3) + unichr(3) + unichr(3) F4 = unichr(4) + unichr(4) + unichr(4) + ZONE_EXPIRE = 30 + def __init__(self, device): """ Constructor @@ -184,6 +189,7 @@ class AD2USB(object): self._bypass_status = None self._armed_status = None self._fire_status = None + self._zone_status = OrderedDict() self.address = 18 self.configbits = 0xFF00 @@ -374,6 +380,37 @@ class AD2USB(object): if old_status is not None: self.on_fire(self._fire_status) + if message.check_zone or (not message.ready and "FAULT" in message.text): + self._update_zone_status(message) + + self._clear_expired_zones(message) + + def _update_zone_status(self, message): + zone = -1 + + try: + zone = int(message.numeric_code) + except ValueError: + zone = int(message.numeric_code, 16) + + if zone not in self._zone_status: + self.on_fault(zone) + + self._last_zone_fault = zone + self._zone_status[zone] = (True, time.time()) + + def _clear_expired_zones(self, message): + clear_time = time.time() + cleared_zones = [] + + for z, status in self._zone_status.iteritems(): + if message.ready or (status[0] and clear_time - status[1] >= self.ZONE_EXPIRE): + cleared_zones.append(z) + + for z in cleared_zones: + del self._zone_status[z] + self.on_restore(z) + def _on_open(self, sender, args): """ Internal handler for opening the device. diff --git a/test.py b/test.py index fff0bfb..48c50ad 100755 --- a/test.py +++ b/test.py @@ -84,6 +84,12 @@ def handle_boot(sender, args): def handle_config(sender, args): print 'config', args +def handle_fault(sender, args): + print 'zone fault', args + +def handle_restore(sender, args): + print 'zone restored', args + def upload_usb(): dev = pyad2usb.ad2usb.devices.USBDevice() @@ -228,12 +234,32 @@ def test_socket(): a2u.on_config_received += handle_config a2u.on_arm += handle_arm a2u.on_disarm += handle_disarm + a2u.on_fault += handle_fault + a2u.on_restore += handle_restore a2u.open() #a2u.save_config() #a2u.reboot() a2u.get_config() + #a2u.address = 18 + #a2u.configbits = 0xff00 + #a2u.address_mask = 0xFFFFFFFF + #a2u.emulate_zone[0] = False + #a2u.emulate_relay[0] = False + #a2u.emulate_lrr = False + #a2u.deduplicate = False + + #time.sleep(3) + #a2u.emulate_zone[1] = True + #a2u.save_config() + + #time.sleep(1) + #a2u.fault_zone(17, True) + + #time.sleep(15) + #a2u.clear_zone(17) + while running: time.sleep(0.1)