Compare commits

..

10 Commits

9 changed files with 501 additions and 389 deletions

50
api.js
View File

@ -199,7 +199,6 @@ export function updateElecSettingRequest(data) {
} }
//冷水表-刷新水表数据 //冷水表-刷新水表数据
export function coldWaterRefreshWaterInfoRequest(data) { export function coldWaterRefreshWaterInfoRequest(data) {
return request({ return request({
@ -321,7 +320,6 @@ export function getIcCardListRequest(data) {
} }
/** /**
* 指纹-添加(永久/限时/单次/循环) * 指纹-添加(永久/限时/单次/循环)
* *
@ -636,7 +634,6 @@ export function getPalmVeinListRequest(data) {
} }
/** /**
* 遥控-添加(永久/限时/循环) * 遥控-添加(永久/限时/循环)
* *
@ -793,3 +790,50 @@ export function getUserLockListRequest(data) {
}) })
} }
/**
* 获取网关配置
* @returns {Promise<unknown>}
*/
export function getGatewayConfig(data) {
return request({
url: '/v1/gateway/getGatewayConfig',
method: 'POST',
data
})
}
/**
* 获取设备配网信息
* @param data.deviceType 设备类型1-wifi网关 2-wifi锁
* @param data.deviceMac 网关/锁MAC地址
* @returns {Promise<unknown>}
*/
export function getDeviceNetworkInfo(data) {
return request({
url: '/v1/deviceNetwork/getNetworkInfo',
method: 'POST',
data
})
}
/**
* 更新设备配网信息
* @param data.deviceType 设备类型1-wifi网关 2-wifi锁
* @param data.deviceMac 网关/锁MAC地址
* @param data.wifiName wifi名称
* @param data.networkMac 网络mac地址
* @param data.secretKey secretKey
* @param data.peerId 设备peerId
* @returns {Promise<unknown>}
*/
export function updateDeviceNetworkInfo(data) {
return request({
url: '/v1/deviceNetwork/setting',
method: 'POST',
data
})
}

View File

@ -3,7 +3,7 @@ import {
arrayToTimestamp, arrayToTimestamp,
convertWeekdaysToNumber, convertWeekdaysToNumber,
createPackageEnd, createPackageEnd,
md5Encrypt, parseWifiList, md5Encrypt, parseNetworkJsonFromDecrypted, parseWifiList,
removeTrailingZeros, removeTrailingZeros,
timestampToArray, timestampToArray,
uint8ArrayToString uint8ArrayToString
@ -30,7 +30,7 @@ import {
getLastRecordTimeRequest, getLastRecordTimeRequest,
getLockNetTokenRequest, getLockNetTokenRequest,
getStarCloudToken, getStarCloudToken,
getUserNoListRequest, getUserNoListRequest, updateDeviceNetworkInfo,
updateElectricQuantityRequest, updateElectricQuantityRequest,
updateFaceRequest, updateFaceRequest,
updateFingerprintRequest, updateFingerprintRequest,
@ -1020,7 +1020,7 @@ export async function parsingCharacteristicValue(binaryData) {
cardRight: this.requestParams.isAdmin, cardRight: this.requestParams.isAdmin,
lockId: this.lockInfo.lockId, lockId: this.lockInfo.lockId,
cardNumber: decrypted[6] * 256 + decrypted[7], cardNumber: decrypted[6] * 256 + decrypted[7],
cardUserNo: this.requestParams.cardUserNo cardUserNo: decrypted[6] * 256 + decrypted[7]
}) })
if (addResult.code === Result.Success.code) { if (addResult.code === Result.Success.code) {
// 增加返回一个卡序号 // 增加返回一个卡序号
@ -1106,7 +1106,7 @@ export async function parsingCharacteristicValue(binaryData) {
fingerRight: this.requestParams.isAdmin, fingerRight: this.requestParams.isAdmin,
lockId: this.lockInfo.lockId, lockId: this.lockInfo.lockId,
fingerprintNumber: decrypted[6] * 256 + decrypted[7], fingerprintNumber: decrypted[6] * 256 + decrypted[7],
fingerprintUserNo: this.requestParams.fingerprintUserNo fingerprintUserNo: decrypted[6] * 256 + decrypted[7]
}) })
if (addResult.code === Result.Success.code) { if (addResult.code === Result.Success.code) {
// 增加返回一个指纹序号 // 增加返回一个指纹序号
@ -1191,7 +1191,7 @@ export async function parsingCharacteristicValue(binaryData) {
fingerRight: this.requestParams.isAdmin, fingerRight: this.requestParams.isAdmin,
lockId: this.lockInfo.lockId, lockId: this.lockInfo.lockId,
faceNumber: decrypted[6] * 256 + decrypted[7], faceNumber: decrypted[6] * 256 + decrypted[7],
faceUserNo: this.requestParams.faceUserNo faceUserNo: decrypted[6] * 256 + decrypted[7]
}) })
if (addResult.code === Result.Success.code) { if (addResult.code === Result.Success.code) {
// 增加返回一个序号 // 增加返回一个序号
@ -1268,7 +1268,7 @@ export async function parsingCharacteristicValue(binaryData) {
palmVeinRight: this.requestParams.isAdmin, palmVeinRight: this.requestParams.isAdmin,
lockId: this.lockInfo.lockId, lockId: this.lockInfo.lockId,
palmVeinNumber: decrypted[6] * 256 + decrypted[7], palmVeinNumber: decrypted[6] * 256 + decrypted[7],
palmVeinUserNo: this.requestParams.palmVeinUserNo palmVeinUserNo: decrypted[6] * 256 + decrypted[7]
}) })
if (addResult.code === Result.Success.code) { if (addResult.code === Result.Success.code) {
// 增加返回一个卡序号 // 增加返回一个卡序号
@ -1343,7 +1343,7 @@ export async function parsingCharacteristicValue(binaryData) {
remoteRight: this.requestParams.isAdmin, remoteRight: this.requestParams.isAdmin,
lockId: this.lockInfo.lockId, lockId: this.lockInfo.lockId,
remoteNumber: decrypted[6] * 256 + decrypted[7], remoteNumber: decrypted[6] * 256 + decrypted[7],
remoteUserNo: this.requestParams.remoteUserNo remoteUserNo: decrypted[6] * 256 + decrypted[7]
}) })
if (addResult.code === Result.Success.code) { if (addResult.code === Result.Success.code) {
// 增加返回一个卡序号 // 增加返回一个卡序号
@ -1494,7 +1494,27 @@ export async function parsingCharacteristicValue(binaryData) {
break; break;
case cmdIds.configureNetworkResult: case cmdIds.configureNetworkResult:
if (decrypted[2] === Result.Success.code) { if (decrypted[2] === Result.Success.code) {
// 提取配网信息
const {
peerId,
wifiName,
secretKey,
deviceMac,
networkMac
} = parseNetworkJsonFromDecrypted(decrypted);
const {code, message} = await updateDeviceNetworkInfo({
deviceType: 2, // 1-wifi网关 2-wifi锁
deviceMac: deviceMac || this.lockInfo.mac,
wifiName: wifiName || this.requestParams.wifiName,
networkMac: networkMac || this.requestParams.wifiName,
secretKey,
peerId
});
if (code === Result.Success.code) {
this.characteristicValueCallback(new Result(decrypted[2], null, "配网成功")) this.characteristicValueCallback(new Result(decrypted[2], null, "配网成功"))
} else {
this.characteristicValueCallback(code, null, message);
}
} else { } else {
this.characteristicValueCallback(new Result(decrypted[2], null, "配网失败")) this.characteristicValueCallback(new Result(decrypted[2], null, "配网失败"))
} }

4
env.js
View File

@ -1,7 +1,7 @@
// uni版本号 // uni版本号
export const uniVersion = '1.0.18' export const uniVersion = '1.0.23'
// uni构建号 // uni构建号
export const uniBuildNumber = 19 export const uniBuildNumber = 24
// web版本号 // web版本号
export const webVersion = '1.0.1' export const webVersion = '1.0.1'

View File

@ -218,3 +218,45 @@ function _bytesToString(bytes) {
} }
return str; return str;
} }
// 解析decrypted中的json数据返回对象
export function parseNetworkJsonFromDecrypted(decrypted) {
let peerId, wifiName, secretKey, deviceMac, networkMac;
try {
const secretKeyJsonLength = (decrypted[4] << 8) + decrypted[3];
const secretKeyList = decrypted.slice(5, 5 + secretKeyJsonLength);
let result;
if (typeof TextDecoder !== 'undefined') {
result = new TextDecoder('utf-8').decode(secretKeyList);
} else {
// 兼容性处理
result = uint8ArrayToString(secretKeyList);
}
const jsonMap = JSON.parse(result);
peerId = jsonMap.peerId;
wifiName = jsonMap.wifiName;
secretKey = jsonMap.secretKey;
deviceMac = jsonMap.deviceMac;
networkMac = jsonMap.networkMac;
console.log('解析配网信息:', jsonMap);
} catch (e) {
console.error('解析配网信息失败:', e);
}
return { peerId, wifiName, secretKey, deviceMac, networkMac };
}
/**
* 生成随机长度字符串
* @param length
* @returns {string}
*/
export function generateRandomString(length) {
const chars = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789';
let result = '';
for (let i = 0; i < length; i++) {
result += chars[Math.floor(Math.random() * chars.length)];
}
return result;
}

View File

@ -1,6 +1,6 @@
{ {
"name": "star-cloud-uni", "name": "star-cloud-uni",
"version": "1.0.18", "version": "1.0.23",
"type": "module", "type": "module",
"main": "./uni/index.js", "main": "./uni/index.js",
"author": "zzc059", "author": "zzc059",

View File

@ -1,9 +1,10 @@
import { import {
checkRequiredFields, checkRequiredFields,
createPackageEnd, createPackageEnd, generateRandomString,
} from "../format.js"; } from "../format.js";
import {cmdIds, Result} from "../constant.js"; import {cmdIds, Result} from "../constant.js";
import {searchAndConnectDevice, writeBLECharacteristicValue} from "../uni/basic.js"; import {searchAndConnectDevice, writeBLECharacteristicValue} from "../uni/basic.js";
import {getDeviceNetworkInfo, getGatewayConfig} from "../api.js";
/** /**
* 开始搜索wifi * 开始搜索wifi
@ -66,32 +67,39 @@ export async function startSearchWiFi(params = {}) {
* @returns {Promise<unknown>} * @returns {Promise<unknown>}
*/ */
export async function connectWiFi(params) { export async function connectWiFi(params) {
const cardRequiredFields = ['ssid', 'password']; const cardRequiredFields = ['ssid', 'password', 'clientId', 'starLockPeerId'];
const missingField = checkRequiredFields(params, cardRequiredFields); const missingField = checkRequiredFields(params, cardRequiredFields);
if (missingField) { if (missingField) {
return new Result(Result.codes.NotMoreData, null, `参数信息不完整: ${missingField}`); return new Result(Result.codes.NotMoreData, null, `参数信息不完整: ${missingField}`);
} }
// 获取网关配置
const config = await getGatewayConfig();
if (config.code !== Result.Success.code) {
return new Result(Result.codes.Fail, null, `获取网关配置失败: ${config.message}`);
}
const clientId = params.clientId;
const starLockPeerId = params.starLockPeerId;
let { let {
ssid, ssid,
password, password,
configureJson = JSON.stringify({ configureJson = JSON.stringify({
starcloudRpcPeerId: "6HnEcGnXMUcLQoE7rnC4aXMVJmojMnKAjqKHrt4TmN1U", starcloudRpcPeerId: config.data.starcloudRpcPeerId,
starcloudReportPeerId: "G3ehYz8djE35CTE2LWn5xe2nD51UpjC4hWd3vqVmXViE", starcloudReportPeerId: config.data.starcloudReportPeerId,
starcloudUrl: "http://cloud.skychip.top", starcloudUrl: config.data.starcloudUrl,
userPeerId: "C2HjHNy9LsjxW2QEmceiNDTN6XSXFDUZ3fYsnBigVQXA", userPeerId: config.data.userPeerId,
scdUrl: "http://scd.skychip.top:8710", scdUrl: config.data.scdUrl,
starlockPeerId: "0b3bd6327daafe2da24fdd0cae76c71477f32e3ef8ab", starlockPeerId: starLockPeerId,
clientId: "sBfWAwdMqVKIMBj4dPuRextHViC266aE", clientId: clientId,
secretKey: "zNn1AluC6sTVAtA4dX", secretKey: generateRandomString(18),
userPeerld: "zC2HjHNy9LsjxW2QEmceiNDTN6XSXFDUZ3fYsnBigVQX"
}) })
} = params } = params
const uid = this.accountInfo.uid.toString() const uid = this.accountInfo.uid.toString()
// 设置执行账号 // 设置执行账号
const result = await this.login(params.uid) const result = await this.login(uid)
if (result.code !== Result.Success.code) { if (result.code !== Result.Success.code) {
return result return result
} }
@ -169,3 +177,29 @@ export async function connectWiFi(params) {
} }
return this.getWriteResult(this.connectWiFi, params) return this.getWriteResult(this.connectWiFi, params)
} }
/**
* 获取锁配网信息
* @param params
* @param {Number} params.uid uid
* @param {Number} params.deviceMac 锁mac地址
* @returns {Promise<void>}
*/
export async function getLockNetworkInfo(params) {
const cardRequiredFields = ['uid', 'deviceMac'];
const missingField = checkRequiredFields(params, cardRequiredFields);
if (missingField) {
return new Result(Result.codes.NotMoreData, null, `参数信息不完整: ${missingField}`);
}
// 设置执行账号
const result = await this.login(params.uid)
if (result.code !== Result.Success.code) {
return result
}
return await getDeviceNetworkInfo({
deviceType: 2,
deviceMac: params.deviceMac,
})
}

View File

@ -66,6 +66,9 @@ export async function selectLock(params) {
*/ */
export async function openDoor(params) { export async function openDoor(params) {
const {type} = params const {type} = params
// ⏱️ 记录开始时间
const startTime = Date.now();
log.info({ log.info({
...new Result( ...new Result(
Result.Success.code, Result.Success.code,
@ -102,7 +105,8 @@ export async function openDoor(params) {
// 确认设备连接正常 // 确认设备连接正常
if (!params.connected) { if (!params.connected) {
const searchResult = await searchAndConnectDevice(this.lockInfo.bluetooth.bluetoothDeviceName) const searchResult = await searchAndConnectDevice(this.lockInfo.bluetooth.bluetoothDeviceName, true, this.lockInfo.bluetooth.bluetoothDeviceId)
log.info({ log.info({
...new Result( ...new Result(
searchResult.code, searchResult.code,
@ -266,8 +270,16 @@ export async function openDoor(params) {
), ),
name: 'openDoor' name: 'openDoor'
}) })
// 获取最终结果
const finalResult = this.getWriteResult(this.openDoor, params);
return this.getWriteResult(this.openDoor, params) // ⏱️ 计算耗时
const endTime = Date.now();
const duration = endTime - startTime;
console.log(`开门耗时:${duration}`)
return finalResult;
} }
/** /**
@ -373,10 +385,16 @@ export async function getLockSupportFeatures(params) {
/** /**
* 远程开锁 * 远程开锁
* @param params * @param params
* @param {Number} params.uid uid
* @param {Number} params.lockId Id * @param {Number} params.lockId Id
* @returns {Promise<void>} * @returns {Promise<void>}
*/ */
export async function remoteUnLock(params) { export async function remoteUnLock(params) {
const cardRequiredFields = ['uid', 'lockId'];
const missingField = checkRequiredFields(params, cardRequiredFields);
if (missingField) {
return new Result(Result.codes.NotMoreData, null, `参数信息不完整: ${missingField}`);
}
// 设置执行账号 // 设置执行账号
const result = await this.login(params.uid) const result = await this.login(params.uid)
if (result.code !== Result.Success.code) { if (result.code !== Result.Success.code) {
@ -403,55 +421,5 @@ export async function getLockList(params) {
} }
/**
* 搜索wifi列表
* @param params
* @returns {Promise<void>}
*/
export async function searchWifiList(params) {
// 需要校验的参数
const baseRequiredFields = [
'uid',
];
const missingField = checkRequiredFields(params, baseRequiredFields);
if (missingField) {
return new Result(Result.NotMoreData, null, `参数信息不完整: ${missingField}`);
}
// 确认设备连接正常
if (!params.connected) {
const searchResult = await searchAndConnectDevice(this.lockInfo.bluetooth.bluetoothDeviceName)
if (searchResult.code !== Result.Success.code) {
return searchResult
}
this.updateLockInfo(searchResult.data)
}
const {uid} = params
const length = 2 + 20
const headArray = this.createPackageHeader(3, length)
const contentArray = new Uint8Array(length)
contentArray[0] = cmdIds.getWifiList / 256
contentArray[1] = cmdIds.getWifiList % 256
for (let i = 0; i < uid.length; i++) {
contentArray[i + 2] = uid.charCodeAt(i)
}
console.log('加密前:', Array.from(contentArray))
const cebArray = sm4.encrypt(contentArray, this.lockInfo.bluetooth.privateKey, {
mode: 'ecb',
output: 'array'
})
const packageArray = createPackageEnd(headArray, cebArray)
await writeBLECharacteristicValue(this.lockInfo.deviceId,
this.lockInfo.serviceId,
this.lockInfo.writeCharacteristicId,
packageArray)
return this.getWriteResult(this.searchWifiList, params)
}

View File

@ -8,13 +8,18 @@ import {Result} from '../constant'
*/ */
// 查找设备并连接 // 查找设备并连接
export function searchAndConnectDevice(name, reset = true) { export function searchAndConnectDevice(name, reset = true, deviceId = null) {
// 循环查找设备 // 循环查找设备
let timer let timer
// 超时计时器 // 超时计时器
let timeoutTimer let timeoutTimer
return new Promise(async resolve => { return new Promise(async resolve => {
// 如果提供了deviceId则直接连接
if (deviceId) {
const connectResult = await createBLEConnection(deviceId)
resolve(connectResult)
}
const result = await startBluetoothDevicesDiscovery() const result = await startBluetoothDevicesDiscovery()
if (result.code === Result.Success.code) { if (result.code === Result.Success.code) {
let searchFlag = false let searchFlag = false
@ -189,28 +194,16 @@ export function createBLEConnection(deviceId, reconnectNumber = 0) {
res.data.serviceId, res.data.serviceId,
res.data.notifyCharacteristicId res.data.notifyCharacteristicId
) )
// 使用同步方法获取系统信息
const systemInfo = uni.getSystemInfoSync();
if (systemInfo.platform === 'android') {
// 如果是Android机型则设置BLE MTU
uni.setBLEMTU({
deviceId: deviceId,
mtu: 512,
fail: res => {
// console.log('mtu fail', res);
},
success: res => {
// console.log('mtu success', res);
}
});
} else {
// 对于非Android设备可以在这里添加其他逻辑或者直接忽略
// console.log('当前设备不是Android跳过设置BLE MTU');
}
resolve(res) resolve(res)
}, },
async fail(err) { async fail(err) {
if (err.errno === 1500101) {
// 未初始化,初始化成功后在重连
const result = await openBluetoothAdapter()
if (result.code === Result.Success.code) {
resolve(await createBLEConnection(deviceId, reconnectNumber + 1))
}
}
if (err.errno === 1509007) { if (err.errno === 1509007) {
const res = await getBLEDeviceServicesAndCharacteristics(deviceId) const res = await getBLEDeviceServicesAndCharacteristics(deviceId)
await notifyBLECharacteristicValueChange( await notifyBLECharacteristicValueChange(

View File

@ -434,3 +434,14 @@ export const startSearchWiFi = async params => {
export const connectWiFi = async params => { export const connectWiFi = async params => {
return await starCloudInstance.connectWiFi(params) return await starCloudInstance.connectWiFi(params)
} }
/**
* 获取设备配网信息
* @param params.uid uid
* @param params.deviceMac 锁mac地址
* @returns {Promise<*>}
*/
export const getLockNetworkInfo = async params => {
return await starCloudInstance.getLockNetworkInfo(params)
}