DSC Alarm integration

@68hc11 just make sure your alarm do not use end of line resistors on the zones (this is used so you can’t just short a sensor’s wire and disable it)

I’ll also be weary of lightning if you hook up all those wires to the rPi!

Point taken, I’ll probably build an opto Isolator board with socketed Optos to run both DSC & Pi concurrently until I’m confident to switch over.

As others mention the Honeywell wired alarms are actually designed to be three states, Open, Closed & SHORTED, which is the point of the EOL (End Of Line) resistor, but in my installation & others I’ve seen the EOL resistor is actually mounted in the box. I haven’t given much thought to the three state concept for the Pi yet. Need to research to see if anyone else has done work to that level.

Thanks!

Calvin

Hi @68hc11, some alarms even use a second resistor for zone doubling or tamper switches at the sensor which give more than three states. Having the EOL in the alarm box is a bit pointless as you mention though.

The easiest way to get three states would be to use an analog input on the rPi, Something like:

GND ____ R1 _____ R2 ___ +3.3V
     |        |
     |__Dete__|___rPi Input
        ctor

Keep the current in the loop low, so R2 high (1M?). Some code to translate levels to state and you’re good to go.

You can try the opto-coupler, but I’m guessing the same idea to keep the current low in the loop above might prevent the opto-coupler from switching on, best to measure it though.

Speaking of Honeywell, do you think the Honeywell Vista 21IP would work with the implementation without Envisalink or do you still have to have Envisalink even though Vista 21IP has a built-in Internet communicator?

http://www.amazon.com/Honeywell-VISTA-21IPSIA-Control-Pilot-V21ipsia/dp/B005G59KNC/ref=sr_1_5?ie=UTF8&qid=1464574112&sr=8-5&keywords=honeywell+vista+21ip

If you’re referring to what i’m doing- then I would bet that it won’t work. I only say that because the API that i’m using is specific to envisalink.

1 Like

Ugh - my schedule has been crazy! Anyway, I have created version 0.4 of pyenvisalink, and have included a “first cut” at a DSC library. Currently the following functionality is supported:

  1. Login
  2. Periodic zone timer dump (the library, by default, will do this every 30 secs to get the zone statuses)
  3. Arm Stay/Arm Away/Arm Max/Disarm

Along with the library, I have included a very simple test harness python script that can be used to try it out. Would you mind installing the pyenvisalink package, and then running the test harness? Right now I’ve run the script using the DSC client, but of course it fails right away.

Here is a link to the test harness (technically it will be installed when you install the pyenvisalink package with pip anyway):

Thanks!

Great work and it is greatly appreciated. I’m new to Home Assistant though and I guess I need some direction on how to integrate that with my existing Home Assistant install? I’ve had an existing install working with Openhab but it just isn’t reliable enough for me.

I had a quick look at it and it needed a few fixes: https://github.com/srirams/pyenvisalink/commit/b77b50f4753488216e8ee7a335abaa8c0b55bb6a

But other than that it seems to work fine! I haven’t checked the actual zone dump, but it seems ok.

A couple of (possible) issues:

  1. I don’t believe the data received has to be in complete lines (maybe this has changed in python3, I’m not sure). So if we get a partial line, we’ll have problems.

  2. python 3.4 doesn’t have asyncio.ensure_future (have to use asyncio.async)

  3. windows doesn’t have signal.pause() (only used in the test_harness I think)

I’ve included a sample output from my dsc if it helps:

Connecting to 10.0.3.1:4025
Connected to 10.0.3.1:4025
RX < 5053CD < 505 - Login Interaction - 3
TX > '005user54\r\n'
RX < 5000052A < 500 - Command Acknowledge - 005
RX < 5051CB < 505 - Login Interaction - 1
TX > '00191\r\n'
RX < 50000126 < 500 - Command Acknowledge - 001
RX < 61000128 < 610 - Zone 001 Restored - 001
RX < 61000229 < 610 - Zone 002 Restored - 002
RX < 6100032A < 610 - Zone 003 Restored - 003
RX < 6100042B < 610 - Zone 004 Restored - 004
RX < 6100052C < 610 - Zone 005 Restored - 005
RX < 6100062D < 610 - Zone 006 Restored - 006
RX < 6100072E < 610 - Zone 007 Restored - 007
RX < 6100082F < 610 - Zone 008 Restored - 008
RX < 61000930 < 610 - Zone 009 Restored - 009
RX < 61001028 < 610 - Zone 010 Restored - 010
RX < 61001129 < 610 - Zone 011 Restored - 011
RX < 6100122A < 610 - Zone 012 Restored - 012
RX < 6100132B < 610 - Zone 013 Restored - 013
RX < 6100142C < 610 - Zone 014 Restored - 014
RX < 6100152D < 610 - Zone 015 Restored - 015
RX < 6100162E < 610 - Zone 016 Restored - 016
RX < 6100172F < 610 - Zone 017 Restored - 017
RX < 61001830 < 610 - Zone 018 Restored - 018
RX < 61001931 < 610 - Zone 019 Restored - 019
RX < 61002029 < 610 - Zone 020 Restored - 020
RX < 6100212A < 610 - Zone 021 Restored - 021
RX < 6100222B < 610 - Zone 022 Restored - 022
RX < 6100232C < 610 - Zone 023 Restored - 023
RX < 6100242D < 610 - Zone 024 Restored - 024
RX < 6100252E < 610 - Zone 025 Restored - 025
RX < 6100262F < 610 - Zone 026 Restored - 026
RX < 61002730 < 610 - Zone 027 Restored - 027
RX < 61002831 < 610 - Zone 028 Restored - 028
RX < 61002932 < 610 - Zone 029 Restored - 029
RX < 6100302A < 610 - Zone 030 Restored - 030
RX < 6100312B < 610 - Zone 031 Restored - 031
RX < 6100322C < 610 - Zone 032 Restored - 032
RX < 6501CC < 650 - Partition 1 Ready - 1
RX < 6732D2 < 673 - Partition 2 is Busy - 2
RX < 8411CE < 841 - Partition 1 Trouble LED OFF - 1
RX < 8412CF < 841 - Partition 2 Trouble LED OFF - 2
RX < 51081FF < 510 - Keypad Led State - Partition 1 - 81```

Thank you very much! This is awesome. I do have a few questions about your changes.

  1. I didn’t see the “to_chars” method in use anywhere, was that supposed to be put in the send_command method? Starting to make me think i should be converting to a byte array for ALL my communications…

  2. On line 25, when you added the ‘\r\n’… that’s supposed to be added by the “send_data” method (implemented in the envisalink_base_client). I think it’s only sending \n at the moment- but I’ll change it to \r\n there. If that ends up breaking the honeywell side of things, then i’ll do some sort of “line terminator” variable to handle the difference.

In terms of signal.pause- yes you’re right- that’s only the test harness- nothing else. I whipped that up very quick- I won’t bother messing with it.

For the complete lines- I think you’re right that we don’t necessarily have to get full lines (and again i’m looking at \n and not \r\n)- so I’ll correct that. I actually found on the honeywell side that i’d sometimes get more than 1 line at once- but I can also buffer up commands in the event that we get a partial line.

In terms of the ensure_future… i’m actually not sure how to handle that, as the asycio.async is no longer valid in 3.5…

Great to hear i’m close though- in general the big difference i’m noticing is that the Honeywell TPI will send 1 event, with more data in it, vs. the DSC TPI will send many events, with little data- so i think it’s going to just be an exercise of mapping all the little events on the DSC to a few larger generic events.

  1. to_chars is used in the get_checksum method. Not too familiar with python3, but isn’t everything a byte array now?

  2. I didn’t check the base method, but it wasn’t working, so I think the \r is necessary for the DSC.

asynchat seems to have been deprecated in python3, so maybe something like asyncio.StreamReader would be easier to implement.

re: ensure_future. not any good options I think. Can either use the deprecated asyncio.async or do an hasattr to check for ensure_future.

To be honest, I haven’t really looked too closely at either api, but it seems to me that the dsc doesn’t need to be polled. Is polling necessary for the Honeywell?

edit: and thanks for adding DSC support. Let me know if you want me to test anything else.

  1. heh- thanks :slight_smile: totally missed that. Okay I’ll get the to_chars in there. Nothing else should be required- it makes sense that you need to get the numerical values for the characters to compute the checksum.

In terms of polling, the envisalink in general does have a keepalive poll that must be pinged every so often- to reset it’s watchdog timer. If you have it hooked up to the “cloud service” then eyezon does it for you. The “zone timer dump” poll does NOT need to be done, and there is a configuration option to turn that off.

Hi, I just got an Evisalink 4 installed on my DSC panel. It’s up an working fine. I’d like to test your integration but am wondering if it will work with my system. I have HASS installed in a virtual environment is there anything special I need to do to get this working? Sorry for the noob questions. The Pi is a new one for me. I know only enough to be dangerous.

Awesome! Yes to my knowledge the only difference between the evl3 (which is what i have), and the evl4 is the maximum number of zones (and that effects a few other things which have been accounted for). I actually have a config parameter where you can specify that you’re using an evl4- so I believe we should be in good shape.

That being said, there’s really 2 projects in flight here - right now any testing should really be in part 1:

  1. the pyenvisalink python library. It’s basically a python library that implements the API of the envisalink. The challenge is that the API is significantly different for the Honeywell systems and the DSC systems. I’ve done a pretty good job at abstracting out the differences- and i’m done implementing the Honeywell half of it.

Now i’m working with sriram (and you?) to get the DSC half of it implemented, since he has a DSC. Right now it can login, i can arm/disarm the board, and the library, by default, requests a zone status dump every 30 seconds. To our knowledge all of that works (with some tweaks made by Sriram that i’ve already merged in).

The next release i’ll implement some of Sriram’s fixes, and also implement live zone state changes, and partition state changes, which should be the lion’s share of what we need for HASS. I expect to have that done in the next day or so- luckily I’ve found it to be easy to implement, just tedious.

  1. the HASS components, i’m basically finished with that- but i may need to make adjustments based upon changes made in the pyenvisalink library. Mostly what remains there is for me to make my code up to snuff with the home-assistant project standards.
2 Likes

Sounds like you’re making great progress. How can I help? Again I’m a bit light on experience with my pi and python. I have not installed it yet cause I’m just making sure I have the process right. I’m using a virtual environment and already have HASS installed and working. So will this work?:

So can someone help out on how I’d get this component installed. I’m at a loss and obviously lacking some basic knowledge here. I’m happy to play with it and report back anything that comes up.

Thanks for any help.

Hi Cub- at this moment we’re probably not QUITE where we need to be for you unless you have some python experience and would like to help test my envisalink library (outside of HASS). That’s really the part i’m trying to finish off at the moment before I commit the home-assistant parts of it.

Do you have a honeywell or DSC? If you have a honeywell board, let me know and I can direct you to try the home assistant component before i get it committed to the project (since the honeywell functionality of the pyenvisalink library is pretty solid).

Right now i’m really trying to get the pyenvisalink library working, using the DSC API. If you wouldn’t mind, just run the following command to install the pyenvisalink library:
pip3 install pyenvisalink

Then you can put the “test harness” code (attached above), and run that. It will ask you a few questions about what your setup is, and then it will initiate a connection with your envisalink, and it will just start listening for events- and you can then either post the responses, or give me feedback of any errors you see (i can’t test it myself- as i have a honeywell board).

I’m going to be posting again here, as I just updated the pyenvisalink library.

Thanks!

Okay everyone- I have posted version 0.5 of pyenvisalink- can i get another test please?

I have made the following changes:

  1. changed asyncio.ensure_future to asyncio.async per Sriram’s recommendation to support python 3.4 (it seems to have worked fine on 3.5 too).

  2. I have added a few other methods per Sriram’s recommendation (get_chars, etc)

  3. Changed the newline delimiter to CR+LF (works on honeywell too- so we’re using common code in the envisalink base class).

  4. I added some basic zone state change handling, as well as some basic partition state change handling- it should be the lion’s share of what HASS needs- but if there are requests for more event handling, we can work that in.

Hopefully we’re really close!

I will update and try another test with the test-harness as well. Cinntax, I have a Envisalink 3 with a DSC panel. I tried the test harness with the last version but it wouldn’t log in. I will try this version and let you know. I have no problems helping test, etc.

I can’t seem to get the test_harness to connect to my Envisalink. I confirmed connectivity with a telnet to the active port. I wonder if I’m missing a dependency in my system some place?
Please input the IP address of your envisalink device: 192.168.15.43
Please input the port of your envisalink device (4025 is default): 4025
Which envisalink device do you have? Enter 3 for evl3 or 4 for evl4: 3
Input DSC if you have a DSC panel, or HONEYWELL if you have a honeywell panel: DSC
Please input your envisalink password:
Config complete. Please press enter now to connect to the envisalink. When finished, use Ctrl+C to disconnect and exit
Thu, 09 Jun 2016 08:42:30 INFO Connecting to envisalink on host: 192.168.15.43, port: 4025
Thu, 09 Jun 2016 08:42:30 DEBUG Using selector: EpollSelector
Thu, 09 Jun 2016 08:42:30 INFO <pyenvisalink.envisalink_base_client envisalink_base_client connect> Started to connect to Envisalink… at 192.168.15.43:4025
Traceback (most recent call last):
File “./test_harness.py”, line 17, in
testpanel.start()
File “/usr/local/lib/python3.4/dist-packages/pyenvisalink/alarm_panel.py”, line 181, in start
self._client.start()
File “/usr/local/lib/python3.4/dist-packages/pyenvisalink/envisalink_base_client.py”, line 30, in start
self.connect()
File “/usr/local/lib/python3.4/dist-packages/pyenvisalink/envisalink_base_client.py”, line 50, in connect
asyncio.ensure_future(coro)
AttributeError: ‘module’ object has no attribute ‘ensure_future’
hass@raspberrypi:~/pyenvisalink/pyenvisalink$ telnet 192.168.15.43 4025
Trying 192.168.15.43…
Connected to 192.168.15.43.
Escape character is ‘^]’.
5053CD
^]

telnet> q
Connection closed.

THis is what I’m getting:

TypeError: to_chars() takes 1 positional argument but 2 were given
Thu, 09 Jun 2016 10:13:22 DEBUG <pyenvisalink.envisalink_base_client envisalink_base_client data_received> ----------------------------------------
Thu, 09 Jun 2016 10:13:22 DEBUG <pyenvisalink.envisalink_base_client envisalink_base_client data_received> RX < 5052CC
Thu, 09 Jun 2016 10:13:22 DEBUG <pyenvisalink.envisalink_base_client envisalink_base_client data_received> calling handler: handle_login_timeout for code: 505
Thu, 09 Jun 2016 10:13:22 ERROR <pyenvisalink.envisalink_base_client envisalink_base_client handle_login_timeout> Envisalink timed out waiting for password, whoops that should never happen. Server is closing socket connection
Thu, 09 Jun 2016 10:13:22 DEBUG <pyenvisalink.envisalink_base_client envisalink_base_client disconnect> Closing connection with server for a reconnect...
Thu, 09 Jun 2016 10:13:22 DEBUG <pyenvisalink.envisalink_base_client envisalink_base_client data_received> Invoking callback: callback_login_timeout
Thu, 09 Jun 2016 10:13:22 DEBUG <pyenvisalink.alarm_panel alarm_panel _defaultCallback> Callback has not been set by client.
Thu, 09 Jun 2016 10:13:22 DEBUG <pyenvisalink.envisalink_base_client envisalink_base_client data_received> ----------------------------------------
Thu, 09 Jun 2016 10:13:22 ERROR <pyenvisalink.envisalink_base_client envisalink_base_client connection_lost> The server closed the connection. Reconnecting...
Thu, 09 Jun 2016 10:13:27 INFO <pyenvisalink.envisalink_base_client envisalink_base_client connect> Started to connect to Envisalink... at 192.168.1.34:4025
Thu, 09 Jun 2016 10:13:27 INFO <pyenvisalink.envisalink_base_client envisalink_base_client connection_made> Connection Successful!
Thu, 09 Jun 2016 10:13:27 DEBUG <pyenvisalink.envisalink_base_client envisalink_base_client data_received> ----------------------------------------
Thu, 09 Jun 2016 10:13:27 DEBUG <pyenvisalink.envisalink_base_client envisalink_base_client data_received> RX < 5053CD
Thu, 09 Jun 2016 10:13:27 DEBUG <pyenvisalink.envisalink_base_client envisalink_base_client data_received> calling handler: handle_login for code: 505
Thu, 09 Jun 2016 10:13:27 ERROR <asyncio base_events default_exception_handler> Exception in callback _SelectorSocketTransport._read_ready()
handle: <Handle _SelectorSocketTransport._read_ready()>
Traceback (most recent call last):
  File "/usr/lib/python3.4/asyncio/events.py", line 120, in _run
    self._callback(*self._args)
  File "/usr/lib/python3.4/asyncio/selector_events.py", line 589, in _read_ready
    self._protocol.data_received(data)
  File "/srv/hass/hass_venv/lib/python3.4/site-packages/pyenvisalink/envisalink_base_client.py", line 143, in data_received
    result = handlerFunc(cmd['code'], cmd['data'])
  File "/srv/hass/hass_venv/lib/python3.4/site-packages/pyenvisalink/dsc_client.py", line 97, in handle_login
    self.send_command(evl_Commands['Login'], self._alarmPanel.password)
  File "/srv/hass/hass_venv/lib/python3.4/site-packages/pyenvisalink/dsc_client.py", line 25, in send_command
    to_send = code + data + self.get_checksum(code, data)
  File "/srv/hass/hass_venv/lib/python3.4/site-packages/pyenvisalink/dsc_client.py", line 21, in get_checksum
    return ("%02X" % sum(self.to_chars(code)+self.to_chars(data)))[-2:]