Ct-Series - Ct310

Sensor

Codec Description

Codec for Ct-Series - Ct310.

Codec Preview

/** * Payload Encoder * * Copyright 2025 Milesight IoT * * @product CT303 / CT305 / CT310 */ var RAW_VALUE = 0x00; /* eslint no-redeclare: "off" */ /* eslint-disable */ // Chirpstack v4 function encodeDownlink(input) { var encoded = milesightDeviceEncode(input.data); return { bytes: encoded }; } // Chirpstack v3 function Encode(fPort, obj) { return milesightDeviceEncode(obj); } // The Things Network function Encoder(obj, port) { return milesightDeviceEncode(obj); } /* eslint-enable */ function milesightDeviceEncode(payload) { var encoded = []; if ("reboot" in payload) { encoded = encoded.concat(reboot(payload.reboot)); } if ("report_interval" in payload) { encoded = encoded.concat(setReportInterval(payload.report_interval)); } if ("report_status" in payload) { encoded = encoded.concat(reportStatus(payload.report_status)); } if ("clear_current_chn1_cumulative" in payload) { encoded = encoded.concat(clearCurrentCumulativeValue(1, payload.clear_current_chn1_cumulative)); } if ("clear_current_chn2_cumulative" in payload) { encoded = encoded.concat(clearCurrentCumulativeValue(2, payload.clear_current_chn2_cumulative)); } if ("clear_current_chn3_cumulative" in payload) { encoded = encoded.concat(clearCurrentCumulativeValue(3, payload.clear_current_chn3_cumulative)); } if ("alarm_report_counts" in payload) { encoded = encoded.concat(alarmReportCounts(payload.alarm_report_counts)); } if ("alarm_report_interval" in payload) { encoded = encoded.concat(alarmReportInterval(payload.alarm_report_interval)); } if ("current_chn1_alarm_config" in payload) { encoded = encoded.concat(setCurrentThresholdAlarmConfig(1, payload.current_chn1_alarm_config)); } if ("current_chn2_alarm_config" in payload) { encoded = encoded.concat(setCurrentThresholdAlarmConfig(2, payload.current_chn2_alarm_config)); } if ("current_chn3_alarm_config" in payload) { encoded = encoded.concat(setCurrentThresholdAlarmConfig(3, payload.current_chn3_alarm_config)); } if ("temperature_alarm_config" in payload) { encoded = encoded.concat(setTemperatureThresholdAlarmConfig(payload.temperature_alarm_config)); } return encoded; } /** * reboot device * @param {number} reboot values: (0: no, 1: yes) * @example { "reboot": 1 } */ function reboot(reboot) { var yes_no_map = { 0: "no", 1: "yes" }; var reboot_values = getValues(yes_no_map); if (reboot_values.indexOf(reboot) === -1) { throw new Error("reboot must be one of " + reboot_values.join(", ")); } if (getValue(yes_no_map, reboot) === 0) { return []; } return [0xff, 0x10, 0xff]; } /** * set report interval * @param {number} report_interval unit: minute * @example { "report_interval": 20 } */ function setReportInterval(report_interval) { if (typeof report_interval !== "number") { throw new Error("report_interval must be a number"); } var buffer = new Buffer(5); buffer.writeUInt8(0xff); buffer.writeUInt8(0x8e); buffer.writeUInt8(0x00); buffer.writeUInt16LE(report_interval); return buffer.toBytes(); } /** * report status * @param {number} report_status values: (0: no, 1: yes) * @example { "report_status": 1 } */ function reportStatus(report_status) { var yes_no_map = { 0: "no", 1: "yes" }; var yes_no_values = getValues(yes_no_map); if (yes_no_values.indexOf(report_status) === -1) { throw new Error("report_status must be one of " + yes_no_values.join(", ")); } if (getValue(yes_no_map, report_status) === 0) { return []; } return [0xff, 0x28, 0xff]; } /** * clear current cumulative value * @param {number} index * @param {number} clear_current_cumulative values: (0: no, 1: yes) * @example { "clear_current_chn1_cumulative": 1 } */ function clearCurrentCumulativeValue(index, clear_current_cumulative) { var yes_no_map = { 0: "no", 1: "yes" }; var yes_no_values = getValues(yes_no_map); if (yes_no_values.indexOf(clear_current_cumulative) === -1) { throw new Error("clear_current_chn" + index + "_cumulative must be one of " + yes_no_values.join(", ")); } if (getValue(yes_no_map, clear_current_cumulative) === 0) { return []; } return [0xff, 0x27, index]; } /** * set current threshold alarm config * @param {number} index * @param {object} current_alarm_config * @param {number} current_alarm_config.condition values: (0: disable, 1: below, 2: above, 3: between, 4: outside) * @param {number} current_alarm_config.threshold_min unit: A * @param {number} current_alarm_config.threshold_max unit: A * @param {number} current_alarm_config.alarm_interval unit: minute * @param {number} current_alarm_config.alarm_counts * @example { "current_chn1_alarm_config": { "condition": 1, "threshold_min": 100, "threshold_max": 200 } } */ function setCurrentThresholdAlarmConfig(index, current_alarm_config) { var condition = current_alarm_config.condition; var threshold_min = current_alarm_config.threshold_min; var threshold_max = current_alarm_config.threshold_max; var alarm_interval = current_alarm_config.alarm_interval; var alarm_counts = current_alarm_config.alarm_counts; var condition_map = { 0: "disable", 1: "below", 2: "above", 3: "between", 4: "outside" }; var condition_values = getValues(condition_map); if (condition_values.indexOf(condition) === -1) { throw new Error("current_chn" + index + "_alarm_config.condition must be one of " + condition_values.join(", ")); } var data = 0x00; data |= index << 3; // phrase A/B/C data |= getValue(condition_map, condition) << 0; var buffer = new Buffer(11); buffer.writeUInt8(0xff); buffer.writeUInt8(0x06); buffer.writeUInt8(data); buffer.writeUInt16LE(threshold_min); buffer.writeUInt16LE(threshold_max); buffer.writeUInt16LE(alarm_interval); buffer.writeUInt16LE(alarm_counts); return buffer.toBytes(); } /** * set temperature threshold alarm config * @param {object} temperature_alarm_config * @param {number} temperature_alarm_config.condition values: (0: disable, 1: below, 2: above, 3: between, 4: outside) * @param {number} temperature_alarm_config.threshold_min unit: °C * @param {number} temperature_alarm_config.threshold_max unit: °C * @example { "temperature_alarm_config": { "condition": 1, "threshold_min": 100, "threshold_max": 200 } } */ function setTemperatureThresholdAlarmConfig(temperature_alarm_config) { var condition = temperature_alarm_config.condition; var threshold_min = temperature_alarm_config.threshold_min; var threshold_max = temperature_alarm_config.threshold_max; var condition_map = { 0: "disable", 1: "below", 2: "above", 3: "between", 4: "outside" }; var condition_values = getValues(condition_map); if (condition_values.indexOf(condition) === -1) { throw new Error("temperature_alarm_config.condition must be one of " + condition_values.join(", ")); } var data = 0x00; data |= 0x04 << 3; // temperature data |= getValue(condition_map, condition) << 0; var buffer = new Buffer(11); buffer.writeUInt8(0xff); buffer.writeUInt8(0x06); buffer.writeUInt8(data); buffer.writeInt16LE(threshold_min * 10); buffer.writeInt16LE(threshold_max * 10); buffer.writeUInt32LE(0x00); // reserved return buffer.toBytes(); } /** * alarm report counts * @param {number} alarm_report_counts, range: [1, 1000] * @example { "alarm_report_counts": 1000 } */ function alarmReportCounts(alarm_report_counts) { if (typeof alarm_report_counts !== "number") { throw new Error("alarm_report_counts must be a number"); } if (alarm_report_counts < 1 || alarm_report_counts > 1000) { throw new Error("alarm_report_counts must be between 1 and 1000"); } var buffer = new Buffer(4); buffer.writeUInt8(0xff); buffer.writeUInt8(0xf2); buffer.writeUInt16LE(alarm_report_counts); return buffer.toBytes(); } /** * alarm report interval * @param {number} alarm_report_interval unit: minute, range: [1, 1440] * @example { "alarm_report_interval": 1 } */ function alarmReportInterval(alarm_report_interval) { if (typeof alarm_report_interval !== "number") { throw new Error("alarm_report_interval must be a number"); } if (alarm_report_interval < 1 || alarm_report_interval > 1440) { throw new Error("alarm_report_interval must be between 1 and 1440"); } var buffer = new Buffer(4); buffer.writeUInt8(0xff); buffer.writeUInt8(0x02); buffer.writeUInt16LE(alarm_report_interval); return buffer.toBytes(); } function getValues(map) { var values = []; for (var key in map) { values.push(RAW_VALUE ? parseInt(key) : map[key]); } return values; } function getValue(map, value) { if (RAW_VALUE) return value; for (var key in map) { if (map[key] === value) { return parseInt(key); } } throw new Error("not match in " + JSON.stringify(map)); } function Buffer(size) { this.buffer = new Array(size); this.offset = 0; for (var i = 0; i < size; i++) { this.buffer[i] = 0; } } Buffer.prototype._write = function (value, byteLength, isLittleEndian) { var offset = 0; for (var index = 0; index < byteLength; index++) { offset = isLittleEndian ? index << 3 : (byteLength - 1 - index) << 3; this.buffer[this.offset + index] = (value >> offset) & 0xff; } }; Buffer.prototype.writeUInt8 = function (value) { this._write(value, 1, true); this.offset += 1; }; Buffer.prototype.writeInt8 = function (value) { this._write(value < 0 ? value + 0x100 : value, 1, true); this.offset += 1; }; Buffer.prototype.writeUInt16LE = function (value) { this._write(value, 2, true); this.offset += 2; }; Buffer.prototype.writeInt16LE = function (value) { this._write(value < 0 ? value + 0x10000 : value, 2, true); this.offset += 2; }; Buffer.prototype.writeUInt32LE = function (value) { this._write(value, 4, true); this.offset += 4; }; Buffer.prototype.writeInt32LE = function (value) { this._write(value < 0 ? value + 0x100000000 : value, 4, true); this.offset += 4; }; Buffer.prototype.toBytes = function () { return this.buffer; };

This codec is sourced from Milesight-IoT. All rights belong to Milesight-IoT.

This codec is licensed under the GNU General Public License v3 (GPL v3). Modifications, if any, are clearly marked. You are free to use, modify, and distribute the codec under the terms of GPL v3.

Community Feedback