Code Monkey home page Code Monkey logo

alarmdecoder's People

Contributors

ajschmidt8 avatar endlesscoil avatar f34rdotcom avatar fabaff avatar gottsman avatar jailbird777 avatar jmgurney avatar jonathanjsimon avatar krkeegan avatar mstovenour avatar olsonse avatar ryandrake08 avatar td22057 avatar weevis avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

alarmdecoder's Issues

Communicator failures not handled

Messages such as this lead to failures when updating zones:

May 12 10:08:59 [00000001000000000A--],0fc,[f704009f10fc000008020000000000],"COMM. FAILURE                   "
May 12 10:09:03 [00000001000000100A--],0bf,[f704009f10bf000208020000000000],"CHECK 103 LngRngRadio       0000"
Traceback (most recent call last):
  File "/usr/local/lib/python3.8/threading.py", line 932, in _bootstrap_inner
    self.run()
  File "/usr/local/lib/python3.8/site-packages/alarmdecoder/devices/base_device.py", line 148, in run
    self._device.read_line(timeout=self.READ_TIMEOUT)
  File "/usr/local/lib/python3.8/site-packages/alarmdecoder/devices/socket_device.py", line 356, in read_line
    self.on_read(data=ret)
  File "/usr/local/lib/python3.8/site-packages/alarmdecoder/event/event.py", line 84, in fire
    func(self.obj, *args, **kwargs)
  File "/usr/local/lib/python3.8/site-packages/alarmdecoder/decoder.py", line 1041, in _on_read
    self._handle_message(data)
  File "/usr/local/lib/python3.8/site-packages/alarmdecoder/decoder.py", line 439, in _handle_message
    msg = self._handle_keypad_message(data)
  File "/usr/local/lib/python3.8/site-packages/alarmdecoder/decoder.py", line 481, in _handle_keypad_message
    self._update_internal_states(msg)
  File "/usr/local/lib/python3.8/site-packages/alarmdecoder/decoder.py", line 632, in _update_internal_states
    self._update_zone_tracker(message)
  File "/usr/local/lib/python3.8/site-packages/alarmdecoder/decoder.py", line 1017, in _update_zone_tracker
    self._zonetracker.update(message)
  File "/usr/local/lib/python3.8/site-packages/alarmdecoder/zonetracking.py", line 209, in update
    self._zones_faulted.sort()
TypeError: '<' not supported between instances of 'str' and 'int'

New Alphanumeric Zone Fault Can Temporarily Cause Other Faulted Zones to Incorrectly Report as Ready

On my alarm panel (Vista 20SE) the status of hardwired(non-expander) zones can only be determined by parsing the alphanumeric messages that cycle through the list of faulted zones.

  1. Normally, faulted zones cycle through from lowest to highest and then loop back again.
  2. When a new fault is detected, that zone is immediately reported and then the loop starts back with the lowest zone again.

This can incorrectly cause faulted zones to be reported as ready. This error happens inside the ZoneTracker class in the _clear_zones() function.

The logic of clear zones is the following:

  1. If the last_faulted_zone is less than the current zone: set to clear any zones between this zone and the last_faulted_zone.
  2. If the last_faulted_zone is greater than the current zone: set to clear any zones that do not fall between this zone and the last_faulted_zone.

The logic is based on the assumption that the zone fault messages always loop in an incrementing order. Which isn't the case when a new zone faults.

When a new zone faults, a whole bunch of faulted zones can become "ready" that shouldn't.

Imagine the following scenario:

  1. zones 1,3,7 are faulted
  2. The keypad reports zone 1 faulted
  3. Then zone 6 is newly faulted, the keypad reports this zone as faulted.
  4. _clear_zones() then changes zone 3 to ready, which is wrong.

Is this only an issue for my or my panel?

I am happy to create a PR that fixes this if this isn't unique to me.

AlarmDecoder API status requests return multiple duplicate messages

I'm using a HomeBridge plugin to integrate with the AlarmDecoder API. The plugin uses an Async/Try/Await construct to get the AlarmDecoder status. Whenever the AlarmDecoder server responds to the request, it frequently sends anywhere from 5-8 duplicate messages as you can see in the following log entry from the plugin. Note the 13:32:26 timestamp with exactly the same data for all of the log entries. Is this normal behavior from the server? Everything else works just great, including Notifications!

My AlarmDecoder server has the following configuration:
OS - Debian 5.10.103+
Python Version - 3.9
Hardware - Raspberry Pi Zero W with AD2pHAT

[17/05/2022, 13:32:26] [ADT Security] {"last_message_received":"[10000001100000003A--],008,[f72200ff1008001c28020000000000]," DISARMED CHIME Ready to Arm "","panel_alarming":false,"panel_armed":false,"panel_armed_stay":false,"panel_battery_trouble":false,"panel_bypassed":{},"panel_chime":true,"panel_entry_delay_off":false,"panel_exit":false,"panel_fire_detected":false,"panel_panicked":false,"panel_perimeter_only":false,"panel_powered":true,"panel_ready":true,"panel_relay_status":[],"panel_type":"ADEMCO","panel_zones_faulted":[]}
[17/05/2022, 13:32:26] [ADT Security] {"last_message_received":"[10000001100000003A--],008,[f72200ff1008001c28020000000000]," DISARMED CHIME Ready to Arm "","panel_alarming":false,"panel_armed":false,"panel_armed_stay":false,"panel_battery_trouble":false,"panel_bypassed":{},"panel_chime":true,"panel_entry_delay_off":false,"panel_exit":false,"panel_fire_detected":false,"panel_panicked":false,"panel_perimeter_only":false,"panel_powered":true,"panel_ready":true,"panel_relay_status":[],"panel_type":"ADEMCO","panel_zones_faulted":[]}
[17/05/2022, 13:32:26] [ADT Security] {"last_message_received":"[10000001100000003A--],008,[f72200ff1008001c28020000000000]," DISARMED CHIME Ready to Arm "","panel_alarming":false,"panel_armed":false,"panel_armed_stay":false,"panel_battery_trouble":false,"panel_bypassed":{},"panel_chime":true,"panel_entry_delay_off":false,"panel_exit":false,"panel_fire_detected":false,"panel_panicked":false,"panel_perimeter_only":false,"panel_powered":true,"panel_ready":true,"panel_relay_status":[],"panel_type":"ADEMCO","panel_zones_faulted":[]}
[17/05/2022, 13:32:26] [ADT Security] {"last_message_received":"[10000001100000003A--],008,[f72200ff1008001c28020000000000]," DISARMED CHIME Ready to Arm "","panel_alarming":false,"panel_armed":false,"panel_armed_stay":false,"panel_battery_trouble":false,"panel_bypassed":{},"panel_chime":true,"panel_entry_delay_off":false,"panel_exit":false,"panel_fire_detected":false,"panel_panicked":false,"panel_perimeter_only":false,"panel_powered":true,"panel_ready":true,"panel_relay_status":[],"panel_type":"ADEMCO","panel_zones_faulted":[]}
[17/05/2022, 13:32:26] [ADT Security] {"last_message_received":"[10000001100000003A--],008,[f72200ff1008001c28020000000000]," DISARMED CHIME Ready to Arm "","panel_alarming":false,"panel_armed":false,"panel_armed_stay":false,"panel_battery_trouble":false,"panel_bypassed":{},"panel_chime":true,"panel_entry_delay_off":false,"panel_exit":false,"panel_fire_detected":false,"panel_panicked":false,"panel_perimeter_only":false,"panel_powered":true,"panel_ready":true,"panel_relay_status":[],"panel_type":"ADEMCO","panel_zones_faulted":[]}
[17/05/2022, 13:32:26] [ADT Security] {"last_message_received":"[10000001100000003A--],008,[f72200ff1008001c28020000000000]," DISARMED CHIME Ready to Arm "","panel_alarming":false,"panel_armed":false,"panel_armed_stay":false,"panel_battery_trouble":false,"panel_bypassed":{},"panel_chime":true,"panel_entry_delay_off":false,"panel_exit":false,"panel_fire_detected":false,"panel_panicked":false,"panel_perimeter_only":false,"panel_powered":true,"panel_ready":true,"panel_relay_status":[],"panel_type":"ADEMCO","panel_zones_faulted":[]}
[17/05/2022, 13:32:26] [ADT Security] {"last_message_received":"[10000001100000003A--],008,[f72200ff1008001c28020000000000]," DISARMED CHIME Ready to Arm "","panel_alarming":false,"panel_armed":false,"panel_armed_stay":false,"panel_battery_trouble":false,"panel_bypassed":{},"panel_chime":true,"panel_entry_delay_off":false,"panel_exit":false,"panel_fire_detected":false,"panel_panicked":false,"panel_perimeter_only":false,"panel_powered":true,"panel_ready":true,"panel_relay_status":[],"panel_type":"ADEMCO","panel_zones_faulted":[]}

Notification Section in WebSever Bug saving settings

Notification Section in WebSever has Bugs saving settings

Using Raspberry Pi 3, Latest Image, Master branch webserver, Using IE 11, + older FoScam cameras, DSC Alarm

Purpose:

I have a bunch of older FoScam cameras that I wanted to turn on Motion Alarm section of camera WHEN Alarm was armed.
I had this working for 3-4 cameras.
Using cgi-bin line commands sent to cameras to start / stop motion recording
When Alarm unarmed , the cameras are not constantly recording (Turns off). Only start when alarm is armed.
So have 1 start and 1 stop entries for each camera.

ISSUE:
Was working years ago.
There is something seriously wrong with the web Notification section saving settings (need 24 custom Keys)
After Entering all 25 custom keys and going Next, selecting 15 Zones, then [Save] ([test & save] option loses everything if test fails)
Going back into Entry, sections of the keys entered are re-sorted and / and parts missing.
I have done this 5-6x now with same result.
These are tedious entries, but can no longer successfully get one entry to save correctly.
Same issue using IE OR Chrome. So it's not the browser.


This is definitely a bug with the Notification entry section. Also not able to insert above / between Custom Keys. So have to start over again. Is there a new better way of doing this? Or controlling cameras to activate Motion on when alarm is armed / disarmed?

Screenshots here if needed;
https://www.alarmdecoder.com/forums/viewtopic.php?f=3&t=936

Decoder sends multiple events if open is called more than once

I'm trying to write a robust handler for converting the alarm messages into MQTT. I have a class that works fine to do this. But - if needs to be robust in the sense that ser2sock might not be running or might start or stop unexpectedly (or might start after my process in the init order). So I wrote my process to detect the connection closing and enter a waiting state where it periodically tries to connect again.

The problem is in decoder.py line 229 in open() where it does this:

self._wire_events()
self._device.open(baudrate=baudrate, no_reader_thread=no_reader_thread)
return self

By having open() call wire events every time, the number of events increases every time open() is called because close doesn't undo this. But the only way to try to connect is to call open() over and over again which causes a lot of problems once a connection is actually made. Is there a reason why wiring the events isn't done in the constructor one time?

ValueError: file descriptor cannot be a negative integer (-1)

When shutting down Home Assistant (whose alarmdecoder component leverages this library), I'm seeing the following error:

2022-02-05 13:49:03 ERROR (Thread-3) [root] Uncaught thread exception
Traceback (most recent call last):
  File "/usr/lib/python3.9/threading.py", line 973, in _bootstrap_inner
    self.run()
  File "/srv/homeassistant/venv/lib/python3.9/site-packages/alarmdecoder/devices/base_device.py", line 148, in run
    self._device.read_line(timeout=self.READ_TIMEOUT)
  File "/srv/homeassistant/venv/lib/python3.9/site-packages/alarmdecoder/devices/socket_device.py", line 323, in read_line
    read_ready, _, _ = select.select([self._device], [], [], 0.5)
ValueError: file descriptor cannot be a negative integer (-1)

Interestingly, this only cropped up since I upgraded from python 3.8 to 3.9. I have, however, seen other error reports with earlier versions.

LRR Events crossing partitions updateing AlarmDecoder state incorrectly.

In "some" cases it may be desirable to have the API parse and update states based upon LRR messages. In others where we have multiple partitions and no support for a filter to block some LRR messages from triggering alarms in cases where we use AUX alarms on zones that we do not want to make the house siren turn on or any actions to take place.

We need a way to turn this feature ON/OFF in the short term and in the long term we need partition support as well as the ability to white list some zones from LRR processing.

It would be nice to use Report Codes like we can on DSC panels then we could have the logic skip CID reports based upon the report code. Since they do not pass through on Ademco we need a way to internally ignore some LRR messages.

We still need to be able to forward the LRR message to subscribers!! so they can also keep remote white lists and do full remote processing.

self._lrr_system.update(msg)

Python 3.12 changes in regex special characters

Getting the following error messages

2024-04-08 08:58:20.108 WARNING (ImportExecutor_0) [py.warnings] /usr/local/lib/python3.12/site-packages/alarmdecoder/decoder.py:605: SyntaxWarning: invalid escape sequence '\.'
  matches = re.match('^!Sending(\.{1,5})done.*', data)

2024-04-08 08:58:20.143 WARNING (ImportExecutor_0) [py.warnings] /usr/local/lib/python3.12/site-packages/alarmdecoder/messages/panel_message.py:73: SyntaxWarning: invalid escape sequence '\['
  _regex = re.compile('^(!KPM:){0,1}(\[[a-fA-F0-9\-]+\]),([a-fA-F0-9]+),(\[[a-fA-F0-9]+\]),(".+")$')

2024-04-08 08:58:20.198 WARNING (ImportExecutor_0) [py.warnings] /usr/local/lib/python3.12/site-packages/alarmdecoder/zonetracking.py:186: SyntaxWarning: invalid escape sequence '\d'
  zone_regex = re.compile('^CHECK (\d+).*$')

This is caused by a change in Python 3.12 (see https://docs.python.org/dev/whatsnew/3.12.html#other-language-changes)

Should be a pretty easy fix to add and r in front of strings containing escape characters.

Zone fault expiration period too short for Vista 128 with 41 zones

The zone time out constant "EXPIRE = 30" in zonetracker is too short for Vista 128 panels with a larger number of zones -- this value needs to be 60 for those panels -- it would be nice if this could be made configurable to allow tuning for specific panel sizes.

Vista20SE Expander Zones Report as Wrong Zone Number

The issue is in the calculation here:

if panel_type == ADEMCO:
# TODO: This is going to need to be reworked to support the larger
# panels without fixed addressing on the expanders.
idx = address - 7 # Expanders start at address 7.
zone = address + channel + (idx * 7) + 1
elif panel_type == DSC:
zone = (address * 8) + channel

The Vista20SE is an ademco panel, so it falls under the first conditional.

The issue is, for the Vista20SE a fault on Zone 13 shows up as the following expander message:

!EXP:01,04,01

I gather that on other Ademco panels the "Address" portion of this starts with 7. But the Vista20SE panels it seems to start with 1. As a result in my case the calculated zone ends up being -36 instead of 13.

I realize the SE panels are old.

If this code is working properly on all other Ademco panels, I don't see a way out of this at least not automatically. The best solution is likely to alter the main alarm decoder package to handle SE panels as a distinct variant that can be configured on the device. That is more than I feel like dealing with.

The funny thing, is that things will work OK with this error. But the zone tracking for all of the expander zones is only handled by the alphanumeric messages. So many users may not notice the glitch, but as a result, expander zones will flutter ready and faulted as a result of the limitations of alphanumeric zone tracking. If things worked correctly, expander zones are never reported incorrectly.

For my own use, I may just fork off and fix what I need as this repo has become a little stale.

Error in on_arm documentation

In decoder.py:32:
on_arm = event.Event("This event is called when the panel is armed.\n\nCallback definition: def callback(device)")

But on line 621:
self.on_arm(stay=message.armed_home)

So I think the docs need to say that the API is "callback(device,stay)".

Delayed or never seeing messages if state does not change at startup of app.

if old_status is not None:

It looks like some alarm states will not generate on_ events upon startup. If the system restarts in Alarming state it wont report the alarm. Not a huge issue if we never restart. AFAIK restarts can happen in gunicorn on some timeouts and that could lead to a long series of repeated messages :(. Not want to change this but wanted to make a note and consider changes.

Zones alternate on and off

Zone status alternates between on and off when more than 8 zones are faulted.

The issue seems to be with EXPIRE being set to 30 in zonetracking.py. When more than 8 zones are faulted, the timeout expires before the faulted zone statuses can be refreshed. Increasing this value to 300 solved the issue in my setup with 42 zones.

Ideally, this variable could be available to adjust in the webapp.

is the API stable?

I see that the latest release is major version 0. Per http://semver.org/#spec-item-4 :

Major version zero (0.y.z) is for initial development. Anything may change at any time. The public API should not be considered stable.

So, this means that anyone developing against the library will have to fix their code against a specific version or commit, and not automatically get any bug fixes that may be release, or they risk the new version of code breaking their library.

Could you please release major version 1 so that developers can depend upon a stable API?

Thanks.

UnicodeDecodeError in multiple places

Every couple days, my USB AlarmDecoder seems to receive some string with garbage characters in it which causes my code to crash with the following exception. There's not a lot of consistency in the position or character. The same error can also occur on the decode commands in the decoder module.

I don't care if the data is discarded, since updates are so frequent, but it is problematic that this is an unhandled exception that crashes my app.

08/22 17:56:08.213 ERROR - 1305 - 40 Exception in thread Thread-1: 08/22 17:56:08.214 ERROR - 1305 - 40 Traceback (most recent call last): 08/22 17:56:08.214 ERROR - 1305 - 40 File "/usr/lib/python3.4/threading.py", line 920, in _bootstrap_inner 08/22 17:56:08.215 ERROR - 1305 - 40 self.run() 08/22 17:56:08.215 ERROR - 1305 - 40 File "/usr/local/lib/python3.4/dist-packages/alarmdecoder/devices.py", line 196, in run 08/22 17:56:08.216 ERROR - 1305 - 40 self._device.read_line(timeout=self.READ_TIMEOUT) 08/22 17:56:08.216 ERROR - 1305 - 40 File "/usr/local/lib/python3.4/dist-packages/alarmdecoder/devices.py", line 915, in read_line 08/22 17:56:08.217 ERROR - 1305 - 40 return data.decode('utf-8') 08/22 17:56:08.217 ERROR - 1305 - 40 UnicodeDecodeError: 'utf-8' codec can't decode byte 0xef in position 61: invalid continuation byte

Localized panel ROMs not working

I got an spanish localized Vista panel that send messages like:

[10000001000000003A--],008,[f70000071008001c08020000000000],"***DESARMADO*** Listo Para Armar"
[00000001000000000A--],002,[f70000071002000008020000000000],"FALLO 02        VOLUMET.HALL    "
[10000001000000003A--],008,[f70000071008001c08020000000000],"***DESARMADO*** Listo Para Armar"
[00000001000000000A--],002,[f70000071002000008020000000000],"FALLO 02        VOLUMET.HALL    "
[10000001000000003A--],008,[f70000071008001c08020000000000],"***DESARMADO*** Listo Para Armar"
[00010001000000003A--],008,[f70000071008000c08020000000000],"***DESARMADO*** * para fallos   "

breaking code that matches message strings "FAULT", ALARM", "SYSTEM" and "CHECK". As a result zone tracking is not working, nor sending "*" when needed and maybe something else. I've translated strings to match my panel on my local install and now it's working fine, but it would be great to add support for localized panels so integration with 3rd party like home assistant can be done easier.

Fire state tracking has timeout?

def _update_fire_status(self, message=None, status=None):

This and battery have some timeouts and states. I am guessing this was because of FIRE bouncing on / off? FIRE bit does disappear on "SYSTEM LO BAT" messages and I have been working on a patch for that as well. I would rather see FIRE be on_fire_change or just on_fire and have it report the bit. I am getting strange results currently.

AlarmDecoder thinks faulted zone is momentarily restored when a function key is pressed

Latest beta firmware.

There is a bug with the zone restore/fault parser when a function key is pressed on the keypad. Pressing the function key (either physically or by sending the ASCII codes) seems to trigger a repeat of the last output message as far as I can see in telnet. If this is a zone fault message, it confuses the zone restore/fault parser and causes it to report a momentary zone restore of the non-repeated zones. The bug doesn't occur if you press a function key within ~1 minute of previously pressing the function key. It seems to occur like 80% of the time with only one zone faulted, but with two+ zones faulted when you press the function key, the chances of all of them being falsely restored go up to 100%. If you have a "low battery" or another kind of non-zone message that happens to be the latest message when you press the function key, this doesn't occur.

[00000001000000000A--],009,[f700001f1009000008020000000000],"FAULT 09                        "
[00000001000000000A--],018,[f700001f1018000008020000000000],"FAULT 18                        "
[00000001000000000A--],009,[f700001f1009000008020000000000],"FAULT 09                        "
[00000001000000000A--],018,[f700001f1018000008020000000000],"FAULT 18                        "
[00000001000000000A--],009,[f700001f1009000008020000000000],"FAULT 09                        "
[00000001000000000A--],018,[f700001f1018000008020000000000],"FAULT 18                        "
[00000001000000000A--],009,[f700001f1009000008020000000000],"FAULT 09                        "
[00000001000000000A--],018,[f700001f1018000008020000000000],"FAULT 18                        "
[00010001000000000A--],018,[f700001f1018000008020000000000],"FAULT 18                        " โ† Pressed the function button here, and the repeated Zone 18 message accompanied with a momentary restore of Zone 9 occurs
[00010001000000000A--],009,[f700001f1009000008020000000000],"FAULT 09                        "
[00010001000000000A--],018,[f700001f1018000008020000000000],"FAULT 18                        "
[00010001000000000A--],009,[f700001f1009000008020000000000],"FAULT 09                        "

Build 1.13.5 and publish to pypi

This is almost entirely self serving. I have some pull requests in at homeassistant that depend on the pull requests I submitted here. They were merged but no new version was published.

Thanks!

ERROR: Error sending notification for Alarm Update:

After going thru 'update' step in alarmdecoder web app screen, i am no longer getting emails from system. Email notification 'save and test' works. Looking at app log, looks like error in decoder.py:

2017-02-16 13:56:33,752 INFO: AlarmDecoder Webapp booting up - v0.7.1-0-g2e4492f [in /opt/alarmdecoder-webapp/ad2web/decoder.py:214]
2017-02-16 13:56:34,145 INFO: Discovery running: loc=10.0.1.2:5000, uuid=e6719d35-d7af-11e6-aafb-b827ebad6eb0 [in /opt/alarmdecoder-webapp/ad2web/discovery.py:69]
2017-02-16 13:56:34,167 INFO: Attempting to reconnect to the AlarmDecoder [in /opt/alarmdecoder-webapp/ad2web/decoder.py:481]
2017-02-16 13:56:35,179 INFO: AlarmDecoder device was opened. [in /opt/alarmdecoder-webapp/ad2web/decoder.py:339]
2017-02-16 13:56:41,558 INFO: Event: The alarm system has been armed. [in /opt/alarmdecoder-webapp/ad2web/notifications/types.py:262]
2017-02-16 13:56:41,671 ERROR: Error sending notification for Alarm Update: invalid literal for int() with base 10: '' [in /opt/alarmdecoder-webapp/ad2web/decoder.py:399]
2017-02-16 13:56:46,479 INFO: Event: The alarm system has been disarmed. [in /opt/alarmdecoder-webapp/ad2web/notifications/types.py:262]
2017-02-16 13:56:46,573 ERROR: Error sending notification for Alarm Update: invalid literal for int() with base 10: '' [in /opt/alarmdecoder-webapp/ad2web/decoder.py:399]

on_alarm and on_alarm_restored zone type?

The callback on_zone_fault passes the zone as an integer. The callbacks on_alarm and on_alarm_restored pass the zone as a string. Should these be consistent? It seems like the alarm callbacks should be changed to pass the zone as an integer.

"Events" log (zone events) log with UTC timestamps despite setting timezone

The other two logs (Live and App) log in the local timezone as expected, but the Events log (the one that displays zone faults and restores, fire alarms, etc.) on the web app seems to always log in UTC time regardless of the local timezone set with dpkg-reconfigure tzdata and displayed with timedatctl or date.

Inefficient socket reading causes failures in home assistant

I'm using my alarmdecoder (AD) with a ser2sock front end in a home assistant installation (HA). When I just have a basic HA with AD and no other components, everything works fine. However, when I add a lot of other integrations into HA, then AD starts missing events - I have multiple wireless zones that report open and never close (or closed and never opened). Unfortunately there is no logging in the library so I can't easily debug where these message are being lost. But - because everything works fine with just HA+AD and it's only if I add more components to HA does it start to fail, I believe I know what the problem is.

HA works using async IO everywhere. The AD network code is very inefficient - it calls select() and reads one character a time when the select triggers. I'm not sure why that's the case but I'm pretty certain that's what's causing the issue as I believe the AD code isn't being run often enough to read all the messages.

A fairly simple change to recv() to read as much data as there and then split that into lines for processing should help. Switching to the the more efficient poll system or better yet, the selectors library would also help.

To help fix my HA problems, I wrote a small alarmdecoder->MQTT bridge app that runs outside HA so it doesn't have any problems with the HA event loop. You can find a the read/parse code I used there as an example if that helps.

Expander Zones Are Reported in Messages

zonetracking.py contains this note:

                # NOTE: Expander zone faults are handled differently than
                #       regular messages.  We don't include them in
                #       self._zones_faulted because they are not reported
                #       by the panel in it's rolling list of faults.

At least on my panel (Vista 20SE) the expander zones are still reported in the rolling messages. They are also reported as ready or faulted using the !EXP messages. Because they appear in the rolling message list, _clear_zones ends up placing them in the _zones_faulted array anyways.

The only concern this causes, is that any error in _clear_zones such as #50 will affect expander zones when it doesn't need to.

pip install is wrong version

Using pip installs an old version of alarmdecoder that does not have class definitions needed by newest alarmdecoder-webapp.

Emulate smoke / co virtual zone

When using the option to emulate a virtual zone (zone expander on Vista Panels) is there a way to send the appropriate signal for fire or co trouble? I have the zone type set to fire but it just says the smoke is offline, not that there is a fire signal when I open the Zone using L0481.

I would have posted this in the forum but no one ever approved my account.

If we ignore processing of states we still process fire state?

self._update_fire_status(status=None)

This is likely a code path that is followed. By default the class is constructed with _ignore_message_states as a False.
Also if _update_internal_states is called directly then it already checks for self._ignore_message_states and then does "not" call update_fire_status so in this case fire is not tracked if this routine is called directly.

AD2 Ready Open

Just recently got AlarmDecoder setup with SmartThings via AD2Pi device with my own provided RPi.

However, when I arm the system through SmartThings SHM the AD2 Ready contact opens and immediately indicates that there is an intrusion detected, I get a text message indicating the intrusion, and SHM also indicates that the "siren and audio were muted"

When the system is not armed, AD2 Ready will flip between open/close as motion sensors etc are tripped.

Any ideas what the issue might be?

system fault bit can be '-'

My alarmdecoder output is much like the example cited at https://www.openhab.org/addons/bindings/alarmdecoder1/:
[0000000110000000----],005,[f70000ff1005000028020000000000],"FAULT 05 MUSIC ROOM WINDOW "
, i.e. the last 4 bits of the bitfield are '----'

I believe the change 0231296 breaks this pattern by expecting that the system_fault is always a hex value whereas on mine it's a '-' as in the example above.

In this really basic example I print my incoming data and it crashes out in handle_message. Note the bitfield is "[0010000100000000----]" so bit 17 is '-' and not castable to int.

testalarmdecoder.txt

data: !>
data: !CONFIG>ADDRESS=18&CONFIGBITS=ff00&LRR=N&EXP=NNNNN&REL=YYYY&MASK=ffffffff&DEDUPLICATE=N
data: !VER:ffffffff,V2.2a.6,TX;RX;SM;VZ;RF;ZX;RE;AU;3X;CG;DD;MF;LR;KE;MK;CB
data: [0010000100000000----],008,[f88000ff1008008c08020000000000],"ARMED ***STAY***                "
Exception in thread Thread-1:
Traceback (most recent call last):
  File "/usr/lib/python3.6/threading.py", line 916, in _bootstrap_inner
    self.run()
  File "/home/tmp/.local/lib/python3.6/site-packages/alarmdecoder/devices/base_device.py", line 148, in run
    self._device.read_line(timeout=self.READ_TIMEOUT)
  File "/home/tmp/.local/lib/python3.6/site-packages/alarmdecoder/devices/socket_device.py", line 356, in read_line
    self.on_read(data=ret)
  File "/home/tmp/.local/lib/python3.6/site-packages/alarmdecoder/event/event.py", line 84, in fire
    func(self.obj, *args, **kwargs)
  File "/home/tmp/.local/lib/python3.6/site-packages/alarmdecoder/decoder.py", line 1041, in _on_read
    self._handle_message(data)
  File "/home/tmp/.local/lib/python3.6/site-packages/alarmdecoder/decoder.py", line 439, in _handle_message
    msg = self._handle_keypad_message(data)
  File "/home/tmp/.local/lib/python3.6/site-packages/alarmdecoder/decoder.py", line 477, in _handle_keypad_message
    msg = Message(data)
  File "/home/tmp/.local/lib/python3.6/site-packages/alarmdecoder/messages/panel_message.py", line 85, in __init__
    self._parse_message(data)
  File "/home/tmp/.local/lib/python3.6/site-packages/alarmdecoder/messages/panel_message.py", line 121, in _parse_message
    self.system_fault = int(self.bitfield[17], 16)
ValueError: invalid literal for int() with base 16: '-'

Alarm Decoder Disconnect - Related to Home Assistant?

Hello Alarm Decoder team, while using Home Assistant, the following error was reported from Alarm Decoder. I am very hopeful you are able to help, I quite enjoy using alarm decoder with my home automation system.

For more information, see:
home-assistant/core#14352

Error during setup of component alarmdecoder
Traceback (most recent call last):
File "/usr/lib/python3.6/site-packages/homeassistant/setup.py", line 145, in _async_setup_component
component.setup, hass, processed_config)
File "/usr/lib/python3.6/concurrent/futures/thread.py", line 56, in run
result = self.fn(*self.args, **self.kwargs)
File "/usr/lib/python3.6/site-packages/homeassistant/components/alarmdecoder.py", line 166, in setup
AlarmDecoder(USBDevice.find())
File "/usr/lib/python3.6/site-packages/alarmdecoder/devices/usb_device.py", line 109, in find
raise ImportError('The USBDevice class has been disabled due to missing requirement: pyftdi or pyusb.')
ImportError: The USBDevice class has been disabled due to missing requirement: pyftdi or pyusb.

Feature Request: Add armed instant status

I would love to be able to check if my alarm is in instant mode and change my smartthings behavior accordingly. I have pets so I never arm my alarm in away mode unless we are on vacation and have the pets boarded. If we are leaving the house, we arm stay, before we go to bed for the night we arm instant. I'd like to differentiate between those so I can do something like the following.

If the alarm is armed_stay, turn on interior and exterior security cameras. If the alarm is armed_instant, only turn on the external security cameras.

serial_device read_line() does not parse lines correctly

Under certain circumstances read_line() does not properly detect the \r\n end of line sequence. This function reads all the data waiting in the serial device buffer and parses it up to the first \r\n. It then saves any remainder in self._buffer for the next function invocation. If that remainder contains a \r\n then the newline is not detected. This results in messages that are concatenated together with \r\n between them.

This occurs because any data waiting in self._buffer is not parsed for newlines.

AD2PI firmware failure - attempting to recover

I noticed this issue back in January and tried to contact Nu Tech for support by email and forums but never got a response or account activated. There is no GitHub project for the AD2PI firmware/hardware, and this seems like the next best location.


Background:

This issue started following a power supply problem with the RPi. The RPi would not boot and made a "hissing" sound. After replacing the USB power supply with a new one and rebuilding the SD card (using the AlarmDecoder image) it booted and there were no unusual sounds.

Issue:

In the AlarmDecoder webapp, the AD2PI was failing setup tests. The webapp prompted "firmware update available", but the update page now displayed the firmware version as "unknown". Attempting to update the FW from the webapp would not complete.

After this I shelled in and tried using ad2-firmwareupload with both localhost:10000 and /dev/serial0 (with ser2sock, nginx, and gunicorn stopped). Both methods only output:

Flashing device: localhost:10000 - 115200 baud
Firmware: ./ademcoemu_V2-2a-8-8.hex

..but nothing else and were still running after 30 minutes.

I also tried using screen to open /dev/serial0. Initially, if I pressed "!" the console would output "!no", "!wait", and a lot of garbage characters. On one attempt this test also output "!lboot" and "!load" but has not been reproducible using screen. The latest attempts using screen will output nothing.

Since then I have also tried using tcpdump to capture ser2sock communication to localhost:10000. In most cases ad2-firmwareupload will open the connection and ser2sock will return a few single-byte payloads and then stop communication (connection is still open). In one case, ser2sock eventually returned "!wait" followed by "!load", then ad2-firmwareupload sent several packets of ASCII data in the form of:

:10000 0000F724 70E23CA3 C4D82C4E E148E43C E8C31
:10000 80039DAA B5279A08 A5D82C4E E148E43C E8C65
:10001 000816CC 9FB056D5 FE26A8EC F0316196 61D00
:10002 00032008 A3DAF0BC 3742F809 946F86CE 50A05
:10003 0000AB18 47DB0743 A53D60F8 25B85CB1 C61C4
...

The reply from ser2sock after every packet in this sequence was always:

!0000 :0000

After 11 such data packets ser2sock stopped replying and ad2-firmwareupload stopped sending. This was the only attempt that even got this far. I can share the .PCAP file if needed (note: if I still have it from 10 months ago).

Request:

My question is what is happening here? Is my AD2PI recoverable, and if so what procedure is involved?

test failure (python3 related?)

I'm getting some test failures while trying to package this for NixOS.

Any suggestions?

> nix-build -A python3Packages.alarmdecoder
these derivations will be built:
  /nix/store/djkyiv0n4si16ddq2b87cfj02db7jyg1-python3.7-alarmdecoder-1.13.9.drv
building '/nix/store/djkyiv0n4si16ddq2b87cfj02db7jyg1-python3.7-alarmdecoder-1.13.9.drv'...
Sourcing python-remove-tests-dir-hook
Sourcing python-catch-conflicts-hook.sh
Sourcing python-remove-bin-bytecode-hook.sh
Sourcing setuptools-build-hook
Using setuptoolsBuildPhase
Using setuptoolsShellHook
Sourcing pip-install-hook
Using pipInstallPhase
Sourcing python-imports-check-hook.sh
Using pythonImportsCheckPhase
Sourcing setuptools-check-hook
Using setuptoolsCheckPhase
unpacking sources
unpacking source archive /nix/store/4wvlpznnsc6j4zk6d1c2935ylppjaqrj-source
source root is source
setting SOURCE_DATE_EPOCH to timestamp 315619200 of file source/test/test_zonetracking.py
patching sources
configuring
no configure script, doing nothing
building
Executing setuptoolsBuildPhase
running bdist_wheel
running build
running build_py
creating build
creating build/lib
creating build/lib/alarmdecoder
copying alarmdecoder/zonetracking.py -> build/lib/alarmdecoder
copying alarmdecoder/util.py -> build/lib/alarmdecoder
copying alarmdecoder/states.py -> build/lib/alarmdecoder
copying alarmdecoder/panels.py -> build/lib/alarmdecoder
copying alarmdecoder/decoder.py -> build/lib/alarmdecoder
copying alarmdecoder/__init__.py -> build/lib/alarmdecoder
creating build/lib/alarmdecoder/devices
copying alarmdecoder/devices/usb_device.py -> build/lib/alarmdecoder/devices
copying alarmdecoder/devices/socket_device.py -> build/lib/alarmdecoder/devices
copying alarmdecoder/devices/serial_device.py -> build/lib/alarmdecoder/devices
copying alarmdecoder/devices/base_device.py -> build/lib/alarmdecoder/devices
copying alarmdecoder/devices/__init__.py -> build/lib/alarmdecoder/devices
creating build/lib/alarmdecoder/event
copying alarmdecoder/event/event.py -> build/lib/alarmdecoder/event
copying alarmdecoder/event/__init__.py -> build/lib/alarmdecoder/event
creating build/lib/alarmdecoder/messages
copying alarmdecoder/messages/rf_message.py -> build/lib/alarmdecoder/messages
copying alarmdecoder/messages/panel_message.py -> build/lib/alarmdecoder/messages
copying alarmdecoder/messages/expander_message.py -> build/lib/alarmdecoder/messages
copying alarmdecoder/messages/base_message.py -> build/lib/alarmdecoder/messages
copying alarmdecoder/messages/aui_message.py -> build/lib/alarmdecoder/messages
copying alarmdecoder/messages/__init__.py -> build/lib/alarmdecoder/messages
creating build/lib/alarmdecoder/messages/lrr
copying alarmdecoder/messages/lrr/system.py -> build/lib/alarmdecoder/messages/lrr
copying alarmdecoder/messages/lrr/message.py -> build/lib/alarmdecoder/messages/lrr
copying alarmdecoder/messages/lrr/events.py -> build/lib/alarmdecoder/messages/lrr
copying alarmdecoder/messages/lrr/__init__.py -> build/lib/alarmdecoder/messages/lrr
running egg_info
creating alarmdecoder.egg-info
writing alarmdecoder.egg-info/PKG-INFO
writing dependency_links to alarmdecoder.egg-info/dependency_links.txt
writing requirements to alarmdecoder.egg-info/requires.txt
writing top-level names to alarmdecoder.egg-info/top_level.txt
writing manifest file 'alarmdecoder.egg-info/SOURCES.txt'
reading manifest file 'alarmdecoder.egg-info/SOURCES.txt'
reading manifest template 'MANIFEST.in'
writing manifest file 'alarmdecoder.egg-info/SOURCES.txt'
running build_scripts
creating build/scripts-3.7
copying and adjusting bin/ad2-sslterm -> build/scripts-3.7
copying and adjusting bin/ad2-firmwareupload -> build/scripts-3.7
changing mode of build/scripts-3.7/ad2-sslterm from 644 to 755
changing mode of build/scripts-3.7/ad2-firmwareupload from 644 to 755
installing to build/bdist.linux-x86_64/wheel
running install
running install_lib
creating build/bdist.linux-x86_64
creating build/bdist.linux-x86_64/wheel
creating build/bdist.linux-x86_64/wheel/alarmdecoder
creating build/bdist.linux-x86_64/wheel/alarmdecoder/messages
creating build/bdist.linux-x86_64/wheel/alarmdecoder/messages/lrr
copying build/lib/alarmdecoder/messages/lrr/__init__.py -> build/bdist.linux-x86_64/wheel/alarmdecoder/messages/lrr
copying build/lib/alarmdecoder/messages/lrr/events.py -> build/bdist.linux-x86_64/wheel/alarmdecoder/messages/lrr
copying build/lib/alarmdecoder/messages/lrr/message.py -> build/bdist.linux-x86_64/wheel/alarmdecoder/messages/lrr
copying build/lib/alarmdecoder/messages/lrr/system.py -> build/bdist.linux-x86_64/wheel/alarmdecoder/messages/lrr
copying build/lib/alarmdecoder/messages/__init__.py -> build/bdist.linux-x86_64/wheel/alarmdecoder/messages
copying build/lib/alarmdecoder/messages/aui_message.py -> build/bdist.linux-x86_64/wheel/alarmdecoder/messages
copying build/lib/alarmdecoder/messages/base_message.py -> build/bdist.linux-x86_64/wheel/alarmdecoder/messages
copying build/lib/alarmdecoder/messages/expander_message.py -> build/bdist.linux-x86_64/wheel/alarmdecoder/messages
copying build/lib/alarmdecoder/messages/panel_message.py -> build/bdist.linux-x86_64/wheel/alarmdecoder/messages
copying build/lib/alarmdecoder/messages/rf_message.py -> build/bdist.linux-x86_64/wheel/alarmdecoder/messages
creating build/bdist.linux-x86_64/wheel/alarmdecoder/event
copying build/lib/alarmdecoder/event/__init__.py -> build/bdist.linux-x86_64/wheel/alarmdecoder/event
copying build/lib/alarmdecoder/event/event.py -> build/bdist.linux-x86_64/wheel/alarmdecoder/event
creating build/bdist.linux-x86_64/wheel/alarmdecoder/devices
copying build/lib/alarmdecoder/devices/__init__.py -> build/bdist.linux-x86_64/wheel/alarmdecoder/devices
copying build/lib/alarmdecoder/devices/base_device.py -> build/bdist.linux-x86_64/wheel/alarmdecoder/devices
copying build/lib/alarmdecoder/devices/serial_device.py -> build/bdist.linux-x86_64/wheel/alarmdecoder/devices
copying build/lib/alarmdecoder/devices/socket_device.py -> build/bdist.linux-x86_64/wheel/alarmdecoder/devices
copying build/lib/alarmdecoder/devices/usb_device.py -> build/bdist.linux-x86_64/wheel/alarmdecoder/devices
copying build/lib/alarmdecoder/__init__.py -> build/bdist.linux-x86_64/wheel/alarmdecoder
copying build/lib/alarmdecoder/decoder.py -> build/bdist.linux-x86_64/wheel/alarmdecoder
copying build/lib/alarmdecoder/panels.py -> build/bdist.linux-x86_64/wheel/alarmdecoder
copying build/lib/alarmdecoder/states.py -> build/bdist.linux-x86_64/wheel/alarmdecoder
copying build/lib/alarmdecoder/util.py -> build/bdist.linux-x86_64/wheel/alarmdecoder
copying build/lib/alarmdecoder/zonetracking.py -> build/bdist.linux-x86_64/wheel/alarmdecoder
running install_egg_info
Copying alarmdecoder.egg-info to build/bdist.linux-x86_64/wheel/alarmdecoder-1.13.9-py3.7.egg-info
running install_scripts
creating build/bdist.linux-x86_64/wheel/alarmdecoder-1.13.9.data
creating build/bdist.linux-x86_64/wheel/alarmdecoder-1.13.9.data/scripts
copying build/scripts-3.7/ad2-firmwareupload -> build/bdist.linux-x86_64/wheel/alarmdecoder-1.13.9.data/scripts
copying build/scripts-3.7/ad2-sslterm -> build/bdist.linux-x86_64/wheel/alarmdecoder-1.13.9.data/scripts
changing mode of build/bdist.linux-x86_64/wheel/alarmdecoder-1.13.9.data/scripts/ad2-firmwareupload to 755
changing mode of build/bdist.linux-x86_64/wheel/alarmdecoder-1.13.9.data/scripts/ad2-sslterm to 755
adding license file "LICENSE" (matched pattern "LICEN[CS]E*")
creating build/bdist.linux-x86_64/wheel/alarmdecoder-1.13.9.dist-info/WHEEL
creating 'dist/alarmdecoder-1.13.9-py3-none-any.whl' and adding 'build/bdist.linux-x86_64/wheel' to it
adding 'alarmdecoder/__init__.py'
adding 'alarmdecoder/decoder.py'
adding 'alarmdecoder/panels.py'
adding 'alarmdecoder/states.py'
adding 'alarmdecoder/util.py'
adding 'alarmdecoder/zonetracking.py'
adding 'alarmdecoder/devices/__init__.py'
adding 'alarmdecoder/devices/base_device.py'
adding 'alarmdecoder/devices/serial_device.py'
adding 'alarmdecoder/devices/socket_device.py'
adding 'alarmdecoder/devices/usb_device.py'
adding 'alarmdecoder/event/__init__.py'
adding 'alarmdecoder/event/event.py'
adding 'alarmdecoder/messages/__init__.py'
adding 'alarmdecoder/messages/aui_message.py'
adding 'alarmdecoder/messages/base_message.py'
adding 'alarmdecoder/messages/expander_message.py'
adding 'alarmdecoder/messages/panel_message.py'
adding 'alarmdecoder/messages/rf_message.py'
adding 'alarmdecoder/messages/lrr/__init__.py'
adding 'alarmdecoder/messages/lrr/events.py'
adding 'alarmdecoder/messages/lrr/message.py'
adding 'alarmdecoder/messages/lrr/system.py'
adding 'alarmdecoder-1.13.9.data/scripts/ad2-firmwareupload'
adding 'alarmdecoder-1.13.9.data/scripts/ad2-sslterm'
adding 'alarmdecoder-1.13.9.dist-info/LICENSE'
adding 'alarmdecoder-1.13.9.dist-info/METADATA'
adding 'alarmdecoder-1.13.9.dist-info/WHEEL'
adding 'alarmdecoder-1.13.9.dist-info/top_level.txt'
adding 'alarmdecoder-1.13.9.dist-info/RECORD'
removing build/bdist.linux-x86_64/wheel
Finished executing setuptoolsBuildPhase
installing
Executing pipInstallPhase
/build/source/dist /build/source
Processing ./alarmdecoder-1.13.9-py3-none-any.whl
Requirement already satisfied: pyserial>=2.7 in /nix/store/rl6rl4g137pgrg22cnkkqwh8xd43wcx3-python3.7-pyserial-3.4/lib/python3.7/site-packages (from alarmdecoder==1.13.9) (3.4)
Installing collected packages: alarmdecoder
Successfully installed alarmdecoder-1.13.9
/build/source
Finished executing pipInstallPhase
post-installation fixup
shrinking RPATHs of ELF executables and libraries in /nix/store/kx0ja8vxy5dv7f1431jb6s7a6jzn9ph2-python3.7-alarmdecoder-1.13.9
strip is /nix/store/nfs9wf6ipffr9g9ylzb4i9c1i607nxvq-binutils-2.31.1/bin/strip
stripping (with command strip and flags -S) in /nix/store/kx0ja8vxy5dv7f1431jb6s7a6jzn9ph2-python3.7-alarmdecoder-1.13.9/lib  /nix/store/kx0ja8vxy5dv7f1431jb6s7a6jzn9ph2-python3.7-alarmdecoder-1.13.9/bin
patching script interpreter paths in /nix/store/kx0ja8vxy5dv7f1431jb6s7a6jzn9ph2-python3.7-alarmdecoder-1.13.9
checking for references to /build/ in /nix/store/kx0ja8vxy5dv7f1431jb6s7a6jzn9ph2-python3.7-alarmdecoder-1.13.9...
Rewriting #!/nix/store/xb1mp0f16lv23rwhfdc1665v5r20jfmm-python3-3.7.6/bin/python3.7 to #!/nix/store/xb1mp0f16lv23rwhfdc1665v5r20jfmm-python3-3.7.6
wrapping `/nix/store/kx0ja8vxy5dv7f1431jb6s7a6jzn9ph2-python3.7-alarmdecoder-1.13.9/bin/ad2-sslterm'...
Rewriting #!/nix/store/xb1mp0f16lv23rwhfdc1665v5r20jfmm-python3-3.7.6/bin/python3.7 to #!/nix/store/xb1mp0f16lv23rwhfdc1665v5r20jfmm-python3-3.7.6
wrapping `/nix/store/kx0ja8vxy5dv7f1431jb6s7a6jzn9ph2-python3.7-alarmdecoder-1.13.9/bin/ad2-firmwareupload'...
Executing pythonRemoveTestsDir
Finished executing pythonRemoveTestsDir
running install tests
no Makefile or custom buildPhase, doing nothing
pythonCatchConflictsPhase
pythonRemoveBinBytecodePhase
pythonImportsCheckPhase
Executing pythonImportsCheckPhase
Check whether the following modules can be imported: alarmdecoder
setuptoolsCheckPhase
Executing setuptoolsCheckPhase
running test
WARNING: Testing via this command is deprecated and will be removed in a future version. Users looking for a generic test entry point independent of test runner are encouraged to use tox.
running egg_info
writing alarmdecoder.egg-info/PKG-INFO
writing dependency_links to alarmdecoder.egg-info/dependency_links.txt
writing requirements to alarmdecoder.egg-info/requires.txt
writing top-level names to alarmdecoder.egg-info/top_level.txt
reading manifest file 'alarmdecoder.egg-info/SOURCES.txt'
reading manifest template 'MANIFEST.in'
writing manifest file 'alarmdecoder.egg-info/SOURCES.txt'
running build_ext
/build/source/alarmdecoder/decoder.py:605: DeprecationWarning: invalid escape sequence \.
  matches = re.match('^!Sending(\.{1,5})done.*', data)
/build/source/alarmdecoder/messages/panel_message.py:73: DeprecationWarning: invalid escape sequence \[
  _regex = re.compile('^(!KPM:){0,1}(\[[a-fA-F0-9\-]+\]),([a-fA-F0-9]+),(\[[a-fA-F0-9]+\]),(".+")$')
/build/source/alarmdecoder/zonetracking.py:188: DeprecationWarning: invalid escape sequence \d
  zone_regex = re.compile('^CHECK (\d+).*$')
test_alarm_event (test.test_ad2.TestAlarmDecoder) ... ok
test_armed_away_event (test.test_ad2.TestAlarmDecoder) ... ok
test_battery_low_event (test.test_ad2.TestAlarmDecoder) ... ok
test_boot (test.test_ad2.TestAlarmDecoder) ... ok
test_chime_changed_event (test.test_ad2.TestAlarmDecoder) ... ok
test_clear_zone (test.test_ad2.TestAlarmDecoder) ... ok
test_close (test.test_ad2.TestAlarmDecoder) ... ok
test_config_message (test.test_ad2.TestAlarmDecoder) ... /build/source/test/test_ad2.py:232: DeprecationWarning: Please use assertEqual instead.
  self.assertEquals(self._decoder.mode, ADEMCO)
ok
test_expander_message (test.test_ad2.TestAlarmDecoder) ... ok
test_fault (test.test_ad2.TestAlarmDecoder) ... ok
test_fault_wireproblem (test.test_ad2.TestAlarmDecoder) ... ok
test_fire_alarm_event (test.test_ad2.TestAlarmDecoder) ... ok
test_fire_lrr (test.test_ad2.TestAlarmDecoder) ... ok
test_get_config (test.test_ad2.TestAlarmDecoder) ... ok
test_hit_for_faults (test.test_ad2.TestAlarmDecoder) ... ok
test_message (test.test_ad2.TestAlarmDecoder) ... ok
test_message_kpm (test.test_ad2.TestAlarmDecoder) ... ok
test_open (test.test_ad2.TestAlarmDecoder) ... ok
test_panic_v1 (test.test_ad2.TestAlarmDecoder) ... ok
test_panic_v2 (test.test_ad2.TestAlarmDecoder) ... ok
test_power_changed_event (test.test_ad2.TestAlarmDecoder) ... ok
test_ready_changed_event (test.test_ad2.TestAlarmDecoder) ... ok
test_reboot (test.test_ad2.TestAlarmDecoder) ... ok
test_relay_message (test.test_ad2.TestAlarmDecoder) ... ok
test_rfx_message (test.test_ad2.TestAlarmDecoder) ... ok
test_save_config (test.test_ad2.TestAlarmDecoder) ... ok
test_send (test.test_ad2.TestAlarmDecoder) ... ok
test_sending_received (test.test_ad2.TestAlarmDecoder) ... ok
test_zone_bypassed_event (test.test_ad2.TestAlarmDecoder) ... ok
test_zone_fault_and_restore (test.test_ad2.TestAlarmDecoder) ... ok
test_open (test.test_devices.TestSerialDevice) ... ok
test_open_failed (test.test_devices.TestSerialDevice) ... ok
test_open_no_interface (test.test_devices.TestSerialDevice) ... ok
test_read (test.test_devices.TestSerialDevice) ... ok
test_read_exception (test.test_devices.TestSerialDevice) ... ok
test_read_line (test.test_devices.TestSerialDevice) ... /build/source/test/test_devices.py:112: DeprecationWarning: Please use assertEqual instead.
  self.assertEquals(ret, "testing")
ok
test_read_line_exception (test.test_devices.TestSerialDevice) ... ok
test_read_line_timeout (test.test_devices.TestSerialDevice) ... ok
test_write (test.test_devices.TestSerialDevice) ... ok
test_write_exception (test.test_devices.TestSerialDevice) ... ok
test_open (test.test_devices.TestSocketDevice) ... ok
test_open_failed (test.test_devices.TestSocketDevice) ... ok
test_read (test.test_devices.TestSocketDevice) ... ok
test_read_exception (test.test_devices.TestSocketDevice) ... ok
test_read_line (test.test_devices.TestSocketDevice) ... ok
test_read_line_exception (test.test_devices.TestSocketDevice) ... ok
test_read_line_timeout (test.test_devices.TestSocketDevice) ... ok
test_ssl (test.test_devices.TestSocketDevice) ... ERROR
test_ssl_exception (test.test_devices.TestSocketDevice) ... ERROR
test_write (test.test_devices.TestSocketDevice) ... ok
test_write_exception (test.test_devices.TestSocketDevice) ... ok
test_expander_message_parse (test.test_messages.TestMessages) ... ok
test_expander_message_parse_fail (test.test_messages.TestMessages) ... ok
test_lrr_event_code_override (test.test_messages.TestMessages) ... /build/source/test/test_messages.py:88: DeprecationWarning: Please use assertEqual instead.
  self.assertEquals(msg.event_code, LRR_CID_EVENT.OPENCLOSE_BY_USER)  # 400 -> 401
ok
test_lrr_message_parse_fail (test.test_messages.TestMessages) ... ok
test_lrr_message_parse_v1 (test.test_messages.TestMessages) ... ok
test_lrr_message_parse_v2 (test.test_messages.TestMessages) ... ok
test_message_parse (test.test_messages.TestMessages) ... ok
test_message_parse_fail (test.test_messages.TestMessages) ... ok
test_rf_message_parse (test.test_messages.TestMessages) ... ok
test_rf_message_parse_fail (test.test_messages.TestMessages) ... ok
test_ECP_failure (test.test_zonetracking.TestZonetracking) ... ok
test_message_fault_text (test.test_zonetracking.TestZonetracking) ... ok
test_message_ready (test.test_zonetracking.TestZonetracking) ... ok
test_zone_fault (test.test_zonetracking.TestZonetracking) ... ok
test_zone_multi_zone_skip_restore (test.test_zonetracking.TestZonetracking) ... ok
test_zone_out_of_order_fault (test.test_zonetracking.TestZonetracking) ... ok
test_zone_restore (test.test_zonetracking.TestZonetracking) ... ok
test_zone_restore_skip (test.test_zonetracking.TestZonetracking) ... ok
test_zone_timeout_restore (test.test_zonetracking.TestZonetracking) ... ok

======================================================================
ERROR: test_ssl (test.test_devices.TestSocketDevice)
----------------------------------------------------------------------
Traceback (most recent call last):
  File "/build/source/test/test_devices.py", line 251, in test_ssl
    with patch.object(socket.socket, '_sock'):
  File "/nix/store/bzvlpxbjp2pp0ag06vl8a1abyy8yr7gl-python3.7-mock-3.0.5/lib/python3.7/site-packages/mock/mock.py", line 1394, in __enter__
    original, local = self.get_original()
  File "/nix/store/bzvlpxbjp2pp0ag06vl8a1abyy8yr7gl-python3.7-mock-3.0.5/lib/python3.7/site-packages/mock/mock.py", line 1368, in get_original
    "{} does not have the attribute {!r}".format(target, name)
AttributeError: <class 'socket.socket'> does not have the attribute '_sock'

======================================================================
ERROR: test_ssl_exception (test.test_devices.TestSocketDevice)
----------------------------------------------------------------------
Traceback (most recent call last):
  File "/build/source/test/test_devices.py", line 278, in test_ssl_exception
    with patch.object(socket.socket, '_sock'):
  File "/nix/store/bzvlpxbjp2pp0ag06vl8a1abyy8yr7gl-python3.7-mock-3.0.5/lib/python3.7/site-packages/mock/mock.py", line 1394, in __enter__
    original, local = self.get_original()
  File "/nix/store/bzvlpxbjp2pp0ag06vl8a1abyy8yr7gl-python3.7-mock-3.0.5/lib/python3.7/site-packages/mock/mock.py", line 1368, in get_original
    "{} does not have the attribute {!r}".format(target, name)
AttributeError: <class 'socket.socket'> does not have the attribute '_sock'

----------------------------------------------------------------------
Ran 70 tests in 0.524s

FAILED (errors=2)
Test failed: <unittest.runner.TextTestResult run=70 errors=2 failures=0>
error: Test failed: <unittest.runner.TextTestResult run=70 errors=2 failures=0>
builder for '/nix/store/djkyiv0n4si16ddq2b87cfj02db7jyg1-python3.7-alarmdecoder-1.13.9.drv' failed with exit code 1
error: build of '/nix/store/djkyiv0n4si16ddq2b87cfj02db7jyg1-python3.7-alarmdecoder-1.13.9.drv' failed
> 

_handle_config() throws error on certain data values - 1.13.9

I discovered this bug in the process of attempting to upgrade Home Assistant to use AlarmDecoder 1.13.9 (we're currently stuck on 1.13.2 with the pinned pyserial and futures dependencies).

It looks like there are some invalid values being passed to the _handle_config() function that causes AlarmDecoder to crash with the following error:

ValueError: too many values to unpack (expected 2)

I captured a screenshot from the Python debugger below

ad_stacktrace

The problematic data value is:

!CONFIG>MODE=A&CONFIGBITS=ff05&ADDRESS=19&LRR=N&COM=N&EXP=NNNNN&REL=NNNN&MASK=ffffffff&DEDUPLICATE=N\r\n!Reading configuration.\r\n!UART init.\r\n!VER:ffffffff,V2.2a.8.8,TX;RX;SM;VZ;RF;ZX;RE;AU;3X;CG;DD;MF;L2;KE;M2;CB;DS;ER;CR\r\n!>\r\n!CONFIG>MODE=A&CONFIGBITS=ff05&ADDRESS=19&LRR=N&COM=N&EXP=NNNNN&REL=NNNN&MASK=ffffffff&DEDUPLICATE=N\r\n!Reading configuration.\r\n!UART init.\r\n!VER:ffffffff,V2.2a.8.8,TX;RX;SM;VZ;RF;ZX;RE;AU;3X;CG;DD;MF;L2;KE;M2;CB;DS;ER;CR\r\n!AUI:1606000000006363024543f531fb456cf5ec01010201

When you run data.split('>') on the above value it returns 4 values instead of 2, thus causing the error:

image

pyserial requirements.txt breaks homeassistant

The highest version of alarmdecoder published on pypi is 1.13.6, but the commit that fixed requirements.txt to allow pyserial>=2.7 instead of pyserial==2.7 was made after that release.

Hard setting pyserial to 2.7 breaks insteonplm in homeassistant. Please ship a new version to pypi with the requirements.txt patch.

Parsing error of older firmware 2.2a.8.6 causes exception.

Old 2.2a.8.6 firmware causes an exception.

[2019-09-03 15:47:58,463] INFO in decoder: AlarmDecoder device was opened.
[2019-09-03 15:48:01,483] INFO in decoder: AlarmDecoder device was closed.
Exception in thread Thread-27:
Traceback (most recent call last):
File "/usr/lib/python2.7/threading.py", line 801, in __bootstrap_inner
self.run()
File "/opt/alarmdecoder/alarmdecoder/devices/base_device.py", line 148,
in run
self._device.read_line(timeout=self.READ_TIMEOUT)
File "/opt/alarmdecoder/alarmdecoder/devices/socket_device.py", line 356,
in read_line
self.on_read(data=ret)
File "/opt/alarmdecoder/alarmdecoder/event/event.py", line 84, in fire
func(self.obj, *args, **kwargs)
File "/opt/alarmdecoder/alarmdecoder/decoder.py", line 1041, in _on_read
self._handle_message(data)
File "/opt/alarmdecoder/alarmdecoder/decoder.py", line 439, in
_handle_message
msg = self._handle_keypad_message(data)
File "/opt/alarmdecoder/alarmdecoder/decoder.py", line 477, in
_handle_keypad_message
msg = Message(data)
File "/opt/alarmdecoder/alarmdecoder/messages/panel_message.py", line 85,
in init
self._parse_message(data)
File "/opt/alarmdecoder/alarmdecoder/messages/panel_message.py", line
121, in _parse_message
self.system_fault = int(self.bitfield[17], 16)
ValueError: invalid literal for int() with base 16: '-'

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    ๐Ÿ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. ๐Ÿ“Š๐Ÿ“ˆ๐ŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google โค๏ธ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.