Skip to content

Commit

Permalink
add dingtek products dc413/dc500/dc510/dc600/df200/df400/df555/df556/…
Browse files Browse the repository at this point in the history
…df701/df703/do200/dt311/dt320 (#636)

Co-authored-by: Jaime Trinidad <[email protected]>
  • Loading branch information
cndingtek and Jaime-Trinidad committed Jul 11, 2023
1 parent f426fdc commit b94b9c5
Show file tree
Hide file tree
Showing 58 changed files with 6,546 additions and 10 deletions.
113 changes: 113 additions & 0 deletions vendor/dingtek/dc413-codec.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,113 @@
# Uplink decoder decodes binary data uplink into a JSON object (optional)
# For documentation on writing encoders and decoders, see: https://thethingsstack.io/integrations/payload-formatters/javascript/
uplinkDecoder:
fileName: dc413.js
# Examples (optional)
examples:
- description: heartbeat upload
input:
fPort: 3
bytes: [0x80, 0x00, 0x01, 0x02, 0x11, 0x06, 0xA4, 0x00, 0x16, 0x01, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x81]
output:
data:
level: 1700
alarmLevel: false
alarmFall: false
alarmBattery: false
angle: 0
temperature: 22
frameCounter: 1

- description: parameter packet
input:
fPort: 3
bytes: [0x80, 0x00, 0x01, 0x03, 0x19, 0x03, 0x02, 0x06, 0x3C, 0x1E, 0x4B, 0x14, 0x01, 0x01, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x81]
output:
data:
firmware: '3.2'
uploadInterval: 6
detectInterval: 60
levelThreshold: 30
fallThreshold: 20
fallEnable: true
workMode: 1

# Downlink encoder encodes JSON object into a binary data downlink (optional)
downlinkEncoder:
fileName: dc413.js
examples:
- description: change periodic upload interval to 4 hours
input:
data:
uploadInterval: 4
output:
bytes: [0x38, 0x30, 0x30, 0x32, 0x39, 0x39, 0x39, 0x39, 0x30, 0x31, 0x30, 0x34, 0x38, 0x31]
fPort: 3
- description: change periodic detection interval to 10 minutes
input:
data:
detectInterval: 10
output:
bytes: [0x38, 0x30, 0x30, 0x32, 0x39, 0x39, 0x39, 0x39, 0x30, 0x38, 0x30, 0x41, 0x38, 0x31]
fPort: 3
- description: change full alarm threshold to 35cm
input:
data:
levelThreshold: 35
output:
bytes: [0x38, 0x30, 0x30, 0x32, 0x39, 0x39, 0x39, 0x39, 0x30, 0x32, 0x32, 0x33, 0x38, 0x31]
fPort: 3
- description: change motion alarm threshold to 45°
input:
data:
fallThreshold: 45
output:
bytes: [0x38, 0x30, 0x30, 0x32, 0x39, 0x39, 0x39, 0x39, 0x30, 0x34, 0x32, 0x44, 0x38, 0x31]
fPort: 3
- description: enable tilt detection
input:
data:
fallEnable: true
output:
bytes: [0x38, 0x30, 0x30, 0x32, 0x39, 0x39, 0x39, 0x39, 0x30, 0x39, 0x30, 0x41, 0x38, 0x31]
fPort: 3

# Downlink decoder decodes the encoded downlink message (optional, must be symmetric with downlinkEncoder)
downlinkDecoder:
fileName: dc413.js
examples:
- description: change periodic upload interval to 4 hours
input:
fPort: 3
bytes: [0x38, 0x30, 0x30, 0x32, 0x39, 0x39, 0x39, 0x39, 0x30, 0x31, 0x30, 0x34, 0x38, 0x31]
output:
data:
uploadInterval: 4
- description: change detection interval to 10 minutes
input:
fPort: 3
bytes: [0x38, 0x30, 0x30, 0x32, 0x39, 0x39, 0x39, 0x39, 0x30, 0x38, 0x30, 0x41, 0x38, 0x31]
output:
data:
detectInterval: 10
- description: change full alarm threshold to 35cm
input:
fPort: 3
bytes: [0x38, 0x30, 0x30, 0x32, 0x39, 0x39, 0x39, 0x39, 0x30, 0x32, 0x32, 0x33, 0x38, 0x31]
output:
data:
levelThreshold: 35
- description: change motion alarm threshold to 45°
input:
fPort: 3
bytes: [0x38, 0x30, 0x30, 0x32, 0x39, 0x39, 0x39, 0x39, 0x30, 0x34, 0x32, 0x44, 0x38, 0x31]
output:
data:
fallThreshold: 45
- description: enable motion detection
input:
fPort: 3
bytes: [0x38, 0x30, 0x30, 0x32, 0x39, 0x39, 0x39, 0x39, 0x30, 0x39, 0x30, 0x41, 0x38, 0x31]
output:
data:
fallEnable: true
223 changes: 223 additions & 0 deletions vendor/dingtek/dc413.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,223 @@
var units = [' ℃', ' hours', ' minutes', ' mm', ' °', ' cm'];
//IEEE754 hex to float convert
function hex2float(num) {
var sign = num & 0x80000000 ? -1 : 1;
var exponent = ((num >> 23) & 0xff) - 127;
var mantissa = 1 + (num & 0x7fffff) / 0x7fffff;
return sign * mantissa * Math.pow(2, exponent);
}

function decodeUplink(input) {
if (input.fPort != 3) {
return {
errors: ['unknown FPort'],
};
}

switch (input.bytes.length) {
case 17:
return {
// Decoded data
data: {
level: (input.bytes[5] << 8) + input.bytes[6],
alarmLevel: Boolean(input.bytes[11] >> 4),
alarmFall: Boolean(input.bytes[12] >> 4),
alarmBattery: Boolean(input.bytes[12] & 0x0f),
angle: input.bytes[9] & (0x0f === 0x00) ? input.bytes[10] : 0 - input.bytes[10],
temperature: input.bytes[8],
frameCounter: (input.bytes[13] << 8) + input.bytes[14],
},
};
case 25:
var data_type = input.bytes[3];
if (data_type === 0x03) {
return {
// Decoded parameter
data: {
firmware: input.bytes[5] + '.' + input.bytes[6],
uploadInterval: input.bytes[7],
detectInterval: input.bytes[8],
levelThreshold: input.bytes[9],
fallThreshold: input.bytes[11],
fallEnable: Boolean(input.bytes[12]),
workMode: input.bytes[14],
},
};
}
default:
return {
errors: ['wrong length'],
};
}
}

function encodeDownlink(input) {
if (input.data.uploadInterval != null && !isNaN(input.data.uploadInterval)) {
var periodic_interval = input.data.uploadInterval;
var periodic_interval_high = periodic_interval.toString(16).padStart(2, '0').toUpperCase()[0].charCodeAt(0);
var periodic_interval_low = periodic_interval.toString(16).padStart(2, '0').toUpperCase()[1].charCodeAt(0);
if (periodic_interval > 168 || periodic_interval < 1) {
return {
errors: ['periodic upload interval range 1-168 hours.'],
};
} else {
return {
// LoRaWAN FPort used for the downlink message
fPort: 3,
// Encoded bytes
bytes: [0x38, 0x30, 0x30, 0x32, 0x39, 0x39, 0x39, 0x39, 0x30, 0x31, periodic_interval_high, periodic_interval_low, 0x38, 0x31],
};
}
}
if (input.data.detectInterval != null && !isNaN(input.data.detectInterval)) {
var detection_interval = input.data.detectInterval;
var detection_interval_high = detection_interval.toString(16).padStart(2, '0').toUpperCase()[0].charCodeAt(0);
var detection_interval_low = detection_interval.toString(16).padStart(2, '0').toUpperCase()[1].charCodeAt(0);
if (detection_interval > 60 || detection_interval < 1) {
return {
errors: ['periodic detection interval range 1-60 minutes.'],
};
} else {
return {
// LoRaWAN FPort used for the downlink message
fPort: 3,
// Encoded bytes
bytes: [0x38, 0x30, 0x30, 0x32, 0x39, 0x39, 0x39, 0x39, 0x30, 0x38, detection_interval_high, detection_interval_low, 0x38, 0x31],
};
}
}
if (input.data.levelThreshold != null && !isNaN(input.data.levelThreshold)) {
var full_alarm_threshold = input.data.levelThreshold;
var full_alarm_threshold_high = full_alarm_threshold.toString(16).padStart(2, '0').toUpperCase()[0].charCodeAt(0);
var full_alarm_threshold_low = full_alarm_threshold.toString(16).padStart(2, '0').toUpperCase()[1].charCodeAt(0);
if (full_alarm_threshold > 255 || full_alarm_threshold < 15) {
return {
errors: ['full alarm threshold range 15-255 cm.'],
};
} else {
return {
// LoRaWAN FPort used for the downlink message
fPort: 3,
// Encoded bytes
bytes: [0x38, 0x30, 0x30, 0x32, 0x39, 0x39, 0x39, 0x39, 0x30, 0x32, full_alarm_threshold_high, full_alarm_threshold_low, 0x38, 0x31],
};
}
}

if (input.data.fallThreshold != null && !isNaN(input.data.fallThreshold)) {
var tilt_alarm_threshold = input.data.fallThreshold;
var tilt_alarm_threshold_high = tilt_alarm_threshold.toString(16).padStart(2, '0').toUpperCase()[0].charCodeAt(0);
var tilt_alarm_threshold_low = tilt_alarm_threshold.toString(16).padStart(2, '0').toUpperCase()[1].charCodeAt(0);
if (tilt_alarm_threshold > 90 || tilt_alarm_threshold < 15) {
return {
errors: ['tilt alarm threshold range 15-90 °.'],
};
} else {
return {
// LoRaWAN FPort used for the downlink message
fPort: 3,
// Encoded bytes
bytes: [0x38, 0x30, 0x30, 0x32, 0x39, 0x39, 0x39, 0x39, 0x30, 0x34, tilt_alarm_threshold_high, tilt_alarm_threshold_low, 0x38, 0x31],
};
}
}
if (input.data.fallEnable != null && input.data.fallEnable === !!input.data.fallEnable) {
var tilt_enable = input.data.fallEnable;
if (tilt_enable === true) {
return {
// LoRaWAN FPort used for the downlink message
fPort: 3,
// Encoded bytes
bytes: [0x38, 0x30, 0x30, 0x32, 0x39, 0x39, 0x39, 0x39, 0x30, 0x39, 0x30, 0x41, 0x38, 0x31],
};
} else {
return {
// LoRaWAN FPort used for the downlink message
fPort: 3,
// Encoded bytes
bytes: [0x38, 0x30, 0x30, 0x32, 0x39, 0x39, 0x39, 0x39, 0x30, 0x39, 0x30, 0x39, 0x38, 0x31],
};
}
}
return {
errors: ['invalid downlink parameter.'],
};
}

function decodeDownlink(input) {
var input_length = input.bytes.length;
if (input.fPort != 3) {
return {
errors: ['invalid FPort.'],
};
}

if (
input_length < 12 ||
input.bytes[0] != 0x38 ||
input.bytes[1] != 0x30 ||
input.bytes[2] != 0x30 ||
input.bytes[3] != 0x32 ||
input.bytes[4] != 0x39 ||
input.bytes[5] != 0x39 ||
input.bytes[6] != 0x39 ||
input.bytes[7] != 0x39 ||
input.bytes[input_length - 2] != 0x38 ||
input.bytes[input_length - 1] != 0x31
) {
return {
errors: ['invalid format.'],
};
}
var option = parseInt(String.fromCharCode(input.bytes[8]) + String.fromCharCode(input.bytes[9]), 16);
var value = parseInt(String.fromCharCode(input.bytes[10]) + String.fromCharCode(input.bytes[11]), 16);
switch (option) {
case 1:
return {
data: {
uploadInterval: value,
},
};
case 8:
return {
data: {
detectInterval: value,
},
};
case 2:
return {
data: {
levelThreshold: value,
},
};
case 4:
return {
data: {
fallThreshold: value,
},
};
case 9:
switch (value) {
case 0x09:
return {
data: {
fallEnable: false,
},
};
case 0x0a:
return {
data: {
fallEnable: true,
},
};
default:
return {
errors: ['invalid parameter value.'],
};
}
default:
return {
errors: ['invalid parameter key.'],
};
}
}
Binary file added vendor/dingtek/dc413.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading

0 comments on commit b94b9c5

Please sign in to comment.