Basic Home Alarm Setup with Zipato Keypad

Is there really no one here who can assist us in this issue?
@skptic or @Soul or perhaps @Tyfoon ?

Have you set the valid codes first using zwave control panel?

If you donā€™t enter a valid code no sensor will change state IIRC.

Well, I always hear in other threads that the control panel isnā€™t necessary any more and shoudlnā€™t be used as all the functionality is included in HA.
Therefore I didnā€™t try it; also I wasnā€™t able to locate zwcp.

Is there a way to do everything in HA?
At least there is a point with something about user codes.

Yes you can set zwave parameters using HA instead of zwcp. Iā€™ve not tried it myself as I use zwcp. I think you go to the Z-wave Manager in HA Configuration, select the node and then send it config settings. There must be guides on how to use that somewhere. Youā€™ll need the keypad manual to know what codes to send etc.

Until youā€™ve set the keypad itself up to have some valid codes using some method of zwave configuration youā€™re not going to get much further.

Ok, I have made some progress here, but not all the way.

In post #1, @skptic wrote:

" 3: Set Configuration of Device (OZWCP)

In ā€œConfiguration, set ā€œFeedback Timeā€ to 10 and ā€œFeedback Timeoutā€ to 10. This will allow us to setup Sound notification and acknowledgment in (Type 3 from the manual) in Home Assistant. This is important as it allows us to get confirmation from HA that it received the message.ā€

In newer versions of Home Assistant, you do this in the built in Z-wave control panel.

  1. Configuration -> Z-wave and select your node. In my case, itā€™s "Kontrollpanel_hallen (node 15 Complete).

  2. Scroll down all the way to ā€œNode config optionsā€. In the Config Parameter dropdown, select ā€œ2: Feedback Timeā€ and set the value to 10. Save by clicking on ā€œSET CONFIG PARAMETERā€.

  3. in that same dropdown, now select ā€œ3: Feedback Timeoutā€ and set itā€™s value to 10. Save by clicking on ā€œSET CONFIG PARAMETERā€.

  4. Wait two hours before you continue (7200 seconds). Sure, there are ways around this, but letā€™s keep it simple for now.

From here on, I donā€™t know how to continue.

I donā€™t understand where I shall find this thing called ā€œEnrollment Codeā€. As far as I can tell, it never appears in the log, nor in states or elsewhere.

A little guidance would sure be appreciated.

Thanks in advance! :wink:

Good morning excuse my ignorance but I can not find the hex code to be copied in free slot slots and even if I put a numeric code and confirm the rescue tells me it has saved but does not keep it in memory. where I mistake thanks in advance

I tried doing what you described directly in home assistant but it seems that the values are not changed. (Even after multiple hours)
Did you try it without OZWCP?

BTW: Does anyone know if it also works with nfc?

Thanks!

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ā€¦