Skip to content

Commit 1c02c8b

Browse files
committed
init addition of some sensecap devices
1 parent e006f0f commit 1c02c8b

29 files changed

Lines changed: 2615 additions & 0 deletions

vendors/seeed-technology-co-ltd/codecs/SenseCAP_LoRaWAN_V2_Decoder.js

Lines changed: 630 additions & 0 deletions
Large diffs are not rendered by default.

vendors/seeed-technology-co-ltd/codecs/SenseCAP_LoRaWAN_V4_Decoder.js

Lines changed: 511 additions & 0 deletions
Large diffs are not rendered by default.
Lines changed: 391 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,391 @@
1+
/**
2+
* Entry, decoder.js
3+
*/
4+
function decodeUplink(input) {
5+
// data split
6+
7+
var bytes = input['bytes']
8+
// init
9+
bytes = bytes2HexString(bytes)
10+
.toLocaleUpperCase()
11+
12+
let result = {
13+
'err': 0, 'payload': bytes, 'valid': true, messages: []
14+
}
15+
let splitArray = dataSplit(bytes)
16+
// data decoder
17+
let decoderArray = []
18+
for (let i = 0; i < splitArray.length; i++) {
19+
let item = splitArray[i]
20+
let dataId = item.dataId
21+
let dataValue = item.dataValue
22+
let messages = dataIdAndDataValueJudge(dataId, dataValue)
23+
decoderArray.push(messages)
24+
}
25+
result.messages = decoderArray
26+
return { data: result }
27+
}
28+
29+
/**
30+
* data splits
31+
* @param bytes
32+
* @returns {*[]}
33+
*/
34+
function dataSplit (bytes) {
35+
let frameArray = []
36+
37+
for (let i = 0; i < bytes.length; i++) {
38+
let remainingValue = bytes
39+
let dataId = remainingValue.substring(0, 2)
40+
let dataValue
41+
let dataObj = {}
42+
switch (dataId) {
43+
case '01' :
44+
case '20' :
45+
case '21' :
46+
case '30' :
47+
case '31' :
48+
case '33' :
49+
case '40' :
50+
case '41' :
51+
case '42' :
52+
case '43' :
53+
case '44' :
54+
case '45' :
55+
dataValue = remainingValue.substring(2, 22)
56+
bytes = remainingValue.substring(22)
57+
dataObj = {
58+
'dataId': dataId, 'dataValue': dataValue
59+
}
60+
break
61+
case '02':
62+
dataValue = remainingValue.substring(2, 18)
63+
bytes = remainingValue.substring(18)
64+
dataObj = {
65+
'dataId': '02', 'dataValue': dataValue
66+
}
67+
break
68+
case '03' :
69+
case '06':
70+
dataValue = remainingValue.substring(2, 4)
71+
bytes = remainingValue.substring(4)
72+
dataObj = {
73+
'dataId': dataId, 'dataValue': dataValue
74+
}
75+
break
76+
case '05' :
77+
case '34':
78+
dataValue = bytes.substring(2, 10)
79+
bytes = remainingValue.substring(10)
80+
dataObj = {
81+
'dataId': dataId, 'dataValue': dataValue
82+
}
83+
break
84+
case '04':
85+
case '10':
86+
case '32':
87+
case '35':
88+
case '36':
89+
case '37':
90+
case '38':
91+
case '39':
92+
dataValue = bytes.substring(2, 20)
93+
bytes = remainingValue.substring(20)
94+
dataObj = {
95+
'dataId': dataId, 'dataValue': dataValue
96+
}
97+
break
98+
default:
99+
dataValue = '9'
100+
break
101+
}
102+
if (dataValue.length < 2) {
103+
break
104+
}
105+
frameArray.push(dataObj)
106+
}
107+
return frameArray
108+
}
109+
110+
function dataIdAndDataValueJudge (dataId, dataValue) {
111+
let messages = []
112+
switch (dataId) {
113+
case '01':
114+
let temperature = dataValue.substring(0, 4)
115+
let humidity = dataValue.substring(4, 6)
116+
let illumination = dataValue.substring(6, 14)
117+
let uv = dataValue.substring(14, 16)
118+
let windSpeed = dataValue.substring(16, 20)
119+
messages = [{
120+
measurementValue: loraWANV2DataFormat(temperature, 10), measurementId: '4097', type: 'Air Temperature'
121+
}, {
122+
measurementValue: loraWANV2DataFormat(humidity), measurementId: '4098', type: 'Air Humidity'
123+
}, {
124+
measurementValue: loraWANV2DataFormat(illumination), measurementId: '4099', type: 'Light Intensity'
125+
}, {
126+
measurementValue: loraWANV2DataFormat(uv, 10), measurementId: '4190', type: 'UV Index'
127+
}, {
128+
measurementValue: loraWANV2DataFormat(windSpeed, 10), measurementId: '4105', type: 'Wind Speed'
129+
}]
130+
break
131+
case '02':
132+
let windDirection = dataValue.substring(0, 4)
133+
let rainfall = dataValue.substring(4, 12)
134+
let airPressure = dataValue.substring(12, 16)
135+
messages = [{
136+
measurementValue: loraWANV2DataFormat(windDirection), measurementId: '4104', type: 'Wind Direction Sensor'
137+
}, {
138+
measurementValue: loraWANV2DataFormat(rainfall, 1000), measurementId: '4113', type: 'Rain Gauge'
139+
}, {
140+
141+
measurementValue: loraWANV2DataFormat(airPressure, 0.1), measurementId: '4101', type: 'Barometric Pressure'
142+
}]
143+
break
144+
case '03':
145+
let Electricity = dataValue
146+
messages = [{
147+
'Battery(%)': loraWANV2DataFormat(Electricity)
148+
}]
149+
break
150+
case '04':
151+
let electricityWhether = dataValue.substring(0, 2)
152+
let hwv = dataValue.substring(2, 6)
153+
let bdv = dataValue.substring(6, 10)
154+
let sensorAcquisitionInterval = dataValue.substring(10, 14)
155+
let gpsAcquisitionInterval = dataValue.substring(14, 18)
156+
messages = [{
157+
'Battery(%)': loraWANV2DataFormat(electricityWhether),
158+
'Hardware Version': `${loraWANV2DataFormat(hwv.substring(0, 2))}.${loraWANV2DataFormat(hwv.substring(2, 4))}`,
159+
'Firmware Version': `${loraWANV2DataFormat(bdv.substring(0, 2))}.${loraWANV2DataFormat(bdv.substring(2, 4))}`,
160+
'measureInterval': parseInt(loraWANV2DataFormat(sensorAcquisitionInterval)) * 60,
161+
'gpsInterval': parseInt(loraWANV2DataFormat(gpsAcquisitionInterval)) * 60
162+
}]
163+
break
164+
case '05':
165+
let sensorAcquisitionIntervalFive = dataValue.substring(0, 4)
166+
let gpsAcquisitionIntervalFive = dataValue.substring(4, 8)
167+
messages = [{
168+
'measureInterval': parseInt(loraWANV2DataFormat(sensorAcquisitionIntervalFive)) * 60,
169+
'gpsInterval': parseInt(loraWANV2DataFormat(gpsAcquisitionIntervalFive)) * 60
170+
}]
171+
break
172+
case '06':
173+
let errorCode = dataValue
174+
let descZh
175+
switch (errorCode) {
176+
case '00':
177+
descZh = 'CCL_SENSOR_ERROR_NONE'
178+
break
179+
case '01':
180+
descZh = 'CCL_SENSOR_NOT_FOUND'
181+
break
182+
case '02':
183+
descZh = 'CCL_SENSOR_WAKEUP_ERROR'
184+
break
185+
case '03':
186+
descZh = 'CCL_SENSOR_NOT_RESPONSE'
187+
break
188+
case '04':
189+
descZh = 'CCL_SENSOR_DATA_EMPTY'
190+
break
191+
case '05':
192+
descZh = 'CCL_SENSOR_DATA_HEAD_ERROR'
193+
break
194+
case '06':
195+
descZh = 'CCL_SENSOR_DATA_CRC_ERROR'
196+
break
197+
case '07':
198+
descZh = 'CCL_SENSOR_DATA_B1_NO_VALID'
199+
break
200+
case '08':
201+
descZh = 'CCL_SENSOR_DATA_B2_NO_VALID'
202+
break
203+
case '09':
204+
descZh = 'CCL_SENSOR_RANDOM_NOT_MATCH'
205+
break
206+
case '0A':
207+
descZh = 'CCL_SENSOR_PUBKEY_SIGN_VERIFY_FAILED'
208+
break
209+
case '0B':
210+
descZh = 'CCL_SENSOR_DATA_SIGN_VERIFY_FAILED'
211+
break
212+
case '0C':
213+
descZh = 'CCL_SENSOR_DATA_VALUE_HI'
214+
break
215+
case '0D':
216+
descZh = 'CCL_SENSOR_DATA_VALUE_LOW'
217+
break
218+
case '0E':
219+
descZh = 'CCL_SENSOR_DATA_VALUE_MISSED'
220+
break
221+
case '0F':
222+
descZh = 'CCL_SENSOR_ARG_INVAILD'
223+
break
224+
case '10':
225+
descZh = 'CCL_SENSOR_RS485_MASTER_BUSY'
226+
break
227+
case '11':
228+
descZh = 'CCL_SENSOR_RS485_REV_DATA_ERROR'
229+
break
230+
case '12':
231+
descZh = 'CCL_SENSOR_RS485_REG_MISSED'
232+
break
233+
case '13':
234+
descZh = 'CCL_SENSOR_RS485_FUN_EXE_ERROR'
235+
break
236+
case '14':
237+
descZh = 'CCL_SENSOR_RS485_WRITE_STRATEGY_ERROR'
238+
break
239+
case '15':
240+
descZh = 'CCL_SENSOR_CONFIG_ERROR'
241+
break
242+
case 'FF':
243+
descZh = 'CCL_SENSOR_DATA_ERROR_UNKONW'
244+
break
245+
default:
246+
descZh = 'CC_OTHER_FAILED'
247+
break
248+
}
249+
messages = [{
250+
measurementId: '4101', type: 'sensor_error_event', errCode: errorCode, descZh
251+
}]
252+
break
253+
case '10':
254+
let statusValue = dataValue.substring(0, 2)
255+
let { status, type } = loraWANV2BitDataFormat(statusValue)
256+
let sensecapId = dataValue.substring(2)
257+
messages = [{
258+
status: status, channelType: type, sensorEui: sensecapId
259+
}]
260+
break
261+
default:
262+
break
263+
}
264+
return messages
265+
}
266+
267+
/**
268+
*
269+
* data formatting
270+
* @param str
271+
* @param divisor
272+
* @returns {string|number}
273+
*/
274+
function loraWANV2DataFormat (str, divisor = 1) {
275+
let strReverse = bigEndianTransform(str)
276+
let str2 = toBinary(strReverse)
277+
if (str2.substring(0, 1) === '1') {
278+
let arr = str2.split('')
279+
let reverseArr = arr.map((item) => {
280+
if (parseInt(item) === 1) {
281+
return 0
282+
} else {
283+
return 1
284+
}
285+
})
286+
str2 = parseInt(reverseArr.join(''), 2) + 1
287+
return '-' + str2 / divisor
288+
}
289+
return parseInt(str2, 2) / divisor
290+
}
291+
292+
/**
293+
* Handling big-endian data formats
294+
* @param data
295+
* @returns {*[]}
296+
*/
297+
function bigEndianTransform (data) {
298+
let dataArray = []
299+
for (let i = 0; i < data.length; i += 2) {
300+
dataArray.push(data.substring(i, i + 2))
301+
}
302+
// array of hex
303+
return dataArray
304+
}
305+
306+
/**
307+
* Convert to an 8-digit binary number with 0s in front of the number
308+
* @param arr
309+
* @returns {string}
310+
*/
311+
function toBinary (arr) {
312+
let binaryData = arr.map((item) => {
313+
let data = parseInt(item, 16)
314+
.toString(2)
315+
let dataLength = data.length
316+
if (data.length !== 8) {
317+
for (let i = 0; i < 8 - dataLength; i++) {
318+
data = `0` + data
319+
}
320+
}
321+
return data
322+
})
323+
let ret = binaryData.toString()
324+
.replace(/,/g, '')
325+
return ret
326+
}
327+
328+
/**
329+
* sensor
330+
* @param str
331+
* @returns {{channel: number, type: number, status: number}}
332+
*/
333+
function loraWANV2BitDataFormat (str) {
334+
let strReverse = bigEndianTransform(str)
335+
let str2 = toBinary(strReverse)
336+
let channel = parseInt(str2.substring(0, 4), 2)
337+
let status = parseInt(str2.substring(4, 5), 2)
338+
let type = parseInt(str2.substring(5), 2)
339+
return { channel, status, type }
340+
}
341+
342+
/**
343+
* channel info
344+
* @param str
345+
* @returns {{channelTwo: number, channelOne: number}}
346+
*/
347+
function loraWANV2ChannelBitFormat (str) {
348+
let strReverse = bigEndianTransform(str)
349+
let str2 = toBinary(strReverse)
350+
let one = parseInt(str2.substring(0, 4), 2)
351+
let two = parseInt(str2.substring(4, 8), 2)
352+
let resultInfo = {
353+
one: one, two: two
354+
}
355+
return resultInfo
356+
}
357+
358+
/**
359+
* data log status bit
360+
* @param str
361+
* @returns {{total: number, level: number, isTH: number}}
362+
*/
363+
function loraWANV2DataLogBitFormat (str) {
364+
let strReverse = bigEndianTransform(str)
365+
let str2 = toBinary(strReverse)
366+
let isTH = parseInt(str2.substring(0, 1), 2)
367+
let total = parseInt(str2.substring(1, 5), 2)
368+
let left = parseInt(str2.substring(5), 2)
369+
let resultInfo = {
370+
isTH: isTH, total: total, left: left
371+
}
372+
return resultInfo
373+
}
374+
375+
function bytes2HexString (arrBytes) {
376+
var str = ''
377+
for (var i = 0; i < arrBytes.length; i++) {
378+
var tmp
379+
var num = arrBytes[i]
380+
if (num < 0) {
381+
tmp = (255 + num + 1).toString(16)
382+
} else {
383+
tmp = num.toString(16)
384+
}
385+
if (tmp.length === 1) {
386+
tmp = '0' + tmp
387+
}
388+
str += tmp
389+
}
390+
return str
391+
}

0 commit comments

Comments
 (0)