远程开门

更新时间:2023-06-15 05:14:58

获取门锁支持的远程开门方式

支持的门锁类型

  • Zigbee 门锁
  • 蓝牙门锁

接口地址

GET /v1.0/devices/{device_id}/door-lock/remote-unlocks

请求参数

参数名 类型 参数类型 说明 必填
device_id String URI 设备 ID

请求示例

GET /v1.0/devices/vdevo153459260090544/door-lock/remote-unlocks

返回参数

参数名 类型 说明
code Integer 错误响应码,成功时为空(详情⻅见错误码)
success Boolean 是否成功:(true:成功,false:失败)
t Long 响应时间
msg String 请求失败的信息,成功为空
result Object 开门指令信息

result

参数名 类型 说明
remote_unlock_type String 开门方式(remoteUnlockWithoutPwd: 免密开门, remoteUnlockWithPwd: 含密开门)
open Boolean 功能是否开启

请求成功返回示例

{
    "result": {
        "remote_unlock_type": "remoteUnlockWithPwd",
        "open": true
    },
    "success": true,
    "t": 1592899848757
}

请求失败返回示例

{
    "success": false,
    "code": 500, // 错误码,详细请见错误码文档
    "msg": "system error,please contact the admin"
}

设置门锁远程开门方式的开关

支持的门锁类型

  • Wi-Fi 门锁
  • Zigbee 门锁
  • 蓝牙门锁

接口地址

POST /v1.0/devices/{device_id}/door-lock/remote-unlock/config

请求参数

参数名 类型 参数类型 说明 必填
device_id String URI 设备 ID
remote_unlock_type String BODY 开门方式(remoteUnlockWithoutPwd: 免密开门, remoteUnlockWithPwd: 含密开门)
open Boolean BODY 功能是否开启

请求示例

POST /v1.0/devices/vdevo153459260090544/door-lock/remote-unlock/config
{
    "remote_unlock_type": "remoteUnlockWithPwd",
    "open": true
}

返回参数

参数名 类型 说明
code Integer 错误响应码,成功时为空(详情⻅见错误码)
success Boolean 是否成功:(true:成功,false:失败)
t Long 响应时间
msg String 请求失败的信息,成功为空
result Boolean 是否成功

请求成功返回示例

{
    "result": true,
    "success": true,
    "t": 1592899848757
}

请求失败返回示例

{
    "success": false,
    "code": 500, // 错误码,详细请见错误码文档
    "msg": "system error,please contact the admin"
}

门锁含密开门

支持的门锁类型

  • Zigbee 门锁

接口地址

POST /v1.0/devices/{device_id}/door-lock/open-door

请求参数

参数名 类型 参数类型 说明 必填
device_id String URI 设备 ID
password String Body 密码原文长度为 6,密码传输加密算法使用 AES,模式:ECB pkcs7padding, 数据块 128为 位,秘钥为通过接口获取的临时 ticket_key 使用开发者accessKey AES解密后的原始秘钥
password_type String BODY 密码加密类型:ticket
ticket_id String BODY 临时秘钥ID

请求示例

POST /v1.0/devices/6c362ac3c53fbd6f3ewqfa/door-lock/open-door

返回信息

参数名 类型 说明
code Integer 响应码(详情见错误码章节)
success Boolean 是否成功:(true:成功,false:失败)
msg String 请求失败的信息,成功为空
result Boolean 返回结果

返回示例

{
    "success": true,
    "t": 1542626129429,
    "result": true
}

门锁免密开门

支持的门锁类型

  • 公版 Wi-Fi 门锁
  • 公版 Zigbee 门锁
  • 酒店 Zigbee 门锁
  • 蓝牙门锁
  • 常保活 Wi-Fi 门锁
  • 可视对讲 Wi-Fi

接口地址

POST /v1.0/devices/{device_id}/door-lock/password-free/open-door

请求参数

参数名 类型 参数类型 说明 必填
device_id String URI 设备 ID
ticket_id String Body 临时秘钥ID

请求示例

POST /v1.0/devices/vdevo153459260090544/door-lock/password-free/open-door
{
    "ticket_id":"xxxxx"
}

返回参数

参数名 类型 说明
code Integer 错误响应码,成功时为空(详情⻅见错误码)
success Boolean 是否成功:(true:成功,false:失败)
t Long 响应时间
msg String 请求失败的信息,成功为空
result Boolean 请求结果

请求成功返回示例

{
    "result": true,
    "success": true,
    "t": 1592899848757
}

请求失败返回示例

{
    "success": false,
    "code": 500, // 错误码,详细请见错误码文档
    "msg": "system error,please contact the admin"
}

门锁免密开门(v1.1)

该接口支持对特定通道执行开门动作。

支持的门锁类型

  • Wi-Fi 门禁

接口地址

POST /v1.1/devices/{device_id}/door-lock/password-free/open-door

请求参数

参数名 类型 参数类型 说明 必填
device_id String URI 设备 ID
ticket_id String Body 临时秘钥 ID。该值通过接口 POST:/v1.0/devices/{device_id}/door-lock/password-ticket 获取
channel_id Integer Body 通道 ID

请求示例

POST /v1.1/devices/vdevo15345926009****/door-lock/password-free/open-door
{
    "ticket_id":"WHmutLIq",
    "channel_id":1
}

返回参数

参数名 类型 说明
code Integer 错误响应码,成功时为空(详情⻅见错误码)
success Boolean 是否成功(true:成功,false:失败)
t Long 响应时间
msg String 请求失败的信息,成功为空
result Boolean 请求结果

请求成功返回示例

{
    "result": true,
    "success": true,
    "t": 1592899848757
}

请求失败返回示例

{
    "success": false,
    "code": 500, // 错误码,详细请见错误码文档
    "msg": "system error,please contact the admin"
}

门锁免密开门撤销

支持的门锁类型

类型 支持
门锁类型 Wi-Fi 门锁

接口地址

PUT /v1.0/devices/{device_id}/door-lock/password-free/open-door/cancel

请求参数

参数名 类型 参数类型 说明 必填
device_id String URI 设备 ID
type Integer BODY 撤销远程开门的原因 1. 拒绝 2.取消

请求示例

PUT /v1.0/devices/vdevo153459260090544/door-lock/password-free/open-door/cancel
{
    "type":1
}

返回参数

参数名 类型 说明
code Integer 错误响应码,成功时为空(详情⻅见错误码)
success Boolean 是否成功:(true:成功,false:失败)
t Long 响应时间
msg String 请求失败的信息,成功为空
result Boolean 是否成功

请求成功返回示例

{
    "result": true,
    "success": true,
    "t": 1592899848757
}

请求失败返回示例

{
    "success": false,
    "code": 500, // 错误码,详细请见错误码文档
    "msg": "system error,please contact the admin"
}

门锁免密开关门

支持的门锁类型

  • 公版 Wi-Fi 门锁
  • 公版 Zigbee 门锁
  • 酒店 Zigbee 门锁
  • 蓝牙门锁
  • 常保活 Wi-Fi 门锁
  • 可视对讲 Wi-Fi

注意:远程开门必须有remote_no_dp_key 或者 remote_no_dp_setkey 这两个DP,且只有公版wifi门锁支持远程关门。

接口地址

POST /v1.0/smart-lock/devices/{device_id}/password-free/door-operate

请求参数

参数名 类型 参数类型 说明 必填
device_id String URI 设备 ID
ticket_id String Body 临时秘钥ID
open Boolean Body 操作(默认开门)
  • true:开门
  • false:关门

请求示例

POST /v1.0/smart-lock/devices/vdevo153459260090544/password-free/door-operate
{
    "ticket_id":"xxxxx",
    "open":false
}

返回参数

参数名 类型 说明
code Integer 错误响应码,成功时为空(详情⻅见错误码)
success Boolean 是否成功:(true:成功,false:失败)
t Long 响应时间
msg String 请求失败的信息,成功为空
result Boolean 请求结果

请求成功返回示例

{
    "result": true,
    "success": true,
    "t": 1592899848757
}

请求失败返回示例

{
    "success": false,
    "code": 500, // 错误码,详细请见错误码文档
    "msg": "system error,please contact the admin"
}

获取密码加密的临时秘钥(门锁免密开关门接口调用)

支持的门锁类型

  • Wi-Fi 门锁
  • Zigbee 门锁
  • 蓝牙门锁
  • 酒店 Zigbee 门锁
  • 可视对讲 Wi-Fi

接口地址

POST /v1.0/smart-lock/devices/{device_id}/password-ticket

请求参数

参数名 类型 参数类型 说明 是否必填
device_id String URI 设备 ID

请求示例

POST /v1.0/smart-lock/devices/vdevo15345926009****/password-ticket

返回参数

参数名 类型 说明
code Integer 返回的错误码,成功时为空,详情⻅返回的错误码
success Boolean 是否成功
true:成功
false:失败
t Long 响应时间
msg String 请求失败的信息,成功为空
result Object 临时密码信息

result

参数名 类型 说明
ticket_id String 临时秘钥 ID
ticket_key String 临时秘钥 Key,需要根据云开发者 accessKey 通过 AES 解密后方可使用
expire_time Long 剩余有效时间

请求成功返回示例

{
    "result": {
        "expire_time": 360,
        "ticket_id": "9wxxoLM",
        "ticket_key": "901CC35A67DA3429C38E9622xxxxx3EAE1CE333462356D257FD1D3E5C"
    },
    "success": true,
    "t": 1592899848757
}

请求失败返回示例

{
    "success": false,
    "code": 500, // 错误码,详细请见错误码文档
    "msg": "system error,please contact the admin"
}

远程开门带抓拍图片

  • 远程开门带抓拍图片流程:
    远程开门

  • 远程开门带抓拍图片-实时场景

    • 用户触发拍照锁开门操作,门锁抓拍图片并上报云服务
    • 云服务存储影像数据,并推送相对存储位置信息到用户端
    • 用户端调用云服务,获得影像存储全路径
    • 用户端获得加密影像数据并解密
    • 用户根据得到影像信息,判断是开门\撤销,并调用相应接口
    • 云服务下发到拍照锁,执行开门\撤销操作
  • 远程开门带抓拍图片-非实时场景

    • 用户端调用云服务查询最近一次90s内的开门\预警影像信息
    • 用户端获得加密影像数据并解密
    • 用户根据得到影像信息,判断是开门\撤销,并调用相应接口
    • 云服务下发到拍照锁,执行开门\撤销操作

影像信息通过AES/CBC/PKCS5Padding加密,规则如下所示:

4 16 44 视频内容
占位 iv 占位 视频内容

解密demo如下所示:

package xxxxxxx;
 
import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.security.InvalidAlgorithmParameterException;
import java.security.InvalidKeyException;
import java.security.NoSuchAlgorithmException;
import java.security.SecureRandom;
import java.util.Random;
 
import javax.crypto.Cipher;
import javax.crypto.CipherInputStream;
import javax.crypto.CipherOutputStream;
import javax.crypto.NoSuchPaddingException;
import javax.crypto.spec.IvParameterSpec;
import javax.crypto.spec.SecretKeySpec;
 
public class EncryptUtils {
 
    private static final String DEFAULT_ALGORITHM = "AES";
    private static final String DEFAULT_FULL_ALGORITHM = "AES/CBC/PKCS5Padding";
 
    //加密
    public static File encryptFile(String key, File originFile, String destPath) {
        FileInputStream in = null;
        FileOutputStream out = null;
        File destFile = null;
        try {
            destFile = new File(destPath);
            if (originFile.exists() && originFile.isFile()) {
                if (!destFile.getParentFile().exists()) {
                    destFile.getParentFile().mkdirs();
                }
                destFile.createNewFile();
                in = new FileInputStream(originFile);
                out = new FileOutputStream(destFile, true);
                byte[] iv = getIv();
                Cipher cipher = initAESCipher(iv, key, Cipher.ENCRYPT_MODE);
                CipherInputStream cipherInputStream = new CipherInputStream(in, cipher);
                byte[] cache = new byte[1024];
                int nRead;
                out.write(new byte[4]);
                out.write(iv);
                out.write(new byte[4]);
                out.write(new byte[40]);
                out.flush();
                while ((nRead = cipherInputStream.read(cache)) != -1) {
                    out.write(cache, 0, nRead);
                    out.flush();
                }
                cipherInputStream.close();
            }
        } catch (Exception e) {
            e.printStackTrace();
        } finally {
            try {
                if (out != null) {
                    out.close();
                }
                if (in != null) {
                    in.close();
                }
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
        return destFile;
    }
 
    //解密
    public static File decryptFile(String key, InputStream in, File destFile) {
        FileOutputStream out = null;
        try {
            if (!destFile.getParentFile().exists()) {
                destFile.getParentFile().mkdirs();
            }
            destFile.createNewFile();
            out = new FileOutputStream(destFile);
 
            byte[] iv = new byte[16];
            in.skip(4);
            int read = in.read(iv);
            if (read != 16) {
                throw new IOException("iv length error");
            }
            in.skip(44);
            Cipher cipher = initAESCipher(iv, key, Cipher.DECRYPT_MODE);
            CipherOutputStream cipherOutputStream = new CipherOutputStream(out, cipher);
            byte[] buffer = new byte[1024];
            int r;
            while ((r = in.read(buffer)) >= 0) {
                cipherOutputStream.write(buffer, 0, r);
            }
            cipherOutputStream.close();
        } catch (Exception e) {
            e.printStackTrace();
        } finally {
            try {
                if (in != null) {
                    in.close();
                }
            } catch (IOException e) {
                e.printStackTrace();
            }
            try {
                if (out != null) {
                    out.close();
                }
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
        return destFile;
    }
 
    private static Cipher initAESCipher(byte[] iv, String sKey, int cipherMode) {
        try {
            IvParameterSpec zeroIv = new IvParameterSpec(iv);
            SecretKeySpec key = new SecretKeySpec(sKey.getBytes(), DEFAULT_ALGORITHM);
            Cipher cipher = Cipher.getInstance(DEFAULT_FULL_ALGORITHM);
            cipher.init(cipherMode, key, zeroIv);
            return cipher;
        } catch (NoSuchAlgorithmException e) {
            e.printStackTrace();
        } catch (NoSuchPaddingException e) {
            e.printStackTrace();
        } catch (InvalidKeyException e) {
            e.printStackTrace();
        } catch (InvalidAlgorithmParameterException e) {
            e.printStackTrace();
        }
        return null;
    }
 
    public static byte[] getIv() {
        StringBuilder uid = new StringBuilder();
        //产生16位的强随机数
        Random rd = new SecureRandom();
        for (int i = 0; i < 16; i++) {
            //产生0-2的3位随机数
            int type = rd.nextInt(3);
            switch (type) {
                case 0:
                    //0-9的随机数
                    uid.append(rd.nextInt(10));
                    break;
                case 1:
                    //ASCII在65-90之间为大写,获取大写随机
                    uid.append((char) (rd.nextInt(25) + 65));
                    break;
                case 2:
                    //ASCII在97-122之间为小写,获取小写随机
                    uid.append((char) (rd.nextInt(25) + 97));
                    break;
                default:
                    break;
            }
        }
        return uid.toString().getBytes();
    }
 
}

获取最近一次的远程开门或告警封面图

支持的门锁类型

  • Wi-Fi 门锁
  • 酒店 Zigbee 门锁
  • 蓝牙门锁

接口地址

GET /v1.0/devices/{device_id}/door-lock/latest/media/url

请求参数

参数名 类型 参数类型 说明 是否必填
device_id String URI 设备 ID
file_type Integer URL 文件类型 1. 远程开门, 2. 告警

请求示例

GET /v1.0/devices/6cdb36b2e489885fa57lzm/door-lock/latest/media/url?file_type=1

返回参数

参数名 类型 说明
code Integer 返回的错误码,成功时为空,详情⻅返回的错误码
success Boolean 是否成功
true:成功
false:失败
t Long 响应时间
msg String 请求失败的信息,成功为空
result Object 返回结果

result

参数名 类型 说明
file_url String 封面图完整路径
file_key String 文件解密密钥
bucket String 封面图完整路径
file_path String 文件的相对路径

请求成功返回示例

{
    "result": {
        "bucket": "ty-cn-storage60-1254153901",
        "file_key": "u8kstrtjm7qun83q",
        "file_path": "/3039e1-30532026.jpg",
        "file_url": "https://ty-cn-storage60-1254153901.cos.tuyacn.com6"
    },
    "success": true,
    "t": 1614147303662
}

请求失败返回示例

{
    "success": false,
    "code": 500, // 错误码,详细请见错误码文档
    "msg": "system error, please contact the admin"
}