Merge branch 'dev-V0.4.5' of https://gitee.com/iotkit-open-source/iotkit-parent into dev-V0.4.5

V0.5.x
荭琪枫 2023-07-18 00:03:07 +08:00
commit 9952f85374
9 changed files with 987 additions and 10 deletions

View File

@ -0,0 +1,322 @@
!function (n) {
"use strict";
function d(n, t) {
var r = (65535 & n) + (65535 & t);
return (n >> 16) + (t >> 16) + (r >> 16) << 16 | 65535 & r
}
function f(n, t, r, e, o, u) {
return d((u = d(d(t, n), d(e, u))) << o | u >>> 32 - o, r)
}
function l(n, t, r, e, o, u, c) {
return f(t & r | ~t & e, n, t, o, u, c)
}
function g(n, t, r, e, o, u, c) {
return f(t & e | r & ~e, n, t, o, u, c)
}
function v(n, t, r, e, o, u, c) {
return f(t ^ r ^ e, n, t, o, u, c)
}
function m(n, t, r, e, o, u, c) {
return f(r ^ (t | ~e), n, t, o, u, c)
}
function c(n, t) {
var r, e, o, u;
n[t >> 5] |= 128 << t % 32, n[14 + (t + 64 >>> 9 << 4)] = t;
for (var c = 1732584193, f = -271733879, i = -1732584194, a = 271733878, h = 0; h < n.length; h += 16) c = l(r = c, e = f, o = i, u = a, n[h], 7, -680876936), a = l(a, c, f, i, n[h + 1], 12, -389564586), i = l(i, a, c, f, n[h + 2], 17, 606105819), f = l(f, i, a, c, n[h + 3], 22, -1044525330), c = l(c, f, i, a, n[h + 4], 7, -176418897), a = l(a, c, f, i, n[h + 5], 12, 1200080426), i = l(i, a, c, f, n[h + 6], 17, -1473231341), f = l(f, i, a, c, n[h + 7], 22, -45705983), c = l(c, f, i, a, n[h + 8], 7, 1770035416), a = l(a, c, f, i, n[h + 9], 12, -1958414417), i = l(i, a, c, f, n[h + 10], 17, -42063), f = l(f, i, a, c, n[h + 11], 22, -1990404162), c = l(c, f, i, a, n[h + 12], 7, 1804603682), a = l(a, c, f, i, n[h + 13], 12, -40341101), i = l(i, a, c, f, n[h + 14], 17, -1502002290), c = g(c, f = l(f, i, a, c, n[h + 15], 22, 1236535329), i, a, n[h + 1], 5, -165796510), a = g(a, c, f, i, n[h + 6], 9, -1069501632), i = g(i, a, c, f, n[h + 11], 14, 643717713), f = g(f, i, a, c, n[h], 20, -373897302), c = g(c, f, i, a, n[h + 5], 5, -701558691), a = g(a, c, f, i, n[h + 10], 9, 38016083), i = g(i, a, c, f, n[h + 15], 14, -660478335), f = g(f, i, a, c, n[h + 4], 20, -405537848), c = g(c, f, i, a, n[h + 9], 5, 568446438), a = g(a, c, f, i, n[h + 14], 9, -1019803690), i = g(i, a, c, f, n[h + 3], 14, -187363961), f = g(f, i, a, c, n[h + 8], 20, 1163531501), c = g(c, f, i, a, n[h + 13], 5, -1444681467), a = g(a, c, f, i, n[h + 2], 9, -51403784), i = g(i, a, c, f, n[h + 7], 14, 1735328473), c = v(c, f = g(f, i, a, c, n[h + 12], 20, -1926607734), i, a, n[h + 5], 4, -378558), a = v(a, c, f, i, n[h + 8], 11, -2022574463), i = v(i, a, c, f, n[h + 11], 16, 1839030562), f = v(f, i, a, c, n[h + 14], 23, -35309556), c = v(c, f, i, a, n[h + 1], 4, -1530992060), a = v(a, c, f, i, n[h + 4], 11, 1272893353), i = v(i, a, c, f, n[h + 7], 16, -155497632), f = v(f, i, a, c, n[h + 10], 23, -1094730640), c = v(c, f, i, a, n[h + 13], 4, 681279174), a = v(a, c, f, i, n[h], 11, -358537222), i = v(i, a, c, f, n[h + 3], 16, -722521979), f = v(f, i, a, c, n[h + 6], 23, 76029189), c = v(c, f, i, a, n[h + 9], 4, -640364487), a = v(a, c, f, i, n[h + 12], 11, -421815835), i = v(i, a, c, f, n[h + 15], 16, 530742520), c = m(c, f = v(f, i, a, c, n[h + 2], 23, -995338651), i, a, n[h], 6, -198630844), a = m(a, c, f, i, n[h + 7], 10, 1126891415), i = m(i, a, c, f, n[h + 14], 15, -1416354905), f = m(f, i, a, c, n[h + 5], 21, -57434055), c = m(c, f, i, a, n[h + 12], 6, 1700485571), a = m(a, c, f, i, n[h + 3], 10, -1894986606), i = m(i, a, c, f, n[h + 10], 15, -1051523), f = m(f, i, a, c, n[h + 1], 21, -2054922799), c = m(c, f, i, a, n[h + 8], 6, 1873313359), a = m(a, c, f, i, n[h + 15], 10, -30611744), i = m(i, a, c, f, n[h + 6], 15, -1560198380), f = m(f, i, a, c, n[h + 13], 21, 1309151649), c = m(c, f, i, a, n[h + 4], 6, -145523070), a = m(a, c, f, i, n[h + 11], 10, -1120210379), i = m(i, a, c, f, n[h + 2], 15, 718787259), f = m(f, i, a, c, n[h + 9], 21, -343485551), c = d(c, r), f = d(f, e), i = d(i, o), a = d(a, u);
return [c, f, i, a]
}
function i(n) {
for (var t = "", r = 32 * n.length, e = 0; e < r; e += 8) t += String.fromCharCode(n[e >> 5] >>> e % 32 & 255);
return t
}
function a(n) {
var t = [];
for (t[(n.length >> 2) - 1] = void 0, e = 0; e < t.length; e += 1) t[e] = 0;
for (var r = 8 * n.length, e = 0; e < r; e += 8) t[e >> 5] |= (255 & n.charCodeAt(e / 8)) << e % 32;
return t
}
function e(n) {
for (var t, r = "0123456789abcdef", e = "", o = 0; o < n.length; o += 1) t = n.charCodeAt(o), e += r.charAt(t >>> 4 & 15) + r.charAt(15 & t);
return e
}
function r(n) {
return unescape(encodeURIComponent(n))
}
function o(n) {
return i(c(a(n = r(n)), 8 * n.length))
}
function u(n, t) {
return function (n, t) {
var r, e = a(n), o = [], u = [];
for (o[15] = u[15] = void 0, 16 < e.length && (e = c(e, 8 * n.length)), r = 0; r < 16; r += 1) o[r] = 909522486 ^ e[r], u[r] = 1549556828 ^ e[r];
return t = c(o.concat(a(t)), 512 + 8 * t.length), i(c(u.concat(t), 640))
}(r(n), r(t))
}
function t(n, t, r) {
return t ? r ? u(t, n) : e(u(t, n)) : r ? o(n) : e(o(n))
}
"function" == typeof define && define.amd ? define(function () {
return t
}) : "object" == typeof module && module.exports ? module.exports = t : n.md5 = t
}(this);
var md5 = this.md5;
/**
网关上线
订阅/sys/hbtgIA0SuVw9lxjB/AA:BB:CC:DD:10/c/#
子设备注册
/sys/hbtgIA0SuVw9lxjB/AA:BB:CC:DD:10/s/register
{
"id": "6",
"params":{
"productKey":"Rf4QSjbm65X45753",
"deviceName":"ABC12400001",
"model":"S1"
}
}
子设备上线
订阅/sys/Rf4QSjbm65X45753/ABC12400001/c/#
数据上报
/sys/Rf4QSjbm65X45753/ABC12400001/s/event/property/post
{
"id": "6",
"params":{
"powerstate": 1
}
}
*/
var registered = {};
function getPkDn(clientId) {
var arr = clientId.split("_");
return {
pk: arr[0],
dn: arr[1]
};
}
function register(payload) {
var auth = JSON.parse(payload);
var arr = auth.clientid.split("_");
if (arr.length < 3) {
throw new Error("incorrect clientid");
}
var pk = arr[0];
var dn = arr[1];
var model = arr[2];
var product = deviceBehaviour.getProductKey(pk)
var pwd = md5(product.getProductSecret() + auth.clientid);
if (pwd.toLocaleLowerCase() != auth.password.toLocaleLowerCase()) {
throw new Error("incorrect password" + "pwd->" + pwd + " productSecret->" + product.productSecret);
}
return {
type: "register",
data: {
productKey: pk,
deviceName: dn,
model: model
}
};
}
function subRegister(topic, parent, payload) {
var params = payload.params;
var reply =
{
productKey: parent.productKey,
deviceName: parent.deviceName,
mid: "0",
content: {
topic: topic.replace("/s/", "/c/") + "_reply",
payload: JSON.stringify({
id: "0",
code: 0,
data: {
"productKey": params.productKey,
"deviceName": params.deviceName
}
})
}
};
return {
type: "register",
data: {
productKey: parent.productKey,
deviceName: parent.deviceName,
subDevices: [{
productKey: params.productKey,
deviceName: params.deviceName,
model: params.model
}]
},
action: {
type: "ack",
content: JSON.stringify(reply)
}
};
}
function deviceStateChange(head, clientId, state) {
var topic = head.topic;
var device = getPkDn(clientId);
var arr = topic.split('/');
if (arr.length < 6) {
throw new Error("incorrect topic")
}
var pk = arr[2];
var dn = arr[3];
return {
type: "state",
data: {
productKey: pk,
deviceName: dn,
state: state,
parent: {
productKey: device.pk,
deviceName: device.dn,
}
}
}
}
function disconnect(clientId) {
var device = getPkDn(clientId);
return {
type: "state",
data: {
productKey: device.pk,
deviceName: device.dn,
state: "offline"
}
}
}
function ota(head, payload) {
payload = JSON.parse(payload);
var topic = head.topic;
var arr = topic.split('/');
if (arr.length < 6) {
throw new Error("incorrect topic")
}
var pk = arr[2];
var dn = arr[3];
return {
type: "ota",
data: {
productKey: pk,
deviceName: dn,
mid: payload.id,
content: {
topic: topic,
payload: payload
}
}
}
}
//必须提供onReceive方法
this.onReceive = function (head, type, payload) {
if (type == 'auth') {
return register(payload);
}
if (type == 'subscribe') {
return deviceStateChange(head, payload, 'online');
}
if (type == 'unsubscribe') {
return deviceStateChange(head, payload, 'offline');
}
if (type == 'disconnect') {
return disconnect(payload);
}
if (type == 'ota') {
return ota(head, payload);
}
var topic = head['topic'];
if (!topic) {
throw new Error("topic is blank")
}
var arr = topic.split('/');
if (arr.length < 6) {
throw new Error("incorrect topic")
}
var pk = arr[2];
var dn = arr[3];
payload = JSON.parse(payload);
//子设备注册
if (topic.endsWith('/register')) {
return subRegister(topic, {productKey: pk, deviceName: dn}, payload);
}
//数据上报
var reply =
{
productKey: pk,
deviceName: dn,
mid: payload.id,
content: {
topic: topic.replace("/s/", "/c/") + "_reply",
payload: JSON.stringify({
id: payload.id,
method: payload.method + "_reply",
code: 0,
})
}
};
var action = {};
if (!topic.endsWith("_reply")) {
//需要回复的消息
action = {
type: "ack",
content: JSON.stringify(reply)
}
}
return {
type: "report",
data: {
productKey: pk,
deviceName: dn,
mid: payload.id,
content: {
topic: topic,
payload: payload
}
},
action: action
}
}
this.onRegistered = function (regInfo, result) {
}

View File

@ -0,0 +1,601 @@
var mid = 1;
function getMid() {
mid++;
if (mid > 10000) {
mid = 1;
}
return mid + "";
}
//上行数据
this.decode = function (msg) {
var content = msg.content;
var topic = content.topic;
var bytes = CRC.strToByte(content.payload);
if (topic.endsWith("/thing/model/up_raw")) {
var byteData = ab2hex(bytes)
var data = arrayGroup(byteData, 2);
var params = {};
var uint8Array = new Uint8Array(bytes.length);
for (var i = 0; i < bytes.length; i++) {
uint8Array[i] = bytes[i] & 0xff;
}
if (data[1] == '03') {
if (byteData.length == 22 ) {
params['Switch'] = Number(parseInt(data[3] + data[4], 16))
params['HandMode'] = Number(parseInt(data[5] + data[6], 16))+1
params['TempGear'] = Number(data[7].slice(1,2))+1
params['RatioGear'] = Number(data[7].slice(0,1))+1
params['PressureGear'] = data[8].slice(0,1) != 'f' ? Number(data[8].slice(0,1))+1 : 0
params['SpeedGear'] = data[8].slice(1,2) != 'f' ? Number(data[8].slice(1,2))+1 : 0
} else if (byteData.length == 126) {
params['Pressure'] = Number((parseInt(data[3] + data[4], 16) / 100).toFixed(1))
params['EmtyRunPressure'] = Number((parseInt(data[5] + data[6], 16) / 100).toFixed(1))
params['StartPressure'] = Number((parseInt(data[7] + data[8], 16) / 100).toFixed(1))
params['WorkMode'] = Number((parseInt(data[9] + data[10], 16)).toFixed(0))
params['ClearIceEn'] = Number((parseInt(data[11] + data[12], 16)).toFixed(0))
params['WaterT'] = Number((parseInt(data[13] + data[14], 16)).toFixed(0))
params['WaterTReset'] = Number((parseInt(data[15] + data[16], 16)).toFixed(0))
params['SensorMode'] = Number((parseInt(data[17] + data[18], 16)).toFixed(0))
params['SensorGroup'] = Number((parseInt(data[19] + data[20], 16)).toFixed(0))
params['ElectronicTMax'] = Number(parseInt(data[59], 16))
params['ElectronicTMaxReset'] = Number(parseInt(data[60], 16))
} else if (byteData.length == 26) {
params['ActiveTime'] = String(parseInt(data[3], 16))+'-'+String(parseInt(data[4], 16))+'-'+String(parseInt(data[5], 16))
} else if (byteData.length == 190) {
params['Pressure'] = Number((parseInt(data[3] + data[4], 16) / 100).toFixed(1))
params['EmtyRunPressure'] = Number((parseInt(data[5] + data[6], 16) / 100).toFixed(1))
params['StartPressure'] = Number((parseInt(data[7] + data[8], 16) / 100).toFixed(1))
params['WorkMode'] = Number((parseInt(data[9] + data[10], 16)).toFixed(0))
params['ClearIceEn'] = Number((parseInt(data[11] + data[12], 16)).toFixed(0))
params['WaterT'] = Number((parseInt(data[13] + data[14], 16)).toFixed(0))
params['WaterTReset'] = Number((parseInt(data[15] + data[16], 16)).toFixed(0))
params['SensorMode'] = Number((parseInt(data[17] + data[18], 16)).toFixed(0))
params['SensorGroup'] = Number((parseInt(data[19] + data[20], 16)).toFixed(0))
params['ElectronicTMax'] = Number(parseInt(data[59], 16))
params['ElectronicTMaxReset'] = Number(parseInt(data[60], 16))
params['SceneMode'] = Number((parseInt(data[63] + data[64], 16)).toFixed(0))
params['EnergyModeTime'] = Number((parseInt(data[65] + data[66], 16)).toFixed(0))
params['WaterTime'] = String(Number((parseInt(data[68].substring(0, 1), 16)).toFixed(0))) + ',' + String(Number((parseInt(data[68].substring(1), 16)).toFixed(0)))
params['HotWaterTime'] = Number((parseInt(data[69] + data[70], 16)).toFixed(0))
params['TempSet'] = String(Number((parseInt(data[71], 16)).toFixed(0)))+','+ String(Number((parseInt(data[72], 16)).toFixed(0)))
params['TimeModeSet'] = parseInt(data[73] + data[74], 16)+'-'+parseInt(data[75] + data[76], 16)+','+ parseInt(data[77] + data[78], 16)+'-'+parseInt(data[79] + data[80], 16)+','+ parseInt(data[81] + data[82], 16)+'-'+parseInt(data[83] + data[84], 16)+','+ parseInt(data[85] + data[86], 16)+'-'+parseInt(data[87] + data[88], 16)+','+ parseInt(data[89] + data[90], 16)+'-'+parseInt(data[91] + data[92], 16)
} else if (byteData.length == 94) {
let timeStamp = parseInt(String(data[41])+String(data[42])+String(data[43])+String(data[44]),16)
let time = timestampToTime(timeStamp)
params['ActiveTime'] = String(parseInt(data[3], 16))+'-'+String(parseInt(data[4], 16))+'-'+String(parseInt(data[5], 16))
params['Time'] = time + '-'+ timeStamp
}
} else if (data[1] == '04') {
if (byteData.length == 54) {
params['ErrorMsg'] = Number(parseInt(data[3]+data[4], 16))
params['Voltage'] = Number(parseInt(data[5]+data[6], 16))
params['Electric'] = Number(parseInt(data[7]+data[8], 16))/10
params['Power'] = Number(parseInt(data[9]+data[10], 16))
params['Speed'] = Number(parseInt(data[11]+data[12], 16))
params['CurrentPressure1'] = data[13] != 'ff' ? Number((parseInt(data[13]+data[14], 16)/100).toFixed(1)) : 0
params['CurrentPressure2'] = data[15] != 'ff' ? Number((parseInt(data[15]+data[16], 16)/100).toFixed(1)) : 0
params['IpmTemperature'] = Number(parseInt(data[17]+data[18], 16))-55
params['MotorTemperature'] = Number(parseInt(data[19]+data[20], 16))-55
params['WaterTemperature'] = Number(parseInt(data[21]+data[22], 16))-55
let warnArray = reverseStr(hex2bin(data[23] + data[24]))
let warnInfo = ""
for (let i = 0; i < warnArray.length; i++) {
if (warnArray[i] === "1") {
if (warnInfo === "") {
warnInfo = DEVICE_ERROR[i]
} else {
warnInfo += `${DEVICE_ERROR[i]}`
}
}
}
params['WarnInfo'] = warnInfo
} else if (byteData.length == 18) {
if (String(byteData) == '130404000800004847') {
params['query'] = String(byteData)
} else if (String(byteData).slice(9,10) == 3) {
params['query'] = String(byteData)
} else if (String(byteData).slice(9,10) == 4) {
params['query'] = String(byteData)
}
} else if (byteData.length == 30) {
params['McuVersion'] = String(Number(parseInt(data[3].slice(1,2), 16)))+'.'+String(Number(parseInt(data[4].slice(0,1), 16)))+'.'+String(Number(parseInt(data[4].slice(1,2), 16)))
params['McuStatus'] = Number(parseInt(data[3].slice(0,1), 16))
params['Scene'] = Number(parseInt(data[9]+data[10], 16))
params['Model'] = String(Number(parseInt(data[11]+data[12], 16)))+'W'
} else if (byteData.length == 66) {
params['ErrorMsg'] = Number(parseInt(data[3]+data[4], 16))
params['Voltage'] = Number(parseInt(data[5]+data[6], 16))
params['Electric'] = Number(parseInt(data[7]+data[8], 16))/10
params['Power'] = Number(parseInt(data[9]+data[10], 16))
params['Speed'] = Number(parseInt(data[11]+data[12], 16))
params['CurrentPressure1'] = data[13] != 'ff' ? Number((parseInt(data[13]+data[14], 16)/100).toFixed(1)) : 0
params['CurrentPressure2'] = data[15] != 'ff' ? Number((parseInt(data[15]+data[16], 16)/100).toFixed(1)) : 0
params['IpmTemperature'] = Number(parseInt(data[17]+data[18], 16))-55
params['MotorTemperature'] = Number(parseInt(data[19]+data[20], 16))-55
params['WaterTemperature'] = Number(parseInt(data[21]+data[22], 16))-55
let warnArray = reverseStr(hex2bin(data[23] + data[24]))
let warnInfo = ""
for (let i = 0; i < warnArray.length; i++) {
if (warnArray[i] === "1") {
if (warnInfo === "") {
warnInfo = DEVICE_ERROR[i]
} else {
warnInfo += `${DEVICE_ERROR[i]}`
}
}
}
params['CountDown'] = Number(parseInt(data[25]+data[26], 16))
params['WarnInfo'] = warnInfo
params['Enabled'] = Number(parseInt(data[29]+data[30], 16))
}
}
params['History'] = byteData
//属性上报
return {
mid: msg.mid,
productKey: msg.productKey,
deviceName: msg.deviceName,
type: "property",
identifier: "report", //属性上报
occur: new Date().getTime(), //时间戳,设备上的事件或数据产生的本地时间
time: new Date().getTime(), //时间戳,消息上报时间
data: params,
};
} else if (topic.indexOf("/event/") > 0) {
//事件上报
} else if (topic.endsWith("/service/property/set_reply")) {
//属性设置回复
} else if (topic.endsWith("/config/set_reply")) {
//设备配置设置回复
} else if (topic.endsWith("/config/get")) {
//设备配置获取
} else if (topic.endsWith("_reply")) {
//服务回复
}
return null;
};
//下行数据
this.encode = function (service, device) {
var deviceMid = getMid();
var method = "thing.service.";
var topic = "/sys/" + service.productKey + "/" + service.deviceName + "/thing/model/down_raw";
var params = {};
var type = service.type;
var identifier = service.identifier;
if (type == "property" && identifier == "get") {
var listParams = []
for (var p in service.params) {
listParams.push(service.params[p]);
}
return {
productKey: service.productKey,
deviceName: service.deviceName,
mid: deviceMid,
content: {
topic: topic,
payload: JSON.stringify({
id: deviceMid,
method: method += "property." + identifier,
params: listParams
})
}
}
} else if (type == "property" && identifier == "set") {
for (var p in service.params) {
params[p] = service.params[p];
}
//站地址
if (paramsArr.includes('query')) {
let queryHexData = arrayGroup(params['query'],2)
let queryData = []
queryHexData.map(function(value) {
queryData.push(parseInt(value,16))
})
payloadArray = queryData
} else {
const stationAddress = "49";
totalArray.push(stationAddress)
//功能码
var functionCode = "";
// 寄存器数量
var register = ''
var baseVal = ''
//起始地址
var startAddressCode = '';
if (paramsArr.length == 1) {
functionCode = '06'
totalArray.push(functionCode)
} else {
functionCode = '10'
paramsArr = ['Pressure', 'EmtyRunPressure', 'StartPressure', 'WorkMode', 'ClearIceEn', 'WaterT', 'WaterTReset']
totalArray.push(parseInt(Number(functionCode),16))
}
if (paramsArr.includes('Switch')) {
startAddressCode = 300
totalArray.push('01','44')
} else if (paramsArr.includes('Pressure')) {
startAddressCode = 400
totalArray.push('01','144')
register = '00' + add0(String(paramsArr.length),2) + add0(String((paramsArr.length*2).toString(16)),2)
totalArray.push('00', add0(paramsArr.length,2), add0(String((paramsArr.length)*2),2))
}
if (functionCode == 6) {
paramsArr.forEach(function(value){
totalArray.push('00',params[value])
itemArray = pad(params[value].toString(16),4)
deviceArray.push(itemArray[0],itemArray[1])
})
} else if (functionCode == 10) {
paramsArr.forEach(function(value, index){
if (index < 3) {
// if (params[value]*100 < 256) {
// totalItemArray = ['00', String((params[value]*100).toFixed(0))]
// itemArray = pad(String((params[value]*100).toString(16)),4)
// totalItemArray = pad(String((params[value]*100).toFixed(0)),4)
// } else {
// outFFIndex = ((Number(params[value]*100))/256).toFixed(0)
// totalItemArray = [outFFIndex, params[value]*100-outFFIndex*256]
// }
itemArray = pad(Number((params[value]*100).toFixed(0)).toString(16),4)
totalItemArray = pad(String((params[value]*100).toFixed(0)),4)
} else {
itemArray = pad(String(params[value].toString(16)),4)
totalItemArray = pad(String(params[value]),4)
}
// totalArray.push(params[value])
// totalArray.push(totalItemArray[0],totalItemArray[1])
totalArray.push(parseInt(itemArray[0],16),parseInt(itemArray[1],16))
// deviceArray.push(parseInt(itemArray[0],16),parseInt(itemArray[1],16))
deviceArray.push(itemArray[0],itemArray[1])
})
}
var startAddressHex = pad(startAddressCode.toString(16), 4);
baseVal = String(stationAddress) + String(functionCode) + String(startAddressHex[0]) + String(startAddressHex[1])
if (functionCode != 6) {
baseVal += register
}
deviceArray.forEach(function(item) {
baseVal += item
})
// baseVal += '00070e0064000a00640001000100370037'
var Crc = CRC.ToModbusCRC16(baseVal)
var crcArray = arrayGroup(Crc,2)
totalArray.push(parseInt(crcArray[0],16),parseInt(crcArray[1],16))
payloadArray = totalArray;
}
// var params = json['params'];
// var prop_float = params['prop_float'];
// var prop_int16 = params['prop_int16'];
// var prop_bool = params['prop_bool'];
// //按照自定义协议格式拼接 rawData。
// payloadArray = payloadArray.concat(buffer_uint8(COMMAND_SET)); //command字段。
// payloadArray = payloadArray.concat(buffer_int32(parseInt(id))); //ALink JSON格式 'id'。
// payloadArray = payloadArray.concat(buffer_int16(prop_int16)); //属性'prop_int16'的值。
// payloadArray = payloadArray.concat(buffer_uint8(prop_bool)); //属性'prop_bool'的值。
// payloadArray = payloadArray.concat(buffer_float32(prop_float)); //属性'prop_float'的值。
}else if (method == 'thing.event.property.post') { //设备上报数据返回结果,如果不需要回复,可以去除该内容
var code = json['code'];
payloadArray = payloadArray.concat(buffer_uint8(COMMAND_REPORT_REPLY)); //command字段
payloadArray = payloadArray.concat(buffer_int32(parseInt(id))); // ALink JSON格式 'id'
payloadArray = payloadArray.concat(buffer_uint8(code));
} else { //未知命令,对于有些命令不做处理
var code = json['code'];
payloadArray = payloadArray.concat(buffer_uint8(COMMAD_UNKOWN)); //command字段
payloadArray = payloadArray.concat(buffer_int32(parseInt(id))); // ALink JSON格式 'id'
payloadArray = payloadArray.concat(buffer_uint8(code));
}
return {
productKey: service.productKey,
deviceName: service.deviceName,
mid: deviceMid,
content: {
topic: topic,
payload: JSON.stringify({
id: deviceMid,
method: method += "property." + identifier,
params: payloadArray
})
}
}
};
const DEVICE_ERROR = [
"压力传感器故障", //0
"高温限功率", //1
"渗漏", // 2
"电机温度传感器故障", //3
"水温传感器故障", //4
"保留", //5
"保留", //6
"保留", //7
"保留", //8
"保留", //9
"保留", //10
"保留", //11
"保留", //12
"保留", //13
"保留", //14
"保留", // 15
"保留", //16
]
function buffer_uint8(value) {
var uint8Array = new Uint8Array(1);
var dv = new DataView(uint8Array.buffer, 0);
dv.setUint8(0, value);
return [].slice.call(uint8Array);
}
function buffer_int16(value) {
var uint8Array = new Uint8Array(2);
var dv = new DataView(uint8Array.buffer, 0);
dv.setInt16(0, value);
return [].slice.call(uint8Array);
}
function buffer_int32(value) {
var uint8Array = new Uint8Array(4);
var dv = new DataView(uint8Array.buffer, 0);
dv.setInt32(0, value);
return [].slice.call(uint8Array);
}
function buffer_float32(value) {
var uint8Array = new Uint8Array(4);
var dv = new DataView(uint8Array.buffer, 0);
dv.setFloat32(0, value);
return [].slice.call(uint8Array);
}
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 arrayGroup(ss, step) {
var r = [];
function doGroup(s) {
if (!s) return;
r.push(s.substr(0, step));
s = s.substr(step);
doGroup(s);
}
doGroup(ss);
return r;
}
var CRC = {};
CRC._auchCRCHi = [
0x00, 0xC1, 0x81, 0x40, 0x01, 0xC0, 0x80, 0x41, 0x01, 0xC0,
0x80, 0x41, 0x00, 0xC1, 0x81, 0x40, 0x01, 0xC0, 0x80, 0x41,
0x00, 0xC1, 0x81, 0x40, 0x00, 0xC1, 0x81, 0x40, 0x01, 0xC0,
0x80, 0x41, 0x01, 0xC0, 0x80, 0x41, 0x00, 0xC1, 0x81, 0x40,
0x00, 0xC1, 0x81, 0x40, 0x01, 0xC0, 0x80, 0x41, 0x00, 0xC1,
0x81, 0x40, 0x01, 0xC0, 0x80, 0x41, 0x01, 0xC0, 0x80, 0x41,
0x00, 0xC1, 0x81, 0x40, 0x01, 0xC0, 0x80, 0x41, 0x00, 0xC1,
0x81, 0x40, 0x00, 0xC1, 0x81, 0x40, 0x01, 0xC0, 0x80, 0x41,
0x00, 0xC1, 0x81, 0x40, 0x01, 0xC0, 0x80, 0x41, 0x01, 0xC0,
0x80, 0x41, 0x00, 0xC1, 0x81, 0x40, 0x00, 0xC1, 0x81, 0x40,
0x01, 0xC0, 0x80, 0x41, 0x01, 0xC0, 0x80, 0x41, 0x00, 0xC1,
0x81, 0x40, 0x01, 0xC0, 0x80, 0x41, 0x00, 0xC1, 0x81, 0x40,
0x00, 0xC1, 0x81, 0x40, 0x01, 0xC0, 0x80, 0x41, 0x01, 0xC0,
0x80, 0x41, 0x00, 0xC1, 0x81, 0x40, 0x00, 0xC1, 0x81, 0x40,
0x01, 0xC0, 0x80, 0x41, 0x00, 0xC1, 0x81, 0x40, 0x01, 0xC0,
0x80, 0x41, 0x01, 0xC0, 0x80, 0x41, 0x00, 0xC1, 0x81, 0x40,
0x00, 0xC1, 0x81, 0x40, 0x01, 0xC0, 0x80, 0x41, 0x01, 0xC0,
0x80, 0x41, 0x00, 0xC1, 0x81, 0x40, 0x01, 0xC0, 0x80, 0x41,
0x00, 0xC1, 0x81, 0x40, 0x00, 0xC1, 0x81, 0x40, 0x01, 0xC0,
0x80, 0x41, 0x00, 0xC1, 0x81, 0x40, 0x01, 0xC0, 0x80, 0x41,
0x01, 0xC0, 0x80, 0x41, 0x00, 0xC1, 0x81, 0x40, 0x01, 0xC0,
0x80, 0x41, 0x00, 0xC1, 0x81, 0x40, 0x00, 0xC1, 0x81, 0x40,
0x01, 0xC0, 0x80, 0x41, 0x01, 0xC0, 0x80, 0x41, 0x00, 0xC1,
0x81, 0x40, 0x00, 0xC1, 0x81, 0x40, 0x01, 0xC0, 0x80, 0x41,
0x00, 0xC1, 0x81, 0x40, 0x01, 0xC0, 0x80, 0x41, 0x01, 0xC0,
0x80, 0x41, 0x00, 0xC1, 0x81, 0x40
];
CRC._auchCRCLo = [
0x00, 0xC0, 0xC1, 0x01, 0xC3, 0x03, 0x02, 0xC2, 0xC6, 0x06,
0x07, 0xC7, 0x05, 0xC5, 0xC4, 0x04, 0xCC, 0x0C, 0x0D, 0xCD,
0x0F, 0xCF, 0xCE, 0x0E, 0x0A, 0xCA, 0xCB, 0x0B, 0xC9, 0x09,
0x08, 0xC8, 0xD8, 0x18, 0x19, 0xD9, 0x1B, 0xDB, 0xDA, 0x1A,
0x1E, 0xDE, 0xDF, 0x1F, 0xDD, 0x1D, 0x1C, 0xDC, 0x14, 0xD4,
0xD5, 0x15, 0xD7, 0x17, 0x16, 0xD6, 0xD2, 0x12, 0x13, 0xD3,
0x11, 0xD1, 0xD0, 0x10, 0xF0, 0x30, 0x31, 0xF1, 0x33, 0xF3,
0xF2, 0x32, 0x36, 0xF6, 0xF7, 0x37, 0xF5, 0x35, 0x34, 0xF4,
0x3C, 0xFC, 0xFD, 0x3D, 0xFF, 0x3F, 0x3E, 0xFE, 0xFA, 0x3A,
0x3B, 0xFB, 0x39, 0xF9, 0xF8, 0x38, 0x28, 0xE8, 0xE9, 0x29,
0xEB, 0x2B, 0x2A, 0xEA, 0xEE, 0x2E, 0x2F, 0xEF, 0x2D, 0xED,
0xEC, 0x2C, 0xE4, 0x24, 0x25, 0xE5, 0x27, 0xE7, 0xE6, 0x26,
0x22, 0xE2, 0xE3, 0x23, 0xE1, 0x21, 0x20, 0xE0, 0xA0, 0x60,
0x61, 0xA1, 0x63, 0xA3, 0xA2, 0x62, 0x66, 0xA6, 0xA7, 0x67,
0xA5, 0x65, 0x64, 0xA4, 0x6C, 0xAC, 0xAD, 0x6D, 0xAF, 0x6F,
0x6E, 0xAE, 0xAA, 0x6A, 0x6B, 0xAB, 0x69, 0xA9, 0xA8, 0x68,
0x78, 0xB8, 0xB9, 0x79, 0xBB, 0x7B, 0x7A, 0xBA, 0xBE, 0x7E,
0x7F, 0xBF, 0x7D, 0xBD, 0xBC, 0x7C, 0xB4, 0x74, 0x75, 0xB5,
0x77, 0xB7, 0xB6, 0x76, 0x72, 0xB2, 0xB3, 0x73, 0xB1, 0x71,
0x70, 0xB0, 0x50, 0x90, 0x91, 0x51, 0x93, 0x53, 0x52, 0x92,
0x96, 0x56, 0x57, 0x97, 0x55, 0x95, 0x94, 0x54, 0x9C, 0x5C,
0x5D, 0x9D, 0x5F, 0x9F, 0x9E, 0x5E, 0x5A, 0x9A, 0x9B, 0x5B,
0x99, 0x59, 0x58, 0x98, 0x88, 0x48, 0x49, 0x89, 0x4B, 0x8B,
0x8A, 0x4A, 0x4E, 0x8E, 0x8F, 0x4F, 0x8D, 0x4D, 0x4C, 0x8C,
0x44, 0x84, 0x85, 0x45, 0x87, 0x47, 0x46, 0x86, 0x82, 0x42,
0x43, 0x83, 0x41, 0x81, 0x80, 0x40
];
CRC.CRC16 = function (buffer) {
var hi = 0xff;
var lo = 0xff;
for (var i = 0; i < buffer.length; i++) {
var idx = hi ^ buffer[i];
hi = (lo ^ CRC._auchCRCHi[idx]);
lo = CRC._auchCRCLo[idx];
}
return CRC.padLeft((hi << 8 | lo).toString(16).toUpperCase(), 4, '0');
};
CRC.isArray = function (arr) {
return Object.prototype.toString.call(arr) === '[object Array]';
};
CRC.ToCRC16 = function (str) {
return CRC.CRC16(CRC.isArray(str) ? str : CRC.strToByte(str));
};
CRC.ToModbusCRC16 = function (str) {
return CRC.CRC16(CRC.isArray(str) ? str : CRC.strToHex(str));
};
CRC.strToByte = function (str) {
var tmp = str.split(''),
arr = [];
for (var i = 0, c = tmp.length; i < c; i++) {
var j = encodeURI(tmp[i]);
if (j.length == 1) {
arr.push(j.charCodeAt());
} else {
var b = j.split('%');
for (var m = 1; m < b.length; m++) {
arr.push(parseInt('0x' + b[m]));
}
}
}
return arr;
};
CRC.convertChinese = function (str) {
var tmp = str.split(''),
arr = [];
for (var i = 0, c = tmp.length; i < c; i++) {
var s = tmp[i].charCodeAt();
if (s <= 0 || s >= 127) {
arr.push(s.toString(16));
} else {
arr.push(tmp[i]);
}
}
return arr;
};
CRC.filterChinese = function (str) {
var tmp = str.split(''),
arr = [];
for (var i = 0, c = tmp.length; i < c; i++) {
var s = tmp[i].charCodeAt();
if (s > 0 && s < 127) {
arr.push(tmp[i]);
}
}
return arr;
};
CRC.strToHex = function (hex, isFilterChinese) {
hex = isFilterChinese ? CRC.filterChinese(hex).join('') : CRC.convertChinese(hex).join('');
//清除所有空格
hex = hex.replace(/\s/g, "");
//若字符个数为奇数,补一个空格
hex += hex.length % 2 != 0 ? " " : "";
var c = hex.length / 2,
arr = [];
for (var i = 0; i < c; i++) {
arr.push(parseInt(hex.substr(i * 2, 2), 16));
}
return arr;
};
CRC.padLeft = function (s, w, pc) {
if (pc == undefined) {
pc = '0';
}
for (var i = 0, c = w - s.length; i < c; i++) {
s = pc + s;
}
return s;
};
function str2ab(str) {
var buffer = new ArrayBuffer(str.length / 2); // 2 bytes for each char
var dataView = new DataView(buffer);
var str = str.split("")
var n = 0;
for (var i = 0; i < str.length; i = i + 2) {
dataView.setUint8(n, `0x${str[i]}${str[i+1]}`)
n++;
}
return buffer;
}
function pad(num, n, flag = false) {
var len = num.toString().length;
while (len < n) {
num = "0" + num;
len++;
}
const arr = arrayGroup(num, 2)
//高低位互换
if (arr[1] == '00') {
flag = true
}
return flag ? [arr[1], arr[0]] : [arr[0], arr[1]];
}
function add0(num,n) {
let len = num.length
while(len < n){
num = '0'+num
len++
}
if (len > n) {
num = String(num).slice(1)
}
//console.log(num)
return num
}
function hex2bin(hex, len) {
var bin = parseInt(hex, 16).toString(2);
var l = bin.length;
for (var i = 0; i < len - l; i++) {
bin = "0" + bin;
}
return bin;
}
//翻转字符串并切割成数组
function reverseStr(str) {
var arr = str.split("");
arr.reverse();
return arr;
}
function timestampToTime(timestamp) {
var date = new Date(timestamp * 1000);//时间戳为10位需*1000时间戳为13位的话不需乘1000
var Y = date.getFullYear() + '-';
var M = (date.getMonth()+1 < 10 ? '0'+(date.getMonth()+1) : date.getMonth()+1) + '-';
var D = date.getDate() + ' ';
var h = date.getHours() + ':';
var m = date.getMinutes() + ':';
var s = date.getSeconds();
return Y+M+D+h+m+s;
}

View File

@ -1994,5 +1994,29 @@
"tag": null,
"group": {},
"createAt": 1689144331356
},
{
"id": "16895701241450testnbpump010000125",
"deviceId": "16895701241450testnbpump010000125",
"productKey": "openiitanbpump01",
"deviceName": "testnbpump01",
"model": null,
"secret": "eY45WnZEWRryR2xt",
"parentId": null,
"uid": "1",
"subUid": null,
"locate": {
"longitude": "113.865453",
"latitude": "22.583686"
},
"state": {
"online": false,
"onlineTime": 0,
"offlineTime": 0
},
"property": null,
"tag": null,
"group": {},
"createAt": 1689570124148
}
]

View File

@ -210,15 +210,15 @@
"createAt": 1649653149339
}, {
"id": 3,
"productKey": "dzxYwDHswecMP3pf",
"productSecret": "730d1137b05b41f280cebbdd47782dd6",
"name": "NB水泵",
"productKey": "openiitanbpump01",
"productSecret": "openiitanbpump01",
"name": "NB透传水泵",
"category": "OpenIitaPump",
"nodeType": 1,
"nodeType": 2,
"uid": "1",
"isOpenLocate": 0,
"isOpenLocate": 1,
"transparent": false,
"locateUpdateType": "manual",
"locateUpdateType": "device",
"createAt": 1649653149339
}
]

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

View File

@ -35,7 +35,7 @@
},
{
"id": 2,
"productKey": "hdX3PCMcFrCYpesJ",
"productKey": "openiitanbpump01",
"model": {
"properties": [
{

View File

@ -46,10 +46,12 @@ import org.springframework.stereotype.Component;
import javax.annotation.PostConstruct;
import java.io.File;
import java.io.IOException;
import java.nio.charset.StandardCharsets;
import java.nio.file.Path;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Objects;
import java.util.concurrent.TimeUnit;
@Slf4j
@ -126,7 +128,7 @@ public class DeviceComponentManager {
scriptEngine = ScriptEngineFactory.getScriptEngine(component.getScriptTyp());
String componentScript = FileUtils.readFileToString(path.
resolve(ProtocolComponent.SCRIPT_FILE_NAME).toFile(), "UTF-8");
resolve(ProtocolComponent.SCRIPT_FILE_NAME).toFile(), StandardCharsets.UTF_8);
componentInstance.setScript(componentScript);
register(id, componentInstance);
} catch (IOException e) {
@ -141,7 +143,7 @@ public class DeviceComponentManager {
// 从文件方式内容
Path converterPath = componentConfig.getConverterFilePath(component.getConverter());
String converterScript = FileUtils.readFileToString(converterPath.
resolve(ProtocolConverter.SCRIPT_FILE_NAME).toFile(), "UTF-8");
resolve(ProtocolConverter.SCRIPT_FILE_NAME).toFile(), StandardCharsets.UTF_8);
// scriptConverter.setScript(protocolConvert.getScript()); // 从数据库加载,以后可以加版本号
scriptConverter.setScript(converterScript);
@ -224,7 +226,11 @@ public class DeviceComponentManager {
//构建必要的设备信息
Map<String, Object> tag = new HashMap<>();
deviceInfo.getTag().forEach((k, v) -> tag.put(k, v.getValue()));
Map<String, DeviceInfo.Tag> tagMap = deviceInfo.getTag();
if(Objects.nonNull(tagMap) && !tagMap.isEmpty()){
tagMap.forEach((k, v) -> tag.put(k, v.getValue()));
}
Device device = new Device(deviceInfo.getDeviceId(),
deviceInfo.getModel(),
deviceInfo.getProperty(),