人脸识别门禁开发文档--V3.0

修改记录

时间 版本 内容 作者
2019-11-29 V1.0 初始版本,有一些接口待定 wangrenyi
2019-12-17 V1.1 1. 增加/set_upload_url/get_upload_url接口,之前过于追求协议简洁,把信令和数据都放在一个tcp里,导致信令有可能被阻塞,响应迟缓等问题,现在改为通行记录上报单独用一个连接实现, 添加两个接口用于配置上传地址 wangrenyi
2. 修改/upload_record接口,增加传送效率,以前图片都是用HEX文本方式传送,现在改为二进制传送,使用http multipart报文传送
3. 修改/upgrade接口,该接口原来用HEX文本方式传送,现在改为标准http文件下载方式
4. 去除/replace_resouce接口,该接口不实用
5. 修改了部分文字表述,力求表达清晰
2019-12-20 V1.2 对若干消息字段进行调整 wangrenyi
2019-12-23 V1.3 IO口配置修改,去除一些意义不大字段; 用户查询接口修改,增加列表获取; 用户组查询接口修改,增加列表获取; 消息模版做了修改,如果没有json数据,也需要发送占位json,以更符合标准 wangrenyi
2019-12-30 V1.4 HTTP回应包里的json统一加上cmd和返回码类型,携带的数据做为二级json放入data字段,目的是方便服务端实现;用户组权限做了修改,有些字段用处不大取消了 wangrenyi
2020-1-9 V2.0 做了重大修改,为方便对接,底层通信协议改为websocket wangrenyi
2020-1-13 V2.1 调整了通行结果类型 wangrenyi
2020-2-14 V3.0 做了重大修改,websocket协议增加ssl加密,同时在登陆时增加密码,服务器端可以进行验证 wangrenyi

设计原理

  1. 本产品针对小型场景使用,协议力求简洁,方便对接
  2. 支持外网穿透,部署在公网的服务器能直接控制内网里的门禁机,比如远程开门,远程添加用户
  3. 整套结构为CS结构,人脸机为客户端,服务端分为信令服务器和数据服务器,可合在一起实现,也可分开独立实现,独立部署
  4. 人脸机开机主动连接服务器,采用websocket ssl协议,除第一条登录命令,其它所以命令都是被动响应服务端的命令,信令服务器端口为端口443
  5. 人脸机产生的通行记录,采用标准http post协议,通过multipart报文发送到一个标准的HTTP服务器上,因为报文里可能包含图片等大数据,所以称为数据服务器
  6. 人脸机可脱机工作,能够缓存一定通行记录在设备端(不带抓拍图),在重新连上数据服务器后,再平滑发送出去
  7. 人脸机支持刷卡,刷脸,刷卡或刷脸,刷卡+刷脸双重认证这4种通行检测模式,检测时带语音和文字提示
  8. 人脸机可通过信令服务器录入用户,并设置用户在不同时间段的通行权限
  9. 人脸机支持4路输入:按钮开关,门磁,报警,防撬。2路输出:门开关继电器,报警
  10. 人脸机可通过信令服务器远程开关门,查看门状态
  11. 人脸机支持常规的基本功能,恢复出厂设置,远程升级,重启,读取调试日志等功能

信令服务器功能

详细实现在接口协议部分描述

  1. 激活设备

    出厂的设备必须通过激活,才能连接上服务器 厂家可自己实现

  1. 注册用户

    录入人脸

    设置用户所属分组

    设置每个分组的时间段权限

  1. 给人脸机下发配置

    同步所有用户信息

    同步时间

    人脸识别算法参数配置

    三路IO输入(开门按钮,门磁,报警输入)的电平配置

    两路IO输出(门闭合继电器,报警输出)的触发时间长度配置

  1. 远程控制门

    门常开

    门常闭

  1. 设备管理

    远程升级

    恢复出厂设置

    重启

    查看日志

数据服务器功能

详细实现在接口协议部分描述

  1. 接收带抓拍照片的记录

  2. 接收离线记录

  3. 接收报警记录

人脸机功能

详细实现在接口协议部分描述

  1. 刷卡开门

  2. 人脸识别开门

  3. 刷卡+人脸识别双重认证开门

  4. 按钮开关,报警,远程开门

  5. 离线记录缓存

  6. 图像+语音提示

  7. 通行记录上传

  8. 支持IO报警信号的输入与输出

内网穿透机制

设备端根据激活前的配置,使用websocket协议,连接服务端,进行双向通信

人脸录入机制

人脸识别是通过"人脸特征"实现的,服务器下发带有人脸的图片到设备,设备提取特征入库。若特征不足则会提示错误

通行判断逻辑

刷卡 + 刷脸 + 门状态 + 用户权限 组合判断

刷卡和刷卡都是通过比对设备上的用户数据库来确定是否成功

门状态有两种方式改变

  1. 通过IO口输入的报警,防撬等信号改变

  2. 通过远程控制指令改变

用户权限包括"用户权限"和"用户组"权限

安全机制

设备通过wss协议与服务端连接,握手校验机制为 device_id + password

例:

{
    "cmd" : "login",
    "data" : { 
        "app_ver" : "0.0.1", 
        "device_id" : "10000001", 
        "password" : "12345678"
    }
}

协议说明

协议概述

  1. 协议采用websocket,版本13

  2. 为方便开发,仅支持websocket里的"文本帧"

  3. 负载数据全部是标准的json字符串,编码为UTF8

  4. json串请严格按后面的规则构造,字符型字段如果为空,请用""来表示,不能直接删除

  5. user和group数据会涉及多条记录,均没有定义修改命令,请用del + add的机制实现

请求包模版

请求包json格式统一包含cmd和data两部分

  1. cmd是请求的类型,一共有21种
  2. data是请求携带的数据,是一个子json,如果某些请求无需数据,比如get_time,data字段可以不加,或者加一个空json:{}
  3. 下面是一个例子

     {
         "cmd": "login",
         "data": {
             "firmware_ver": "1",
             "device_id": "1234567890",
             "device_type": "zhongding_mj"
         }
     }
    

回应包模版

回应包json格式统一包含cmd,ret,msg,data四个字段

  1. cmd是对应请求包加上后缀"_resp"构成

  2. ret目前只有两个值,200表示成功,500表示失败

  3. msg字段用于简短描述操作,比如失败的话给出失败的原因

  4. data是回应的数据,是一个子json,如果某些请求无需数据,可以不加,或者加一个空json:{}

  5. 下面是一个例子

    {
         "cmd": "get_time_resp",
         "ret": 200,
         "msg": "get time OK",
         "data": {
             "time": "2020-01-09 12:47:47"
         }
    }
    
  6. 下面是一个没有数据携带时的例子,后面描述具有协议时,没数据的回应包均按此定义,不再赘述

    {
         "cmd": "login_resp",
         "ret": 500,
         "msg": "xxx"
    }
    

信令服务器接口协议

登录

命令

login

请求数据

字段 类型 说明
device_id string 设备ID
password string 密码,服务器根据设备ID和密码可以进行鉴权
device_type string 用于软件兼容多款设备
app_ver string 应用版本,同一个固件上,app可单独替换
firmware_ver string 固件版本,升级需要用

回应数据

心跳

命令

heartbeat

请求数据

回应数据

时间设置

命令

set_time

请求数据

字段 类型 说明
time string 格式为"yyyy-mm-dd hh:mm:ss"

回应数据

时间查询

命令

get_time

请求数据

回应数据

字段 类型 说明
time string 设备当前时间,格式为"yyyy-mm-dd hh:mm:ss"

备注:时间设置如果不正确,会导致与时间相关的通行权限判断异常,上报的通行记录时间也不正确

人脸参数设置

命令

set_face_cfg

请求数据

字段 类型 说明
min_face_size int 人脸检测最小宽度,默认910,范围182 -- 1024
check_area_left int 识别区域左上角X坐标,默认0,范围0 -- 8192
check_area_top int 识别区域左上角Y坐标,默认0,范围0 -- 8192
check_area_right int 识别区域右下角X坐标,默认8190,范围0 -- 8192
check_area_bottom int 识别区域右下角Y坐标,默认8190,范围0 -- 8192
recognition_threshold int 设别率阀值,范围0 -- 1000,用户数小于100推荐438,用户数大于100小于1000推荐509,用户数大于1000推荐575,低于阀值的将被当成陌生人上传
clearness_threshold int 图片清晰度阀值,默认92,范围0 – 100,图片只有足够清晰才触发识别,这个可以避免图像运动,拖尾,模糊,聚焦不准时触发刷脸
sensitivity int 识别灵敏度,默认1,范围0(低),1(中),2(高),高灵敏度可以增加运动模糊人脸、遮挡人脸、复杂光线人脸、大角度人脸的检出效果,但会增加误检率
expand_scale int 抓拍人脸时的抠图范围,默认1000,范围1000 – 4000,系数越小,抠图范围越小,反之。具体参看后面的示例图
alive_enable int 活体识别开关,默认1,范围0(关闭),1(启动),该配置修改后必须重启设备
alive_threshold int 活体分数阀值,默认50,范围0 – 100,抓拍出来的人脸,如果活体分数低于阀值,认为是假脸
two_check_time int 双重认证超时时间,默认5秒

回应数据

人脸参数查询

命令

get_face_cfg

请求数据

回应数据

参看“人脸参数设置”,数据和设置数据一样

录上报地址设置

命令

set_upload_url

请求数据

字段 类型 说明
url string 标准url格式,端口不是80用冒号指明端口

回应数据

通行记录上报地址查询

命令

get_upload_url

请求数据

回应数据

字段 类型 说明
url string 通行记录上传的http地址,标准url格式

IO口设置

命令

set_io_cfg

请求数据

字段 类型 说明
door_button json 按钮配置,格式为嵌套Json字符串
door_magnetic json 门磁配置,格式为嵌套Json字符串
alarm_input json 报警输入配置,格式为嵌套Json字符串
prevent_pry json 防撬传感器配置,格式为嵌套Json字符串
door_relay json 门闭合继电器配置,格式为嵌套Json字符串
alarm_output json 报警输出配置,格式为嵌套Json字符串

door_button,door_magnetic,alarm_input,prevent_pry 嵌套的Json格式为

{
    "enable": true, //是否启用
    "level": 0      //0低电平触发,1高电平触发
}

door_relay 嵌套的Json格式为

{
    "enable": true, //是否启用
    "duration": 5   //信号持续时间,用于自动关门,单位为秒,0为无限长
                    //因为开门继电器比较特殊,总是高电平有效,所以这里不需要再去配置电平
}

alarm_output 嵌套的Json格式为

{
    "enable": true, //是否启用
    "level": 0,     //0低电平触发,1高电平触发
    "duration": 5   //信号持续时间,用于自动停止报警,单位为秒,0为无限长
}

回应数据

IO口查询

命令

get_io_cfg

请求数据

回应数据

字段 类型 说明
door_button json 按钮配置,格式为嵌套Json字符串
door_magnetic json 门磁配置,格式为嵌套Json字符串
alarm_input json 报警输入配置,格式为嵌套Json字符串
prevent_pry json 防撬传感器配置,格式为嵌套Json字符串
door_relay json 门闭合继电器配置,格式为嵌套Json字符串
alarm_output json 报警输出配置,格式为嵌套Json字符串

嵌套的Json参看“IO口设置”

用户添加

命令

add_user

请求数据

字段 类型 说明
user_id string 用户id,全局唯一,设备不做唯一性检查,请服务器做好判断
card_id string 用户持有的门禁卡id,全局唯一,设备不做唯一性检查,请服务器做好判断
group_id string 关联到用户组,目地是批量设置用户的使用权限
name string 用户名
start_time string 有效期开始时间,格式为"yyyy-mm-dd hh:mm:ss"
end_time string 有效期结束时间,格式为"yyyy-mm-dd hh:mm:ss"
face_feature string 最重要的参数,人脸特征,为4096个字符,数据编码为"HEX"格式,即每字节用2位十六进制数字的大写字符表示

回应数据

备注:user_id是必须存在的,如果用户只是刷脸,card_id可以为空字符串,如果用户只刷卡,face_feature可以为空字符串

用户删除

命令

del_user

请求数据

字段 类型 说明
user_id string 用户id,用户唯一标识。如果等于"ALL",表示删除所有用户

回应数据

用户查询

命令

query_user

请求数据

字段 类型 说明
user_id string 用户id,用户唯一标识。如果等于"ALL",表示获取所有用户id列表

单个用户回应数据

字段 类型 说明
user_id string 用户id,全局唯一,设备不做唯一性检查,请服务器做好判断
card_id string 用户持有的门禁卡id,全局唯一,设备不做唯一性检查,请服务器做好判断
group string 关联到用户组,目地是批量设置用户的使用权限
name string 用户名
start_time string 有效期开始时间,格式为"yyyy-mm-dd hh:mm:ss"
end_time string 有效期结束时间,格式为"yyyy-mm-dd hh:mm:ss"

所有用户回应数据

字段 类型 说明
list_len int 用户个数
user_id_list array 所有用户id组成的数组

例子如下

{
    "list_len": 5,
    "user_id_list": [
        "001",
        "002",
        "003",
        "004"
    ]
}

备注:因为数据量比较大,查询不会返回特征信息

用户组添加

命令

add_group

请求数据

字段 类型 说明
group_id string 组id,全局唯一,设备不做唯一性检查,请服务器做好判断
valid_time1 json 有效时间区间1,格式为嵌套Json字符串
valid_time2 json 有效时间区间2,格式为嵌套Json字符串
valid_time3 json 有效时间区间3,格式为嵌套Json字符串
valid_time4 json 有效时间区间4,格式为嵌套Json字符串
valid_time5 json 有效时间区间5,格式为嵌套Json字符串

嵌套的Json格式为

{
    "start_time": "00:00", //开始时间
    "end_time":"24:00", //结束时间,和开始时间一起,决定了能在什么时间段里工作
    "op_type":1 //操作类型,0:特权,1:刷卡,2:人脸,3:人脸或刷卡,4:人脸加刷卡,5:禁止通行
}

回应数据

备注:用户组目地是为了批量给用户赋予在不同时间段开门的权限,比如可以建立一个特权组,把所有时间段的操作都设为“特权”,那么用户可以不受限的通行;建立一个行政组,每天5:30以后就不能开门;建立一个程序员组,凌晨2点以后不能开门。这里预设了5组时间,可以灵活配置,设备不负责检测时间段重叠,只按照第一个匹配成功的时间段进行操作。如果一个时间段都没匹配上,那么当无权开门处理。注意“0特权”,当门状态为“禁止通行”时,依然可以开门

用户组删除

命令

del_group

请求数据

字段 类型 说明
group_id string 组id,组唯一标识。如果等于"ALL",表示删除所有用户组

回应数据

备注:如果已经有用户关联的组被删掉后,用户在开门时将提示“权限配置丢失”的错误,无法开门

用户组查询

命令

query_group

请求数据

字段 类型 说明
group_id string 组id,组唯一标识。如果等于"ALL",表示获取所有用户组id列表

单组回应数据

字段 类型 说明
group_id string 组id,全局唯一,设备不做唯一性检查,请服务器做好判断
valid_time1 json 有效时间区间1,格式为嵌套Json字符串
valid_time2 json 有效时间区间2,格式为嵌套Json字符串
valid_time3 json 有效时间区间3,格式为嵌套Json字符串
valid_time4 json 有效时间区间4,格式为嵌套Json字符串
valid_time5 json 有效时间区间5,格式为嵌套Json字符串

嵌套的Json格式参看“用户组添加”

所有组回应数据

字段 类型 说明
list_len int 用户个数
group_id_list array 所有用户组id组成的数组

例子如下

{
    "list_len": 5,
    "group_id_list": [
        "001",
        "002",
        "003",
        "004"
    ]
}

门远程控制

命令

remote_ctrl

请求数据

字段 类型 说明
ctrl_type int 控制类型,0:正常,1:常开,2:禁止通行,3:报警输出,4:紧急开门(常开+报警)
duration int 持续时间,单位秒,时间到达后,自动切回正常状态,0表示无限长

回应数据

备注:切回正常状态时,如果门是开着的,会自动关门;如果有报警输出,会自动关闭报警输出。控制类型会影响用户通行,比如“禁止通行”下,除了特权用户,其它都无法开门

门状态查询

命令

get_door_status

请求数据

回应数据

字段 类型 说明
door_status int 0:正常,1:常开,2:禁止通行,3:报警输出,4:紧急开门(常开+报警)
door_button boolean false:没按,true:按下,读取的是按钮开关IO口
door_magnetic boolean false:关闭,true:打开,读取的是门磁传感器IO口
alarm_input boolean false:报警输出关闭,true:报警输出打开,读取的是报警输出IO口
prevent_pry boolean false:防撬关闭,true:防撬打开,读取的是报警输出IO口

备注:方便服务器远程检查门的状态,以做出相应操作。比如监控门是否被非法打开。第一项是门的逻辑状态,其余项是传感器的状态值(经过IO口的配置项转换过)

二维码下发

命令

set_qrcode

请求数据

字段 类型 说明
url string 二维码内容,一个任一字符串

回应数据

备注:收到二维码后,设备屏幕会立刻更新二维码显示,手机扫描后,可以实现访客远程开门

恢复出厂设置

命令

factory_reset

请求数据

回应数据

备注:设备会重启

远程升级

命令

upgrade

请求数据

字段 类型 说明
url string 升级文件必须放在一个http服务器里,给出其url,设备直接下载该url指向的升级文件

回应数据

备注:升级文件下载好后,会关闭所有功能,开始烧写flash,烧写完成后会重启

远程重启

命令

restart

请求数据

回应数据

调试日志读取

命令

get_log

请求数据

回应数据

字段 类型 说明
message string 设备运行日志

备注:设备上一个循环写的日志文件,该文件通过该协议可以被读出,方便测试

数据服务器接口协议

通行记录上传

命令

为/set_upload_url接口里设置的url

请求数据

格式为multipart报文,分为两部分,第一部分是json字符串,内容如下

字段 类型 说明
record_type int 记录类型,0:在线通行记录,1:离线通行记录,2:异常记录
device_id string 设备id
user_id string 用户id
card_id string 卡号
group_id string
user_name string 用户名
time string 产生时间,格式为"yyyy-mm-dd hh:mm:ss"
pass_result int 通行结果,正数表示通过,负数表示拒绝,实际数值能体现具体的原因,参看下面的描述
message string 用于发送一段描述到服务器,比如record_type=3时,可以用这个上传异常信息
similarity int 人脸相似度,范围0--100
jpg_len int 人脸jpeg文件长度,如果为0,表示不携带图片

第二部分是jpg文件,整个报文示例如下

POST /xmmj/upload HTTP/1.1
Host: 10.2.5.56:8080
Connection: keep-alive
Content-Type: multipart/form-data; boundary=xiongmaitech-boundary
Content-Length: 100

--xiongmaitech-boundary
Content-Disposition: form-data; name="record"
Content-Type: application/json

...json data...
--xiongmaitech-boundary
Content-Disposition: form-data; name="jpg"; filename="000000001.jpg"
Content-Type: image/jpeg

...jpg data...
--xiongmaitech-boundary--

回应数据

pass_result 详细说明:

类型 说明
0 该值不使用
1 刷卡成功
2 刷脸成功
3 刷卡 and 刷脸双重认证成功
4 刷卡 or 刷脸任意一种成功
5 特权用户
6 帐号时间即将过期(作用是在开门时增加一个语音提示)
-1 门被锁定,禁止通行(VIP用户不受影响)
-2 帐号过期
-3 帐号时间未到
-4 用户开门权限未配置(没找到对应的用户组)
-5 用户当前时间段内的权限为:无权通行
-6 用户当前时间段内的权限为:必须刷卡(如果刷脸会触发这个)
-7 用户当前时间段内的权限为:必须刷脸(如果刷卡会触发这个)
-8 未知人脸,识别率低于识别率阀值,参看“人脸参数设置”
-9 未知卡号
-10 人脸+卡模式下,先取到卡,然后在x秒内没等到人脸(x在人脸参数设置里可以配置)
-11 人脸+卡模式下,先取到人脸,然后在x秒内没等到卡(x在人脸参数设置里可以配置)
-12 人卡不一致

备注:

  • 刷卡通行,离线记录,异常记录都不携带抓拍照片,报文里不会携带jpg部分
  • 异常记录只有device_id,time,message这3个字段有效,其余字段置空
  • record_type=0表示实时通行记录,record_type=1表示离线通行记录,record_type=2表示报警信息
  • card_id, group_id, name看上去比较冗余,实际上都可以通过查询user_id获取,这里提供出来是为了方便