Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Implementing custom Keystroke command #66

Open
adrianmihalko opened this issue May 5, 2017 · 17 comments
Open

Implementing custom Keystroke command #66

adrianmihalko opened this issue May 5, 2017 · 17 comments

Comments

@adrianmihalko
Copy link

adrianmihalko commented May 5, 2017

I really want to implement custom Keystroke command.

So I started to search in this topic and I found that I need to send '071' command to Envisalink:

'071' Keystroke String 1-6 Characters - [1-6 ASCII Character String] Envisalink

I started with httpslistener.py:

elif request == 'disarm':
            #if parameters['alarmcode'] == None: raise tornado.web.HTTPError(404)
            response = {'response' : 'Request to disarm partition %s received' % parameters['partition']}
elif request == 'keystroke':
             response = {'response' : 'Custom keystroke for partition %s received' % parameters['partition']}
...
(r'/api/alarm/(arm|stayarm|armwithcode|disarm)', ApiAlarmHandler),
(r'/api/(refresh|pgm|keystroke)', ApiAlarmHandler),
   

envisalink.py, I added:

elif type == 'keystroke':
                self.send_command('071', str('*106#1234'))

(*106#1234 === *1 bypass 06 zone # usercode).

Then I tried:

$ curl "https://192.168.x.xx:8111/api/keystroke"
{"response": "Custom keystroke for partition 1 received"}

but nothing happens on the alarm. Is there anything that I am missing? 👍

(I have Envisalink 4 with DSC alarm).

Edit:

Oh, in the log I see:

May 05 23:03:10 - INFO: 200 GET /api/keystroke (192.168.xx.xx) 20.26ms
May 05 23:03:11 - DEBUG - core/envisalink.py:handle_line@134: RX < 502 - System Error 021
@rct
Copy link
Collaborator

rct commented May 5, 2017

Interesting. Two experiments to try after you enable the chime via send key press:

  1. what happens if you go to a keypad and try to toggle the chime? What state does it think the chime was in at that point?
  2. Separately, if you repeat the command via the envisalink send key press, which I think is a toggle, does it respond saying the chime is now disabled indicating that the state had changed on the panel and that chime was in fact previously enabled?

Those experiments might yield some clues about where the state of the chime is being kept.

Given that you are getting back the correct response code, my guess is the command is making it correctly to the panel. I don't think the envisalink is generating the responses like 663 (Partition Home Chime Enabled) by itself. I think that must be coming over the keybus from the panel.

I can try some experiments on this over the weekend. It would be good to get the send keystroke command well implemented. Though it's one of those things that might need some throttling. Probably want to at a minimum wait for the command acknowledgement and maybe pause a little more before sending subsequent keystrokes.

It is probably worth reporting this on the envisalink support forum.

@adrianmihalko
Copy link
Author

adrianmihalko commented May 5, 2017

@rct thanks for the reply, in meantime I removed my second commend.

Here is the actual state:

I found the problem: I am trying to send too long commands.

But how I can send longer commands? Like *10602#, or *10602#1234?

CODE: SELECT ALL
TX > 0711*10602#0F
May 05 23:54:48 - INFO: 200 GET /api/keystroke (192.168.1.54) 17.64ms
May 05 23:54:48 - DEBUG - core/envisalink.py:handle_line@134: RX < 501 - Command Error

Sending a single command works, example: *106#,*4#.

Maybe can I send more commands one after another like *106# + *102# +*101# etc... then arm?

I thought that chime is not working, because there was no audio feedback from the Keypad (like when I enable manually). Is this normal? But as you wrote I enabled/disabled chime from keypad and from AlarmServer and I verified that it works.

Bypassing single zone also works: *106# -> then in another command usercode.

The Envisalink TPI document says:

Send Keystroke String (Max: 6 Keystrokes)
This command allows the application to send a keystroke string as if the user pressed the equivalent key sequence on an existing keypad. WARNING: There is no error checking for state of the panel so the application must know what mode the panel is beforehand, before sending key presses.

Commadn 071, # of Data Bytes 2-7, Data Bytes Partition (1-8), ASCII(0..9, *,#,A)

@rct
Copy link
Collaborator

rct commented May 5, 2017

@adrianmihalko -

I have two keypads, if I remember correctly, when I toggle the chime from one, it doesn't beep the other keypad.

It's been a while since I looked at this, need to go back the TPI manual and/or the envisalink forum, but - off the top of my head:

  • For user codes, there is a sequence, where you send a command that requires a user code, without the code
    • The envisalink responds with a specific response code, indicating it needs a user code
    • The software then sends the user code to the envisalink.
  • I believe it is possible to send key presses across multiple commands. It doesn't loose state between the commands, not sure what the time out is. It is all a big looser/not as deterministic as you'd like.

@adrianmihalko
Copy link
Author

Thank you, then I have to look further into this question this weekend.

I attach my current code, maybe someone would find it useful:

envisalink.py.txt
httpslistener.py.txt

$curl "https://192.168..x.xx:8111/api/keystroke?sequence=*4#"

@rct
Copy link
Collaborator

rct commented May 5, 2017

I'll take a look, is it in a branch on your repo?

This functionality would be useful to have implemented in the main code, maybe controlled by a configuration to disable it. So I hope you'll submit a PR at some point.

@adrianmihalko
Copy link
Author

Yep, just uploaded:

https://github.com/adrianmihalko/AlarmServer

@adrianmihalko
Copy link
Author

One more info:

I don't know if following project is a fork from this project, but it does have implemented the bypass zone function:

elif query.path == '/api/alarm/bypass':
           try:
               zones = str(query_array['zone'][0]).split(',')
               for zone in zones:
                   if len(zone) == 1: zone = '0' + zone
                   alarmserver_logger("request to bypass zone %s" % zone)
                   channel.pushok(json.dumps({'response' : 'Request to bypass zone received'}))
                   self._envisalinkclient.send_command('071', part + '*1' + str(zone)+ '#')
                   time.sleep(2)
           except:
               channel.pushok(json.dumps({'response' : 'Request to bypass zone received but invalid zone given!'}))

Isn't this what we are looking for?
Too bad I am not too good in python. 👎

@rct
Copy link
Collaborator

rct commented May 6, 2017

@adrianmihalko - There is no link, what repo did you find that in? I can't tell from that snippet whether it's from the pre-tornado version or not. Or whether it matters. Hopefully @juggie can take a look.

Certainly we'd all like that, and other functionality including the key pres send, to have a robust, complete api in AlarmServer.

Also, I think there is a relatively recent (< 1 year old) envisalink response that shows what zones are bypassed. IIRC, AlarmServer recognizes the response code, but doesn't have code to parse it and change the state for the zones.

@adrianmihalko
Copy link
Author

Ahh, sorry, I forgot the link:

https://github.com/LXXero/DSCAlarm/

It seem to be actively developed, but it's modified for Smartthings(?!):

https://community.smartthings.com/t/dsc-evl-3-4-alarmserver-smartthings/

@juggie
Copy link
Owner

juggie commented May 18, 2017

@adrianmihalko That looks ok to me, did you try that change to see if it would work for you? Do you need me to create a branch with the change so you can try it out?

@adrianmihalko
Copy link
Author

@juggie I checked LXXero's code and I found this relevant part:

elif query.path == '/api/alarm/bypass':
            try:
                zones = str(query_array['zone'][0]).split(',')
                for zone in zones:
                    if len(zone) == 1: zone = '0' + zone
                    alarmserver_logger("request to bypass zone %s" % zone)
                    channel.pushok(json.dumps({'response' : 'Request to bypass zone received'}))
                    self._envisalinkclient.send_command('071', part + '*1' + str(zone)+ '#')
                    time.sleep(2)
            except:
                channel.pushok(json.dumps({'response' : 'Request to bypass zone received but invalid zone given!'}))

This is what I need? It would be great if you could make a new beta branch with this modification.

Other:

Sadly, Alarmserver runs for 1-2 day only. I see it in the list of running processes:

@ubuntu:~$ ps ax | grep Alarm
  314 ?        Ss     7:51 /usr/bin/python /home/xy/domoticz/userscripts/AlarmServer/alarmserver.py -c /home/xy/domoticz/userscripts/AlarmServer/alarmserver.cfg
May 17 17:28:17 - DEBUG - plugins/pushover.py:sendNotification@30: Hello defaultStatus: {'fault': False, 'alarm': False, 'open': False, 'tamper': False}
May 17 17:28:17 - DEBUG - core/envisalink.py:handle_line@134: RX < 510 - Keypad Led State - Partition 1
May 17 17:28:17 - DEBUG - core/envisalink.py:handle_line@134: RX < 650 - Partition Home Ready
May 17 17:28:17 - DEBUG - plugins/pushover.py:sendNotification@24: Hello message: Partition Home Ready
May 17 17:28:17 - DEBUG - plugins/pushover.py:sendNotification@25: Hello eventType: statechange
May 17 17:28:17 - DEBUG - plugins/pushover.py:sendNotification@26: Hello type: partition
May 17 17:28:17 - DEBUG - plugins/pushover.py:sendNotification@27: Hello parameters: 1
May 17 17:28:17 - DEBUG - plugins/pushover.py:sendNotification@28: Hello code: 650
May 17 17:28:17 - DEBUG - plugins/pushover.py:sendNotification@29: Hello event: {'status': {'ready': True, 'pgm_output': False}, 'type': 'partition', 'name': 'Partition {0} Ready', 'description': 'Partition can now be armed (all zones restored, no troubles, etc). Also issued at the end of Bell Timeout if the partition was READY when an alarm occurred.'}
May 17 17:28:17 - DEBUG - plugins/pushover.py:sendNotification@30: Hello defaultStatus: {'armed_bypass': False, 'trouble_led': False, 'alarm': False, 'entry_delay': False, 'ready': False, 'tamper': False, 'trouble': False, 'armed': False, 'exit_delay': False, 'chime': False}

(current time when I wrote this: 18.05.2017, 19:05) -> nothing else is in the log, just sitting here.

Even the webinfo works, but no new data is added from Envisalink. Of course Envisalink works correctly.

@juggie
Copy link
Owner

juggie commented May 18, 2017

Do you have the full log eg including the last envisalink event?

@juggie
Copy link
Owner

juggie commented May 18, 2017

Looks like you have not updated as well. Pull the latest version as I added a keep alive for envisalink.

@adrianmihalko
Copy link
Author

adrianmihalko commented May 18, 2017

Ahh, this is why new keepalive function is for. We'll see, I update ASAP. Thank you.

@juggie
Copy link
Owner

juggie commented May 18, 2017

@adrianmihalko Give it a try and let me know. I'll try to replicate issues on my unit but I have no issues with it running for weeks.

@adrianmihalko
Copy link
Author

With keep alive it is very stable, it's running several weeks now.

@adrianmihalko
Copy link
Author

Is there anybody who implemented bypass multiple zones feature?

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

3 participants