介绍
门锁对家庭的安全至关重要,因此通信必须可靠和快速。本文档汇集了许多门锁存在的问题,并指导开发人员实现最健壮和可互操作的门锁应用。这些大多是建议,而不是要求,并不能保证Z-Wave认证。Z-Wave允许大量的产品差异化,但重要的是,普通的门锁功能可以最好的可互操作方式工作。
Z-Wave门锁于2008年进入市场。问题是当时Z-Wave命令类缺少锁状态和用户代码的标准报告。最初,门锁使用Alarm CC向Hub发送各种通知更新门锁状态。这种方法的问题在于,每个制造商使用一组特有的命令来上报不同的状态更新。这些原始的门锁进入市场后不久,随着Z-Wave联盟的到来,Z-Wave规范得到了更新,现在门锁可以发送标准化消息来传递状态变化。标准化的消息使Hub的软件更加容易,因为可以接收基本的操作,而不需要为每个门锁制造商编写专门的代码。
用于门锁的Z-Wave命令类
在文档SDS14224 Z-Wave Plus v2 Device Type Specification section 4.5.1中有定义门锁设备类型强制和推荐命令类(CC),及认证所需的最低版本。但是,开发人员可以自由选择满足产品需求的command类版本。随着命令类的成熟,更多的命令被添加了进来,这又增加了复杂性和更多的代码空间。命令类中的每个命令都必须根据所支持的版本由门锁设备实现。如果您不想在以后的版本中支持某些命令,那么只在Version CC中声明早期版本。
强制命令类
- Door Lock CC (V4 or later)
- Battery (V1) – 如果门锁使用电池供电
- Basic CC - 00=UNLOCK, FF=LOCK (不能列表在 NIF)
- Security S0 CC – 为兼容不支持 S2的网关
- 未来可能会改为推荐命令,但在目前是强制性的
所有Z-Wave Plus v2设备强制的通用CC
- Association, version 2
- Association Group Information
- Device Reset Locally
- Firmware Update Meta Data, version 5
- Indicator, version 3
- Manufacturer Specific
- Multi-Channel Association, version 3
- Powerlevel
- Security 2
- Supervision - See discussion below - you SHOULD be using Supervision!
- Transport Service, version 2
- Version, version 2
- Z-Wave Plus Info, version 2
这些命令类中的大多数是由SDK和/或Z-Wave应用程序框架(ZAF)处理的。对这些命令类中的许多类都有一些自定义,但工作量很小。
推荐命令类
-
User Code CC -如果锁有键盘,这个CC是用来输入Code
-
Notification CC -发送各种锁定状态消息 Lifeline NodeID (网关)
-
Time CC - 请参阅下面 time/clock CC
- Clock CC
- Time Parameters CC
-
Generic Schedule CC - 定义启用/禁用用户代码的时间/日期范围
-
Schedule CC - 使用Z-Wave命令简单但不太灵活的调度
-
Authentication CC - 与RFID、NFC、Mag卡等一起使用,并将scheduleid与用户代码连接
其他命令类 -
Door Lock Logging CC
- Door lock logging CC提供了一种检索跟踪门锁操作日志的方法
- 典型应用: 如果Hub脱机,则记录所有操作的日志,然后可以在Hub恢复联机时发送给Hub
-
Barrier Operator CC - 通常用于像锁一样的电动入口大门
-
Entry Control CC –输入用户Code
- 依赖Hub对字符串进行身份验证,然后发送解锁命令
- 通常用于不能控制锁的键盘
- 对锁使用Authentication CC
-
Configuration CC (V3) - 配置其他CCs不支持的特定特性
- 只有在真正需要时才应该使用配置CC,因为它的互操作性较差
- 请参阅门锁配置设置命令,该命令应该提供所需的大部分配置
-
Application Status - 可以用来回复中心锁当前处于忙碌状态,不能执行刚刚接收到的命令
- 使用 Supervision 替代
-
Protection CC – 使能儿童保护模式
-
AntiTheft CC (v3) - 锁上设备
-
Multi-channel - Multichannel 不是必须的
-
Multi-command - 可用于在单一帧中返回多个命令,以减少电池消耗,但在S2中负载较小的情况下,不建议使用此方法
-
过时的命令类——不要使用这些
- Schedule Entry Lock CC – 使用 Generic Schedule CC 替代
- Alarm CC – 使用 Notification CC (V3 or later) 替代
安全等级
S2有三个安全级别,而S0有一个安全级别,总共有四个不同的安全级别:
- Security S2 Access Control -最强的安全级别仅用于提供进入安全区域的设备——门锁
- Security S2 Authenticated - SmartStart需要一个二维码/DSK -灯/恒温器/传感器
- Security S2 UnAuthenticated -少量早期S2设备不需要二维码/DSK,一般不推荐使用
- Security S0 -传统安全模式——速度较慢,消耗更多电池电量,安全性低于S2
由于潜在的安全漏洞,不建议使用S2 Unauthenticated密钥和S2 Authenticated 密钥。S2正在迅速普及,因此预计S0将不再是强制性的,而是推荐的。S0速度较慢,消耗的电池电量更多,而且安全性不如S2,因为网络密钥是使用已知的加密密钥交换的。安全S2使用Diffie-Hellman椭圆曲线来交换密钥,一个带外的DSK被要求加入网络和Nonces是预先计算的,使用单一命令可以数据交互,相比S0 (Nonce Get, Nonce Report,加密帧)通信数据量大大减小。门锁需要使用S2 Access Control level。
推荐的安全级别:
- S2 Access Control
- S0 目前是强制的
报告状态改变
当所有Z-Wave Plus设备的状态发生变化时,它们都需要发送状态到Lifeline NodeID(通常是Hub)。Z-Wave Application Framework True-State Engine(TSE)可以用来发送状态更改。锁的主要状态变化是:
- Secured vs. Non-secured (locked vs. unlocked)
- Keypad entry of a code
- Battery level
调度
目前,大多数锁依赖于Hub来安装/删除用户代码,并管理代码有效的时间和日期。因此,锁不需要知道当前日期/时间,也不需要存储计划并将其应用于用户代码。这使得锁固件简单,并保持了Hub调度的复杂性,以及其显著提高的处理、存储和用户界面功能。然而,许多租赁公司更喜欢电池供电的锁,以便有内置的时间表,即使有一个延长电源或互联网故障,适当的用户代码是启用/禁用在适当的时间。因此,需要在锁本身内管理这些调度。幸运的是,Z-Wave已经有了支持它们的命令类,但是调很复杂。
Generic Schedule CC – 推荐
Generic Schedule CC可以设置时间范围,然后设置由一个或多个时间范围组成的调度。时间范围有开始和停止日期/时间字段,每个字段可以启用或忽略。例如,时间范围可以是每个星期一从下午1点到下午3点(日期和分钟字段被忽略),或者可以包括特定的日期,比如2022年5月24日从11:23am到4:57pm。这使得时间范围非常灵活,可以指定几乎任何类型的日期/时间组合。
日程安排是一个时间范围列表,在构建日程安排时可以包含这些时间范围,也可以排除这些时间范围。因此,M-F 8am -5pm的时间范围可以包括在内,但是2022年1月1日下午4点到5点的时间范围可以排除在外。在本例中,Schedule包括第一个时间范围,并排除第二个时间范围。泛型调度只创建ScheduleIDs。它不保存任何命令或执行操作。然后使用Authentication CC将调度链接到用户代码或其他身份验证方法。有多达64K的计划和时间范围,尽管每个设备报告数字支持的通用计划能力报告。由于时间表和时间范围所需的内存。
Schedule CC
Schedule CC不同于一般调度,因为Z-Wave命令被使用,而不是scheduleid / authenticationid /UserCodes。Schedule CC可用于任何Z-Wave命令,而不仅仅是那些使用Schedule id的命令。Schedule CC最常用于恒温器或其他根据时间/日期自动改变状态的设备。虽然调度CC可以用来执行用户代码设置命令来启用/禁用调度中的用户代码,但它没有一般的ScheduleCC灵活。对于简单的每周调度,这个调度CC可以工作,但试图建立更复杂的调度迅速变得麻烦。
Schedule Entry Lock CC
Schedule Entry Lock CC已经被弃用,因此不应该在新锁中使用。使用通用的Schedule CC代替。有少于十几个认证的锁带有Schedule Entry Lock CC。Hub可能想要控制这个CC来支持特定的锁,但这不是必需的。
Authentication CC
Authentication CC用于将User Code连接到。Authentication CC还可以与RFID、NFC、mag stripes、BLE或其他形式的用户身份验证一起使用。然后使用它来根据计划启用/禁用各种访问方法。因此,身份验证是灵活的,但这种灵活性也带来了复杂性。
Time CC vs. Clock CC vs. Time
Parameters CC
如果锁支持schedules来启用/禁用用户代码,那么它需要一些方法来确定日期和时间。例如,吸尘器只在周二下午2点到4点工作。锁应该如何获取当前本地时间和日期,以便知道何时启用吸尘器?
有三个不同的命令类用于获取时间/日期的不同部分。Time Command类是所有网关的必需的,也是功能最完善的方法。不幸的是,并不是所有的网关都支持它,所以大多数设备需要支持其他的一个才能与旧的Hub一起使用。Clock CC is defined in SDS13781 - Z-Wave Application CC but the other two are defined in SDS13782.
Time CC | Clock CC | Time Parameters CC | |
---|---|---|---|
Second | V1(Local) | V1 (UTC) | |
Minute | V1(Local) | V1 | V1 (UTC) |
Hour | V1(Local) | V1 | V1 (UTC) |
Day of Week | V1 | ||
Day of Month | V1(Local) | V1 (UTC) | |
Month | V1(Local) | V1 (UTC) | |
Year | V1(Local) | V1 (UTC) | |
Time Zone Offset Hour, Minute | V2 | ||
DST Offset | V2 | ||
DST Start Month, Day Hour | V2 | ||
DST End Month, Day Hour | V2 |
Time CC –推荐
Time command class在SDS13782 (Z-Wave Management Command Class Specification)中有描述。Time CC对于所有的Z-Wave加网关都是强制性的,因此建议锁将其时钟设置为当前本地日期和时间。如果需要,Time CC Version 2增加了时区和夏令时支持,但是V1在大多数情况下提供了必要的功能。
Z-Wave规范建议使用一个关联组来识别时间服务器节点,但是网关期望有一个准确的时间引用,所以使用生命线是可以接受的。
Time CC没有date/time SET命令。因此,Hub不能设置日期/时间,而应该等待锁来获取它。当网络中包含锁时,Hub可以向锁发送时间/日期报告。然而,锁必须在最初几分钟内发送Time GET命令来精确地设置它的内部时钟。然后,锁应该定期发送一个Time GET,以确保内部时钟保持对本地时间的精确。只有锁知道它的实时时钟的准确性。因此,锁将确定需要多久更新它的内部时钟,并在需要时发送一个Time GET。Hub不应该发送时间报告,除非在包含后立即响应Time GET。注意,出于认证的目的,门锁CONTROLsTime CC,它不支持它。Hub需要支持时间CC。
Time Parameters CC –可选
Time Parameters command 能SET/GET/REPORT UTC时间的年、月、日、小时、分钟和秒。但是,它没有设置时区,而时区必须通过Time CC V2来完成。因此,Time Parameters CC依赖于Hub发送当前UTC时间,但锁也可以发送GET并调整其内部时钟以匹配来自Hub的时钟。然而,这需要Hub软件的支持,这不是强制性的,所以不是所有Hub都能够提供当前的日期/时间。
Clock CC – 不推荐
Clock command class由Hub发送,可以设置本地工作日和时间。因此,它只支持7天的日程安排,因为它不能设置日期,只能设置星期几。通常,Hub会发送一个时钟集作为网络的一部分。由于锁上的时钟将漂移,锁必须定期发送时钟到达中心,以保持准确的时间。不推荐使用这种方法。然而,在一些旧的Hub上,这是唯一可用的方法。
推荐时间设置算法
下面的算法提供了设置时间的基本指南。第一步是等待包含和安全组网完成。然后发送一个Time GET并启动一个30秒的计时器。如果Time REPORT在30秒计时器结束之前到达,则Hub支持Time CC,因此使用该Time CC。如果Hub转而发送一个Clock REPORT或Time Parameters SET,那么它将设置锁的初始时间。锁将不得不继续定期发送时钟获取命令到Hub,以保持时钟的准确性。如果Hub没有响应,那么锁别无选择,只能禁用schedule特性,因为它们需要准确的本地时间。
根据本地时钟电路的准确性,功能时间设置命令类应该被用来以一个足够的速率更新本地时钟,以匹配所需的设置。通常,这将是每天一次假设一个100ppm或更好的32Khz晶体用于时钟(见部分实时时钟(RTC) 32Khz晶体下面)。
Notification CC
Notification CC最初被称为AlarmCC,在V2中被弃用,被NotificationCC CC代替。当第一个Z-Wave锁被开发时,没有标准的方法来通知Hub当锁状态改变时。每个锁制造商可以自由选择报警类型和报警级别,以沟通各种状态的变化。不幸的是,这导致了非标准和不可互操作的Z-Wave命令。Notification CC V3定义了一组访问控制通知类型和事件,这些在SDS13713中描述,SDS13713列出所有标准通知types/events。对于新的锁开发,建议使用这里描述的标准化命令,而不是旧的Alarm CC命令(建议使用V8或更新版本)。如果使用安全S0加入锁以实现向后兼容性,则仍然可以发送Alarm CC,但如果使用安全S2加入锁,则不建议使用Alarm CC。或者,可以使用一个配置参数来启用/禁用Alarm CC命令。发送这些旧命令会浪费电池能量,阻塞Z-Wave网络。
Notification CC通常用于与Door Lock或User Code CCs之外的特定状态更改通信。有些通知和一些Door Lock命令有重叠。建议使用门锁CC,并且只在没有重叠的情况下使用通知。下面的示例通信部分展示了一些示例。
Supervision CC
所有S2设备必须支持Supervision CC。提供财产安全自锁和用户对可靠性和鲁棒性有很高期望的锁定操作,强烈建议所有通信从锁被包裹在Supervision CC。Supervision 就不需要发送一个通知,用户代码已经设置为Supervision 报告确认了收到命令,解密并执行。请参阅附录A,了解门锁固件的Supervision CC的样例实现。
下面的示例显示了一个由用户手动解锁的锁。锁需要100%确定它通知Hub门现在已解锁。为此,DoorLock_Operation报告被封装在一个Supervision GET命令中。第一次尝试被射频噪声阻止,但协议将自动重试发送帧到五个不同的路径使用网状网络,因为ACK没有收到。第二次尝试交付帧到Hub,但由于更多的射频噪声,Hub无法解密消息。Hub已经断开了帧,所以协议已经将帧从传输队列中退出,并且不会再尝试。但是,SDK已经启动了一个500ms的计时器,期望在这个时间内收到Supervision REPORT。由于Hub不能解密消息,它已经丢弃了帧。一旦500ms超时过期,锁将重新发送帧。这一次,它通过了,Hub能够解密消息和响应的Supervision REPORT与一个成功的状态。在这一点上,锁100%确定帧已经被交付、解密和执行。使用Supervision CC确保交付和执行任何Z-Wave命令,并应用于任何设备的任何关键功能。
Door Lock Command Class
大多数Door Lock CC是直接的,并在SDS13781中有文档记录。不过,锁定超时vs.自动重新锁定功能还需要一点额外的解释。Door Lock Operation Set (V1)命令包括分配超时模式或恒定模式的模式。Door Lock Configuration Set(V1)命令以分钟+秒为单位设置超时,以及锁定是默认为常量模式还是超时模式。Door Lock CC的新版本允许在Operation Set command中发送超时或自动重新锁定时间。自动重新锁定只有在锁定处于恒定模式时才有效。如果锁定处于超时模式,则使用正常超时分钟/秒,并忽略自动重新锁定的值。考虑到对超时模式的更常见支持,建议使用此模式来改进互操作性。注意,有些锁将超时或模式作为配置参数。虽然可以通过Configuration CC读取/写入这些模式,但同样的值也必须反映在Door Lock Configuration命令中。
通信示例
本节描述在各种场景中锁和Hub之间的通信。所有通信都是安全S2加密的,这在大多数示例中都有体现。建议将所有帧封装在Supervision 中,以确保帧被交付和解密。
用户手动锁定/解锁
当用户手动旋转螺栓/杠杆锁定或解锁该锁时,该锁必须向Lifeline NodeID(s) (Hub)发送以下信息:
当用户手动旋转螺栓/杠杆锁定或解锁该锁时,该锁必须向Lifeline NodeID(s)
(Hub)发送以下信息:
Byte # | Value | Name | Description |
---|---|---|---|
1 | 0x6C | CmdClass | Supervision CC |
2 | 0x01 | Cmd | Supervision GET |
3 | Properties1 | Supervision SessionID incremented with each new GET | |
4 | 0x09 | Len | Supervision Length |
5 | 0x62 | CmdClass | Door Lock Operation CC V4 |
6 | 0x03 | Cmd | Door Lock Operation Report |
7 | LockMode | 00=unsecured, FF=secured - See SDS13781 table 44 | |
8 | Properties1 | In/out Handles Mode - table 45 | |
9 | DoorCondition | Door/bolt/latch state - table 46 | |
10 | 0xFE | TimeoutMin | Lock returns to secured after these many minutes |
11 | 0xFE | TimeoutSec | Lock returns to secured after these many seconds |
12 | TargetMode | Target Mode if in transition or LockMode | |
13 | 0x00 | Duration | Seconds to reach target mode - 0=already at target |
如果使用安全S0包含锁,则可以发送Notification
CC来向后兼容。如果锁使用安全S2,则不建议这样做,因为安全S2依赖于Supervision
CC来确保交付。
Byte # | Value | Name | Description |
---|---|---|---|
1 | 0x71 | CmdClass | Notification CC |
2 | 0x05 | Cmd | Notification REPORT |
3 | 0x00 | V1AlarmType | V1Alarm can be non-zero IF documented in the user manual |
4 | 0x00 | V1AlarmLevel | These are used for backwards compatibility |
5 | 0x00 | Reserved | |
6 | 0xFF | Status | 00=notifications are disabled, FF=enabled |
7 | 0x06 | Type | 06=Access Control |
8 | Event | 01=Manual Lock, 02=Manual Unlock | |
9 | 0x00 | Properties1 | Parameters Length |
用户输入一个正确的User Code
用户代码“1234”已被设置在一个死锁与键盘在UserID=03。锁被锁定,然后用户输入1234解锁锁。发送一个Notification
CC,通知Hub使用了哪个用户代码。
Byte # | Value | Name | Description |
---|---|---|---|
1 | 0x6C | CmdClass | Supervision CC |
2 | 0x01 | Cmd | Supervision GET |
3 | 0x13 | Properties1 | Supervision SessionID incremented since this is a new frame |
4 | 0x09 | Len | Supervision Length |
5 | 0x71 | CmdClass | Notification CC |
6 | 0x05 | Cmd | Notification REPORT |
7 | 0x00 | V1AlarmType | V1Alarm can be non-zero IF documented in the user manual |
8 | 0x00 | V1AlarmLevel | These are used for backwards compatibility |
9 | 0x00 | Reserved | |
10 | 0xFF | Status | 00=notifications are disabled, FF=enabled |
11 | 0x06 | Type | 06=Access Control |
12 | 0x06 | Event | 05=keypad Lock, 06=keypad Unlock |
13 | 0x63 | Param | User Code CC |
14 | 0x03 | Param | User Code CC cmd = REPORT |
15 | 0x03 | Param | UserID=0x03 |
16 | 0x01 | Param | UserID Status = occupied & enabled |
17 | 0x31 | Param | User Code = ASCII “1” |
18 | 0x32 | Param | User Code = ASCII “2” |
19 | 0x33 | Param | User Code = ASCII “3” |
20 | 0x34 | Param | User Code = ASCII “4” |
可选地,可以发送Door Lock Operation来通知Hub门现在已解锁。
Byte # | Value | Name | Description |
---|---|---|---|
1 | 0x6C | CmdClass | Supervision CC |
2 | 0x01 | Cmd | Supervision GET |
3 | 0x12 | Properties1 | Supervision SessionID=0x12 |
4 | 0x09 | Len | Supervision Length |
5 | 0x62 | CmdClass | Door Lock Operation CC V4 |
6 | 0x03 | Cmd | Door Lock Operation Report |
7 | 0x00 | LockMode | 00=unsecured, FF=secured - See SDS13781 table 44 |
8 | 0x00 | Properties1 | In/out Handles Mode - table 45 |
9 | 0x00 | DoorCondition | Door/bolt/latch state - table 46 |
10 | 0xFE | TimeoutMin | Lock returns to secured after these many minutes |
11 | 0xFE | TimeoutSec | Lock returns to secured after these many seconds |
12 | 0x00 | TargetMode | Target Mode if in transition or LockMode |
13 | 0x00 | Duration | Seconds to reach target mode |
用户输入了错误的User Code
当前,当用户输入错误代码时,不会发送任何信息。有人讨论说,锁应该发送坏代码,这样集线器就可以收集用户尝试输入代码的次数和代码是什么。这将需要一个新的通知访问控制事件。请让我们知道您对这个想法的看法,或者参与到Z-Wave联盟标准开发组织并提出建议。
Hub发送锁/解锁命令
Hub发送锁或解锁命令。大多数锁需要几秒钟才能滑动一个螺栓,这个顺序显示了使用一个Supervision
Report,即WORKING状态,然后SUCCESS。
Byte # | Value | Name | Description |
---|---|---|---|
1 | 0x6C | CmdClass | Supervision CC |
2 | 0x01 | Cmd | Supervision GET |
3 | 0x95 | Properties1 | Supervision SessionID=0x15 with Status Updates |
4 | 0x03 | Len | Supervision Length |
5 | 0x62 | CmdClass | Door Lock Operation CC V4 |
6 | 0x01 | Cmd | Door Lock Operation SET |
7 | 0xFF | LockMode | 00=unsecured, FF=secured |
锁立即响应一个Supervision WORKING report
,更多的状态更新位设置表明另一个报告将在接下来的7秒内到来。WORKING状态意味着锁正忙着移动螺栓,它将需要几秒钟来确定它是否被正确地使用。如果状态更新位为0,则只发送此监督报告。如果锁(或者更典型的门)花费超过10秒的时间到达最终状态,建议每5-10秒发送一个WORKING
报告。每次都应该更新Duration字段以估计完成时间。
Byte # | Value | Name | Description |
---|---|---|---|
1 | 0x6C | CmdClass | Supervision CC |
2 | 0x02 | Cmd | Supervision REPORT |
3 | 0x95 | Properties1 | Supervision SessionID=0x15 - More Status Updates set |
4 | 0x01 | Status | WORKING - Once the bolt has finished moving another report will be sent |
5 | 0x07 | Duration | Next report will be in 7 seconds or less. The duration should be a worst-case number to handle the case when the lock is jammed. |
当锁完成操作时,它会发送另一个Supervision Report,状态更新位被清除,状态SUCCESS
(如果在Supervision GET中设置了Status
Updates)。这个帧应该在锁完成操作后立即发送。
Byte # | Value | Name | Description |
---|---|---|---|
1 | 0x6C | CmdClass | Supervision CC |
2 | 0x01 | Cmd | Supervision GET |
3 | 0x15 | Properties1 | Supervision SessionID=0x15 |
4 | 0xFF | Status | SUCCESS |
5 | 0 | Duration | Target mode completed |
此时,Hub可以确保锁完成了操作,因为Supervision
CC确认了命令已执行。但是,大多数Hub希望接收状态更新,因此可以发送Notification
CC、Access Control和0x03(锁)或0x04(解锁)的Event 。建议发送一个包裹在Supervision
Get中的门锁操作报告,如图所示。
Byte # | Value | Name | Description |
---|---|---|---|
1 | 0x6C | CmdClass | Supervision CC |
2 | 0x01 | Cmd | Supervision GET |
3 | 0x0A | Properties1 | Supervision SessionID=0x0A |
4 | 0x09 | Len | Supervision Length |
5 | 0x62 | CmdClass | Door Lock Operation CC V4 |
6 | 0x03 | Cmd | Door Lock Operation REPORT |
7 | 0xFF | LockMode | 00=unsecured, FF=secured |
8 | 0x00 | HandlesMode | In/out Handles Mode |
9 | 0x00 | DoorCondition | Door/bolt/latch state |
10 | 0xFE | TimeoutMin | Lock returns to secured after these many minutes |
11 | 0xFE | TimeoutSec | Lock returns to secured after these many seconds |
12 | 0xFF | TargetMode | Target Mode if in transition or LockMode |
13 | 0x00 | Duration | Seconds to reach target mode |
Hub发送User Code Set
Supervision封装了User Code SET,使User ID 为5的User Code为“1234”。
Byte # | Value | Name | Description |
---|---|---|---|
1 | 0x6C | CmdClass | Supervision CC |
2 | 0x01 | Cmd | Supervision GET |
3 | 0x01 | Properties1 | Supervision SessionID=0x01 |
4 | 0x08 | Len | Supervision Length |
5 | 0x63 | CmdClass | User Code CC |
6 | 0x01 | Cmd | User Code SET |
7 | 0x05 | UserID | User Identifier = 0x0005 |
8 | 0x01 | UserIDStatus | 0x00=available, 0x01=Access Enabled, 0x02=Disabled, 0x03=Messaging, 0x04=Passage Mode |
9 | 0x31 | UserCode1 | ASCII ‘1’ |
10 | 0x32 | UserCode2 | ASCII ‘2’ |
11 | 0x33 | UserCode3 | ASCII ‘3’ |
12 | 0x34 | UserCode4 | ASCII ‘4’ - total length of the code is 4 to 10 digits |
如果User Code被正确执行,锁将发送一个带有SUCCESS值的Supervision CC
REPORT,否则它将返回FAIL。如果UserID大于255,就会使用Extended User Code Set
命令。该命令还可以在一个帧中设置多个代码。
当Hub发送User Code
SET,Hub通常希望确认代码实际上是正确设置。虽然这没有必要如果使用监督,是一种很好的做法,这是唯一的方法,pre-S2锁可以确认用户代码集。因为upervision
Report已经证实User
Code已经设置,没有必要用这个框架在监督只是信息。如果锁使用安全S0,建议使用确认User
Code的通知报告。
Byte # | Value | Name | Description |
---|---|---|---|
1 | 0x71 | CmdClass | Notification CC |
2 | 0x05 | Cmd | Notification REPORT |
3 | 0x00 | V1AlarmType | V1Alarm can be non-zero IF documented in the user manual |
4 | 0x00 | V1AlarmLevel | These are used for backwards compatibility |
5 | 0x00 | Reserved | |
6 | 0xFF | Status | 00=notifications are disabled, FF=enabled |
7 | 0x06 | Type | 06=Access Control |
8 | 0x0E | Event | 0E=New User Code added |
9 | 0x00 | Properties1 | Parameters Length = none |
Hub发送一个重复的用户代码
如果Hub发送另一个具有不同UserID但具有相同UserCode的User Code
SET,则锁必须返回一个Notification CC Type=Access Control (0x06)和一个 Event=New
User Code Not Added (0x0F)。如果锁使用S2,则此通知应封装在Supervision CC中发送。
锁发送低电量警告
大多数锁使用简单的碱性电池,所battery command
class的version1就足够了。可充电或复杂的电池使用较新的版本。
电池驱动的锁应自动发送电池水平到Hub,每当电池水平变化了一个重要的level。如果电池电量与上次报告相比变化超过5%,锁应该发送一个更新。触发更新所需的更改量由您决定,但应该足够大,可以每隔几天甚至几周发送一次电池更新。请注意,温度的变化会导致电池电量上升,所以触发器应该要求电量降低。请注意,大多数Hub会偶尔轮询电池电量,这就是为什么发送更新是不需要的,除非水平已经从上一个报告显著改变。零电量仍然允许锁可靠地运行,但只是勉强。100%的电池水平应该是可以实现的,与广泛的电池。
当达到临界电池水平时,锁必须发送低电量警告(0xFF)。每个锁都有不同的临界级别,但通常在5%到20%的范围内。当第一次达到临界水平时,必须向Lifeline发送电量不足的警告。此警告只能发送一次。通常,RAM变量有一个标志,当低电量警告被发送时设置,只有在电池被替换时开机复位时才会被清除。低电量警告应该在Supervision
command
class中包装发送,以确保Hub接收到它。正常的电池报告不需要包装在Supervision。
Battery Report – 低电量报警
Byte # | Value | Name | Description |
---|---|---|---|
1 | 0x6C | CmdClass | Supervision CC |
2 | 0x01 | Cmd | Supervision GET |
3 | 0x01 | Properties1 | Supervision SessionID=0x01 |
4 | 0x03 | Len | Supervision Length |
5 | 0x63 | CmdClass | Battery CC |
6 | 0x03 | Cmd | Battery Report |
7 | 0xFF | Level | 0xFF=Low Battery Warning, 0-100 otherwise |
锁本地时间更新
如果一个锁有在特定的日期/时间启用User
Codes的调度,那么它需要知道当前的本地时间。请参阅上面关于可使用的不同命令类的讨论,以及本文档后面关于支持计时所需硬件的考虑事项。通常,锁将每天发送一次该帧以同步到本地时间。注意,在这种情况下,没有使用监视,因为时钟更新不够重要,不足以保证额外的开销和电池电源。如果中心没有自动设置时间,下面的框架应该在包含后的前五分钟内发送。注意,由于系统范围的延迟,时间可能会延迟几秒钟。
锁发送Time GET向Hub同步时间
Byte # | Value | Name | Description |
---|---|---|---|
1 | 0x8A | CmdClass | Time CC |
2 | 0x01 | Cmd | Time GET |
Hub通过Time REPORT进行响应,该报告将本地时间设置为5:6:7(凌晨5点后的6分7秒)。
Byte # | Value | Name | Description |
---|---|---|---|
1 | 0x8A | CmdClass | Time CC |
2 | 0x02 | Cmd | Time Report |
3 | 0x05 | Hour | Local Hour |
4 | 0x06 | Minute | Local Minute |
5 | 0x07 | Second | Local Second |
锁发送Date GET向Hub同步日期
Byte # | Value | Name | Description |
---|---|---|---|
1 | 0x8A | CmdClass | Time CC |
2 | 0x03 | Cmd | Date GET |
该Hub以Date REPORT 回应,将本地日期设置为2019年9月10日
Byte # | Value | Name | Description |
---|---|---|---|
1 | 0x8A | CmdClass | Time CC |
2 | 0x04 | Cmd | Date Report |
3 | 0x07 | Year1 | Local year MSB |
4 | 0xE3 | Year2 | Local year LSB - 0x7E3=2019 |
5 | 0x09 | Month | Local Month - 0x09=September |
6 | 0x0A | Day | Local Day - 0x0A=10th day |
锁必须根据当前日期计算星期几。如果需要的话,V2中的Time Offset
Get命令还可以用于获取夏令时日期/时间。每天在3:10左右检查当地时间/日期应该保持锁准确到当前的当地夏令时。
Generic Schedule启用一个User Code
下面的序列分配User Code0x05,以启用M-F
8am-5pm,除了在2019年6月5日从1:23pm到6:45pm。第一步是设置两个时间范围(01和02)。Hub应该首先发送一个Generic
Schedule Capabilities Get ,以确定锁支持多少时间范围和调度。
时间范围星期一到星期五上午8点到下午5点
Byte # | Value | Name | Description |
---|---|---|---|
1 | 0x6C | CmdClass | Supervision CC |
2 | 0x01 | Cmd | Supervision GET |
3 | 0x09 | Properties1 | Supervision SessionID=0x09 |
4 | 0x15 | Len | Supervision Length |
5 | 0xA3 | CmdClass | Generic Schedule |
6 | 0x03 | Cmd | Generic Schedule Time Range Set |
7 | 0x00 | TRngID1 | |
8 | 0x01 | TRngID2 | Time Range ID=0x0001 |
9 | 0xBE | Weekday | Weekday Mask = M-F |
10 | 0x00 | StartYear1 | Note the InUse bit (MSB) is zero for all fields that are not used |
11 | 0x00 | StartYear2 | Start Year not used |
12 | 0x00 | StopYear1 | |
13 | 0x00 | StopYear2 | Stop Year not used |
14 | 0x00 | StartMon | Start Month |
15 | 0x00 | StopMon | Stop Month |
16 | 0x00 | StartDay | Start Day |
17 | 0x00 | StopDay | Stop Day |
18 | 0x00 | StartHour | Start Hour |
19 | 0x00 | StopHour | Stop Hour |
18 | 0x00 | StartMin | Start Minute |
19 | 0x00 | StopMin | Stop Minute |
20 | 0x88 | DayStartHr | Daily Start Hour = 8am |
21 | 0x91 | DayStopHr | Daily Stop Hour = 17:00=5pm |
22 | 0x00 | DayStartMin | Daily Start Minute |
23 | 0x00 | DayStopMin | Daily Stop Minute |
时间范围2019年6月5日下午1:23到6:45:
Byte # | Value | Name | Description |
---|---|---|---|
1 | 0x6C | CmdClass | Supervision CC |
2 | 0x01 | Cmd | Supervision GET |
3 | 0x0A | Properties1 | Supervision SessionID=0x0A |
4 | 0x15 | Len | Supervision Length |
5 | 0xA3 | CmdClass | Generic Schedule |
6 | 0x03 | Cmd | Generic Schedule Time Range Set |
7 | 0x00 | TRngID1 | |
8 | 0x02 | TRngID2 | Time Range ID=0x0002 |
9 | 0x00 | Weekday | Weekday Mask not used |
10 | 0x87 | StartYear1 | |
11 | 0xE3 | StartYear2 | Start Year = 2019 |
12 | 0x87 | StopYear1 | |
13 | 0xE3 | StopYear2 | Stop Year = 2019 |
14 | 0x86 | StartMon | Start Month = June |
15 | 0x86 | StopMon | Stop Month = June |
16 | 0x85 | StartDay | Start Day = 5th |
17 | 0x85 | StopDay | Stop Day = 5th |
18 | 0x8E | StartHour | Start Hour = 1pm |
19 | 0x92 | StopHour | Stop Hour = 6pm |
20 | 0x97 | StartMin | Start Minute = 23 minutes after the hour |
21 | 0xAD | StopMin | Stop Minute = 45 min after the hour |
22 | 0x00 | DayStartHr | Daily Start Hour |
23 | 0x00 | DayStopHr | Daily Stop Hour |
24 | 0x00 | DayStartMin | Daily Start Minute |
25 | 0x00 | DayStopMin | Daily Stop Minute |
现在已经定义了两个时间范围,下一步是将它们相互链接,以创建一个ScheduleID。在本例中,包含了时间范围0001,排除了时间范围0002,以制定所需的日程安排。
Byte # | Value | Name | Description |
---|---|---|---|
1 | 0x6C | CmdClass | Supervision CC |
2 | 0x01 | Cmd | Supervision GET |
3 | 0x0B | Properties1 | Supervision SessionID=0x0B |
4 | 0x09 | Len | Supervision Length |
5 | 0xA3 | CmdClass | Generic Schedule |
6 | 0x06 | Cmd | Generic Schedule Schedule Set |
7 | 0x00 | SchedID1 | |
8 | 0x01 | SchedID2 | Schedule ID = 0001 |
9 | 0x02 | NumIDs | Number of Time Range IDs = 2 |
10 | 0x80 | TimeRngID1 | |
11 | 0x01 | TimeRngID2 | Include Time Range 0001 |
12 | 0x00 | TimeRngID1 | |
13 | 0x02 | TimeRngID2 | Exclude Time Range 0002 |
最后,使用Authentication CC将Schedule ID链接到User Code CC UserID
Byte # | Value | Name | Description |
---|---|---|---|
1 | 0x6C | CmdClass | Supervision CC |
2 | 0x01 | Cmd | Supervision GET |
3 | 0x0C | Properties1 | Supervision SessionID=0x0C |
4 | 0x0A | Len | Supervision Length |
5 | 0xA1 | CmdClass | Authentication CC |
6 | 0x06 | Cmd | Authentication Technologies Combination Set |
7 | 0x00 | AuthID1 | |
8 | 0x05 | AuthID2 | Schedule ID = 0005 - can be any value but matching with the UserID is easier to match them up |
9 | 0x01 | FallBack | Fallback Status = 01 = enable access based on the schedule |
10 | 0x00 | UserID1 | |
11 | 0x05 | UserID2 | User Code CC UserID=0005 |
12 | 0x00 | SchedID1 | |
13 | 0x01 | SchedID2 | Generic Schedule CC ScheduleID=0001 |
14 | 0x00 | NumAuthID | Only the User Code is enabled |
在任何情况下,都应该使用Supervision
来确认时间表和时间范围的正确设置。或者,如果锁只使用安全S0,则应该使用GET。如果使用NFC、BLE或其他身份验证技术,那么NumAuthID将大于零,以包括这些其他形式的身份验证。
锁有一个硬件故障
如果锁出现某种类型的硬件故障,则可以发送几个Notification
Events。最常见的是锁被卡住了,螺栓不是在锁或不锁的位置,而是在中间的某个位置。其他选择是发送一个家庭安全篡改事件时,电池盖被删除。如果加速度计检测到锁被打碎,则可以使用撞击检测事件。如果有人干扰RF试图绕过锁,然后RF干扰信息可以被发送。在这种情况下,锁应存储射频干扰消息,如果该消息不承认集线器由于干扰。在重试之间出现更大的超时时,锁应该继续尝试传递。
Byte # | Value | Name | Description |
---|---|---|---|
1 | 0x6C | CmdClass | Supervision CC |
2 | 0x01 | Cmd | Supervision GET |
3 | 0x01 | Properties1 | Supervision SessionID=0x01 |
4 | 0x08 | Len | Supervision Length |
5 | 0x71 | CmdClass | Notification CC |
6 | 0x05 | Cmd | Notification Report |
7 | 0x00 | V1AlarmType | V1Alarm can be non-zero IF documented in the user manual |
8 | 0x00 | V1AlarmLevel | These are used for backwards compatibility |
9 | 0x00 | Reserved | |
10 | 0xFF | Status | 00=notifications are disabled, FF=enabled |
11 | 0x06 | Type | 06=Access Control |
12 | 0x0B | Event | 0B=Lock Jammed |
如果螺栓没有处于锁定或解锁模式,锁还应该发送一个值为0xFE(Door Mode
Unknown)的Door Lock Operation Report。
长距离Z-Wave
建议为锁提供Z-Wave Long Range (ZWLR) 支持。Z-Wave Long
Range是一种非常长范围的星形拓扑。ZWLR是一个理想的电池备份中心直接对话到一个遥远的锁,即使电源是out和Z-Wave
网格中继器关闭。ZWLR将于2020年底上市,它是一个可以与现有设备同步的软件升级。可能需要重新进行射频监管测试(FCC),以确保ZWLR满足适用的监管限制。
硬件方面的考虑
700 系列
Z-Wave硬件是典型的FLiRS(频繁侦听路由奴隶)设备。在这种模式下,典型的功率消耗在平均10uA的数量级上,在传输期间短暂的峰值为12mA。每秒钟芯片短暂地醒来,并监听从中心或邻近节点发出的唤醒波束。如果Hub想要和锁通话,它就会发送信号来唤醒锁,然后两者就可以通信了。一旦通信完成,锁将再次进入低功耗状态。250ms的FLiRS模式可以用来减少唤醒锁的延迟,以额外的能量消耗的权衡。
实时时钟(RTC) 32KHz晶体
大多数锁需要精确地测量时间,并保持何时启User
Codes的时间表。700系列内部有一个低功率低频RC振荡器(LFRCO=32KHz)。但是,振荡器不够精确,不能在没有时间服务器频繁更新的情况下保持时间表的精确(LFRCO可以漂移超过1分钟/小时)。因此,建议使用32KHz晶体连接到EFR32的LFXO。一个低成本的100ppm
32KHz晶体可以提供9秒的精度每天。注意,如果您的锁不支持Time
CC,那么就不需要外部晶体。
- 如果支持schedules ,则为LFXO使用32KHz晶体
一个MCU还是多个?
Z-Wave
700系列是一款内置加密加速器和大量低功耗外设的ARM处理器。ZGM130S有大量的GPIO,可以通过I2C或SPI使用简单的GPIO扩展器轻松扩展。在大多数情况下,ZGM130S足够强大,可以使用单个处理器运行整个锁。这避免了在锁内使用多个微控制器所涉及的复杂性和安全性问题。如果选用多MCU方案,则ZGM130与lock
MCU的通信方式应为UART、SPI或I2C,并进行加密。不要在ZGM130上使用SerialAPI !
SerialAPI用于具有大量FLASH/RAM/CPU的Internet网关处理器。SerialAPI不提供对嵌入SDK内建的安全加密/解密的支持。建议在处理器之间开发自己的加密串行协议。
附录A: Supervision 封装终端设备示例
Z-Wave SDK 7.14不直接支持用Supervision
CC封装帧,但是很容易手动添加。下面的例子简单地用SuperVisionGet包装了DoorLockOperationReport,如果设备被添加为S2,这意味着Hub支持Supervision
CC。如果响应来自Hub的GET,框架就不封装。
n CC_DoorLock.c - Add the following code to this function:
static uint8_t prepare_operation_report(ZW_APPLICATION_TX_BUFFER *pTxBuffer, uint8_t enableSuper)
{
ZW_APPLICATION_TX_BUFFER * ptr = pTxBuffer;
memset((uint8_t*)pTxBuffer, 0, sizeof(ZW_APPLICATION_TX_BUFFER) );
uint8_t len=sizeof(ZW_DOOR_LOCK_OPERATION_REPORT_V4_FRAME);
if (SECURITY_KEY_S2_ACCESS == GetHighestSecureLevel(ZAF_GetSecurityKeys()) && enableSuper) { // add supervision if S2 enabled
ptr->ZW_SupervisionGetFrame.cmdClass = COMMAND_CLASS_SUPERVISION;
ptr->ZW_SupervisionGetFrame.cmd = SUPERVISION_GET;
DL_SessionID = CC_SUPERVISION_ADD_SESSION_ID((DL_SessionID+1));
ptr->ZW_SupervisionGetFrame.properties1 = DL_SessionID;
ptr->ZW_SupervisionGetFrame.encapsulatedCommandLength = sizeof(ZW_DOOR_LOCK_OPERATION_REPORT_V4_FRAME);
ptr=(ZW_APPLICATION_TX_BUFFER*)((uint8_t*)ptr+sizeof(ZW_SUPERVISION_GET_FRAME)); // skip 4 bytes
len+=sizeof(ZW_SUPERVISION_GET_FRAME);
}
ptr->ZW_DoorLockOperationReportV4Frame.cmdClass = COMMAND_CLASS_DOOR_LOCK_V4;
ptr->ZW_DoorLockOperationReportV4Frame.cmd = DOOR_LOCK_OPERATION_REPORT_V4;
cc_door_lock_operation_report_t operation_report;
CC_DoorLock_OperationGet_handler(&operation_report);
ptr->ZW_DoorLockOperationReportV4Frame.currentDoorLockMode = (uint8_t)operation_report.mode;
ptr->ZW_DoorLockOperationReportV4Frame.properties1 =
(operation_report.outsideDoorHandleMode << 4) | operation_report.insideDoorHandleMode;
ptr->ZW_DoorLockOperationReportV4Frame.doorCondition = operation_report.condition;
ptr->ZW_DoorLockOperationReportV4Frame.lockTimeoutMinutes = operation_report.lockTimeoutMin;
ptr->ZW_DoorLockOperationReportV4Frame.lockTimeoutSeconds = operation_report.lockTimeoutSec;
ptr->ZW_DoorLockOperationReportV4Frame.targetDoorLockMode = operation_report.targetMode;
ptr->ZW_DoorLockOperationReportV4Frame.duration = operation_report.duration;
return(len);
}
Z-Wave/Zigbee门锁项目定制开发:279716582