Basic Home Alarm Setup with Zipato Keypad

Got mine yesterday and works fine.

Pincodes can be set via HA. To set a pincode, select the node and a slot and type in the pin, for example 1234. Then set pincode. To wakeup the keypad, make a fake scan with the RFID tag. Then go to the HA overview and back to z-wave management. Select the node and the slot and the pincode will be there.

The RFID code can only be set with ozwcp and not via HA at the moment.

https://github.com/home-assistant/home-assistant/issues/10754

@ibennani The “Enrollment Code” is in HA z-wave management above code 1 slot. You cannot see it, but select code 1 and press the arrow key up and enter.

1 Like

This works perfect, thanks!

The issue you posted on github also seems to be fixed already: https://github.com/home-assistant/home-assistant-polymer/pull/677/files

Did anyone solve this without having to write an appdaemon app?

I’ve been able to include and set up user codes on my keypad with a 1 week old python virtual env setup and without using ozwcp; but only after some fiddling.

  1. my device identified as Type ID:6131 and Product ID:5501, I added a line to components/manufacturer_specific.xml, copying from the Product ID:4501 line, then reincluded my node. (This is the openzwave db entry for 4501, there is no 5501 (yet?) http://www.openzwave.com/device-database/0097%3A4501%3A6131)
  2. The user codes section in HA zwave config would not update; the lock/zwave platform was not loading, so no lock.set_usercode service was available. I added “lock: \n - platform: zwave” to my configuration.yaml which brought forth more errors as it was trying to access hass.data[zwave_network] before it was defined, and therefore failed to register the 3 usercode services. I edited components/lock/zwave.py to defer access to zwave_network to within the services themselves and the services appeared
  3. Copying an “Enrolment Code” to a user slot had some parsing issues with leading zeros. As with the github issue mentioned earlier, applying hex codes is now possible, though any hex code like \x0a would render as \xa within the Enrolment Code and copy paste to a user code would shift the ASCII when it was set and later retrieved. I manually reinserted the leading zeros after pasting and before “Set Usercode”. The retrieved panel state user code correctly matched the previous Enrolment code.

I have yet to apply any automations. I am seeing the issue with invisible event when unarming an already unarmed panel. I will keep an eye on this thread and update as my story progresses.

Cheers to the above contributors that have helped me get this far.

I’m back in the game :wink:

I have just tried to add a user code using the new Zwave config from within HA (v0.59.2) and can confirm the problem from @merredin above.

WARNING (MainThread) [homeassistant.core] Unable to find service lock/set_usercode

I’ll try with ozwcp now but am now using HassIO and don’t have ozwcp installed.

@merredin

I edited components/lock/zwave.py to defer access to zwave_network to within the services themselves and the services appeared

Can you provide these changes?

Please excuse I’m not up to speed with git/patching/pull requests etc, so I will paste here what my changes looked like with comments;

@asyncio.coroutine
def async_setup_platform(hass, config, async_add_devices, discovery_info=None):
    """Set up the Z-Wave Lock platform."""
    yield from zwave.async_setup_platform(
        hass, config, async_add_devices, discovery_info)

    descriptions = load_yaml_config_file(
        path.join(path.dirname(__file__), 'services.yaml'))
    // Fails here // network = hass.data[zwave.const.DATA_NETWORK]

    def set_usercode(service):
        """Set the usercode to index X on the lock."""
        network = hass.data[zwave.const.DATA_NETWORK] // defer to here
        node_id = service.data.get(zwave.const.ATTR_NODE_ID)
        lock_node = network.nodes[node_id]
        code_slot = service.data.get(ATTR_CODE_SLOT)
        usercode = service.data.get(ATTR_USERCODE)

        for value in lock_node.get_values(
                class_id=zwave.const.COMMAND_CLASS_USER_CODE).values():  
            if value.index != code_slot:
                continue
            if len(str(usercode)) < 4:
                _LOGGER.error("Invalid code provided: (%s) "
                              "usercode must be atleast 4 and at most"
                              " %s digits",
                              usercode, len(value.data))
                break
            value.data = str(usercode)
            break

    def get_usercode(service):
        """Get a usercode at index X on the lock."""
        network = hass.data[zwave.const.DATA_NETWORK] // defer to here
        node_id = service.data.get(zwave.const.ATTR_NODE_ID)
        lock_node = network.nodes[node_id]
        code_slot = service.data.get(ATTR_CODE_SLOT)

        for value in lock_node.get_values(
            class_id=zwave.const.COMMAND_CLASS_USER_CODE).values():
            if value.index != code_slot:
                continue
            _LOGGER.info("Usercode at slot %s is: %s", value.index, value.data)
            break

    def clear_usercode(service):
        """Set usercode to slot X on the lock."""
        network = hass.data[zwave.const.DATA_NETWORK] // defer to here
        node_id = service.data.get(zwave.const.ATTR_NODE_ID)
        lock_node = network.nodes[node_id]
        code_slot = service.data.get(ATTR_CODE_SLOT)
        data = ''

        for value in lock_node.get_values(
            class_id=zwave.const.COMMAND_CLASS_USER_CODE).values():
            if value.index != code_slot:
                continue
            for i in range(len(value.data)):
                data += '\0'
                i += 1
            _LOGGER.debug('Data to clear lock: %s', data)
            value.data = data
            _LOGGER.info("Usercode at slot %s is cleared", value.index)
            break

    // now these can get registered
    hass.services.async_register(
        DOMAIN, SERVICE_SET_USERCODE, set_usercode,
        descriptions.get(SERVICE_SET_USERCODE), schema=SET_USERCODE_SCHEMA)
    hass.services.async_register(
        DOMAIN, SERVICE_GET_USERCODE, get_usercode,
        descriptions.get(SERVICE_GET_USERCODE), schema=GET_USERCODE_SCHEMA)
    hass.services.async_register(
        DOMAIN, SERVICE_CLEAR_USERCODE, clear_usercode,
        descriptions.get(SERVICE_CLEAR_USERCODE), schema=CLEAR_USERCODE_SCHEMA)
1 Like

Thanks @merredin I can confirm that enrolling codes does not work with the the Home Assistant Zwave Panel.

This is a a bit of a pain in the ass as HassIO does not contain OZWCP.

I could however use the original method with OZWCP (as I had detailed in the first post on this thread) on another computer and then copying over the ozwcfg file containing the enrollment codes which were also registered on the device.

I believe I have found a way to avoid using AppDaemon to keep the HA Manual Alarm and the Zipato Keypad in sync with each other @smi :grinning:

I have moved from using AppDaemon to doing a simple API call using shell_command and an automation. Not sure why I didn’t think of this before.

One thing to note below is that I renamed the keypad from “schlage_link_mini_keypad_rfid” to “alarm_keypad”.

In the config:

shell_command:
  set_keypad_home: "curl -H \"Content-Type: application/json\" -X POST -d '{\"entity_id\": \"sensor.alarm_keypad_alarm_level\", \"state\": \"0\", \"attributes\":{\"friendly_name\": \"Alarm Keypad Alarm Level\"} }' https://[YOUR_DUCKDNS].duckdns.org:8123/api/states/sensor.alarm_keypad_alarm_level?api_password=[YOUR_API_PASSWORD]"
  set_keypad_away: "curl -H \"Content-Type: application/json\" -X POST -d '{\"entity_id\": \"sensor.alarm_keypad_alarm_level\", \"state\": \"255\", \"attributes\":{\"friendly_name\": \"Alarm Keypad Alarm Level\"} }' https://[YOUR_DUCKDNS].duckdns.org:8123/api/states/sensor.alarm_keypad_alarm_level?api_password=[YOUR_API_PASSWORD]"

which are run by following automations (taken direct from my automations.yaml file):

- action:
  - service: shell_command.set_keypad_away
  alias: Keypad to Armed
  condition: []
  id: '1513678597078'
  trigger:
  - entity_id: alarm_control_panel.ha_alarm
    platform: state
    to: armed_away

- action:
  - service: shell_command.set_keypad_home
  alias: Keypad to Home
  condition: []
  id: '1513678726380'
  trigger:
  - entity_id: alarm_control_panel.ha_alarm
    platform: state
    to: disarmed

I’m sure it could be improved a lot but this should work in principle. I’ll be doing some more testing over the next few days.

Hi skptic!

Thanks for your tutorial.

I set it up as you did, only changed the name of the keypad and changed it to be run by sudo.

Activating the alarm works but deactivating it doesn’t and also when I set the alarm on/off from the frontend the status of the keypad doesn’t change.

Any idea why this happens?

This is what I added to the scripts part:
set_keypad_home: “sudo curl -H “Content-Type: application/json” -X POST -d ‘{“entity_id”: “sensor.keypad_alarm_level”, “state”: “0”, “attributes”:{“friendly_name”: “Keypad Alarm Level”} }’ http://myip:8123/api/states/sensor.keypad_alarm_level?api_password=MYPW
set_keypad_away: “sudo curl -H “Content-Type: application/json” -X POST -d ‘{“entity_id”: “sensor.keypad_alarm_level”, “state”: “255”, “attributes”:{“friendly_name”: “Keypad Alarm Level”} }’ http://myip:8123:8123/api/states/sensor.keypad_alarm_level?api_password=MYPW”

I just added sudo since all my other scripts also run under sudo.

Interestingly, all scripts show up in frontend under scripts except these two.

Thanks

@smi First you must get the shell commands to show up in the font end. Check your logs to debug. I needed to escape the double quotes.

The commands I posted above (#54) only replaces the AppDaemon part. You still need the basic automations to arm/disarm the alarm based on the state of sensor.alarm_keypad_alarm_level (either 255=armed and 0=disarmed).

I have these as:

- action:
  - data:
      entity_id: alarm_control_panel.ha_alarm
    service: alarm_control_panel.alarm_arm_away
  alias: Alarm to Armed
  condition: []
  id: '1513634400284'
  trigger:
  - above: '254'
    entity_id: sensor.schlage_link_mini_keypad_rfid_alarm_level
    platform: numeric_state

- action:
  - data:
      entity_id: alarm_control_panel.ha_alarm
    service: alarm_control_panel.alarm_disarm
  alias: Alarm to Home
  condition: []
  id: '1513671114417'
  trigger:
  - below: '1'
    entity_id: sensor.schlage_link_mini_keypad_rfid_alarm_level
    platform: numeric_state

Hi!

Thanks, I also have that basic automation thing; will try the appdeamon replacement (the script) without double quotes, with and without sudo and so on.

Regards

Great. Just to be clear, I have this as a shell command which I think is different from a script. See here.

I have been testing all day and it seems to work fine. I will post a complete config with instructions when I have finalised everything :+1:

Yeah, mixed scripts and shell commands up. :confused:
That’s also the reason why it doesn’t appear in frontend.

Unfortunately the shell command still doesn’t set the keypad alarm level even after various changes on the shell command …

Thanks @skptic for the examples to help me with my keypad.

What I have working is;

  • Away/home button with enrolled-keypad-code or enrolled-rfid-tag results in double-beep success indicator sound (only when HA cache for sensor.schlage_link_mini_keypad_rfid_access_control is in disarmed/armed state respectively, otherwise 4-beep error)
  • Away/home button with wrong code results in 4-beep error indicator sound
  • Switch to change HA state cache for keypad (contrary to above, I don’t think you can set the state of the keypad itself, there are no command classes to achieve that, rather you can change the state cache of HA so that when the keypad sends a correct arm/disarm, HA can trigger an automation. I used the shell_command: curl config to change HA state, thanks!)
  • Automation to toggle Dome Siren primary/secondary siren/chime based on armed/disarmed states respectively.

The keypad indicator sounds were achieved thanks to https://github.com/OpenZWave/open-zwave/pull/1315/files/b14932f945415907c1e871af9c6b0b808df867bc applying the source file changes to a master git clone, and installed via pip uninstall python_openzwave and pip install python_openzwave --install-option="--flavor=dev". The dev flavor enabled me to softlink my custom open-zwave directory so that pip install picked it up.

My HA version is 0.60, my python_openzwave is v0.4.0.35, my open-zwave is custom ontop of 1.5, which results in sensor.schlage_link_mini_keypad_rfid_access_control as my state to trigger upon, state of 6=disarmed and 5=armed. The differences could also be because my keypad identifies as 6131:5501 instead of 6131:4501

I’ve yet to employ my siren set-off automations with door/motion sensors. Going to wait until I can find time to test and not scare the kids…

Dear all, I’ve been following this thread with interest.

Right now I’m in the process of getting my HA based alarm system up and running, Fibaro motion sensors working like a charm. Currently triggering my Sonos to play an alarm sound until my siren comes (in back-order duh). Actually using the alternative alarm setup as described here: Alternative Home Assistant Alarm

I also ordered 2 of the Zipato (Benext) Tag readers and frankly am having a bit of trouble.

I managed to securely connect one to my HA setup, renamed the node to Tag_Reader_I. So far so good, but when I press any of the buttons on the keypad (‘home’ or ‘away’) I seem to only get errors in the logfile:

> 2018-01-13 19:09:19.759 Detail, Node007,   Received: 0x01, 0x0d, 0x00, 0x04, 0x00, 0x07, 0x07, 0x88, 0x03, 0x66, 0x00, 0x00, 0x01, 0x2c, 0x36
> 2018-01-13 19:09:19.760 Detail, 
> 2018-01-13 19:09:19.761 Info, Node007, ApplicationCommandHandler - Unhandled Command Class 0x88

So not even at the point of figuring out how to get the codes/tags recognized. Let alone syncing with the HA alarm state :-).

Does anybody recognise this behaviour? suggestions?

Many thanks in advance!

Setup: HA 0.60.1 / PI3 / Python 3.6.4.

If you are using openzwave, could you look in your openzwave cache xml file, locate your Node007 entry and list here the manufacturer id and product id? That would tell us what your openzwave thinks Node007 is.

Hi @merredin thanks for your reply. I made some progress in the meanwhile:

It turns out one of the tag readers is defective, I cannot get the ‘set code’ segments to display for this device. When I tried the other one it does register. So that was a day and a half gone before I figured that out :-). I think this caused the ‘unhandled command class error’.

Following your guidance (loading the lock zwave platform and changing the lock/zwave.py code) I am able to register tags via HA. So that is great as well, many thanks for that. One question around setting pin codes, suppose you want to set the pin to 1234, do you simply register 0x31 0x32 0x33 0x34 + trailing 0x00’s through HA? I was having some trouble with that, but need to try again tonight.

So next step is making sure the reader syncs status as described in this thread.

Thanks for you help, I’ll let you know once it’s all up & running.

@merredin Thanks for pointing to the Pull Request. I have to check that. My instalaltion is using the Dev branch since I have the Eurotronic Spirits. Unfortunately the PR is not merged yet, so I will have to use the dev flavor instead of ozwdev.

Considering the sync state I have a very simple approach in my setup.
I use sensor.keypad_access_control as the trigger. This has states “Access Control - KeyPad Unlock” or “Access Control - KeyPad Lock”.

The keypad always sends an event to HA when a button has been send, no matter if it was the same button again or not. The reason why the automation is not triggered is that trigger trigger only fires if the state is different from the old state. So if you press the same button again, then you do get an event in HA, but the automnation is not triggered since the state has not changed.

The solution here is to use a state trigger and only define the entity_id and not define to and from. Then check the state in a condition.

- alias: Set Alarm Home
  trigger:
    - platform: state
      entity_id: sensor.keypad_access_control
  condition:
    - condition: state
      entity_id: sensor.keypad_access_control
      state: Access Control - KeyPad Unlock
  action:
    - service: alarm_control_panel.alarm_disarm
      entity_id: alarm_control_panel.ha_alarm

- alias: Set Alarm Away
  trigger:
    - platform: state
      entity_id: sensor.keypad_access_control
  condition:
    - condition: state
      entity_id: sensor.keypad_access_control
      state: Access Control - KeyPad Lock
  action:
    - service: alarm_control_panel.alarm_arm_away
      entity_id: alarm_control_panel.ha_alarm

This is also mentioned in the documentation for the state trigger

Triggers when the state of tracked entities change. If only entity_id given will match all state changes, even if only state attributes change.

1 Like

Woah looks like this has moved on a far bit since I last checked :smiley:

Did you guys manage to get the keypad to start beeping once say the door opens, to give you an audible warning that you need to go over and disarm? Or is that still not possible as the keypad is asleep and HA can’t send it messages?

What’s this syntax? All my automations start with a trigger and the action is last.

Ooh is this a siren that can do chimes as well as sirens based on different actions? I’ve been trying to find one as my Neo Coolcam one seems to only be able to do one or the other once it’s set up.

edit having googled it, it looks like it’s identical to my Neo! So how do you make it do different noises? Mine only has 1 switch which sets off the siren.