更新时间:2023-06-15 05:25:33
本文介绍梯控开放能力接入的相关说明。
功能点相关接口,请参考 修改设备功能点。
功能点 Code | 说明 |
---|---|
face_lift | 支持刷脸乘梯。 |
qrcode_lift | 支持扫二维码乘梯。 |
out_lift | 支持外呼。 |
unify_lift | 支持外呼联动内呼,有电梯状态上报。上报的状态包含电梯井、轿厢当前楼层和上下行方向等数据。 |
out_auth | 支持外呼联动内呼,无电梯状态上报。 |
public_lift | 支持公共楼层。 |
API 名称 | 接口地址 |
---|---|
删除人员 | DELETE:/v1.0/elevator-control/{device_id}/persons/{person_id} |
更新人员 | PUT:/v1.0/elevator-control/{device_id}/persons/{person_id} |
新增人员 | POST:/v1.0/elevator-control/{device_id}/persons/{person_id} |
API 名称 | 接口地址 |
---|---|
删除人脸 | DELETE:/v1.0/elevator-control/{device_id}/persons/{person_id}/faces/{face_id} |
新增人脸 | POST:/v1.0/elevator-control/{device_id}/persons/{person_id}/faces/{face_id} |
更新人脸 | PUT:/v1.0/elevator-control/{device_id}/persons/{person_id}/faces/{face_id} |
API 名称 | 接口地址 |
---|---|
解冻梯控卡 | PUT:/v1.0/elevator-control/{device_id}/persons/{person_id}/card/{card_no}/unfreeze |
冻结梯控卡 | PUT:/v1.0/elevator-control/{device_id}/persons/{person_id}/card/{card_no}/freeze |
新增梯控卡 | POST:/v1.0/elevator-control/{device_id}/persons/{person_id}/card/{card_no} |
删除梯控卡 | DELETE:/v1.0/elevator-control/{device_id}/persons/{person_id}/card/{card_no} |
API 名称 | 接口地址 |
---|---|
呼梯指令发送 | POST:/v1.0/elevator-control/{device_id}/persons/{person_id}/actions/call |
API 名称 | 接口地址 |
---|---|
删除二维码 | DELETE:/v1.0/elevator-control/{device_id}/persons/{person_id}/qrcodes/{qr_code} |
更新二维码 | PUT:/v1.0/elevator-control/{device_id}/persons/{person_id}/qrcodes/{qr_code} |
新增二维码 | POST:/v1.0/elevator-control/{device_id}/persons/{person_id}/qrcodes/{qr_code} |
云开发项目 开启消息订阅 后,可以收到梯控设备端上报的事件消息。消息队列接入流程的详细介绍,请参考 消息队列。
用户触发梯控通行,梯控会上报用户的通行事件给开发者。事件 Code:pass_event
。
参数名 | 类型 | 说明 | 必填 |
---|---|---|---|
uid | String | 通行人员 ID。如果是陌生人,默认传 -1 。 |
是 |
way | Integer | 通行方式。
|
是 |
t | Long | 通行时间,13 位时间戳。 | 是 |
success | Integer | 是否成功。
|
是 |
message | String | 通行事件描述。如果通行失败,则返回失败原因。 | 否 |
picUrl | String | 通行照片的 URL。人员通行时,设备抓拍的人员照片。通行照片的 URL 是临时 URL,开发者需要根据 URL 下载照片并存储。 | 否 |
temp | String | 体温。 | 否 |
startFloor | Integer | 开始楼层。 | 否 |
endFloor | Integer | 结束楼层。 | 否 |
lifeNum | Integer | 电梯井号。 | 否 |
extend | String | 扩展字段。 | 否 |
{
"dataId": "AAXRV4BrtW9BRB9A2JYW****",
"devId": "6ca****",
"productKey": "e6rz6vba81wm****",
"status": [
{
"12": "{\"message\":\"ok\",\"success\":1,\"t\":1637548630452,\"uid\":\"zs123\",\"way\":4}",
"code": "pass_event",
"t": 1637548630455,
"value": "{\"message\":\"ok\",\"success\":1,\"t\":1637548630452,\"uid\":\"zs123\",\"way\":1}"
}
]
}
上报轿厢当前楼层、上下行方向等数据。事件 Code:function_data
。
参数名 | 类型 | 说明 | 必填 |
---|---|---|---|
shaftList | List |
轿厢列表 | 是 |
参数名 | 类型 | 说明 | 必填 |
---|---|---|---|
lifeNum | Integer | 电梯井号。 | 否 |
status | Integer | 电梯状态。
|
否 |
direction | Integer | 电梯运行方向。
|
否 |
curFloor | Integer | 当前楼层,为物理楼层。 | 否 |
{
"dataId": "AAXRV4BrtW9BRB9A2JYW****",
"devId": "6ca****",
"productKey": "e6rz6vba81wm****",
"status": [
{
"6": "{\"shaftList\":[{\"lifeNum\":1,\"curFloor\":1,\"direction\":0,\"status\":1},{\"lifeNum\":2,\"curFloor\":1,\"direction\":0,\"status\":1}]}",
"code": "function_data",
"t": 1637548630455,
"value": "{\"shaftList\":[{\"lifeNum\":1,\"curFloor\":1,\"direction\":0,\"status\":1},{\"lifeNum\":2,\"curFloor\":1,\"direction\":0,\"status\":1}]}"
}
]
}
目前二维码分为静态二维码和动态二维码。
二维码内容格式:
{
"qrcode": "7kCzIejJVhfwYOGGJLr1iUUPRXP69AiNMGcMhowRSVA=" //value:Base64编码后字符串
}
静态二维码生成步骤如下:
示例:
用户 ID: ay16110581781387****
用户二维码内容: 46bff10b9bf843fab194cf246bfedda8
对"ay16110581781387****|46bff10b9bf843fab194cf246bfedda8"进行base64编码,
生成的字符串:
YXkxNjExMDU4MTc4MTM4N240Mjd8NDZiZmYxMGI5YmY4NDNmYWIxOTRjZjI0NmJmZWRkYTg=
二维码的内容:
{
"qrcode": "YXkxNjExMDU4MTc4MTM4N240Mjd8NDZiZmYxMGI5YmY4NDNmYWIxOTRjZjI0NmJmZWRkYTg="
}
动态二维码生成步骤如下:
generateTOTP
方法生成二维码信息。generateTOTP
方法参考代码:
/**
* 生成动态码
*
* @param uid 涂鸦用户 ID
* @param secretKey 秘钥,32 位字符串,建议由 UUID 生成
* @param refreshTime 二维码刷新时间
* @return
*/
public static TOTPTokenCodeDTO generateTOTP(String uid, String secretKey, Long refreshTime) {
if (StringUtils.isBlank(uid) || StringUtils.isBlank(secretKey) || refreshTime == null) {
log.error("请求参数有误, uid:{}, secretKey:{}, refreshTime:{}", uid, secretKey, refreshTime);
throw new RuntimeException("请求参数有误");
}
// 获取当前时间的时间戳
long now = new Date().getTime();
// 将动态因子转为16进制
String time = Long.toHexString(timeFactor(now, refreshTime)).toUpperCase();
String totp = doGenerateTOTP(uid + secretKey, time);
//本周期动态码已生成时长
long usedTime = validTime(now, refreshTime);
return new TOTPTokenCodeDTO(totp, usedTime);
}
/**
* @param key 用户 ID+种子密钥
* @param time 时间因子
* @return
*/
private static String doGenerateTOTP(String key, String time) {
// 1、如果 time 小于 16 个字符,则用零补齐,例如:30B649C -> 00000000030B649C
StringBuilder timeBuilder = new StringBuilder(time);
while (timeBuilder.length() < 16) {
timeBuilder.insert(0, "0");
}
time = timeBuilder.toString();
// 2、16 进制转 2 进制
byte[] msg = hexStr2Bytes(time);
// 3、将 key 转为字节
byte[] k = key.getBytes();
// 4、哈希加密
byte[] hash = hmac_sha("HmacSHA256", k, msg);
// 5、返回指定位数的动态口令
String encodeHexStr = Hex.encodeHexString(hash);
StringBuilder result = new StringBuilder(encodeHexStr);
//6. 如果返回值小于指定的位数,则用 0 补齐
while (result.length() < 8) {
result.insert(0, "0");
}
return result.substring(0, 8);
}
/**
* 获取动态因子
*
* @param targetTime 指定时间
* @param refreshTime 时间步长,单位:毫秒。用作动态口令变化的时间周期
* @return long
*/
private static long timeFactor(Long targetTime, long refreshTime) {
return targetTime / refreshTime;
}
/**
* 获取本周期动态码已生成时长
*
* @param targetTime
* @param refreshTime
* @return
*/
private static long validTime(long targetTime, long refreshTime) {
return targetTime % refreshTime;
}
/**
* 哈希加密
*
* @param crypto 加密算法
* @param keyBytes 密钥数组
* @param text 加密内容
* @return byte[]
*/
private static byte[] hmac_sha(String crypto, byte[] keyBytes, byte[] text) {
try {
Mac hmac;
hmac = Mac.getInstance(crypto);
SecretKeySpec macKey = new SecretKeySpec(keyBytes, "AES");
hmac.init(macKey);
return hmac.doFinal(text);
} catch (GeneralSecurityException gse) {
throw new RuntimeException(gse);
}
}
private static byte[] hexStr2Bytes(String hex) {
byte[] sourceArray = new BigInteger("10" + hex, 16).toByteArray();
byte[] targetArray = new byte[sourceArray.length - 1];
// 将原数组 copy 到目标数组
// src:表示源数组,srcPos:源数组要复制的起始位置,dest:表示目标数组,destPos:目标数组要复制的起始位置,length:表示要复制的长度
System.arraycopy(sourceArray, 1, targetArray, 0, targetArray.length);
return targetArray;
}
示例:
用户 ID:ay16110581781387****
密钥:46bff10b9bf843fab194cf246bfedda8
二维码刷新时间:5 * 60 * 1000
generateTOTP方法生成二维码信息:e4af23e6
对"ay16110581781387****|e4af23e6"进行base64编码,
生成的字符串:
7kCzIejJVhfwYOGGJLr1iUUPRXP69AiNMGcMhowRSVA=
二维码的内容:
{
"qrcode": "7kCzIejJVhfwYOGGJLr1iUUPRXP69AiNMGcMhowRSVA="
}
设备事件消息兼容 1.0 版本格式。如需开通 1.0 版本格式,请联系涂鸦工作人员。接入流程参考 行业三方设备事件 1.0 版本格式。
用户触发梯控通行,梯控会上报用户的通行事件给开发者。
参数名 | 类型 | 说明 | 必填 |
---|---|---|---|
bizCode | String | 事件业务 code,默认 edge_device 。 |
是 |
eventType | String | 事件类型,默认 edge_report_data 。 |
是 |
mode | String | 事件模式,默认 elevator-pass 。 |
是 |
deviceId | String | 涂鸦设备 ID。 | 是 |
uid | String | 通行人员 ID。如果是陌生人,默认传 -1 。 |
是 |
way | Integer | 通行方式。
|
是 |
t | Long | 通行时间,13 位时间戳。 | 是 |
success | Integer | 是否成功。
|
是 |
message | String | 通行事件描述。如果通行失败,则返回失败原因。 | 否 |
passUrl | String | 通行照片 URL。人员通行时,设备抓拍的人员照片。通行照片的 URL 是临时 URL,开发者需要根据 URL 下载照片并存储。 | 否 |
temp | String | 体温。 | 否 |
startFloor | Integer | 开始楼层。 | 否 |
endFloor | Integer | 结束楼层。 | 否 |
lifeNum | Integer | 电梯井号。 | 否 |
extend | String | 扩展字段。 | 否 |
{
"data": "{\"mode\":\"elevator-pass\",\"data\":\"{\\\"deviceId\\\":\\\"002dj00118fe34d9****\\\",\\\"t\\\":1612514362591,\\\"message\\\":\\\"success\\\",\\\"passUrl\\\":\\\"http://www.xxx.com/image.jpg\\\",\\\"uid\\\":\\\"ay16110581781387n***\\\",\\\"way\\\":4}\",\\\"success\\\":1}\"}",
"bizCode": "edge_device",
"eventType": "edge_report_data"
}
该内容对您有帮助吗?
是意见反馈该内容对您有帮助吗?
是意见反馈