kk7ds/pynx584

stevedore plugins

Closed this issue · 4 comments

Hi,

I found your library and was going to attempt to extend it to push zone change and system status messages into Homebridge (and onward to iOS land). I saw references in the message processing code to the stevedore extension system. I didn't find a defined abstract base class to guide the plugin development and I also noticed that the email notification system seems to have been hard-coded in vs. using the plugin system.

Before I started, I was curious as to whether anyone has ever used the stevedore system or whether that's not worth the trouble to get working. I've never actually used stevedore but figured it might be easier than bolting on something directly into the codebase.

Thanks for any guidance!

kk7ds commented

I wrote this so I could write my own plugin to integrate with my custom HA stuff. It works, and it's how you should do it. Here's a test extension I wrote while testing it. I imagine it should still work or get you close:

from nx584 import model

class TestMe(model.NX584Extension):
    def zone_status(self, zone):
        print 'Zone status for %i' % zone.number

    def partition_status(self, part):
        print 'Partition status for %i' % part.number

and then just this in a setup.py:

from setuptools import setup

from nx584 import model

setup(name='testnx584',
      version='1.0',
      py_modules=['testnx584'],
      entry_points={
          'pynx584': ['test=testnx584:TestMe'],
      },
)

I really just wrote it for myself so that I wouldn't have to have a modified pynx584 for my setup, which is why it's not really documented. Obviously a doc patch with what you discover would be appreciated. I wrote it (and have been using it) a few years ago, so I'd have to go read and parse it in order to document it as well.

Thanks! It's my brother's system that I'm automating as a Christmas present w/ an RPi and an NX584 board. I'm going to have to code it without testing and then spend a day at his house debugging it to get it working. Once I'm done I'll document and send the pull request and share a link to my Homebridge plugin.

Homekit needs to do if the alarm state is 'alarming'. The panel itself doesn't seem to have an easy way to detect this. I've thought through two options and curious if you have any insights into the best way.

  1. zone.state appears to be true/false depending on whether it's faulted. it also has a bypassed property so if any zone is faulted and not bypassed while the partition is armed then I can assume 'alarming'
  2. check for partition condition flags as either 'fire', 'siren on', 'steady siren on' or 'previous alarm'

Issue with # 2 seems like it would miss silent alarms but not sure if I'm missing something in # 1.

I do see a zone event code for 'alarm' but I don't see where that state is managed within the client. My plugin minimizes the tracking of state directly since messages can get lost and instead queries the partition and zones with each status request after getting 'pinged' when a message comes through that might impact state (message types 4,6,8,9,10)

kk7ds commented

Homekit needs to do if the alarm state is 'alarming'. The panel itself doesn't seem to have an easy way to detect this. I've thought through two options and curious if you have any insights into the best way.

  1. zone.state appears to be true/false depending on whether it's faulted. it also has a bypassed property so if any zone is faulted and not bypassed while the partition is armed then I can assume 'alarming'
  2. check for partition condition flags as either 'fire', 'siren on', 'steady siren on' or 'previous alarm'

Yep, I capture and represent disarmed, arming, armed, and alarm in my setup too. Here's a chunk of code from my own stuff that looks at partition flags on partition status update and decides what state it is in, which seems to work:

    armtype = 'Entryguard (stay mode)' in flags and 'stay' or 'away'
    if 'Armed' not in flags:
        return {'state': 'disarmed'}
    else:
        if 'Siren on' in flags:
            return {'state': 'alarm'}
        elif set(['Exit 1', 'Exit 2']) & flags:
            return {'state': 'arming'}
        else:
            return {'state': 'armed',
                    'armtype': armtype}

Note that it doesn't handle fire or panic alarms.

Hope that helps.