import sm4 from "./sm4";
import md5 from "./md5.min";
import crc from "./crc-index";

var userIdSaved;
var authUserIdSaved;
var deviceNameSaved;
var pwdSaved;
var indexSaved;
var fingerNoSaved;
var startTimeSaved;
var endTimeSaved;
var useCountLimitSaved;
var staticCallback;
var keyIdSaved;
var signKeySaved;
var roleSaved;
var pwdNoSaved;
var actionSaved;
var alarmFingerSaved;
var encKeySaved;
var openModeSaved;
var blueKeyIdSaved;
const constString = "uiYMMSwerw122@^#&@87";
var receDataSaved = "";
var fileVersionSaved;
var fileSizeSaved;
var fileCRCSaved;
var tokenSaved;
var packageSize;
var blueKey;

export default class ICINLocker {
    constructor(obj) {
        this.callback = obj;
    }

    static checkTheWechatVersion() {
        if (wx.openBluetoothAdapter) {
            wx.openBluetoothAdapter();
            return true;
        } else {
            return false;
        }
    }

    static disConnect(lockId) {
        // let connectedDeviceId = wx.getStorageSync('connectedDeviceId')
        wx.closeBLEConnection({
            deviceId: lockId,
            success: function (res) {
                console.log("断开连接成功");
            },
        });
    }

    static showLoading(msg) {
        wx.showLoading({
            title: msg,
        });
    }

    static getLocationPermission() {
        return new Promise(function (resolve, reject) {
            wx.getLocation({
                type: "wgs84",
                success(res) {
                    resolve({
                        status: 0,
                        statusReason: "获取地理位置成功",
                    });
                    console.log(res);
                },
                fail(res) {
                    reject({
                        status: 1,
                        statusReason: res.errMsg,
                    });
                    return;
                },
            });
        });
    }

    /**
     * 扫描周围蓝牙设备中的名称为deviceName的设备
     * @param {*} deviceName 
     */
    static scanDevices(deviceName) {
        return new Promise(function (resolve, reject) {
            wx.openBluetoothAdapter({
                success: function (res) {
                    let deviceId;
                    let isLockerExist = false;
                    /****** 超时计时器 */
                    let timeoutInterval;
                    /****** 搜寻列表计时器 */
                    let intervalForScanedList;
                    /****** 记录扫描的具体位置 */
                    let devicesScanedPos = 0
                    console.log("初始化蓝牙适配器成功");

                    // 设置计时器 10s直接超时
                    timeoutInterval = setInterval(function () {
                        wx.closeBluetoothAdapter({
                            success: (res) => {
                                clearInterval(timeoutInterval);
                                clearInterval(intervalForScanedList);
                                reject({
                                    status: 1,
                                    statusReason: "超时搜索蓝牙设备,请靠近设备后再试",
                                })
                                return;
                            },
                        })
                    }, 10000)

                    // 如上一次与这一次的蓝牙连接目标相同,不用继续搜寻直接返回之前的connectedDeviceId
                    let imei = wx.getStorageSync("deviceName");
                    let connectedDeviceId = wx.getStorageSync("connectedDeviceId");
                    if (imei == deviceName) {
                        if (connectedDeviceId) {
                            ICINLocker.disConnect(connectedDeviceId);
                            clearInterval(timeoutInterval);
                            resolve({
                                status: 0,
                                deviceId: connectedDeviceId,
                            });
                            return;
                        }
                    }

                    // 本机蓝牙适配器状态
                    wx.getBluetoothAdapterState({
                        success: function (res) {
                            // console.log("搜索状态" + res.discovering);
                            // console.log("可用状态" + res.available);
                        },
                    });


                    //开始搜索设备 start----
                    wx.startBluetoothDevicesDiscovery({
                        allowDuplicatesKey: false,
                        success: function (res) {
                            // 设置定时器 0.5s一次查看所有搜索出来的设备
                            intervalForScanedList = setInterval(function () {
                                wx.getBluetoothDevices({
                                    success: function (res) {
                                        // 搜不到设备直接返回
                                        if (res.devices.length == 0) {
                                            console.log("未搜索到蓝牙设备,请稍后再试");
                                            clearInterval(timeoutInterval);
                                            clearInterval(intervalForScanedList);
                                            reject({
                                                status: 1,
                                                statusReason: "未搜索到蓝牙设备,请靠近设备后再试",
                                            });
                                            return;
                                        }
                                        /***** 单个发现新设备,如有设备直接返回 */
                                        wx.onBluetoothDeviceFound(function (res) {
                                             console.log(res.devices[0])
                                            var ondeviceNameOfitem = res.devices[0].name;
                                            
                                            if (ondeviceNameOfitem && ondeviceNameOfitem === deviceName) {
                                                deviceId = res.devices[0].deviceId;
                                                wx.setStorage({
                                                    data: res.devices[0].deviceId,
                                                    key: "connectedDeviceId",
                                                });
                                                wx.setStorageSync("deviceName", deviceName);
                                                isLockerExist = true;
                                                clearInterval(timeoutInterval);
                                                clearInterval(intervalForScanedList);
                                                resolve({
                                                    status: 0,
                                                    deviceId: deviceId,
                                                });
                                                return;
                                            }
                                        });

                                        /***** 在搜索到的设备列表中查询需要连接的设备 */
                                        for (; devicesScanedPos <= res.devices.length; devicesScanedPos++) {
                                            let deviceNameOfitem = res.devices[devicesScanedPos].name;
                                            if (deviceNameOfitem === deviceName) {
                                                deviceId = res.devices[devicesScanedPos].deviceId;
                                                wx.setStorage({
                                                    data: res.devices[devicesScanedPos].deviceId,
                                                    key: "connectedDeviceId",
                                                });
                                                wx.setStorageSync("deviceName", deviceName);
                                                isLockerExist = true;
                                                clearInterval(timeoutInterval);
                                                clearInterval(intervalForScanedList);
                                                resolve({
                                                    status: 0,
                                                    deviceId: deviceId,
                                                });
                                                return;
                                            }
                                        }
                                    },
                                });
                            }, 500)
                        },
                    });
                },
                fail: function (res) {
                    console.log("调用失败,请打开蓝牙");
                    clearInterval(timeoutInterval);
                    reject({
                        status: 1,
                        statusReason: res,
                    });
                    return;
                },
            });
        });
    }

    /**
     * 连接设备
     * @param {设备ID, 从scanDevice方法的回调获取} deviceId 
     * @param {*} isBlue 
     */
    static connect(deviceId, isBlue) {
        return new Promise(function (resolve, reject) {
            var primaryServiceId = "";
            var connectedDeviceId = deviceId;
            wx.setStorage({
                data: connectedDeviceId,
                key: "connectedDeviceId",
            });
            wx.createBLEConnection({
                deviceId: deviceId,
                success: function (res) {
                    ICINLocker.stopBluetoothDevicesDiscovery();
                    wx.getBLEDeviceServices({
                        deviceId: connectedDeviceId,
                        success: function (res) {
                            for (let i = 0; i < res.services.length; i++) {
                                let primaryUUid = res.services[i].uuid.substring(0, 8);
                                let uuid;
                                if (isBlue) {
                                    //蓝牙扣的
                                    uuid = "F000C0E0";
                                    packageSize = 40
                                    blueKey = true
                                } else {
                                    //锁的
                                    uuid = "0000FFF0";
                                    packageSize = 360
                                }
                                if (res.services[i].isPrimary && primaryUUid === uuid) {
                                    primaryServiceId = res.services[i].uuid;
                                }
                            }
                            wx.getBLEDeviceCharacteristics({
                                deviceId: connectedDeviceId,
                                serviceId: primaryServiceId,
                                success: function (res) {
                                    for (var i = 0; i < res.characteristics.length; i++) {
                                        if (res.characteristics[i].properties.notify) {
                                            console.log(
                                                "获取开启notify的ServicweId:",
                                                primaryServiceId
                                            );
                                            console.log(
                                                "获取开启notify的CharacteristicsId:",
                                                res.characteristics[i].uuid
                                            );
                                            try {
                                                wx.setStorageSync("notifyServicweId", primaryServiceId);
                                                wx.setStorageSync(
                                                    "notifyCharacteristicsId",
                                                    res.characteristics[i].uuid
                                                );
                                            } catch (e) {
                                                console.log("notifyCharacteristicsId get wrong");
                                            }
                                        }
                                        if (res.characteristics[i].properties.write) {
                                            console.log(
                                                "获取开启write的ServicweId:",
                                                primaryServiceId
                                            );
                                            console.log(
                                                "获取开启write的CharacteristicsId:",
                                                res.characteristics[i].uuid
                                            );
                                            try {
                                                wx.setStorageSync("writeServicweId", primaryServiceId);
                                                if (isBlue) {
                                                    wx.setStorageSync(
                                                        "writeCharacteristicsId",
                                                        res.characteristics[i].uuid
                                                    );
                                                } else {
                                                    wx.setStorageSync(
                                                        "writeCharacteristicsId",
                                                        res.characteristics[1].uuid
                                                    );
                                                }
                                            } catch (e) {
                                                console.log("writeCharacteristicsId get wrong");
                                            }
                                        }
                                        if (res.characteristics[i].properties.read) {
                                            console.log("读取函数ServiceId:", primaryServiceId);
                                            console.log(
                                                "读取函数CharacteristicsId:",
                                                res.characteristics[i].uuid
                                            );
                                            try {
                                                wx.setStorageSync("readServicweId", primaryServiceId);
                                                wx.setStorageSync(
                                                    "readCharacteristicsId",
                                                    res.characteristics[i].uuid
                                                );
                                            } catch (e) {
                                                console.log("readCharacteristicsId get wrong");
                                            }
                                        }
                                    }
                                    console.log(
                                        "device getBLEDeviceCharacteristics:",
                                        res.characteristics
                                    );

                                    var notifyServicweId = wx
                                        .getStorageSync("notifyServicweId")
                                        .toUpperCase();
                                    var notifyCharacteristicsId = wx
                                        .getStorageSync("notifyCharacteristicsId")
                                        .toUpperCase();
                                    console.log("启用notify的serviceId", notifyServicweId);
                                    console.log(
                                        "启用notify的notifyCharacteristicsId",
                                        notifyCharacteristicsId
                                    );
                                    wx.notifyBLECharacteristicValueChange({
                                        state: true,
                                        type: "notification",
                                        deviceId: connectedDeviceId,
                                        serviceId: primaryServiceId,
                                        characteristicId: notifyCharacteristicsId,
                                        success: function (res) {
                                            console.log(
                                                "启用通知notifyBLECharacteristicValueChange success",
                                                res.errMsg
                                            );
                                            setTimeout(function () {
                                                ICINLocker.onBLECharacteristicValueChange();
                                            }, 1000);
                                            resolve({
                                                status: 0,
                                                mac: connectedDeviceId,
                                                uuid: primaryServiceId,
                                                statusReason: "成功连接",
                                            });
                                        },
                                        fail: function (res) {
                                            console.log("未能打开监听");
                                            console.log("notifyServicweId" + notifyServicweId);
                                            console.log(
                                                "notifyCharacteristicsId" + notifyCharacteristicsId
                                            );
                                            reject({
                                                status: 1,
                                                statusReason: "未能打开监听",
                                            });
                                            ICINLocker.disConnect(connectedDeviceId);
                                        },
                                    });
                                },
                                fail: function (res) {
                                    reject({
                                        status: 1,
                                        statusReason: res.errMsg,
                                    });
                                    //ICINLocker.disConnect(connectedDeviceId)
                                },
                                complete: function () {
                                    console.log("complete");
                                },
                            });
                        },
                    });
                },
                fail: function (res) {
                    if(res.errno === 1509007){ //设备已连接
                        return
                    }
                    if(res.errCode === 10012){ //超时
                        ICINLocker.connect(connectedDeviceId)
                        return 
                    }
                    reject({
                        status: 1,
                        statusReason: res.errMsg,
                    });
                },
                complete: function () {
                    console.log("调用结束");
                },
            });
            console.log(connectedDeviceId);
        });
    }

    static onBLECharacteristicValueChange() {
        wx.onBLECharacteristicValueChange(function (res) {
           

            // 获取多包
            let tempData = "" + ab2hex(res.value);
            receDataSaved += tempData;
            let dataLength = (parseInt(receDataSaved.substring(16, 20), 16) + 14) * 2;
            if (receDataSaved.length < dataLength) {
                return;
            }

            let receData = "";
            let resultData = receDataSaved;
            let ciper = resultData.substring(15, 16);
        
            if (ciper == "3" || ciper == "2") {
                let encData = resultData.substring(24, resultData.length - 4);
                let decData = byte2HexStr(
                    sm4.sm4_dec(
                        hexStr2Byte(encData),
                        encData.length / 2,
                        hexStr2Byte(encKeySaved)
                    )
                );
                receData =
                    resultData.substring(0, 24) +
                    decData +
                    resultData.substring(resultData.length - 4, resultData.length);
            } else {
                receData = resultData;
            }
       

            if (receData == "") {
                return;
            }
            wx.setStorage({
                data: receData,
                key: "receData",
            });
            let cmdId = receData.substring(24, 28);
            let cmdStatus = receData.substring(28, 30);

            let signKey = "";
            let commonKey = "";
            switch (cmdId) {
                case "300a":
                    if (cmdStatus == "00") {
                        let softWareVersion =
                            hex2int(receData.substring(30, 32)) +
                            "." +
                            hex2int(receData.substring(32, 34)) +
                            "." +
                            hex2int(receData.substring(34, 36)) +
                            "." +
                            hex2int(receData.substring(36, 38));
                        let appUserCount = parseInt(receData.substring(124, 128), 16);
                        let remainCount = parseInt(receData.substring(132, 136), 16);
                        let notUploadCount = parseInt(receData.substring(136, 140), 16);
                        let pwdCount = parseInt(receData.substring(140, 142), 16);
                        let lockStatus = receData.substring(154, 156);
                        let lockerMode = hexToString(receData.substring(184, 200));
                        let power = parseInt(receData.substring(38, 40), 16);
                        let nbStat = receData.substring(40, 42);
                        let nbSignal = parseInt(receData.substring(42, 44));
                        let nbIMEI = hexToString(receData.substring(44, 84));
                        let nvIMSI = hexToString(receData.substring(84, 124));
                        let blackListCount = parseInt(receData.substring(128, 130), 16);
                        let bleKeyCount = parseInt(receData.substring(130, 132), 16);
                        let fingerPrintsCount = parseInt(receData.substring(142, 144), 16);
                        let RFCount = parseInt(receData.substring(144, 146), 16);
                        let lockTime = timeConvert(
                            parseInt(receData.substring(146, 154), 16),
                            1
                        );
                        let lockSn = hexToString(receData.substring(200, 240));
                        let wifiSsid = hexToString(receData.substring(240, 304));
                        let serverIp = hexToString(receData.substring(304, 344));
                        let serverPort = hexToString(receData.substring(344, 356));
                        let isNbLock = parseInt(hex2int(receData.substring(30, 32)))
                            .toString(2)
                            .PadLeft(8, "0")
                            .substring(3, 4);
                        let isWifiLock = parseInt(hex2int(receData.substring(30, 32)))
                            .toString(2)
                            .PadLeft(8, "0")
                            .substring(2, 3);

                        staticCallback({
                            cmdId: cmdId,
                            status: cmdStatus,
                            softWareVersion: softWareVersion,
                            appUserCount: appUserCount,
                            remainCount: remainCount,
                            notUploadCount: notUploadCount,
                            pwdCount: pwdCount,
                            lockStatus: lockStatus,
                            lockerMode: lockerMode,
                            power: power,
                            nbStat: nbStat,
                            nbSignal: nbSignal,
                            nbIMEI: nbIMEI,
                            nvIMSI: nvIMSI,
                            blackListCount: blackListCount,
                            bleKeyCount: bleKeyCount,
                            fingerPrintsCount: fingerPrintsCount,
                            lockTime: lockTime,
                            RFCount: RFCount,
                            lockSn: lockSn,
                            wifiSsid: wifiSsid,
                            serverIp: serverIp,
                            serverPort: serverPort,
                            isNbLock: isNbLock,
                            isWifiLock: isWifiLock,
                        });
                    } else {
                        staticCallback({
                            cmdId: cmdId,
                            status: cmdStatus,
                        });
                    }
                    break;

                case "3092":
                    if (cmdStatus == "00") {
                        signKey = receData.substring(62, 94);
                        commonKey = receData.substring(30, 62);
                        try {
                            wx.setStorageSync("authUserSignKey", signKey);
                            wx.setStorageSync("commonKey", commonKey);
                            signKeySaved = signKey;
                        } catch (e) {}
                        staticCallback({
                            cmdId: cmdId,
                            status: cmdStatus,
                            signKey: signKey,
                            commonKey: commonKey,
                        });
                    } else {
                        staticCallback({
                            cmdId: cmdId,
                            status: cmdStatus,
                        });
                    }
                    break;

                case "3093":
                    if (cmdStatus == "00") {
                        commonKey = receData.substring(30, 62);
                        wx.setStorageSync("commonKey", commonKey);
                        staticCallback({
                            cmdId: cmdId,
                            status: cmdStatus,
                            commonKey: commonKey,
                        });
                    } else {
                        staticCallback({
                            cmdId: cmdId,
                            status: cmdStatus,
                        });
                    }
                    break;

                case "3094":
                    if (cmdStatus == "00") {
                        let userSignKey = receData.substring(62, 94);
                        let userCommonKey = receData.substring(30, 62);
                        wx.setStorageSync("userSignKey", userSignKey);
                        wx.setStorageSync("userCommonKey", userCommonKey);

                        staticCallback({
                            cmdId: cmdId,
                            status: cmdStatus,
                            userSignKey: userSignKey,
                            userCommonKey: userCommonKey,
                        });
                    } else {
                        staticCallback({
                            cmdId: cmdId,
                            status: cmdStatus,
                        });
                    }
                    break;

                case "3095":
                    // let nbIotResp = receData.substring(28, receData.length);
                    // staticCallback({
                    //     cmdId: cmdId,
                    //     nbIotResp: nbIotResp
                    // })
                    // break;
                    let dataLength = parseInt(receData.substring(16, 24));
                    console.log("3095截取本次的数据长度是" + dataLength);
                    let nbIotResp = receData.substring(28, 28 + dataLength);
                    staticCallback({
                        cmdId: cmdId,
                        nbIotResp: nbIotResp
                    })
                    break;

                case "3001":
                    let addUserToken = receData.substring(108, 116);
                    let status3001 = receData.substring(116, 118);
                    console.log("cmdId" + cmdId + ", status3001" + status3001);
                    if (status3001 == "06") {
                        // signKey = wx.getStorageSync('authUserSignKey');
                        if (signKeySaved) {
                            ICINLocker.addUserToLock(
                                deviceNameSaved,
                                authUserIdSaved,
                                userIdSaved,
                                keyIdSaved,
                                roleSaved,
                                signKeySaved,
                                addUserToken,
                                encKeySaved,
                                startTimeSaved,
                                endTimeSaved,
                                staticCallback
                            );
                        } else {
                            staticCallback({
                                cmdId: cmdId,
                                status: status3001,
                            });
                        }
                    } else if (status3001 == "00") {
                        console.log("添加用户成功");
                        staticCallback({
                            cmdId: cmdId,
                            status: status3001,
                        });
                    } else {
                        staticCallback({
                            cmdId: cmdId,
                            status: status3001,
                        });
                    }
                    break;

                case "3005":
                    let tokenOfOpenTheDoor = receData.substring(28, 36);
                    let status3005 = receData.substring(36, 38);
                    if (status3005 == "06") {
                        ICINLocker.openTheDoor(
                            deviceNameSaved,
                            userIdSaved,
                            signKeySaved,
                            keyIdSaved,
                            tokenOfOpenTheDoor,
                            openModeSaved,
                            encKeySaved,
                            staticCallback
                        );
                    } else if (status3005 == "00") {
                        staticCallback({
                            cmdId: cmdId,
                            status: status3005,
                        });
                    } else {
                        staticCallback({
                            cmdId: cmdId,
                            status: status3005,
                        });
                    }
                    break;

                case "3004":
                    let tokenOfResetLock = receData.substring(28, 36);
                    let status3004 = receData.substring(36, 38);
                    if (status3004 == "06") {
                        // signKey = wx.getStorageSync('authUserSignKey');
                        ICINLocker.resetLock(
                            deviceNameSaved,
                            userIdSaved,
                            tokenOfResetLock,
                            signKeySaved,
                            encKeySaved,
                            staticCallback
                        );
                    } else if (status3004 == "00") {
                        staticCallback({
                            cmdId: cmdId,
                            status: status3004,
                        });
                    } else {
                        staticCallback({
                            cmdId: cmdId,
                            status: status3004,
                        });
                    }
                    break;

                case "3002":
                    let tokenOfDelUser = receData.substring(28, 36);
                    let status3002 = receData.substring(36, 38);
                    if (status3002 == "06") {
                        wx.setStorageSync("tokenOfDelUser", tokenOfDelUser);
                        ICINLocker.deleteUser(
                            deviceNameSaved,
                            authUserIdSaved,
                            userIdSaved,
                            keyIdSaved,
                            tokenOfDelUser,
                            signKeySaved,
                            encKeySaved,
                            staticCallback
                        );
                    } else if (status3002 == "00") {
                        staticCallback({
                            cmdId: cmdId,
                            status: status3002,
                        });
                    } else {
                        staticCallback({
                            cmdId: cmdId,
                            status: status3002,
                        });
                    }
                    break;

                case "3008":
                    let status3008 = receData.substring(108, 110);
                    if (status3008 == "00") {
                        let lockRecordTotal = receData.substring(110, 114);
                        let lockRecordOpenStatus = receData.substring(114, 118);
                        let lockRecordCount = receData.substring(118, 122);
                        let lockRecordLen = receData.substring(122, 126);
                        let forLoop = receData.substring(126, receData.length);
                        console.log("循环体为-----" + forLoop);
                        let lockRecordList = [];
                        for (let i = 1; i <= parseInt(lockRecordLen, 16) * 2; i++) {
                            if (i % 54 == 0) {
                                let tempRecords = forLoop.substring(i - 54, i);
                                console.log(tempRecords);
                                /**
                                 * 0x1F防撬报警;0x2F胁迫指纹报警;0x3X试错报警(低4位代表具体开锁方式);0x4F预留(重置报警)
                                 * 开锁方式:0机械钥匙;1指纹;2密码;3app;4蓝扣;5远程;6RF卡;7人脸;8虹膜;9临时授权;21常开;22落锁;
                                 */
                                let data = {
                                    userId: hexToString(tempRecords.substring(0, 40)),
                                    openMode: tempRecords.substring(40, 42),
                                    openTime: timeConvert(
                                        parseInt(tempRecords.substring(42, 50), 16),
                                        1
                                    ),
                                    uploadFlag: tempRecords.substring(50, 52),
                                    power: parseInt(tempRecords.substring(52, 54), 16),
                                };
                                lockRecordList.push(data);
                            }
                        }
                        staticCallback({
                            cmdId: cmdId,
                            status: status3008,
                            lockRecordLen: parseInt(lockRecordLen, 16) * 2,
                            lockRecordTotal: parseInt(lockRecordTotal, 16),
                            lockRecordList: lockRecordList,
                        });
                    } else {
                        staticCallback({
                            cmdId: cmdId,
                            status: status3008,
                        });
                    }

                    break;

                case "3009":
                    let status3009 = receData.substring(28, 30);
                    staticCallback({
                        cmdId: cmdId,
                        status: status3009,
                    });
                    break;

                case "3010":
                    let status3010 = receData.substring(28, 30);
                    let blueKeyId = receData.substring(30, 70);
                    staticCallback({
                        cmdId: cmdId,
                        status: status3010,
                        blueKeyId: blueKeyId,
                    });
                    break;

                case "3011":
                    let tokenOfBlueKey = receData.substring(28, 36);
                    let status3011 = receData.substring(36, 38);
                    if (status3011 == "06") {
                        ICINLocker.registeBluetoothBuckle(
                            authUserIdSaved,
                            blueKeyIdSaved,
                            keyIdSaved,
                            pwdSaved,
                            tokenOfBlueKey,
                            signKeySaved,
                            encKeySaved,
                            staticCallback
                        );
                    } else {
                        staticCallback({
                            status: status3011,
                        });
                    }
                    break;

                case "300b":
                    let tokenOf300b = receData.substring(28, 36);
                    let status300b = receData.substring(36, 38);
                    if (status300b == "06") {
                        ICINLocker.updateFirmware(
                            deviceNameSaved,
                            authUserIdSaved,
                            fileVersionSaved,
                            fileSizeSaved,
                            fileCRCSaved,
                            tokenOf300b,
                            signKeySaved,
                            encKeySaved,
                            staticCallback
                        );
                    } else {
                        staticCallback({
                            token: tokenOf300b,
                            status: status300b,
                        });
                    }
                    break;

                case "300c":
                    let status300c = receData.substring(28, 30);
                    staticCallback({
                        status: status300c,
                    });
                    break;

                case "3012":
                    let status3012 = receData.substring(36, 38);
                    staticCallback({
                        cmdId: cmdId,
                        status: status3012,
                    });
                    break;

                case "3030":
                    let subCmdId = receData.substring(30, 32);
                    let status3030 = receData.substring(28, 30);
                    switch (subCmdId) {
                        case "01":
                            staticCallback({
                                cmdId: cmdId,
                                status: status3030,
                                subCmdId: subCmdId,
                            });
                            break;

                        case "02":
                            if (status3030 == "00") {
                                let IMEI = receData.substring(34, 74);
                                let IMSI = receData.substring(74, 114);
                                staticCallback({
                                    cmdId: cmdId,
                                    status: status3030,
                                    subCmdId: subCmdId,
                                    IMEI: IMEI,
                                    IMSI: IMSI,
                                });
                            } else {
                                staticCallback({
                                    cmdId: cmdId,
                                    status: status3030,
                                    subCmdId: subCmdId,
                                });
                            }
                            break;

                        case "03":
                            let tokenOfHandlePwd = receData.substring(34, 42);
                            if (status3030 == "06") {
                                ICINLocker.handlePwd(
                                    deviceNameSaved,
                                    authUserIdSaved,
                                    userIdSaved,
                                    pwdSaved,
                                    pwdNoSaved,
                                    keyIdSaved,
                                    signKeySaved,
                                    tokenOfHandlePwd,
                                    startTimeSaved,
                                    endTimeSaved,
                                    useCountLimitSaved,
                                    encKeySaved,
                                    staticCallback
                                );
                            } else if (status3030 == "00") {
                                staticCallback({
                                    cmdId: cmdId,
                                    status: status3030,
                                    subCmdId: subCmdId,
                                });
                            } else {
                                staticCallback({
                                    cmdId: cmdId,
                                    status: status3030,
                                    subCmdId: subCmdId,
                                });
                            }
                            break;

                        case "05":
                            let pwdCount = receData.substring(34, 36);
                            let pwdAllInfo = receData.substring(36, receData.length);
                            let pwdLength = parseInt(pwdCount, 16) * 4;
                            console.log(pwdAllInfo);
                            let pwdList = [];
                            for (let i = 1; i <= pwdLength; i++) {
                                if (i % 4 == 0) {
                                    let tempCard = pwdAllInfo.substring(i - 4, i);
                                    let data = {
                                        pwdNo: tempCard.substring(0, 2),
                                        useCountLimit: tempCard.substring(2, 4),
                                    };
                                    pwdList.push(data);
                                }
                            }
                            staticCallback({
                                cmdId: cmdId,
                                status: status3030,
                                subCmdId: subCmdId,
                                pwdList: pwdList,
                            });
                            break;

                        case "09":
                            let tokenOfFinger = receData.substring(34, 42);
                            let completeFlag = receData.substring(46, 48);
                            let fingerprintNo = receData.substring(48, 52);
                            if (status3030 == "06") {
                                ICINLocker.addFingerPrints(
                                    deviceNameSaved,
                                    authUserIdSaved,
                                    userIdSaved,
                                    keyIdSaved,
                                    tokenOfFinger,
                                    signKeySaved,
                                    startTimeSaved,
                                    endTimeSaved,
                                    alarmFingerSaved,
                                    encKeySaved,
                                    staticCallback
                                );
                            } else if (completeFlag == "01" && status3030 == "00") {
                                staticCallback({
                                    cmdId: cmdId,
                                    status: status3030,
                                    subCmdId: subCmdId,
                                    fingerprintNo: fingerprintNo,
                                    completeFlag: completeFlag,
                                });
                            } else {
                                staticCallback({
                                    cmdId: cmdId,
                                    status: status3030,
                                    subCmdId: subCmdId,
                                    completeFlag: completeFlag,
                                });
                            }
                            break;

                        case "0a":
                            let fingerprintTotalCnt = receData.substring(34, 36);
                            let currCnt = receData.substring(36, 38);
                            let fingerprintAllInfo = receData.substring(38, receData.length);
                            let fingerprintLength = parseInt(fingerprintTotalCnt, 16) * 62;

                            console.log(fingerprintAllInfo);
                            console.log("length---" + fingerprintAllInfo.length);
                            let fingerprintList = [];
                            for (let i = 1; i <= fingerprintLength; i++) {
                                if (i % 62 == 0) {
                                    let tempFingerPrints = fingerprintAllInfo.substring(
                                        i - 62,
                                        i
                                    );
                                    console.log(tempFingerPrints);
                                    let data = {
                                        fingerprintNo: tempFingerPrints.substring(0, 4),
                                        belongsTo: tempFingerPrints.substring(4, 44),
                                        isAlarmFinger: tempFingerPrints.substring(44, 46),
                                        startTime: tempFingerPrints.substring(46, 54),
                                        endTime: tempFingerPrints.substring(54, 62),
                                    };
                                    fingerprintList.push(data);
                                }
                            }
                            staticCallback({
                                status: status3030,
                                subCmdId: subCmdId,
                                fingerprintList: fingerprintList,
                                fingerprintTotalCnt: fingerprintTotalCnt,
                                currCnt: currCnt,
                            });

                            break;

                        case "10":
                            let rfCardTotalCnt = receData.substring(34, 36);
                            let rfCardAllInfo = receData.substring(36, receData.length);
                            let rfCardlength = parseInt(rfCardTotalCnt, 16) * 18;
                            console.log(rfCardAllInfo);
                            let rfCardList = [];
                            for (let i = 1; i <= rfCardlength; i++) {
                                if (i % 18 == 0) {
                                    let tempCard = rfCardAllInfo.substring(i - 18, i);
                                    let data = {
                                        cardIndex: tempCard.substring(0, 2),
                                        startTime: tempCard.substring(2, 10),
                                        endTime: tempCard.substring(10, 18),
                                    };
                                    rfCardList.push(data);
                                }
                            }
                            staticCallback({
                                status: status3030,
                                subCmdId: subCmdId,
                                rfCardList: rfCardList,
                                totalCnt: rfCardTotalCnt,
                            });
                            break;

                        case "0f":
                            let tokenOfRfCard = receData.substring(34, 42);
                            if (status3030 == "06") {
                                ICINLocker.RfCardRegister(
                                    deviceNameSaved,
                                    authUserIdSaved,
                                    userIdSaved,
                                    keyIdSaved,
                                    indexSaved,
                                    tokenOfRfCard,
                                    signKeySaved,
                                    startTimeSaved,
                                    endTimeSaved,
                                    encKeySaved,
                                    staticCallback
                                );
                            } else if (status3030 == "00") {
                                let cardNo = receData.substring(44, 84);

                                /**
                                 * 第21-22位如果为01、02、03为非安全卡,其他则是安全卡
                                 */
                                let safeCardFlag = cardNo.substring(20, 22);
                                // console.log('cardNo------------' + cardNo);
                                // console.log('safeCardFlag______' + safeCardFlag);
                                if (
                                    safeCardFlag == "01" ||
                                    safeCardFlag == "02" ||
                                    safeCardFlag == "03"
                                ) {
                                    ICINLocker.rFcardAddControl(
                                        authUserIdSaved,
                                        userIdSaved,
                                        keyIdSaved,
                                        indexSaved,
                                        signKeySaved,
                                        cardNo,
                                        "01",
                                        encKeySaved,
                                        staticCallback
                                    );
                                } else {
                                    let completeFlag = receData.substring(42, 44);
                                    staticCallback({
                                        cmdId: cmdId,
                                        status: status3030,
                                        subCmdId: subCmdId,
                                        cardNo: cardNo,
                                        completeFlag: completeFlag,
                                    });
                                }
                            } else {
                                staticCallback({
                                    cmdId: cmdId,
                                    status: status3030,
                                    subCmdId: subCmdId,
                                });
                            }
                            break;

                        case "0b":
                            let tokenOfModifyFinger = receData.substring(34, 42);
                            if (status3030 == "06") {
                                ICINLocker.modifyFingerPrints(
                                    deviceNameSaved,
                                    authUserIdSaved,
                                    userIdSaved,
                                    keyIdSaved,
                                    actionSaved,
                                    fingerNoSaved,
                                    tokenOfModifyFinger,
                                    signKeySaved,
                                    alarmFingerSaved,
                                    startTimeSaved,
                                    endTimeSaved,
                                    encKeySaved,
                                    staticCallback
                                );
                            } else if (status3030 == "00") {
                                staticCallback({
                                    cmdId: cmdId,
                                    status: status3030,
                                    subCmdId: subCmdId,
                                });
                            } else {
                                staticCallback({
                                    cmdId: cmdId,
                                    status: status3030,
                                    subCmdId: subCmdId,
                                });
                            }
                            break;

                        case "11":
                            if (status3030 == "06") {
                                let tokenOfModifyFinger = receData.substring(34, 42);
                                ICINLocker.modifyRFCard(
                                    deviceNameSaved,
                                    authUserIdSaved,
                                    userIdSaved,
                                    keyIdSaved,
                                    indexSaved,
                                    tokenOfModifyFinger,
                                    actionSaved,
                                    signKeySaved,
                                    startTimeSaved,
                                    endTimeSaved,
                                    encKeySaved,
                                    staticCallback
                                );
                            } else {
                                staticCallback({
                                    cmdId: cmdId,
                                    status: status3030,
                                    subCmdId: subCmdId,
                                });
                            }
                            break;

                        case "12":
                            if (status3030 == "00") {
                                let tokenOfRFControl = receData.substring(34, 42);
                                let completeFlag = receData.substring(42, 44);
                                let cardNo = receData.substring(44, 84);
                                staticCallback({
                                    cmdId: cmdId,
                                    status: status3030,
                                    subCmdId: subCmdId,
                                    tokenOfRFControl: tokenOfRFControl,
                                    completeFlag: completeFlag,
                                    cardNo: cardNo,
                                });
                            }
                            break;

                        case "13":
                            staticCallback({
                                cmdId: cmdId,
                                status: status3030,
                                subCmdId: subCmdId,
                            });
                            break;

                        case "15":
                            let privateKey = receData.substring(34, 66);
                            staticCallback({
                                status: status3030,
                                privateKey: privateKey,
                            });

                        case "0c":
                            staticCallback({
                                status: status3030,
                            });
                            break;

                        case "14":
                            let completeFlagOfFiveKeys = receData.substring(34, 36);
                            staticCallback({
                                status: status3030,
                                completeFlag: completeFlagOfFiveKeys,
                            });
                    }
                    break;
            }
            receDataSaved = "";
        });
    }


    static stopBluetoothDevicesDiscovery() {
        wx.stopBluetoothDevicesDiscovery({
            success: function (res) {
                console.log("停止搜索设备" + JSON.stringify(res.errMsg));
            },
        });
    }

    /**
     * *读取锁信息
     * @param {门锁ID – 最多40字节} _lockId
     * @param {用户ID – 最多20字节} usrID
     * @param {回调} callback
     */
    static readLockerInfo(_lockId, usrID, callback) {
        console.log('读取锁信息参数',_lockId, usrID)
        deviceNameSaved = _lockId;
        let head = makeHeader("300a");
        let cmdID = "300a";
        let lockerID = str2Hex(_lockId).PadRight(80, "0");
        let userID = str2Hex(usrID).PadRight(40, "0");
        let dataModular = (cmdID + lockerID + userID).replace("0x", "");
        let dataModularLength = (dataModular.length / 2)
            .toString(16)
            .PadLeft(4, "0");
        let templateResult = (
            head +
            dataModularLength +
            dataModularLength +
            dataModular
        ).replace("0x", "");
        let resultData = templateResult;
        let crcData = crc
            .crc16kermit(hex2Ab(resultData))
            .toString(16)
            .PadLeft(4, "0");
        resultData += crcData;
        console.log("读取锁信息发送的数据(300a)" + JSON.stringify(resultData));
        sendDataTolock(resultData);
        staticCallback = callback;
    }

    /**
     * *获取超管鉴权秘钥
     * @param {门锁ID – 最多40字节} _lockId
     * @param {用户ID – 最多20字节} usrID
     * @param {钥匙ID – 最多40字节} _keyId
     * @param {回调} callback
     */
    static getSignKey(_lockId, usrID, _keyId, callback) {
        deviceNameSaved = _lockId;
        authUserIdSaved = usrID;
        keyIdSaved = _keyId;
        let head = makeHeader("3092");
        let cmdId = "3092";
        let lockID4AuthCode = str2Hex(_lockId);
        encKeySaved = lockID4AuthCode;
        let keyID4AuthCode = str2Hex(_keyId);
        let authuserID4AuthCode = str2Hex(usrID);
        let tempNowTime = new Date().getTime() / 1000;
        let nowTime = parseInt(new Date().getTime() / 1000).toString(16);

        let lockID = lockID4AuthCode.PadRight(80, "0");
        let keyID = keyID4AuthCode.PadRight(80, "0");
        let authUserID = authuserID4AuthCode.PadRight(40, "0");

        let authCode = ab2hex(
            md5.digest(
                hexStr2Byte(
                    authuserID4AuthCode + keyID4AuthCode + nowTime + lockID4AuthCode
                )
            )
        );
        let authCodeLen = (authCode.length / 2).toString(16).PadLeft(2, "0");
        let dataModular =
            cmdId + lockID + keyID + authUserID + nowTime + authCodeLen + authCode;

        let dataModularLength = (dataModular.length / 2)
            .toString(16)
            .PadLeft(4, "0");
        let dataModularSM4 = sm4.sm4_enc(
            hexStr2Byte(dataModular),
            dataModular.length / 2,
            hexStr2Byte(lockID4AuthCode)
        );
        let dataModularSM4HexString = byte2HexStr(dataModularSM4);
        let dataModularSM4Length = (dataModularSM4HexString.length / 2)
            .toString(16)
            .PadLeft(4, "0");
        let resultData =
            head + dataModularSM4Length + dataModularLength + dataModularSM4HexString;
        console.log(
            "加密前:" + head + dataModularSM4Length + dataModularLength + dataModular
        );
        let crcData = crc
            .crc16kermit(hexStr2Byte(resultData))
            .toString(16)
            .PadLeft(4, "0");
        resultData += crcData;
        sendDataTolock(resultData);
        staticCallback = callback;
    }

    /**
     * *协商秘钥
     * @param {门锁ID – 最多40字节} _lockId
     * @param {用户ID – 最多20字节} _usrID
     * @param {钥匙ID – 最多40字节} _keyId
     * @param {用户的signKey} _userSignKey
     * @param {回调函数} callback
     */
    static getCommonKey(_lockId, _usrID, _keyId, _userSignKey, callback) {
        console.log("获取commonkey", [...arguments]);
        userIdSaved = _usrID;
        keyIdSaved = _keyId;
        signKeySaved = _userSignKey;
        let _signKey = _userSignKey;
        let head = makeHeader("3093");
        let cmdId = "3093";
        let lockID4AuthCode = str2Hex(_lockId);
        encKeySaved = lockID4AuthCode;
        let keyID4AuthCode = str2Hex(_keyId);
        let authuserID4AuthCode = str2Hex(_usrID);
        let nowTime = parseInt(new Date().getTime() / 1000).toString(16);

        let lockID = lockID4AuthCode.PadRight(80, "0");
        let keyID = keyID4AuthCode.PadRight(80, "0");
        let authUserID = authuserID4AuthCode.PadRight(40, "0");

        let authCode = ab2hex(
            md5.digest(
                hexStr2Byte(authuserID4AuthCode + keyID4AuthCode + nowTime + _signKey)
            )
        );
        let authCodeLen = (authCode.length / 2).toString(16).PadLeft(2, "0");
        let dataModular =
            cmdId + lockID + keyID + authUserID + nowTime + authCodeLen + authCode;
        console.log(dataModular);
        let dataModularLength = (dataModular.length / 2)
            .toString(16)
            .PadLeft(4, "0");
        let dataModularSM4 = sm4.sm4_enc(
            hexStr2Byte(dataModular),
            dataModular.length / 2,
            hexStr2Byte(lockID4AuthCode)
        );
        let dataModularSM4HexString = byte2HexStr(dataModularSM4);
        let dataModularSM4Length = (dataModularSM4HexString.length / 2)
            .toString(16)
            .PadLeft(4, "0");
        let resultData =
            head + dataModularSM4Length + dataModularLength + dataModularSM4HexString;
        console.log(
            "包头信息 +++++++++++" + head + dataModularSM4Length + dataModularLength
        );
        let crcData = crc
            .crc16kermit(hexStr2Byte(resultData))
            .toString(16)
            .PadLeft(4, "0");
        resultData += crcData;
        sendDataTolock(resultData);
        staticCallback = callback;
    }

    /**
     * *获取用户signkey
     * @param {门锁ID – 最多40字节} _lockId
     * @param {超管ID} _superAdminId
     * @param {用户ID – 最多20字节} _usrID
     * @param {超管的keyId – 最多40字节} _keyId
     * @param {超管的signkey 或者 authKey} _authUserSignKeyOrAuthKey
     * @param {传入数据类型 String 01: 传入了authUserSignKey, 02:传入了authKey} _accessType
     * @param {回调} callback
     */
    static getUserSignKey(
        _lockId,
        _superAdminId,
        _userID,
        _keyId,
        _authUserSignKeyOrAuthKey,
        _accessType,
        callback
    ) {
        authUserIdSaved = _superAdminId;
        userIdSaved = _userID;
        keyIdSaved = _keyId;
        let head = makeHeader("3094");
        let cmdId = "3094";
        let lockID4AuthCode = str2Hex(_lockId);
        encKeySaved = lockID4AuthCode;
        let keyID4AuthCode = str2Hex(_keyId);
        let authuserID4AuthCode = str2Hex(_superAdminId);
        let userID4AuthCode = str2Hex(_userID);
        let nowTime = parseInt(new Date().getTime() / 1000).toString(16);
        let lockID = lockID4AuthCode.PadRight(80, "0");
        let keyID = keyID4AuthCode.PadRight(80, "0");
        let authUserID = authuserID4AuthCode.PadRight(40, "0");
        let userID = userID4AuthCode.PadRight(40, "0");
        let authCode = "";
        switch (_accessType) {
            case "01":
                authCode = ab2hex(
                    md5.digest(
                        hex2Ab(
                            authuserID4AuthCode +
                            keyID4AuthCode +
                            userID4AuthCode +
                            _authUserSignKeyOrAuthKey
                        )
                    )
                );
                break;

            case "02":
                authCode = _authUserSignKeyOrAuthKey;
                break;

            default:
                break;
        }
        let authCodeLen = (authCode.length / 2).toString(16).PadLeft(2, "0");
        let dataModular =
            cmdId +
            lockID +
            authUserID +
            keyID +
            userID +
            nowTime +
            authCodeLen +
            authCode;
        console.log(dataModular);
        let dataModularLength = (dataModular.length / 2)
            .toString(16)
            .PadLeft(4, "0");
        let dataModularSM4 = sm4.sm4_enc(
            hexStr2Byte(dataModular),
            dataModular.length / 2,
            hexStr2Byte(lockID4AuthCode)
        );
        let dataModularSM4HexString = byte2HexStr(dataModularSM4);
        let dataModularSM4Length = (dataModularSM4HexString.length / 2)
            .toString(16)
            .PadLeft(4, "0");
        let resultData =
            head + dataModularSM4Length + dataModularLength + dataModularSM4HexString;
        console.log(
            "包头信息 +++++++++++" +
            head +
            dataModularSM4Length +
            dataModularLength +
            dataModular
        );
        let crcData = crc
            .crc16kermit(hex2Ab(resultData))
            .toString(16)
            .PadLeft(4, "0");
        resultData += crcData;
        sendDataTolock(resultData);
        staticCallback = callback;
    }

    /**
     * *添加用户
     * @param {锁ID} _lockId
     * @param {超管ID} _superAdminId
     * @param {添加的用户ID} usrId blueName
     * @param {超管的keyId} _keyId 
     * @param {00普通用户 01管理员 FF超级管理员} _role
     * @param {superAdmin的signkey} _signKey
     * @param {传入空字符串即可} _token
     * @param {通讯秘钥,getCommonKey命令可以获取} _commonKey
     * @param {设置开始时间-8位timestamp字符串,eg:'00000000'} _startTime
     * @param {设置结束时间-8位timestamp字符串,eg:'00000000'} _endTime
     * @param {回调} callback
     */
    static addUserToLock(
        _lockId,
        _superAdminId,
        _usrId,
        _keyId,
        _role,
        _signKey,
        _token,
        _commonKey,
        _startTime,
        _endTime,
        callback
    ) {
        console.log('添加用户参数', [...arguments])
        deviceNameSaved = _lockId;
        authUserIdSaved = _superAdminId;
        userIdSaved = _usrId;
        keyIdSaved = _keyId;
        signKeySaved = _signKey;
        roleSaved = _role;
        encKeySaved = _commonKey;
        startTimeSaved = _startTime;
        endTimeSaved = _endTime;
        let signKey = _signKey;
        let head = makeHeader("3001");
        let cmdId = "3001";
        let lockId4AuthCode = str2Hex(_lockId);
        let lockId = lockId4AuthCode.PadRight(80, "0");
        let authuserID4AuthCode = str2Hex(_superAdminId);
        let authUserID = authuserID4AuthCode.PadRight(40, "0");
        let keyID4AuthCode = str2Hex(_keyId);
        let keyID = keyID4AuthCode.PadRight(80, "0");
        let userId = str2Hex(_usrId).PadRight(40, "0");
        let openMode
        if (blueKey) { //蓝牙扣
            openMode = '04'
        } else { //正常用户
            openMode = "03";
        }
        let keyType = "00";
        let startDate = _startTime;
        let expireDate = _endTime;
        var passWord = "".PadRight(40, "0");
        var token = "".PadRight(8, "0");
        var authCode = "";
        var authCodeLen = "00";
        if (_token != "") {
            token = _token;
            authCode = ab2hex(
                md5.digest(
                    hexStr2Byte(authuserID4AuthCode + keyID4AuthCode + token + signKey)
                )
            );
            authCodeLen = (authCode.length / 2).toString(16).PadLeft(2, "0");
        }
        let dataModular =
            cmdId +
            lockId +
            authUserID +
            keyID +
            userId +
            openMode +
            keyType +
            startDate +
            expireDate +
            _role +
            passWord +
            token +
            authCodeLen +
            authCode;
        let dataModularLength = (dataModular.length / 2)
            .toString(16)
            .PadLeft(4, "0");
        let dataModularSM4 = sm4.sm4_enc(
            hexStr2Byte(dataModular),
            dataModular.length / 2,
            hexStr2Byte(_commonKey)
        );
        let dataModularSM4HexString = byte2HexStr(dataModularSM4);
        console.log(
            "dataModularSM4String---------------------" + dataModularSM4HexString
        );
        let dataModularSM4Length = (dataModularSM4HexString.length / 2)
            .toString(16)
            .PadLeft(4, "0");
        let resultData =
            head + dataModularSM4Length + dataModularLength + dataModularSM4HexString;
        console.log(
            "加密前:" + head + dataModularSM4Length + dataModularLength + dataModular
        );
        let crcData = crc
            .crc16kermit(hexStr2Byte(resultData))
            .toString(16)
            .PadLeft(4, "0");
        resultData += crcData;
        sendDataTolock(resultData);
        staticCallback = callback;
    }

    static addBlueKeyToLock(
        _lockId,
        _superAdminId,
        _usrId,
        _keyId,
        _role,
        _signKey,
        _token,
        _commonKey,
        _startTime,
        _endTime,
        callback
    ) {
        console.log('添加用户参数', [...arguments])
        deviceNameSaved = _lockId;
        authUserIdSaved = _superAdminId;
        userIdSaved = _usrId;
        keyIdSaved = _keyId;
        signKeySaved = _signKey;
        roleSaved = _role;
        encKeySaved = _commonKey;
        startTimeSaved = _startTime;
        endTimeSaved = _endTime;
        let signKey = _signKey;
        let head = makeHeader("3001");
        let cmdId = "3001";
        let lockId4AuthCode = str2Hex(_lockId);
        let lockId = lockId4AuthCode.PadRight(80, "0");
        let authuserID4AuthCode = str2Hex(_superAdminId);
        let authUserID = authuserID4AuthCode.PadRight(40, "0");
        let keyID4AuthCode = str2Hex(_keyId);
        let keyID = keyID4AuthCode.PadRight(80, "0");
        let userId = str2Hex(_usrId).PadRight(40, "0");
        let openMode
        if (blueKey) { //蓝牙扣
            openMode = '04'
        } else { //正常用户
            openMode = "03";
        }
        let keyType = "00";
        let startDate = _startTime;
        let expireDate = _endTime;
        var passWord = "".PadRight(40, "0");
        var token = "".PadRight(8, "0");
        var authCode = "";
        var authCodeLen = "00";
        if (_token != "") {
            token = _token;
            authCode = ab2hex(
                md5.digest(
                    hexStr2Byte(authuserID4AuthCode + keyID4AuthCode + token + signKey)
                )
            );
            authCodeLen = (authCode.length / 2).toString(16).PadLeft(2, "0");
        }
        let dataModular =
            cmdId +
            lockId +
            authUserID +
            keyID +
            userId +
            openMode +
            keyType +
            startDate +
            expireDate +
            _role +
            passWord +
            token +
            authCodeLen +
            authCode;
        let dataModularLength = (dataModular.length / 2)
            .toString(16)
            .PadLeft(4, "0");
        let dataModularSM4 = sm4.sm4_enc(
            hexStr2Byte(dataModular),
            dataModular.length / 2,
            hexStr2Byte(_commonKey)
        );
        let dataModularSM4HexString = byte2HexStr(dataModularSM4);
        console.log(
            "dataModularSM4String---------------------" + dataModularSM4HexString
        );
        let dataModularSM4Length = (dataModularSM4HexString.length / 2)
            .toString(16)
            .PadLeft(4, "0");
        let resultData =
            head + dataModularSM4Length + dataModularLength + dataModularSM4HexString;
        console.log(
            "加密前:" + head + dataModularSM4Length + dataModularLength + dataModular
        );
        let crcData = crc
            .crc16kermit(hexStr2Byte(resultData))
            .toString(16)
            .PadLeft(4, "0");
        resultData += crcData;
        sendDataTolock(resultData);
        staticCallback = callback;
    }
    /**
     * *开门
     * @param {锁ID} _lockId
     * @param {开门的用户} usrID
     * @param {开门用户的signkey} _signKey
     * @param {开门用户的keyId} _keyId
     * @param {传入空字符串} _tokenOfOpenTheDoor
     * @param {开锁方式 '00' 离线 '01'在线} _openMode
     * @param {开门用户的commonKey} _commonKey
     * @param {回调} callback
     */
    static openTheDoor(
        _lockId,
        usrID,
        _signKey,
        _keyId,
        _tokenOfOpenTheDoor,
        _openMode,
        _commonKey,
        callback
    ) {
        console.log("开门参数", [...arguments]);
        deviceNameSaved = _lockId;
        userIdSaved = usrID;
        keyIdSaved = _keyId;
        signKeySaved = _signKey;
        encKeySaved = _commonKey;
        openModeSaved = _openMode;
        let authUserId = wx.getStorageSync("userSignKey");
        let lockId4AuthCode = str2Hex(_lockId);
        let lockId = lockId4AuthCode.PadRight(80, "0");
        let head = makeHeader("3005");
        let cmdId = "3005";
        let keyID4AuthCode = str2Hex(_keyId);
        let keyID = keyID4AuthCode.PadRight(80, "0");
        let userID4AuthCode = str2Hex(usrID);
        let userId = userID4AuthCode.PadRight(40, "0");
        let openMode = _openMode;
        let openTime = parseInt(new Date().getTime() / 1000).toString(16);
        let token = "".PadRight(8, "0");
        let authCode = "";
        let authCodeLen = "00";
        if (_tokenOfOpenTheDoor != "") {
            token = _tokenOfOpenTheDoor;
            authCode = ab2hex(
                md5.digest(
                    hexStr2Byte(keyID4AuthCode + userID4AuthCode + token + _signKey)
                )
            );
            authCodeLen = (authCode.length / 2).toString(16).PadLeft(2, "0");
        }
        let dataModular =
            cmdId +
            keyID +
            userId +
            openMode +
            openTime +
            token +
            authCodeLen +
            authCode;
        let dataModularLength = (dataModular.length / 2)
            .toString(16)
            .PadLeft(4, "0");
        let dataModularSM4 = sm4.sm4_enc(
            hexStr2Byte(dataModular),
            dataModular.length / 2,
            hexStr2Byte(_commonKey)
        );
        let dataModularSM4HexString = byte2HexStr(dataModularSM4);
        console.log(
            "dataModularSM4String---------------------" + dataModularSM4HexString
        );
        let dataModularSM4Length = (dataModularSM4HexString.length / 2)
            .toString(16)
            .PadLeft(4, "0");
        let resultData =
            head + dataModularSM4Length + dataModularLength + dataModularSM4HexString;
        console.log(
            "加密前:" + head + dataModularSM4Length + dataModularLength + dataModular
        );
        let crcData = crc
            .crc16kermit(hexStr2Byte(resultData))
            .toString(16)
            .PadLeft(4, "0");
        resultData += crcData;
        sendDataTolock(resultData);
        staticCallback = callback;
    }

    /**
     * *重置门锁
     * @param {门锁ID – 最多40字节} _lockId
     * @param {用户ID – 最多20字节} _usrID
     * @param {传入空字符串即可} _resetLockToken
     * @param {用户的signkey} _signkey
     * @param {用户的commonKey} _commonKey
     * @param {回调} callback
     */
    static resetLock(
        _lockId,
        _usrID,
        _resetLockToken,
        _signkey,
        _commonKey,
        callback
    ) {
        deviceNameSaved = _lockId;
        userIdSaved = _usrID;
        signKeySaved = _signkey;
        encKeySaved = _commonKey;

        let head = makeHeader("3004");
        let cmdId = "3004";
        let lockId4AuthCode = str2Hex(_lockId);
        let lockId = lockId4AuthCode.PadRight(80, "0");
        let userId = str2Hex(_usrID).PadRight(40, "0");
        let token = "".PadRight(8, "0");
        var authCodeLen = "00";
        var authCode = "";
        if (_resetLockToken != "") {
            token = _resetLockToken;
            authCode = ab2hex(md5.digest(hex2Ab(lockId4AuthCode + token + _signkey)));
            authCodeLen = (authCode.length / 2).toString(16).PadLeft(2, "0");
        }
        let dataModular = cmdId + lockId + userId + token + authCodeLen + authCode;
        let dataModularLength = (dataModular.length / 2)
            .toString(16)
            .PadLeft(4, "0");
        let dataModularSM4 = sm4.sm4_enc(
            hexStr2Byte(dataModular),
            dataModular.length / 2,
            hexStr2Byte(_commonKey)
        );
        let dataModularSM4HexString = byte2HexStr(dataModularSM4);
        console.log(
            "dataModularSM4String---------------------" + dataModularSM4HexString
        );
        let dataModularSM4Length = (dataModularSM4HexString.length / 2)
            .toString(16)
            .PadLeft(4, "0");
        let resultData =
            head + dataModularSM4Length + dataModularLength + dataModularSM4HexString;
        console.log(
            "加密前:" + head + dataModularSM4Length + dataModularLength + dataModular
        );
        let crcData = crc
            .crc16kermit(hex2Ab(resultData))
            .toString(16)
            .PadLeft(4, "0");
        resultData += crcData;
        sendDataTolock(resultData);
        staticCallback = callback;
    }

    /**
     * 同步时间
     * @param {门锁ID – 最多40字节} _lockId
     * @param {用户ID – 最多20字节} usrId
     * @param {时间- long型秒级时间戳} _time
     * @param {NB接入域名IP} _NBDomainIP
     * @param {用户的commonKey} _commonKey
     * @param {回调函数} callback
     */
    static updateTime(_lockId, usrId, _time, _NBDomainIP, _commonKey, callback) {
        encKeySaved = _commonKey;
        let head = makeHeader("3009");
        let cmdId = "3009";
        let lockId4AuthCode = str2Hex(_lockId);
        let lockerId = lockId4AuthCode.PadRight(80, "0");
        let userId = str2Hex(usrId).PadRight(40, "0");
        let time = parseInt(_time).toString(16);
        let NBDomainIPHex = str2Hex(_NBDomainIP);
        let NBDomainIP = NBDomainIPHex.PadRight(40, "0");
        let dataModular = cmdId + lockerId + userId + time + NBDomainIP;
        let dataModularLength = (dataModular.length / 2)
            .toString(16)
            .PadLeft(4, "0");
        let dataModularSM4 = sm4.sm4_enc(
            hexStr2Byte(dataModular),
            dataModular.length / 2,
            hexStr2Byte(_commonKey)
        );
        let dataModularSM4HexString = byte2HexStr(dataModularSM4);
        console.log(
            "dataModularSM4String---------------------" + dataModularSM4HexString
        );
        let dataModularSM4Length = (dataModularSM4HexString.length / 2)
            .toString(16)
            .PadLeft(4, "0");
        let resultData =
            head + dataModularSM4Length + dataModularLength + dataModularSM4HexString;
        console.log(
            "加密前:" + head + dataModularSM4Length + dataModularLength + dataModular
        );
        let crcData = crc
            .crc16kermit(hex2Ab(resultData))
            .toString(16)
            .PadLeft(4, "0");
        resultData += crcData;
        sendDataTolock(resultData);
        staticCallback = callback;
    }
    /**
     * 更新固件确认token
     * @param {门锁ID – 最多40字节} _lockId
     * @param {系统管理员ID - 最多20字节} _systemUserId
     * @param {固件升级程序版本 - 4字节 16进制} _fileVersion
     * @param {升级文件总字节数  - 4字节 16进制} _fileSize
     * @param {升级文件crc校验码  - 4字节 16进制} _fileCRC
     * @param {传入空字符串} _updateFirewareToken
     * @param {系统管理员singkey} _signKey
     * @param {通讯密钥} _commonKey
     * @param {回调} callback
     */
    static updateFirmware(
        _lockId,
        _systemUserId,
        _fileVersion,
        _fileSize,
        _fileCRC,
        _updateFirewareToken,
        _signKey,
        _commonKey,
        callback
    ) {
        console.log("更新固件确认token参数", [...arguments]);
        deviceNameSaved = _lockId;
        authUserIdSaved = _systemUserId;
        fileVersionSaved = _fileVersion
        fileSizeSaved = _fileSize;
        fileCRCSaved = _fileCRC;
        signKeySaved = _signKey;
        encKeySaved = _commonKey;
        let head = makeHeader("300b");
        let cmdId = "300b";
        let lockId4AuthCode = str2Hex(_lockId);
        let lockerId = lockId4AuthCode.PadRight(80, "0");
        let userID4AuthCode = str2Hex(_systemUserId);
        let userId = userID4AuthCode.PadRight(40, "0");
        let fileVersion = _fileVersion;
        let fileSize = _fileSize;
        let fileCRC = _fileCRC;
        let token = "00000000";
        let authCodeLen = "00";
        let authCode = "";
        if (_updateFirewareToken != "") {
            token = _updateFirewareToken;
            authCode = ab2hex(md5.digest(hex2Ab(lockId4AuthCode + token + _signKey)));
            authCodeLen = (authCode.length / 2).toString(16).PadLeft(2, "0");
        }
        let dataModular =
            cmdId +
            lockerId +
            userId +
            fileVersion +
            fileSize +
            fileCRC +
            token +
            authCodeLen +
            authCode;
        let dataModularLength = (dataModular.length / 2)
            .toString(16)
            .PadLeft(4, "0");
        let dataModularSM4 = sm4.sm4_enc(
            hexStr2Byte(dataModular),
            dataModular.length / 2,
            hexStr2Byte(_commonKey)
        );
        let dataModularSM4HexString = byte2HexStr(dataModularSM4);
        console.log(
            "dataModularSM4String---------------------" + dataModularSM4HexString
        );
        let dataModularSM4Length = (dataModularSM4HexString.length / 2)
            .toString(16)
            .PadLeft(4, "0");
        let resultData =
            head + dataModularSM4Length + dataModularLength + dataModularSM4HexString;
        console.log(
            "加密前:" + head + dataModularSM4Length + dataModularLength + dataModular
        );
        let crcData = crc
            .crc16kermit(hex2Ab(resultData))
            .toString(16)
            .PadLeft(4, "0");
        resultData += crcData;
        sendDataTolock(resultData);
        staticCallback = callback;
    }

    /**
     * 发送更新文件
     * @param {从更新固件获取的token} _token
     * @param {文件大小 - 4字节 16进制} _fileSize
     * @param {当前数据偏移量 - 4字节 16进制} _dataOffset
     * @param {数据长度 - 4字节 16进制 每次最大发送1K} _dataLength
     * @param {升级文件数据} _data
     * @param {通讯密钥} _commonKey
     */
    static transforUpdateFile(
        _token,
        _fileSize,
        _dataOffset,
        _dataLength,
        _data,
        _commonKey,
        callback
    ) {
        encKeySaved = _commonKey;
        let head = makeHeader("300c");
        let cmdId = "300c";
        let dataModular =
            cmdId + _token + _fileSize + _dataOffset + _dataLength + _data;
        let dataModularLength = (dataModular.length / 2)
            .toString(16)
            .PadLeft(4, "0");
        let dataModularSM4 = sm4.sm4_enc(
            hexStr2Byte(dataModular),
            dataModular.length / 2,
            hexStr2Byte(_commonKey)
        );
        let dataModularSM4HexString = byte2HexStr(dataModularSM4);
        let dataModularSM4Length = (dataModularSM4HexString.length / 2)
            .toString(16)
            .PadLeft(4, "0");
        let resultData =
            head + dataModularSM4Length + dataModularLength + dataModularSM4HexString;
        console.log(
            "加密前:" + head + dataModularSM4Length + dataModularLength + dataModular
        );
        let crcData = crc
            .crc16kermit(hex2Ab(resultData))
            .toString(16)
            .PadLeft(4, "0");
        resultData += crcData;
        sendDataTolock(resultData);
        staticCallback = callback;
    }

    /**
     * *删除用户
     * @param {门锁ID} _lockId
     * @param {超管ID – 最多20字节} _superAdminId
     * @param {用户ID – 最多20字节} usrId
     * @param {超管keyId} _keyId
     * @param {置空即可} delUserToken
     * @param {超管的signkey} _signkey
     * @param {用户的commonKey} _commonKey
     * @param {回调} callback
     */
    static deleteUser(
        _lockId,
        _superAdminId,
        usrId,
        _keyId,
        delUserToken,
        _signkey,
        _commonKey,
        callback
    ) {
        deviceNameSaved = _lockId;
        authUserIdSaved = _superAdminId;
        userIdSaved = usrId;
        keyIdSaved = _keyId;
        signKeySaved = _signkey;
        encKeySaved = _commonKey;
        let head = makeHeader("3002");
        let cmdId = "3002";
        let lockId4AuthCode = str2Hex(_lockId);
        let lockId = lockId4AuthCode.PadRight(80, "0");
        let authuserID4AuthCode = str2Hex(_superAdminId);
        let authUserId = authuserID4AuthCode.PadRight(40, "0");
        let keyID4AuthCode = str2Hex(_keyId);
        let keyId = keyID4AuthCode.PadRight(80, "0");
        let delUserId = str2Hex(usrId).PadRight(40, "0");
        let token = "".PadRight(8, "0");
        let authCodeLen = "00";
        let authCode = "";
        if (delUserToken != "") {
            token = delUserToken;
            authCode = ab2hex(
                md5.digest(
                    hex2Ab(authuserID4AuthCode + keyID4AuthCode + token + _signkey)
                )
            );
            authCodeLen = (authCode.length / 2).toString(16).PadLeft(2, "0");
        }
        let dataModular =
            cmdId +
            lockId +
            authUserId +
            keyId +
            delUserId +
            token +
            authCodeLen +
            authCode;
        let dataModularLength = (dataModular.length / 2)
            .toString(16)
            .PadLeft(4, "0");
        let dataModularSM4 = sm4.sm4_enc(
            hexStr2Byte(dataModular),
            dataModular.length / 2,
            hexStr2Byte(_commonKey)
        );
        let dataModularSM4HexString = byte2HexStr(dataModularSM4);
        console.log(
            "dataModularSM4String---------------------" + dataModularSM4HexString
        );
        let dataModularSM4Length = (dataModularSM4HexString.length / 2)
            .toString(16)
            .PadLeft(4, "0");
        let resultData =
            head + dataModularSM4Length + dataModularLength + dataModularSM4HexString;
        console.log(
            "加密前:" + head + dataModularSM4Length + dataModularLength + dataModular
        );
        let crcData = crc
            .crc16kermit(hex2Ab(resultData))
            .toString(16)
            .PadLeft(4, "0");
        resultData += crcData;
        sendDataTolock(resultData);
        staticCallback = callback;
    }

    /**
     * *添加指纹
     * @param {门锁ID} _lockId
     * @param {超管ID – 最多20字节} _superAdminId
     * @param {用户ID – 最多20字节} _userId
     * @param {超管的keyId} _keyId
     * @param {置空即可} _fingerToken
     * @param {超管的signKey} _signKey
     * @param {设置开始时间-8位timestamp字符串,eg:'00000000'} _startTime
     * @param {设置结束时间-8位timestamp字符串,eg:'FFFFFFFF'} _endTime
     * @param {是否为报警指纹,'00'为否,'01'为是} _alarmFinger
     * @param {超管的commonKey} _commonKey
     * @param {回调方法} callback
     */
    static addFingerPrints(
        _lockId,
        _superAdminId,
        _userId,
        _keyId,
        _fingerToken,
        _signKey,
        _startTime,
        _endTime,
        _alarmFinger,
        _commonKey,
        callback
    ) {
        deviceNameSaved = _lockId;
        authUserIdSaved = _superAdminId;
        userIdSaved = _userId;
        signKeySaved = _signKey;
        startTimeSaved = _startTime;
        endTimeSaved = _endTime;
        alarmFingerSaved = _alarmFinger;
        keyIdSaved = _keyId;
        encKeySaved = _commonKey;
        let head = makeHeader("3030");
        let cmdId = "3030";
        let subCmdId = "09";
        let lockId4AuthCode = str2Hex(_lockId);
        let authuserID4AuthCode = str2Hex(_superAdminId);
        let authUserId = authuserID4AuthCode.PadRight(40, "0");
        let keyID4AuthCode = str2Hex(_keyId);
        let keyId = keyID4AuthCode.PadRight(80, "0");
        let userID4AuthCode = str2Hex(_userId);
        let userId = userID4AuthCode.PadRight(40, "0");
        let alarmFinger = _alarmFinger;
        let authCodeLen = "00";
        let authCode = "";
        let token = "00000000";
        if (_fingerToken != "") {
            token = _fingerToken;
            authCode = ab2hex(
                md5.digest(
                    hex2Ab(
                        authuserID4AuthCode +
                        keyID4AuthCode +
                        userID4AuthCode +
                        token +
                        _signKey
                    )
                )
            );
            authCodeLen = (authCode.length / 2).toString(16).PadLeft(2, "0");
        }
        let reqData =
            authUserId +
            keyId +
            userId +
            _startTime +
            _endTime +
            alarmFinger +
            token +
            authCodeLen +
            authCode;
        let reqDataLength = (reqData.length / 2).toString(16).PadLeft(2, "0");
        let dataModular = cmdId + subCmdId + reqDataLength + reqData;
        let dataModularLength = (dataModular.length / 2)
            .toString(16)
            .PadLeft(4, "0");
        let dataModularSM4 = sm4.sm4_enc(
            hexStr2Byte(dataModular),
            dataModular.length / 2,
            hexStr2Byte(_commonKey)
        );
        let dataModularSM4HexString = byte2HexStr(dataModularSM4);
        console.log(
            "dataModularSM4String---------------------" + dataModularSM4HexString
        );
        let dataModularSM4Length = (dataModularSM4HexString.length / 2)
            .toString(16)
            .PadLeft(4, "0");
        let resultData =
            head + dataModularSM4Length + dataModularLength + dataModularSM4HexString;
        console.log(
            "加密前:" + head + dataModularSM4Length + dataModularLength + dataModular
        );
        let crcData = crc
            .crc16kermit(hex2Ab(resultData))
            .toString(16)
            .PadLeft(4, "0");
        resultData += crcData;
        sendDataTolock(resultData);
        staticCallback = callback;
    }

    /**
     * *指纹管理
     * @param {*门锁ID – 最多40字节} _lockId
     * @param {*超管ID – 最多20字节} _superAdminId
     * @param {*用户ID – 最多20字节} _userID
     * @param {*用户keyId} _keyId
     * @param {* 01为删除 02修改 03设置报警指纹 } _action
     * @param {*指纹编号 eg:'0001'’} _fingerNo
     * @param {*置空即可} _fingerToken
     * @param {*superAdmin的signKey} _signKey
     * @param {是否为报警指纹,'00'为否,'01'为是} _alarmFinger
     * @param {设置开始时间-8位timestamp字符串,eg:'00000000'} _startTime
     * @param {设置结束时间-8位timestamp字符串,eg:'FFFFFFFF'} _endTime
     * @param {超管的commonKey} _commonKey
     * @param {*回调} callback
     */
    static modifyFingerPrints(
        _lockId,
        _superAdminId,
        _userID,
        _keyId,
        _action,
        _fingerNo,
        _fingerToken,
        _signKey,
        _alarmFinger,
        _startTime,
        _endTime,
        _commonKey,
        callback
    ) {
        deviceNameSaved = _lockId;
        authUserIdSaved = _superAdminId;
        userIdSaved = _userID;
        fingerNoSaved = _fingerNo;
        signKeySaved = _signKey;
        keyIdSaved = _keyId;
        actionSaved = _action;
        alarmFingerSaved = _alarmFinger;
        startTimeSaved = _startTime;
        endTimeSaved = _endTime;
        encKeySaved = _commonKey;

        let head = makeHeader("3030");
        let cmdId = "3030";
        let subCmdId = "0b";
        let lockId4AuthCode = str2Hex(_lockId);

        let authuserID4AuthCode = str2Hex(_superAdminId);
        let authUserId = authuserID4AuthCode.PadRight(40, "0");
        let keyID4AuthCode = str2Hex(_keyId);
        let keyId = keyID4AuthCode.PadRight(80, "0");
        let userID4AuthCode = str2Hex(_userID);
        let userId = userID4AuthCode.PadRight(40, "0");
        let alarmFinger = _alarmFinger;
        let startTime = _startTime;
        let endTime = _endTime;
        let authCodeLen = "00";
        let authCode = "";
        let fingerNo = _fingerNo;
        let token = "00000000";
        if (_fingerToken != "") {
            token = _fingerToken;
            authCode = ab2hex(
                md5.digest(
                    hex2Ab(
                        authuserID4AuthCode +
                        keyID4AuthCode +
                        userID4AuthCode +
                        token +
                        _signKey
                    )
                )
            );
            authCodeLen = (authCode.length / 2).toString(16).PadLeft(2, "0");
        }
        let reqData =
            authUserId +
            keyId +
            userId +
            startTime +
            endTime +
            fingerNo +
            alarmFinger +
            _action +
            token +
            authCodeLen +
            authCode;
        let reqDataLength = (reqData.length / 2).toString(16).PadLeft(2, "0");
        let dataModular = cmdId + subCmdId + reqDataLength + reqData;
        let dataModularLength = (dataModular.length / 2)
            .toString(16)
            .PadLeft(4, "0");
        let dataModularSM4 = sm4.sm4_enc(
            hexStr2Byte(dataModular),
            dataModular.length / 2,
            hexStr2Byte(_commonKey)
        );
        let dataModularSM4HexString = byte2HexStr(dataModularSM4);
        console.log(
            "dataModularSM4String---------------------" + dataModularSM4HexString
        );
        let dataModularSM4Length = (dataModularSM4HexString.length / 2)
            .toString(16)
            .PadLeft(4, "0");
        let resultData =
            head + dataModularSM4Length + dataModularLength + dataModularSM4HexString;
        console.log(
            "加密前:" + head + dataModularSM4Length + dataModularLength + dataModular
        );
        let crcData = crc
            .crc16kermit(hex2Ab(resultData))
            .toString(16)
            .PadLeft(4, "0");
        resultData += crcData;
        sendDataTolock(resultData);
        staticCallback = callback;
    }

    /**
     * *查询指纹列表
     * @param {*门锁ID – 最多40字节} _lockId
     * @param {*用户ID – 最多20字节} _userID
     * @param {*用户keyId} _keyId
     * @param {超管的commonKey} _commonKey
     * @param {回调函数} callback
     */
    static queryFingerprintsList(_lockId, _userID, _keyId, _commonKey, callback) {
        encKeySaved = _commonKey;
        let cmdId = "3030";
        let head = makeHeader("3030");
        let lockId4AuthCode = str2Hex(_lockId);
        let lockId = lockId4AuthCode.PadRight(80, "0");
        let subCmdId = "0a";
        let keyID4AuthCode = _keyId;
        let keyId = keyID4AuthCode.PadRight(80, "0");
        let userId = str2Hex(_userID).PadRight(40, "0");
        let reqData = keyId + userId;
        let reqDataLength = (reqData.length / 2).toString(16).PadLeft(2, "0");
        let dataModular = cmdId + subCmdId + reqDataLength + reqData;
        let dataModularLength = (dataModular.length / 2)
            .toString(16)
            .PadLeft(4, "0");
        let dataModularSM4 = sm4.sm4_enc(
            hexStr2Byte(dataModular),
            dataModular.length / 2,
            hexStr2Byte(_commonKey)
        );
        let dataModularSM4HexString = byte2HexStr(dataModularSM4);
        console.log(
            "dataModularSM4String---------------------" + dataModularSM4HexString
        );
        let dataModularSM4Length = (dataModularSM4HexString.length / 2)
            .toString(16)
            .PadLeft(4, "0");
        let resultData =
            head + dataModularSM4Length + dataModularLength + dataModularSM4HexString;
        console.log(
            "加密前:" + head + dataModularSM4Length + dataModularLength + dataModular
        );
        let crcData = crc
            .crc16kermit(hex2Ab(resultData))
            .toString(16)
            .PadLeft(4, "0");
        resultData += crcData;
        sendDataTolock(resultData);
        staticCallback = callback;
    }

    /**
     * *密码管理
     * @param {门锁ID – 最多40字节} _lockId
     * @param {超管ID – 最多20字节} _superAdminId
     * @param {用户ID – 最多20字节} _userID
     * @param {开锁密码 - 6位数字的字符串} _pwd
     * @param {密码编号 - 取值范围 00-FF } _pwdNo
     * @param {超管的keyId} _keyId
     * @param {superAdmin的signKey} _signKey
     * @param {传入空字符串即可} _pwdToken
     * @param {设置开始时间-8位timestamp字符串,eg:'00000000'} _startTime
     * @param {设置结束时间-8位timestamp字符串,eg:'FFFFFFFF'} _endTime
     * @param {使用次数限制 - 整型,取值范围是0-255,0表示删除密码} _useCountLimit
     * @param {超管的commonKey} _commonKey
     * @param {回调} callback
     */
    static handlePwd(
        _lockId,
        _superAdminId,
        _userID,
        _pwd,
        _pwdNo,
        _keyId,
        _signKey,
        _pwdToken,
        _startTime,
        _endTime,
        _useCountLimit,
        _commonKey,
        callback
    ) {
        console.log("密码参数", [...arguments]);
        deviceNameSaved = _lockId;
        authUserIdSaved = _superAdminId;
        userIdSaved = _userID;
        pwdSaved = _pwd;
        startTimeSaved = _startTime;
        endTimeSaved = _endTime;
        useCountLimitSaved = _useCountLimit;
        keyIdSaved = _keyId;
        signKeySaved = _signKey;
        pwdNoSaved = _pwdNo;
        encKeySaved = _commonKey;
        let head = makeHeader("3030");
        let cmdId = "3030";
        let subCmdId = "03";
        let lockId4AuthCode = str2Hex(_lockId);

        let authuserID4AuthCode = str2Hex(_superAdminId);
        let authUserId = authuserID4AuthCode.PadRight(40, "0");
        let keyID4AuthCode = str2Hex(_keyId);
        let keyId = keyID4AuthCode.PadRight(80, "0");
        let userID4AuthCode = str2Hex(_userID);
        let userId = userID4AuthCode.PadRight(40, "0");
        let pwd = str2Hex(_pwd).PadRight(40, "0");
        let useCountLimit = _useCountLimit.toString(16).PadLeft(2, "0");
        let token = "00000000".PadRight(8, "0");
        let startTime = _startTime.PadRight(8, "0");
        let endTime = _endTime.PadRight(8, "0");
        let authCodeLen = "00";
        let authCode = "";
        if (_pwdToken != "") {
            token = _pwdToken;
            authCode = ab2hex(
                md5.digest(
                    hex2Ab(
                        authuserID4AuthCode +
                        keyID4AuthCode +
                        userID4AuthCode +
                        token +
                        _signKey
                    )
                )
            );
            authCodeLen = (authCode.length / 2).toString(16).PadLeft(2, "0");
        }
        let reqData =
            authUserId +
            keyId +
            userId +
            _pwdNo +
            pwd +
            useCountLimit +
            token +
            startTime +
            endTime +
            authCodeLen +
            authCode;
        let reqDataLength = (reqData.length / 2).toString(16).PadLeft(2, "0");
        let dataModular = cmdId + subCmdId + reqDataLength + reqData;
        let dataModularLength = (dataModular.length / 2)
            .toString(16)
            .PadLeft(4, "0");
        let dataModularSM4 = sm4.sm4_enc(
            hexStr2Byte(dataModular),
            dataModular.length / 2,
            hexStr2Byte(_commonKey)
        );
        let dataModularSM4HexString = byte2HexStr(dataModularSM4);
        console.log(
            "dataModularSM4String---------------------" + dataModularSM4HexString
        );
        let dataModularSM4Length = (dataModularSM4HexString.length / 2)
            .toString(16)
            .PadLeft(4, "0");
        let resultData =
            head + dataModularSM4Length + dataModularLength + dataModularSM4HexString;
        console.log(
            "加密前:" + head + dataModularSM4Length + dataModularLength + dataModular
        );
        let crcData = crc
            .crc16kermit(hex2Ab(resultData))
            .toString(16)
            .PadLeft(4, "0");
        resultData += crcData;
        sendDataTolock(resultData);
        staticCallback = callback;
    }

    /**
     * *密码列表
     * @param {门锁ID – 最多40字节} _lockId
     * @param {用户ID – 最多20字节} _userID
     * @param {用户keyId} _keyId
     * @param {用户的commonKey} _commonKey
     * @param {回调} callback
     */
    static queryPwdList(_lockId, _userID, _keyId, _commonKey, callback) {
        encKeySaved = _commonKey;
        let cmdId = "3030";
        let head = makeHeader("3030");
        let lockId4AuthCode = str2Hex(_lockId);
        let lockId = lockId4AuthCode.PadRight(80, "0");
        let userId = str2Hex(_userID).PadRight(40, "0");
        let keyID4AuthCode = str2Hex(_keyId);
        let keyId = keyID4AuthCode.PadRight(80, "0");
        let subCmdId = "05";

        let reqData = keyId + userId;
        let reqDataLength = (reqData.length / 2).toString(16).PadLeft(2, "0");
        let dataModular = cmdId + subCmdId + reqDataLength + reqData;
        let dataModularLength = (dataModular.length / 2)
            .toString(16)
            .PadLeft(4, "0");
        let dataModularSM4 = sm4.sm4_enc(
            hexStr2Byte(dataModular),
            dataModular.length / 2,
            hexStr2Byte(_commonKey)
        );
        let dataModularSM4HexString = byte2HexStr(dataModularSM4);
        console.log(
            "dataModularSM4String---------------------" + dataModularSM4HexString
        );
        let dataModularSM4Length = (dataModularSM4HexString.length / 2)
            .toString(16)
            .PadLeft(4, "0");
        let resultData =
            head + dataModularSM4Length + dataModularLength + dataModularSM4HexString;
        console.log(
            "加密前:" + head + dataModularSM4Length + dataModularLength + dataModular
        );
        let crcData = crc
            .crc16kermit(hex2Ab(resultData))
            .toString(16)
            .PadLeft(4, "0");
        resultData += crcData;
        sendDataTolock(resultData);
        staticCallback = callback;
    }

    /**
     * 读取开锁记录
     * @param {门锁ID – 最多40字节} _lockId
     * @param {用户ID – 最多20字节} _userID
     * @param {2个字节 0000: 启动读取记录 0001:上条记录操作同步正常,读取下一条记录(确认存储完上次的记录,再传入0001,会删除上次记录) } _openStatus
     * @param {用户的commonKey} _commonKey
     * @param {回调函数} callback
     */
    static queryLockRecord(_lockId, _userID, _openStatus, _commonKey, callback) {
        encKeySaved = _commonKey;
        let cmdId = "3008";
        let head = makeHeader("3008");
        let lockId4AuthCode = str2Hex(_lockId);
        let lockId = lockId4AuthCode.PadRight(80, "0");
        let userId = str2Hex(_userID).PadRight(40, "0");
        let lockRecordCount = "0004";
        let dataModular = cmdId + lockId + userId + _openStatus + lockRecordCount;
        let dataModularLength = (dataModular.length / 2)
            .toString(16)
            .PadLeft(4, "0");
        let dataModularSM4 = sm4.sm4_enc(
            hexStr2Byte(dataModular),
            dataModular.length / 2,
            hexStr2Byte(_commonKey)
        );
        let dataModularSM4HexString = byte2HexStr(dataModularSM4);
        console.log(
            "dataModularSM4String---------------------" + dataModularSM4HexString
        );
        let dataModularSM4Length = (dataModularSM4HexString.length / 2)
            .toString(16)
            .PadLeft(4, "0");
        let resultData =
            head + dataModularSM4Length + dataModularLength + dataModularSM4HexString;
        console.log(
            "加密前:" + head + dataModularSM4Length + dataModularLength + dataModular
        );
        let crcData = crc
            .crc16kermit(hex2Ab(resultData))
            .toString(16)
            .PadLeft(4, "0");
        resultData += crcData;
        sendDataTolock(resultData);
        staticCallback = callback;
    }

    /**
     * 读取蓝扣ID
     * @param {门锁ID – 最多40字节} _lockId
     * @param {用户的commonKey} _commonKey
     * @param {回调函数} callback
     */
    static readBluetoothBuckle(_lockId, _commonKey, callback) {
        console.log('读取蓝牙扣id参数', [...arguments])
        encKeySaved = _commonKey.substring(0, 32)
        let cmdId = "3010";
        let head = makeHeader("3010");
        console.log('head', head)
        let lockId4AuthCode = str2Hex(_lockId);
        let lockId = lockId4AuthCode.PadRight(80, "0");
        let dataModular = cmdId + lockId;
        let dataModularLength = (dataModular.length / 2)
            .toString(16)
            .PadLeft(4, "0");
        let dataModularSM4 = sm4.sm4_enc(
            hexStr2Byte(dataModular),
            dataModular.length / 2,
            hexStr2Byte(encKeySaved)
        );
        let dataModularSM4HexString = byte2HexStr(dataModularSM4);
        console.log(
            "dataModularSM4String---------------------" + dataModularSM4HexString
        );
        let dataModularSM4Length = (dataModularSM4HexString.length / 2)
            .toString(16)
            .PadLeft(4, "0");
        let resultData =
            head + dataModularSM4Length + dataModularLength + dataModularSM4HexString;
        console.log(
            "加密前:" + head + dataModularSM4Length + dataModularLength + dataModular
        );
        let crcData = crc
            .crc16kermit(hex2Ab(resultData))
            .toString(16)
            .PadLeft(4, "0");
        resultData += crcData;
        sendDataTolock(resultData);
        staticCallback = callback;
    }

    /**
     * 注册蓝牙扣
     * @param {授权用户ID – 最多20字节 } _authUserId
     * @param {蓝牙钥匙扣ID - 最多20字节 返回的蓝牙扣名称} _blueKeyId
     * @param {授权用户keyID - 最多40字节 蓝牙扣返回的id } _keyId
     * @param {开锁密码,该密码会写入锁内 - 最多20字节 40个0} _password 
     * @param {传入空字符串即可} _bluetoothBuckleToken
     * @param {授权者的signkey } _singkey
     * @param {通讯密钥} _commonKey
     * @param {回调方法} callback
     */
    static registeBluetoothBuckle(
        _authUserId,
        _blueKeyId,
        _keyId,
        _password,
        _bluetoothBuckleToken,
        _signKey,
        _commonKey,
        callback
    ) {
        console.log('注册蓝牙扣参数', [...arguments])
        authUserIdSaved = _authUserId;
        blueKeyIdSaved = _blueKeyId;
        keyIdSaved = _keyId;
        pwdSaved = _password;
        signKeySaved = _signKey;
        encKeySaved = _commonKey.substring(0, 32)
        let cmdId = "3011";
        let head = makeHeader("3011");
        let authuserID4AuthCode = str2Hex(_authUserId);
        let authUserId = str2Hex(_authUserId).PadRight(40, "0");
        let blueKeyId = str2Hex(_blueKeyId).PadRight(40, '0')
        let keyID4AuthCode = str2Hex(_keyId);
        let keyId = str2Hex(_keyId).PadRight(80, "0");
        let password = _password;
        let token = "00000000";
        let authCodeLen = "00";
        let authCode = "";
        if (_bluetoothBuckleToken != "") {
            token = _bluetoothBuckleToken;
            let ii = getIIData();
            console.log('ii', ii)
            authCode = ab2hex(
                md5.digest(
                    hex2Ab(
                        authuserID4AuthCode + keyID4AuthCode + token + '7569594d4d5377657277313232405e23264038370a0d1112151A212A3542'
                    )
                )
            );
            authCodeLen = (authCode.length / 2).toString(16).PadLeft(2, "0");
        }

        let authSingkey = ab2hex(md5.digest(
            hex2Ab(
                authuserID4AuthCode + keyID4AuthCode + str2Hex(_blueKeyId) + _signKey
            )))
        console.log(_authUserId, _keyId, _blueKeyId, _signKey)

        let dataModular =
            cmdId +
            authUserId +
            blueKeyId +
            keyId +
            password +
            token +
            authCodeLen +
            authCode +
            authSingkey;
        console.log('authcode', authCode)
        let dataModularLength = (dataModular.length / 2)
            .toString(16)
            .PadLeft(4, "0");

        let dataModularSM4 = sm4.sm4_enc(
            hexStr2Byte(dataModular),
            dataModular.length / 2,
            hexStr2Byte(encKeySaved)
        );
        let dataModularSM4HexString = byte2HexStr(dataModularSM4);
        console.log(
            "dataModularSM4String---------------------" + dataModularSM4HexString
        );
        let dataModularSM4Length = (dataModularSM4HexString.length / 2)
            .toString(16)
            .PadLeft(4, "0");
        let resultData =
            head + dataModularSM4Length + dataModularLength + dataModularSM4HexString;
        console.log(
            "加密前:" + head + dataModularSM4Length + dataModularLength + dataModular
        );
        let crcData = crc
            .crc16kermit(hex2Ab(resultData))
            .toString(16)
            .PadLeft(4, "0");
        resultData += crcData;
        sendDataTolock(resultData);
        staticCallback = callback;
    }

    /**
     * *查询RF卡列表
     * @param {门锁ID – 最多40字节} _lockId
     * @param {用户ID – 最多20字节} _userID
     * @param {用户的commonKey} _commonKey
     * @param {回调函数} callback
     */
    static queryRFCard(_lockId, _userID, _keyId, _commonKey, callback) {
        encKeySaved = _commonKey;
        let cmdId = "3030";
        let head = makeHeader("3030");
        let lockId4AuthCode = str2Hex(_lockId);
        let lockId = lockId4AuthCode.PadRight(80, "0");
        let subCmdId = "10";
        let keyID4AuthCode = str2Hex(_keyId);
        let keyId = keyID4AuthCode.PadRight(80, "0");
        let userId = str2Hex(_userID).PadRight(40, "0");
        let reqData = keyId + userId;
        let reqDataLength = (reqData.length / 2).toString(16).PadLeft(2, "0");
        let dataModular = cmdId + subCmdId + reqDataLength + reqData;
        let dataModularLength = (dataModular.length / 2)
            .toString(16)
            .PadLeft(4, "0");
        let dataModularSM4 = sm4.sm4_enc(
            hexStr2Byte(dataModular),
            dataModular.length / 2,
            hexStr2Byte(_commonKey)
        );
        let dataModularSM4HexString = byte2HexStr(dataModularSM4);
        console.log(
            "dataModularSM4String---------------------" + dataModularSM4HexString
        );
        let dataModularSM4Length = (dataModularSM4HexString.length / 2)
            .toString(16)
            .PadLeft(4, "0");
        let resultData =
            head + dataModularSM4Length + dataModularLength + dataModularSM4HexString;
        console.log(
            "加密前:" + head + dataModularSM4Length + dataModularLength + dataModular
        );
        let crcData = crc
            .crc16kermit(hex2Ab(resultData))
            .toString(16)
            .PadLeft(4, "0");
        resultData += crcData;
        sendDataTolock(resultData);
        staticCallback = callback;
    }

    /**
     * *录制RF卡
     * @param {门锁ID – 最多40字节} _lockId
     * @param {超管ID – 最多20字节} _superAdminId
     * @param {用户ID – 最多20字节} _userID
     * @param {超管的keyId} _keyId
     * @param {RF卡的索引号-取值范围 00-FF} _index
     * @param {传入空字符串即可} _rfToken
     * @param {superAdmin的signKey} _signKey
     * @param {设置开始时间-8位timestamp字符串,eg:'00000000'} _startTime
     * @param {设置结束时间-8位timestamp字符串,eg:'FFFFFFFF'} _endTime
     * @param {超管的commonKey} _commonKey
     * @param {回调函数} callback
     */
    static RfCardRegister(
        _lockId,
        _superAdminId,
        _userID,
        _keyId,
        _index,
        _rfToken,
        _signKey,
        _startTime,
        _endTime,
        _commonKey,
        callback
    ) {
        deviceNameSaved = _lockId;
        authUserIdSaved = _superAdminId;
        userIdSaved = _userID;
        keyIdSaved = _keyId;
        indexSaved = _index;
        signKeySaved = _signKey;
        startTimeSaved = _startTime;
        endTimeSaved = _endTime;
        encKeySaved = _commonKey;
        let cmdId = "3030";
        let head = makeHeader("3030");
        let lockId4AuthCode = str2Hex(_lockId);
        let lockId = lockId4AuthCode.PadRight(80, "0");
        let subCmdId = "0F";

        let authuserID4AuthCode = str2Hex(_superAdminId);
        let authUserId = authuserID4AuthCode.PadRight(40, "0");
        let keyID4AuthCode = str2Hex(_keyId);
        let keyId = keyID4AuthCode.PadRight(80, "0");
        let userID4AuthCode = str2Hex(_userID);
        let userId = userID4AuthCode.PadRight(40, "0");
        let index = _index;
        let token = "00000000";
        let authCodeLen = "00";
        let authCode = "";
        if (_rfToken != "") {
            token = _rfToken;
            authCode = ab2hex(
                md5.digest(
                    hex2Ab(
                        authuserID4AuthCode +
                        keyID4AuthCode +
                        userID4AuthCode +
                        token +
                        _signKey
                    )
                )
            );
            authCodeLen = (authCode.length / 2).toString(16).PadLeft(2, "0");
        }
        let reqData =
            authUserId +
            keyId +
            userId +
            index +
            _startTime +
            _endTime +
            token +
            authCodeLen +
            authCode;
        let reqDataLength = (reqData.length / 2).toString(16).PadLeft(2, "0");
        let dataModular = cmdId + subCmdId + reqDataLength + reqData;
        let dataModularLength = (dataModular.length / 2)
            .toString(16)
            .PadLeft(4, "0");
        let dataModularSM4 = sm4.sm4_enc(
            hexStr2Byte(dataModular),
            dataModular.length / 2,
            hexStr2Byte(_commonKey)
        );
        let dataModularSM4HexString = byte2HexStr(dataModularSM4);
        let dataModularSM4Length = (dataModularSM4HexString.length / 2)
            .toString(16)
            .PadLeft(4, "0");
        let resultData =
            head + dataModularSM4Length + dataModularLength + dataModularSM4HexString;
        console.log(
            "加密前:" + head + dataModularSM4Length + dataModularLength + dataModular
        );
        let crcData = crc
            .crc16kermit(hex2Ab(resultData))
            .toString(16)
            .PadLeft(4, "0");
        resultData += crcData;
        sendDataTolock(resultData);
        staticCallback = callback;
    }

    /**
     * *RF卡管理
     * @param {门锁ID – 最多40字节} _lockId
     * @param {超管ID – 最多20字节} _superAdminId
     * @param {用户ID – 最多20字节} _userID
     * @param {用户keyId} _keyId
     * @param {RF卡的索引号-取值范围 00-FF} _index
     * @param {置空即可} _rfToken
     * @param {01删除 02修改} _action
     * @param {superAdmin的signKey} _signKey
     * @param {设置开始时间-8位timestamp字符串,eg:'00000000'} _startTime
     * @param {设置结束时间-8位timestamp字符串,eg:'FFFFFFFF'} _endTime
     * @param {超管的commonKey} _commonKey
     * @param {回调函数} callback
     */
    static modifyRFCard(
        _lockId,
        _superAdminId,
        _userID,
        _keyId,
        _index,
        _rfToken,
        _action,
        _signKey,
        _startTime,
        _endTime,
        _commonKey,
        callback
    ) {
        deviceNameSaved = _lockId;
        authUserIdSaved = _superAdminId;
        userIdSaved = _userID;
        keyIdSaved = _keyId;
        indexSaved = _index;
        signKeySaved = _signKey;
        startTimeSaved = _startTime;
        endTimeSaved = _endTime;
        actionSaved = _action;
        encKeySaved = _commonKey;
        let cmdId = "3030";
        let head = makeHeader("3030");
        let lockId4AuthCode = str2Hex(_lockId);
        let lockId = lockId4AuthCode.PadRight(80, "0");
        let subCmdId = "11";

        let authuserID4AuthCode = str2Hex(_superAdminId);
        let authUserId = authuserID4AuthCode.PadRight(40, "0");
        let keyID4AuthCode = str2Hex(_keyId);
        let keyId = keyID4AuthCode.PadRight(80, "0");
        let userID4AuthCode = str2Hex(_userID);
        let userId = userID4AuthCode.PadRight(40, "0");
        let index = _index;
        let token = "00000000";
        let authCodeLen = "00";
        let authCode = "";
        if (_rfToken != "") {
            token = _rfToken;
            authCode = ab2hex(
                md5.digest(
                    hex2Ab(
                        authuserID4AuthCode +
                        keyID4AuthCode +
                        userID4AuthCode +
                        token +
                        _signKey
                    )
                )
            );
            authCodeLen = (authCode.length / 2).toString(16).PadLeft(2, "0");
        }
        let reqData =
            authUserId +
            keyId +
            userId +
            index +
            _action +
            _startTime +
            _endTime +
            token +
            authCodeLen +
            authCode;
        let reqDataLength = (reqData.length / 2).toString(16).PadLeft(2, "0");
        let dataModular = cmdId + subCmdId + reqDataLength + reqData;
        let dataModularLength = (dataModular.length / 2)
            .toString(16)
            .PadLeft(4, "0");
        let dataModularSM4 = sm4.sm4_enc(
            hexStr2Byte(dataModular),
            dataModular.length / 2,
            hexStr2Byte(_commonKey)
        );
        let dataModularSM4HexString = byte2HexStr(dataModularSM4);
        let dataModularSM4Length = (dataModularSM4HexString.length / 2)
            .toString(16)
            .PadLeft(4, "0");
        let resultData =
            head + dataModularSM4Length + dataModularLength + dataModularSM4HexString;
        let crcData = crc
            .crc16kermit(hex2Ab(resultData))
            .toString(16)
            .PadLeft(4, "0");
        resultData += crcData;
        sendDataTolock(resultData);
        staticCallback = callback;
    }

    /**
     * rf卡添加非安全卡控制
     * @param {*} _superAdminId
     * @param {*} _userID
     * @param {*} _keyId
     * @param {*} _index
     * @param {*} _signKey
     * @param {*} _cardNo
     * @param {*} _cardFlag
     * @param {*} _commonKey
     * @param {*} callback
     */
    static rFcardAddControl(
        _superAdminId,
        _userID,
        _keyId,
        _index,
        _signKey,
        _cardNo,
        _cardFlag,
        _commonKey,
        callback
    ) {
        let cmdId = "3030";
        let head = makeHeader("3030");
        let subCmdId = "12";
        let authuserID4AuthCode = str2Hex(_superAdminId);
        let authUserId = authuserID4AuthCode.PadRight(40, "0");
        let keyID4AuthCode = str2Hex(_keyId);
        let keyId = keyID4AuthCode.PadRight(80, "0");
        let userID4AuthCode = str2Hex(_userID);
        let userId = userID4AuthCode.PadRight(40, "0");
        let index = _index;
        let cardNo = _cardNo;
        let cardFlag = _cardFlag;
        let reqData = authUserId + keyId + userId + index + cardNo + cardFlag;
        let reqDataLength = (reqData.length / 2).toString(16).PadLeft(2, "0");
        let dataModular = cmdId + subCmdId + reqDataLength + reqData;
        let dataModularLength = (dataModular.length / 2)
            .toString(16)
            .PadLeft(4, "0");
        let dataModularSM4 = sm4.sm4_enc(
            hexStr2Byte(dataModular),
            dataModular.length / 2,
            hexStr2Byte(_commonKey)
        );
        let dataModularSM4HexString = byte2HexStr(dataModularSM4);
        let dataModularSM4Length = (dataModularSM4HexString.length / 2)
            .toString(16)
            .PadLeft(4, "0");
        let resultData =
            head + dataModularSM4Length + dataModularLength + dataModularSM4HexString;
        console.log(
            "加密前:" + head + dataModularSM4Length + dataModularLength + dataModular
        );
        let crcData = crc
            .crc16kermit(hex2Ab(resultData))
            .toString(16)
            .PadLeft(4, "0");
        resultData += crcData;
        sendDataTolock(resultData);
        staticCallback = callback;
    }

    /**
     * *设置音量
     * @param {门锁ID – 最多40字节} _lockId
     * @param {用户ID – 最多20字节} _userId
     * @param {声音选项(string) 00 静音 01 低音 02 高音} _volume
     * @param {用户的commonKey} _commonKey
     * @param {回调} callback
     */
    static setVolume(_lockId, _userId, _volume, _commonKey, callback) {
        encKeySaved = _commonKey;
        let cmdId = "3030";
        let head = makeHeader("3030");
        let lockId4AuthCode = str2Hex(_lockId);
        let lockId = lockId4AuthCode.PadRight(80, "0");
        let subCmdId = "0C";
        let userId = str2Hex(_userId).PadRight(40, "0");

        let reqData = lockId + userId + _volume;
        let reqDataLength = (reqData.length / 2).toString(16).PadLeft(2, "0");
        let dataModular = cmdId + subCmdId + reqDataLength + reqData;
        let dataModularLength = (dataModular.length / 2)
            .toString(16)
            .PadLeft(4, "0");
        let dataModularSM4 = sm4.sm4_enc(
            hexStr2Byte(dataModular),
            dataModular.length / 2,
            hexStr2Byte(_commonKey)
        );
        let dataModularSM4HexString = byte2HexStr(dataModularSM4);
        console.log(
            "dataModularSM4String---------------------" + dataModularSM4HexString
        );
        let dataModularSM4Length = (dataModularSM4HexString.length / 2)
            .toString(16)
            .PadLeft(4, "0");
        let resultData =
            head + dataModularSM4Length + dataModularLength + dataModularSM4HexString;
        console.log(
            "加密前:" + head + dataModularSM4Length + dataModularLength + dataModular
        );
        let crcData = crc
            .crc16kermit(hex2Ab(resultData))
            .toString(16)
            .PadLeft(4, "0");
        resultData += crcData;
        sendDataTolock(resultData);
        staticCallback = callback;
    }

    /**
     * *设置 NB 物联网关 IP
     * @param {NB物联网关IP地址 String 20字节} _NbGwIp
     * @param {端口号 String 6字节} _NbGwPort
     * @param {超管的commonKey} _commonKey
     * @param {回调函数} callback
     */
    static setIpOfNb(_NbGwIp, _NbGwPort, _commonKey, callback) {
        console.log("设置 ip参数", [...arguments]);
        encKeySaved = _commonKey;
        let cmdId = "3030";
        let head = makeHeader("3030");
        let subCmdId = "01";
        let NbGwIp = str2Hex(_NbGwIp).PadRight(40, "0");
        let NbGwPort = str2Hex(_NbGwPort).PadRight(12, "0");
        let reqData = NbGwIp + NbGwPort;
        let reqDataLength = (reqData.length / 2).toString(16).PadLeft(2, "0");
        let dataModular = cmdId + subCmdId + reqDataLength + reqData;
        let dataModularLength = (dataModular.length / 2)
            .toString(16)
            .PadLeft(4, "0");
        let dataModularSM4 = sm4.sm4_enc(
            hexStr2Byte(dataModular),
            dataModular.length / 2,
            hexStr2Byte(_commonKey)
        );
        let dataModularSM4HexString = byte2HexStr(dataModularSM4);
        console.log(
            "dataModularSM4String---------------------" + dataModularSM4HexString
        );
        let dataModularSM4Length = (dataModularSM4HexString.length / 2)
            .toString(16)
            .PadLeft(4, "0");
        let resultData =
            head + dataModularSM4Length + dataModularLength + dataModularSM4HexString;
        console.log(
            "加密前:" + head + dataModularSM4Length + dataModularLength + dataModular
        );
        let crcData = crc
            .crc16kermit(hex2Ab(resultData))
            .toString(16)
            .PadLeft(4, "0");
        resultData += crcData;
        sendDataTolock(resultData);
        staticCallback = callback;
    }

    //读取 NB IMEI 号码
    // Todo: 回复02 密码错误  暂不使用此指令
    static getNbImeiNumber(_lockId, _commonKey, callback) {
        encKeySaved = _commonKey;
        let cmdId = "3030";
        let head = makeHeader("3030");
        let subCmdId = "02";
        let lockId = str2Hex(_lockId).PadRight(80, "0");
        let reqData = lockId;
        let reqDataLength = (reqData.length / 2).toString(16).PadLeft(2, "0");
        let dataModular = cmdId + subCmdId + reqDataLength + reqData;
        let dataModularLength = (dataModular.length / 2)
            .toString(16)
            .PadLeft(4, "0");
        let dataModularSM4 = sm4.sm4_enc(
            hexStr2Byte(dataModular),
            dataModular.length / 2,
            hexStr2Byte(_commonKey)
        );
        let dataModularSM4HexString = byte2HexStr(dataModularSM4);
        console.log(
            "dataModularSM4String---------------------" + dataModularSM4HexString
        );
        let dataModularSM4Length = (dataModularSM4HexString.length / 2)
            .toString(16)
            .PadLeft(4, "0");
        let resultData =
            head + dataModularSM4Length + dataModularLength + dataModularSM4HexString;
        console.log(
            "加密前:" + head + dataModularSM4Length + dataModularLength + dataModular
        );
        let crcData = crc
            .crc16kermit(hex2Ab(resultData))
            .toString(16)
            .PadLeft(4, "0");
        resultData += crcData;
        sendDataTolock(resultData);
        staticCallback = callback;
    }

    /**
     * *设置 WIFI AP 信息
     * @param {wifi的名称} _wifiApSsid
     * @param {wifi密码} _wifiApPwd
     * @param {超管的commonKey} _commonKey
     * @param {回调} callback
     */
    static setWifiApInfo(_wifiApSsid, _wifiApPwd, _commonKey, callback) {
        console.log("设置wifi信息", [...arguments]);
        encKeySaved = _commonKey;
        let cmdId = "3030";
        let head = makeHeader("3030");
        let subCmdId = "13";
        let wifiApSsid = str2Hex(_wifiApSsid).PadRight(64, "0");
        let wifiApPwd = str2Hex(_wifiApPwd).PadRight(40, "0");

        let reqData = wifiApSsid + wifiApPwd;
        let reqDataLength = (reqData.length / 2).toString(16).PadLeft(2, "0");
        let dataModular = cmdId + subCmdId + reqDataLength + reqData;
        let dataModularLength = (dataModular.length / 2)
            .toString(16)
            .PadLeft(4, "0");
        let dataModularSM4 = sm4.sm4_enc(
            hexStr2Byte(dataModular),
            dataModular.length / 2,
            hexStr2Byte(_commonKey)
        );
        let dataModularSM4HexString = byte2HexStr(dataModularSM4);
        console.log(
            "dataModularSM4String---------------------" + dataModularSM4HexString
        );
        let dataModularSM4Length = (dataModularSM4HexString.length / 2)
            .toString(16)
            .PadLeft(4, "0");
        let resultData =
            head + dataModularSM4Length + dataModularLength + dataModularSM4HexString;
        console.log(
            "加密前:" + head + dataModularSM4Length + dataModularLength + dataModular
        );
        let crcData = crc
            .crc16kermit(hex2Ab(resultData))
            .toString(16)
            .PadLeft(4, "0");
        resultData += crcData;
        sendDataTolock(resultData);
        staticCallback = callback;
    }

    // 用户权限移交
    // Todo: 移交权限signkey
    static transferAuth(
        _lockId,
        _transferFromUserId,
        _transferToUserId,
        _transferFromkeyId,
        _transferFromUserRole,
        _transferToUserRole,
        _signKey,
        _commonKey,
        callback
    ) {
        encKeySaved = _commonKey;
        let head = makeHeader("3012");
        let cmdId = "3012";
        let lockId = str2Hex(_lockId).PadRight(80, "0");
        let authuserID4AuthCode = str2Hex(_transferFromUserId);
        let authUserId = authuserID4AuthCode.PadRight(40, "0");
        let keyID4AuthCode = str2Hex(_transferFromkeyId);
        let keyId = keyID4AuthCode.PadRight(80, "0");
        let userID4AuthCode = str2Hex(_transferToUserId);
        let userId = userID4AuthCode.PadRight(40, "0");
        let authUserNewRole = _transferFromUserRole;
        let userNewRole = _transferToUserRole;
        let token = _lockId.substring(4, 12);
        let authCode = ab2hex(
            md5.digest(
                hex2Ab(
                    authuserID4AuthCode +
                    keyID4AuthCode +
                    userID4AuthCode +
                    token +
                    _signKey
                )
            )
        );
        let authCodeLen = (authCode.length / 2).toString(16).PadLeft(2, "0");

        let dataModular =
            cmdId +
            lockId +
            authUserId +
            keyId +
            userId +
            authUserNewRole +
            userNewRole +
            token +
            authCodeLen +
            authCode;
        let dataModularLength = (dataModular.length / 2)
            .toString(16)
            .PadLeft(4, "0");
        let dataModularSM4 = sm4.sm4_enc(
            hexStr2Byte(dataModular),
            dataModular.length / 2,
            hexStr2Byte(_commonKey)
        );
        let dataModularSM4HexString = byte2HexStr(dataModularSM4);
        console.log(
            "dataModularSM4String---------------------" + dataModularSM4HexString
        );
        let dataModularSM4Length = (dataModularSM4HexString.length / 2)
            .toString(16)
            .PadLeft(4, "0");
        let resultData =
            head + dataModularSM4Length + dataModularLength + dataModularSM4HexString;
        console.log(
            "加密前:" + head + dataModularSM4Length + dataModularLength + dataModular
        );
        let crcData = crc
            .crc16kermit(hex2Ab(resultData))
            .toString(16)
            .PadLeft(4, "0");
        resultData += crcData;
        sendDataTolock(resultData);
        staticCallback = callback;
    }

    /**
     * 获取锁端私钥
     * @param {门锁ID – 最多40字节} _lockId
     * @param {通讯密钥} _commonKey
     * @param {回调} callback
     */
    static getPirvateKey(_lockId, _commonKey, callback) {
        encKeySaved = _commonKey;
        let cmdId = "3030";
        let head = makeHeader("3030");
        let subCmdId = "15";
        let lockId = str2Hex(_lockId).PadRight(80, "0");
        let reqData = lockId;
        let reqDataLength = (reqData.length / 2).toString(16).PadLeft(2, "0");
        let dataModular = cmdId + subCmdId + reqDataLength + reqData;
        let dataModularLength = (dataModular.length / 2)
            .toString(16)
            .PadLeft(4, "0");
        let dataModularSM4 = sm4.sm4_enc(
            hexStr2Byte(dataModular),
            dataModular.length / 2,
            hexStr2Byte(_commonKey)
        );
        let dataModularSM4HexString = byte2HexStr(dataModularSM4);
        console.log(
            "dataModularSM4String---------------------" + dataModularSM4HexString
        );
        let dataModularSM4Length = (dataModularSM4HexString.length / 2)
            .toString(16)
            .PadLeft(4, "0");
        let resultData =
            head + dataModularSM4Length + dataModularLength + dataModularSM4HexString;
        console.log(
            "加密前:" + head + dataModularSM4Length + dataModularLength + dataModular
        );
        let crcData = crc
            .crc16kermit(hex2Ab(resultData))
            .toString(16)
            .PadLeft(4, "0");
        resultData += crcData;
        sendDataTolock(resultData);
        staticCallback = callback;
    }

    /**
     * 添加五组密钥
     * @param {门锁ID – 最多40字节} _lockId
     * @param {写入时间-8位timestamp字符串 eg: "00000000"} _writeTime
     * @param {是否写入通讯密钥('01':写入;'00':不写入)} _isComKey
     * @param {通讯密钥} _comKey
     * @param {是否写入园区密钥('01':写入;'00':不写入)} _isParkKey
     * @param {园区密钥} _parkKey
     * @param {是否写入楼号密钥('01':写入;'00':不写入)} _isTowerKey
     * @param {楼号密钥} _towerKey
     * @param {是否写入层号密钥('01':写入;'00':不写入)} _isFloorKey
     * @param {层号密钥} _floorKey
     * @param {是否写入同层区域密钥('01':写入;'00':不写入)} _isAreaKey
     * @param {同层区域密钥} _areaKey
     * @param {通信密钥} _commonKey
     */
    static addFiveKeys(
        _lockId,
        _writeTime,
        _isComKey,
        _comKey,
        _isParkKey,
        _parkKey,
        _isTowerKey,
        _towerKey,
        _isFloorKey,
        _floorKey,
        _isAreaKey,
        _areaKey,
        _commonKey,
        callback
    ) {
        encKeySaved = _commonKey;
        let cmdId = "3030";
        let head = makeHeader("3030");
        let subCmdId = "14";
        let lockId = str2Hex(_lockId).PadRight(80, "0");
        let comKey = _comKey.PadRight(32, "0");
        let parkKey = _parkKey.PadRight(32, "0");
        let towerKey = _towerKey.PadRight(32, "0");
        let floorKey = _floorKey.PadRight(32, "0");
        let areaKey = _areaKey.PadRight(32, "0");

        let reqData =
            lockId +
            _writeTime +
            _isComKey +
            comKey +
            _isParkKey +
            parkKey +
            _isTowerKey +
            towerKey +
            _isFloorKey +
            floorKey +
            _isAreaKey +
            areaKey;
        let reqDataLength = (reqData.length / 2).toString(16).PadLeft(2, "0");
        let dataModular = cmdId + subCmdId + reqDataLength + reqData;
        let dataModularLength = (dataModular.length / 2)
            .toString(16)
            .PadLeft(4, "0");
        let dataModularSM4 = sm4.sm4_enc(
            hexStr2Byte(dataModular),
            dataModular.length / 2,
            hexStr2Byte(_commonKey)
        );
        let dataModularSM4HexString = byte2HexStr(dataModularSM4);
        console.log(
            "dataModularSM4String---------------------" + dataModularSM4HexString
        );
        let dataModularSM4Length = (dataModularSM4HexString.length / 2)
            .toString(16)
            .PadLeft(4, "0");
        let resultData =
            head + dataModularSM4Length + dataModularLength + dataModularSM4HexString;
        console.log(
            "加密前:" + head + dataModularSM4Length + dataModularLength + dataModular
        );
        let crcData = crc
            .crc16kermit(hex2Ab(resultData))
            .toString(16)
            .PadLeft(4, "0");
        resultData += crcData;
        sendDataTolock(resultData);
        staticCallback = callback;
    }

    /**
     * NBIOT通道转发
     * @param {*} _nbIotCmd 
     * @param {*} _commonKey 
     */
    static nbIotTransmit(_nbIotCmd,_commonKey,callback) {
        encKeySaved = _commonKey
        let head = makeHeader('3095');
        let cmdId = "3095";
        let dataModular = cmdId + _nbIotCmd;
        let dataModularLength = (dataModular.length / 2).toString(16).PadLeft(4, '0');
        let dataModularSM4 = sm4.sm4_enc(hexStr2Byte(dataModular), dataModular.length / 2, hexStr2Byte(_commonKey));
        let dataModularSM4HexString = byte2HexStr(dataModularSM4);
        console.log('dataModularSM4String---------------------' + dataModularSM4HexString)
        let dataModularSM4Length = (dataModularSM4HexString.length / 2).toString(16).PadLeft(4, '0');
        let resultData = head + dataModularSM4Length + dataModularLength + dataModularSM4HexString;
        console.log('加密前:' + head + dataModularSM4Length + dataModularLength + dataModular)
        let crcData = (crc.crc16kermit(hexStr2Byte(resultData)).toString(16)).PadLeft(4, '0');
        resultData += crcData;
        sendDataTolock(resultData);
        staticCallback = callback;
    }
}

String.prototype.PadLeft = function (len, charStr) {
    var s = this + "";
    return new Array(len - s.length + 1).join(charStr, "") + s;
};

String.prototype.PadRight = function (len, charStr) {
    var s = this + "";
    return s + new Array(len - s.length + 1).join(charStr, "");
};

/**
 * String转16进制
 * @param {字符串} str
 */
function str2Hex(str) {
    var val = "";
    for (var i = 0; i < str.length; i++) {
        if (val == "") val = str.charCodeAt(i).toString(16);
        else val += str.charCodeAt(i).toString(16);
    }
    return val;
}

/**
 * 16进制转String
 */
function hexToString(hex) {
    var arr = hex.split("");
    var out = "";
    for (var i = 0; i < arr.length / 2; i++) {
        var tmp = "0x" + arr[i * 2] + arr[i * 2 + 1];
        var charValue = String.fromCharCode(tmp);
        out += charValue;
    }
    return out;
}

function ab2hex(buffer) {
    var hexArr = Array.prototype.map.call(new Uint8Array(buffer), function (bit) {
        return ("00" + bit.toString(16)).slice(-2);
    });
    return hexArr.join("");
}

function getIIData() {
    let ii = 0;
    for (let i = 0; i < 8; i++) {
        ii = 0x11 + i * i;
    }
    return ii;
}

//分包
function datasubpck(datahex) {
    var arrayObj = new Array();
    let dataPackageLength = packageSize
    console.log('分包大小', dataPackageLength)
    for (var i = 0; i < datahex.length; i += dataPackageLength) {
        // 预加 最大包长度,如果依然小于总数据长度,可以取最大包数据大小
        if (i + dataPackageLength < datahex.length) {
            arrayObj.push(datahex.substring(i, i + dataPackageLength));
        } else {
            arrayObj.push(datahex.substring(i));
        }
    }
    return arrayObj;
}

/**
 * 向锁端写入数据
 * @param {*} connectedDeviceId
 * @param {*} writeServicweId
 * @param {*} writeCharacteristicsId
 * @param {*} dataArray
 * @param {*} index
 */
var totalLength = 0;

function deviceWrite(
    connectedDeviceId,
    writeServicweId,
    writeCharacteristicsId,
    dataArray,
    index
) {
    totalLength = dataArray.length;
    var subhex = "";
    subhex = dataArray[index];
    index = index + 1;
    var bufferSuplied = hex2Ab(subhex);

    try {
        wx.writeBLECharacteristicValue({
            // 这里的 deviceId 需要在上面的 getBluetoothDevices 或 onBluetoothDeviceFound 接口中获取
            deviceId: connectedDeviceId,
            // 这里的 serviceId 需要在上面的 getBLEDeviceServices 接口中获取
            serviceId: writeServicweId,
            // 这里的 characteristicId 需要在上面的 getBLEDeviceCharacteristics 接口中获取
            characteristicId: writeCharacteristicsId,
            value: bufferSuplied,
            success: function (res) {
                //递归发送
                if (index < totalLength) {
                    deviceWrite(
                        connectedDeviceId,
                        writeServicweId,
                        writeCharacteristicsId,
                        dataArray,
                        index
                    );
                }
            },
            fail: function (res) {
                console.log("写入失败", res);
                //如果写入事变
                ICINLocker.connect(connectedDeviceId);
                throw new Error(res);
            },
        });
    } catch (e) {
        throw e;
    }
}

function calculateAuthKey(_superAdminId, _keyId, _userId, _signKey) {
    return ab2hex(
        md5.digest(hex2Ab(_superAdminId + _keyId + _userId + _signkey))
    );
}

/**
 * 向锁发送数据
 * @param {*} _hexData
 */
function sendDataTolock(_hexData) {
    var receData = "";

    wx.setStorage({
        data: receData,
        key: "receData",
    });
    var hex = _hexData;
    console.log("发送的指令" + hex);
    var connectedDeviceId = wx.getStorageSync("connectedDeviceId");
    var writeServicweId = wx.getStorageSync("writeServicweId");
    var writeCharacteristicsId = wx.getStorageSync("writeCharacteristicsId");
    var dataArray = datasubpck(hex);
    deviceWrite(
        connectedDeviceId,
        writeServicweId,
        writeCharacteristicsId,
        dataArray,
        0
    );
}

function makeHeader(type) {
    let normalHead = "EF01EE02";
    let headType = "01";
    let headNo = "0001";
    var headSta = "";
    if (type == "300a") {
        headSta = "10";
    } else if (type == "3093" || type == "3092" || type == "3094" || type == "3010" || type == "3011") {
        headSta = "12";
    } else {
        headSta = "13";
    }
    let result = normalHead + headType + headNo + headSta;
    return result;
}

function isLockID(value) {
    var rule = "^ICIN_[\\da-zA-Z]{12}$";
    var re = new RegExp(rule);
    if (re.test(value)) {
        return true;
    } else {
        return false;
    }
}

function str2Ascii(data) {
    var result = "";
    for (var i = data.length - 1; i >= 0; i--) {
        var str = data.charAt(i);
        var code = str.charCodeAt();
        result += code;
    }
    return result;
}

function hex2Ab(value) {
    var typedArray = new Uint8Array(
        value.match(/[\da-f]{2}/gi).map(function (h) {
            return parseInt(h, 16);
        })
    );
    return typedArray.buffer;
}

function hexStr2Byte(hexStr) {
    var pos = 0;
    var len = hexStr.length;
    if (len % 2 !== 0) {
        return null;
    }
    len /= 2;
    var hexA = [];
    for (var i = 0; i < len; i++) {
        var s = hexStr.substr(pos, 2);
        var v = parseInt(s, 16);
        hexA.push(v);
        pos += 2;
    }
    return hexA;
}

function ip2hex(_ip) {
    var REG =
        /^(\d{1,2}|1\d\d|2[0-4]\d|25[0-5])\.(\d{1,2}|1\d\d|2[0-4]\d|25[0-5])\.(\d{1,2}|1\d\d|2[0-4]\d|25[0-5])\.(\d{1,2}|1\d\d|2[0-4]\d|25[0-5])$/;
    var xH = "",
        result = REG.exec(_ip);
    if (!result) return -1;
    for (var i = 1; i <= 4; i++) {
        var h = parseInt(result[i]);
        xH += (h > 15 ? "" : "0") + h.toString(16);
    }
    return parseInt(xH, 16).toString();
}

function timeConvert(timestamp, num) {
    //num:0 YYYY-MM-DD  num:1  YYYY-MM-DD hh:mm:ss // timestamp:时间戳
    timestamp = timestamp + "";
    timestamp = timestamp * 1000;
    var date = new Date(timestamp);
    var y = date.getFullYear();
    var m = date.getMonth() + 1;
    m = m < 10 ? "0" + m : m;
    var d = date.getDate();
    d = d < 10 ? "0" + d : d;
    var h = date.getHours();
    h = h < 10 ? "0" + h : h;
    var minute = date.getMinutes();
    var second = date.getSeconds();
    minute = minute < 10 ? "0" + minute : minute;
    second = second < 10 ? "0" + second : second;
    if (num == 0) {
        return y + "-" + m + "-" + d;
    } else {
        return y + "-" + m + "-" + d + " " + h + ":" + minute + ":" + second;
    }
}

// 16进制数转10进制
var ex16hex = function (value) {
    value = stripscript(value);
    value = value.replace("0x", "");
    var arr = value.split("");
    arr = arr.reverse();
    var len = arr.length;
    var res = 0;
    $.each(arr, function (i, v) {
        var num = hex_change(v);
        console.log(num);
        res += muti16(num, i);
    });
    return res;
};

function hex2int(hex) {
    var len = hex.length,
        a = new Array(len),
        code;
    for (var i = 0; i < len; i++) {
        code = hex.charCodeAt(i);
        if (48 <= code && code < 58) {
            code -= 48;
        } else {
            code = (code & 0xdf) - 65 + 10;
        }
        a[i] = code;
    }
    return a.reduce(function (acc, c) {
        acc = 16 * acc + c;
        return acc;
    }, 0);
}

function byte2HexStr(byteArray) {
    if (byteArray) {
        var str = "";
        for (var i = 0; i < byteArray.length; i++) {
            var tmp = byteArray[i].toString(16);
            if (tmp.length === 1) {
                tmp = "0" + tmp;
            }
            str += tmp;
        }
        return str;
    } else {
        return null;
    }
}