Sensor
/** * Payload Encoder * * Copyright 2025 Milesight IoT * * @product EM300-DI (HALL) */ 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 ("query_device_status" in payload) { encoded = encoded.concat(queryDeviceStatus(payload.query_device_status)); } if ("sync_time" in payload) { encoded = encoded.concat(syncTime(payload.sync_time)); } if ("report_interval" in payload) { encoded = encoded.concat(setReportInterval(payload.report_interval)); } if ("collection_interval" in payload) { encoded = encoded.concat(setCollectionInterval(payload.collection_interval)); } if ("time_zone" in payload) { encoded = encoded.concat(setTimeZone(payload.time_zone)); } if ("temperature_alarm_settings" in payload) { encoded = encoded.concat(setTemperatureAlarmSettings(payload.temperature_alarm_settings)); } if ("clear_counter" in payload) { encoded = encoded.concat(clearCounter(payload.clear_counter)); } if ("stop_counter" in payload) { encoded = encoded.concat(stopCounter(payload.stop_counter)); } if ("start_counter" in payload) { encoded = encoded.concat(startCounter(payload.start_counter)); } if ("counter" in payload) { encoded = encoded.concat(setCounter(payload.counter)); } if ("water_flow_alarm_settings" in payload) { encoded = encoded.concat(setWaterFlowAlarmSettings(payload.water_flow_alarm_settings)); } if ("water_flow_timeout_alarm_settings" in payload) { encoded = encoded.concat(setWaterFlowTimeoutAlarmConfig(payload.water_flow_timeout_alarm_settings)); } if ("water_outage_timeout_alarm_settings" in payload) { encoded = encoded.concat(setWaterOutageTimeoutAlarmSettings(payload.water_outage_timeout_alarm_settings)); } if ("pulse_conversion_settings" in payload) { encoded = encoded.concat(setPulseConversionSettings(payload.pulse_conversion_settings)); } if ("pulse_filter_enable" in payload) { encoded = encoded.concat(setPulseFilterEnable(payload.pulse_filter_enable)); } if ("water_flow_determination" in payload) { encoded = encoded.concat(setWaterFlowDetermination(payload.water_flow_determination)); } if ("d2d_key" in payload) { encoded = encoded.concat(setD2DKey(payload.d2d_key)); } if ("d2d_master_config" in payload) { for (var i = 0; i < payload.d2d_master_config.length; i++) { encoded = encoded.concat(setD2DMasterConfig(payload.d2d_master_config[i])); } } if ("gpio_mode" in payload) { encoded = encoded.concat(setGPIOMode(payload.gpio_mode)); } if ("history_enable" in payload) { encoded = encoded.concat(setHistoryEnable(payload.history_enable)); } if ("retransmit_enable" in payload) { encoded = encoded.concat(setRetransmitEnable(payload.retransmit_enable)); } if ("retransmit_interval" in payload) { encoded = encoded.concat(setRetransmitInterval(payload.retransmit_interval)); } if ("resend_interval" in payload) { encoded = encoded.concat(setResendInterval(payload.resend_interval)); } if ("fetch_history" in payload) { encoded = encoded.concat(fetchHistory(payload.fetch_history)); } if ("clear_history" in payload) { encoded = encoded.concat(clearHistory(payload.clear_history)); } if ("stop_transmit" in payload) { encoded = encoded.concat(stopTransmit(payload.stop_transmit)); } return encoded; } /** * reboot * @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]; } /** * query device status * @param {number} query_device_status values: (0: no, 1: yes) * @example { "query_device_status": 1 } */ function queryDeviceStatus(query_device_status) { var yes_no_map = { 0: "no", 1: "yes" }; var yes_no_values = getValues(yes_no_map); if (yes_no_values.indexOf(query_device_status) === -1) { throw new Error("query_device_status must be one of " + yes_no_values.join(", ")); } if (getValue(yes_no_map, query_device_status) === 0) { return []; } return [0xff, 0x28, 0xff]; } /** * sync time * @param {number} sync_time values: (0: no, 1: yes) * @example { "sync_time": 1 } */ function syncTime(sync_time) { var yes_no_map = { 0: "no", 1: "yes" }; var yes_no_values = getValues(yes_no_map); if (yes_no_values.indexOf(sync_time) === -1) { throw new Error("sync_time must be one of " + yes_no_values.join(", ")); } if (getValue(yes_no_map, sync_time) === 0) { return []; } return [0xff, 0x4a, 0x00]; } /** * report interval configuration * @param {number} report_interval uint: second, range: [60, 64800] * @example { "report_interval": 1200 } */ function setReportInterval(report_interval) { if (typeof report_interval !== "number") { throw new Error("report_interval must be a number"); } if (report_interval < 60 || report_interval > 64800) { throw new Error("report_interval must be in the range of [60, 64800]"); } var buffer = new Buffer(4); buffer.writeUInt8(0xff); buffer.writeUInt8(0x03); buffer.writeUInt16LE(report_interval); return buffer.toBytes(); } /** * collection interval * @param {number} collection_interval unit: second, range: [60, 64800] * @example { "collection_interval": 60 } */ function setCollectionInterval(collection_interval) { if (typeof collection_interval !== "number") { throw new Error("collection_interval must be a number"); } if (collection_interval < 60 || collection_interval > 64800) { throw new Error("collection_interval must be in range [60, 64800]"); } var buffer = new Buffer(4); buffer.writeUInt8(0xff); buffer.writeUInt8(0x02); buffer.writeUInt16LE(collection_interval); return buffer.toBytes(); } /** * set time zone * @param {number} time_zone unit: minute, UTC+8 -> 8 * 10 = 80 * @example { "time_zone": 80 } */ function setTimeZone(time_zone) { var timezone_map = { "-120": "UTC-12", "-110": "UTC-11", "-100": "UTC-10", "-95": "UTC-9:30", "-90": "UTC-9", "-80": "UTC-8", "-70": "UTC-7", "-60": "UTC-6", "-50": "UTC-5", "-40": "UTC-4", "-35": "UTC-3:30", "-30": "UTC-3", "-20": "UTC-2", "-10": "UTC-1", 0: "UTC", 10: "UTC+1", 20: "UTC+2", 30: "UTC+3", 35: "UTC+3:30", 40: "UTC+4", 45: "UTC+4:30", 50: "UTC+5", 55: "UTC+5:30", 57: "UTC+5:45", 60: "UTC+6", 65: "UTC+6:30", 70: "UTC+7", 80: "UTC+8", 90: "UTC+9", 95: "UTC+9:30", 100: "UTC+10", 105: "UTC+10:30", 110: "UTC+11", 120: "UTC+12", 127: "UTC+12:45", 130: "UTC+13", 140: "UTC+14" }; var timezone_values = getValues(timezone_map); if (timezone_values.indexOf(time_zone) === -1) { throw new Error("time_zone must be one of " + timezone_values.join(", ")); } var buffer = new Buffer(4); buffer.writeUInt8(0xff); buffer.writeUInt8(0x17); buffer.writeInt16LE(getValue(timezone_map, time_zone)); return buffer.toBytes(); } /** * set temperature alarm config * @param {object} temperature_alarm_settings * @param {number} temperature_alarm_settings.condition values: (0: disable, 1: below, 2: above, 3: between, 4: outside) * @param {number} temperature_alarm_settings.threshold_min unit: °C * @param {number} temperature_alarm_settings.threshold_max unit: °C * @example { "temperature_alarm_settings": { "condition": 1, "threshold_min": 100, "threshold_max": 200 } } */ function setTemperatureAlarmSettings(temperature_alarm_settings) { var condition = temperature_alarm_settings.condition; var threshold_min = temperature_alarm_settings.threshold_min; var threshold_max = temperature_alarm_settings.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_settings.condition must be one of " + condition_values.join(", ")); } var data = 0x00; data |= 0x01 << 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.writeUInt16LE(0x00); buffer.writeUInt16LE(0x00); return buffer.toBytes(); } /** * set clear counter * @param {number} clear_counter values: (0: no, 1: yes) * @example { "clear_counter": 1 } */ function clearCounter(clear_counter) { var yes_no_map = { 0: "no", 1: "yes" }; var yes_no_values = getValues(yes_no_map); if (yes_no_values.indexOf(clear_counter) === -1) { throw new Error("clear_counter must be one of " + yes_no_values.join(", ")); } if (getValue(yes_no_map, clear_counter) === 0) { return []; } return [0xff, 0x4e, 0x01, 0x00]; } /** * stop counter * @param {number} stop_counter values: (0: no, 1: yes) * @example { "stop_counter": 1 } */ function stopCounter(stop_counter) { var yes_no_map = { 0: "no", 1: "yes" }; var yes_no_values = getValues(yes_no_map); if (yes_no_values.indexOf(stop_counter) === -1) { throw new Error("stop_counter must be one of " + yes_no_values.join(", ")); } if (getValue(yes_no_map, stop_counter) === 0) { return []; } return [0xff, 0x4e, 0x01, 0x01]; } /** * start counter * @param {number} start_counter values: (0: no, 1: yes) * @example { "start_counter": 1 } */ function startCounter(start_counter) { var yes_no_map = { 0: "no", 1: "yes" }; var yes_no_values = getValues(yes_no_map); if (yes_no_values.indexOf(start_counter) === -1) { throw new Error("start_counter must be one of " + yes_no_values.join(", ")); } if (getValue(yes_no_map, start_counter) === 0) { return []; } return [0xff, 0x4e, 0x01, 0x02]; } /** * set counter * @param {number} counter * @example { "counter": 1200 } */ function setCounter(counter) { if (counter < 0) { throw new Error("counter must be greater than 0"); } var buffer = new Buffer(7); buffer.writeUInt8(0xff); buffer.writeUInt8(0x92); buffer.writeUInt8(0x01); buffer.writeUInt32LE(counter); return buffer.toBytes(); } /** * set water flow alarm config * @param {object} water_flow_alarm_settings * @param {number} water_flow_alarm_settings.enable values: (0: disable, 1: enable) * @param {number} water_flow_alarm_settings.duration unit: minute, range: [1, 64800] * @example { "water_flow_alarm_settings": { "enable": 1, "duration": 1200 } } */ function setWaterFlowAlarmSettings(water_flow_alarm_settings) { var enable = water_flow_alarm_settings.enable; var duration = water_flow_alarm_settings.duration; var enable_map = { 0: "disable", 1: "enable" }; var enable_values = getValues(enable_map); if (enable_values.indexOf(enable) === -1) { throw new Error("water_flow_alarm_settings.enable must be one of " + enable_values.join(", ")); } var buffer = new Buffer(9); buffer.writeUInt8(0xff); buffer.writeUInt8(0xa1); buffer.writeUInt8(0x01); buffer.writeUInt8(0x00); // water flow buffer.writeUInt8(getValue(enable_map, enable)); buffer.writeUInt32LE(duration); return buffer.toBytes(); } /** * set water flow timeout alarm config * @param {object} water_flow_timeout_alarm_settings * @param {number} water_flow_timeout_alarm_settings.enable values: (0: disable, 1: enable) * @param {number} water_flow_timeout_alarm_settings.duration unit: minute, range: [1, 64800] * @example { "water_flow_timeout_alarm_settings": { "enable": 1, "duration": 1200 } } */ function setWaterFlowTimeoutAlarmConfig(water_flow_timeout_alarm_settings) { var enable = water_flow_timeout_alarm_settings.enable; var duration = water_flow_timeout_alarm_settings.duration; var enable_map = { 0: "disable", 1: "enable" }; var enable_values = getValues(enable_map); if (enable_values.indexOf(enable) === -1) { throw new Error("water_flow_timeout_alarm_settings.enable must be one of " + enable_values.join(", ")); } var buffer = new Buffer(9); buffer.writeUInt8(0xff); buffer.writeUInt8(0xa1); buffer.writeUInt8(0x01); buffer.writeUInt8(0x01); // water flow timeout buffer.writeUInt8(getValue(enable_map, enable)); buffer.writeUInt32LE(duration); return buffer.toBytes(); } /** * set water outage timeout alarm config * @param {object} water_outage_timeout_alarm_settings * @param {number} water_outage_timeout_alarm_settings.enable values: (0: disable, 1: enable) * @param {number} water_outage_timeout_alarm_settings.duration unit: minute, range: [1, 64800] * @example { "water_outage_timeout_alarm_settings": { "enable": 1, "duration": 1200 } } */ function setWaterOutageTimeoutAlarmSettings(water_outage_timeout_alarm_settings) { var enable = water_outage_timeout_alarm_settings.enable; var duration = water_outage_timeout_alarm_settings.duration; var enable_map = { 0: "disable", 1: "enable" }; var enable_values = getValues(enable_map); if (enable_values.indexOf(enable) === -1) { throw new Error("water_outage_timeout_alarm_settings.enable must be one of " + enable_values.join(", ")); } var buffer = new Buffer(9); buffer.writeUInt8(0xff); buffer.writeUInt8(0xa1); buffer.writeUInt8(0x01); buffer.writeUInt8(0x02); // water outage timeout buffer.writeUInt8(getValue(enable_map, enable)); buffer.writeUInt32LE(duration); return buffer.toBytes(); } /** * set pulse conversion config * @param {object} pulse_conversion_settings * @param {number} pulse_conversion_settings.enable values: (0: disable, 1: enable) * @param {number} pulse_conversion_settings.water decimal: 0.1 * @param {number} pulse_conversion_settings.pulse decimal: 0.1 * @param {string} pulse_conversion_settings.unit * @example { "pulse_conversion_settings": { "enable": 1, "water": 1000, "pulse": 1000, "unit": "mL" } } */ function setPulseConversionSettings(pulse_conversion_settings) { var enable = pulse_conversion_settings.enable; var water = pulse_conversion_settings.water; var pulse = pulse_conversion_settings.pulse; var unit = pulse_conversion_settings.unit; var enable_map = { 0: "disable", 1: "enable" }; var enable_values = getValues(enable_map); if (enable_values.indexOf(enable) === -1) { throw new Error("pulse_conversion_settings.enable must be one of " + enable_values.join(", ")); } var buffer = new Buffer(11); buffer.writeUInt8(0xff); buffer.writeUInt8(0xa2); buffer.writeUInt8(getValue(enable_map, enable)); buffer.writeUInt16LE(water * 10); buffer.writeUInt16LE(pulse * 10); buffer.writeUtf8(unit); return buffer.toBytes(); } /** * set pulse filter enable * @param {number} pulse_filter_enable values: (0: disable, 1: enable) * @example { "pulse_filter_enable": 1 } */ function setPulseFilterEnable(pulse_filter_enable) { var enable_map = { 0: "disable", 1: "enable" }; var enable_values = getValues(enable_map); if (enable_values.indexOf(pulse_filter_enable) === -1) { throw new Error("pulse_filter_enable must be one of " + enable_values.join(", ")); } var buffer = new Buffer(4); buffer.writeUInt8(0xff); buffer.writeUInt8(0xa3); buffer.writeUInt8(0x01); buffer.writeUInt8(getValue(enable_map, pulse_filter_enable)); return buffer.toBytes(); } /** * set water flow determination * @param {number} water_flow_determination unit: second * @example { "water_flow_determination": 1 } */ function setWaterFlowDetermination(water_flow_determination) { var buffer = new Buffer(4); buffer.writeUInt8(0xff); buffer.writeUInt8(0xa4); buffer.writeUInt16LE(water_flow_determination); return buffer.toBytes(); } /** * set d2d key * @since hardware_version v2.0, firmware_version v1.7 * @param {string} d2d_key * @example { "d2d_key": "0000000000000000" } */ function setD2DKey(d2d_key) { if (typeof d2d_key !== "string") { throw new Error("d2d_key must be a string"); } if (d2d_key.length !== 16) { throw new Error("d2d_key must be 16 characters"); } if (!/^[0-9a-fA-F]+$/.test(d2d_key)) { throw new Error("d2d_key must be hex string [0-9A-F]"); } var data = hexStringToBytes(d2d_key); var buffer = new Buffer(10); buffer.writeUInt8(0xff); buffer.writeUInt8(0x35); buffer.writeBytes(data); return buffer.toBytes(); } /** * set d2d master config * @param {object} d2d_master_config * @param {number} d2d_master_config.mode values: (1: water outage timeout alarm, 2: water outage timeout alarm release, 3: water flow timeout alarm, 4: water flow timeout alarm release, 5: gpio high, 6: gpio low) * @param {number} d2d_master_config.enable values: (0: disable, 1: enable) * @param {number} d2d_master_config.lora_uplink_enable values: (0: d2d command, 1: d2d command release) * @param {string} d2d_master_config.d2d_cmd * @example { "d2d_master_config": { "mode": 1, "enable": 1, "d2d_cmd_type": 0, "d2d_cmd": "0000" } } */ function setD2DMasterConfig(d2d_master_config) { var mode = d2d_master_config.mode; var enable = d2d_master_config.enable; var lora_uplink_enable = d2d_master_config.lora_uplink_enable; var d2d_cmd = d2d_master_config.d2d_cmd; var mode_map = { 1: "water outage timeout alarm", 2: "water outage timeout alarm release", 3: "water flow timeout alarm", 4: "water flow timeout alarm release", 5: "gpio high", 6: "gpio low" }; var mode_values = getValues(mode_map); if (mode_values.indexOf(mode) === -1) { throw new Error("d2d_master_config._item.mode must be one of " + mode_values.join(", ")); } var enable_map = { 0: "disable", 1: "enable" }; var enable_values = getValues(enable_map); if (enable_values.indexOf(enable) === -1) { throw new Error("d2d_master_config._item.enable must be one of " + enable_values.join(", ")); } if (enable_values.indexOf(lora_uplink_enable) === -1) { throw new Error("d2d_master_config._item.lora_uplink_enable must be one of " + enable_values.join(", ")); } var data = 0x00; data |= getValue(enable_map, enable) << 0; data |= getValue(enable_map, lora_uplink_enable) << 1; var buffer = new Buffer(6); buffer.writeUInt8(0xff); buffer.writeUInt8(0x79); buffer.writeUInt8(getValue(mode_map, mode)); buffer.writeUInt8(data); buffer.writeD2DCommand(d2d_cmd, "0000"); return buffer.toBytes(); } /** * set gpio mode * @param {number} gpio_mode values: (1: digital, 2: counter) * @example { "gpio_mode": 1 } */ function setGPIOMode(gpio_mode) { var mode_map = { 1: "digital", 2: "counter" }; var mode_values = getValues(mode_map); if (mode_values.indexOf(gpio_mode) === -1) { throw new Error("gpio_mode must be one of " + mode_values.join(", ")); } var buffer = new Buffer(3); buffer.writeUInt8(0xff); buffer.writeUInt8(0xc3); buffer.writeUInt8(getValue(mode_map, gpio_mode)); return buffer.toBytes(); } /** * history enable * @param {number} history_enable values: (0: disable, 1: enable) * @example { "history_enable": 1 } */ function setHistoryEnable(history_enable) { var enable_map = { 0: "disable", 1: "enable" }; var enable_values = getValues(enable_map); if (enable_values.indexOf(history_enable) === -1) { throw new Error("history_enable must be one of " + enable_values.join(", ")); } var buffer = new Buffer(3); buffer.writeUInt8(0xff); buffer.writeUInt8(0x68); buffer.writeUInt8(getValue(enable_map, history_enable)); return buffer.toBytes(); } /** * retransmit enable * @param {number} retransmit_enable values: (0: disable, 1: enable) * @example { "retransmit_enable": 1 } */ function setRetransmitEnable(retransmit_enable) { var enable_map = { 0: "disable", 1: "enable" }; var enable_values = getValues(enable_map); if (enable_values.indexOf(retransmit_enable) === -1) { throw new Error("retransmit_enable must be one of " + enable_values.join(", ")); } var buffer = new Buffer(3); buffer.writeUInt8(0xff); buffer.writeUInt8(0x69); buffer.writeUInt8(getValue(enable_map, retransmit_enable)); return buffer.toBytes(); } /** * retransmit interval * @param {number} retransmit_interval unit: seconds * @example { "retransmit_interval": 300 } */ function setRetransmitInterval(retransmit_interval) { if (typeof retransmit_interval !== "number") { throw new Error("retransmit_interval must be a number"); } if (retransmit_interval < 1 || retransmit_interval > 64800) { throw new Error("retransmit_interval must be between 1 and 64800"); } var buffer = new Buffer(5); buffer.writeUInt8(0xff); buffer.writeUInt8(0x6a); buffer.writeUInt8(0x00); buffer.writeUInt16LE(retransmit_interval); return buffer.toBytes(); } /** * retransmit interval * @param {number} resend_interval unit: seconds * @example { "resend_interval": 300 } */ function setResendInterval(resend_interval) { if (typeof resend_interval !== "number") { throw new Error("resend_interval must be a number"); } if (resend_interval < 1 || resend_interval > 64800) { throw new Error("resend_interval must be between 1 and 64800"); } var buffer = new Buffer(5); buffer.writeUInt8(0xff); buffer.writeUInt8(0x6a); buffer.writeUInt8(0x01); buffer.writeUInt16LE(resend_interval); return buffer.toBytes(); } /** * fetch history * @param {object} fetch_history * @param {number} fetch_history.start_time * @param {number} fetch_history.end_time * @example { "fetch_history": { "start_time": 1609459200, "end_time": 1609545600 } } */ function fetchHistory(fetch_history) { var start_time = fetch_history.start_time; var end_time = fetch_history.end_time || 0; if (typeof start_time !== "number") { throw new Error("start_time must be a number"); } if ("end_time" in fetch_history && typeof end_time !== "number") { throw new Error("end_time must be a number"); } if ("end_time" in fetch_history && start_time > end_time) { throw new Error("start_time must be less than end_time"); } var buffer; if (end_time === 0) { buffer = new Buffer(6); buffer.writeUInt8(0xfd); buffer.writeUInt8(0x6b); buffer.writeUInt32LE(start_time); } else { buffer = new Buffer(10); buffer.writeUInt8(0xfd); buffer.writeUInt8(0x6c); buffer.writeUInt32LE(start_time); buffer.writeUInt32LE(end_time); } return buffer.toBytes(); } /** * clear history * @param {number} clear_history values: (0: no, 1: yes) * @example { "clear_history": 1 } */ function clearHistory(clear_history) { var yes_no_map = { 0: "no", 1: "yes" }; var yes_no_values = getValues(yes_no_map); if (yes_no_values.indexOf(clear_history) === -1) { throw new Error("clear_history must be one of " + yes_no_values.join(", ")); } if (getValue(yes_no_map, clear_history) === 0) { return []; } return [0xff, 0x27, 0x01]; } /** * history stop transmit * @param {number} stop_transmit values: (0: no, 1: yes) * @example { "stop_transmit": 1 } */ function stopTransmit(stop_transmit) { var yes_no_map = { 0: "no", 1: "yes" }; var yes_no_values = getValues(yes_no_map); if (yes_no_values.indexOf(stop_transmit) === -1) { throw new Error("stop_transmit must be one of " + yes_no_values.join(", ")); } if (getValue(yes_no_map, stop_transmit) === 0) { return []; } return [0xfd, 0x6d, 0xff]; } 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.writeUInt24LE = function (value) { this._write(value, 3, true); this.offset += 3; }; Buffer.prototype.writeInt24LE = function (value) { this._write(value < 0 ? value + 0x1000000 : value, 3, true); this.offset += 3; }; 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; }; Buffer.prototype.writeUtf8 = function (str) { var bytes = []; for (var i = 0; i < str.length; i++) { var charCode = str.charCodeAt(i); if (charCode < 0x80) { bytes.push(charCode); } else if (charCode < 0x800) { bytes.push(0xc0 | (charCode >> 6)); bytes.push(0x80 | (charCode & 0x3f)); } else if (charCode < 0x10000) { bytes.push(0xe0 | (charCode >> 12)); bytes.push(0x80 | ((charCode >> 6) & 0x3f)); bytes.push(0x80 | (charCode & 0x3f)); } else if (charCode < 0x200000) { bytes.push(0xf0 | (charCode >> 18)); bytes.push(0x80 | ((charCode >> 12) & 0x3f)); bytes.push(0x80 | ((charCode >> 6) & 0x3f)); bytes.push(0x80 | (charCode & 0x3f)); } } this.writeBytes(bytes); }; Buffer.prototype.writeD2DCommand = function (value, defaultValue) { if (typeof value !== "string") { value = defaultValue; } if (value.length !== 4) { throw new Error("d2d_cmd length must be 4"); } this.buffer[this.offset] = parseInt(value.substr(2, 2), 16); this.buffer[this.offset + 1] = parseInt(value.substr(0, 2), 16); this.offset += 2; }; Buffer.prototype.toBytes = function () { return this.buffer; }; Buffer.prototype.writeBytes = function (bytes) { for (var i = 0; i < bytes.length; i++) { this.buffer[this.offset + i] = bytes[i]; } this.offset += bytes.length; }; function hexStringToBytes(hex) { var bytes = []; for (var c = 0; c < hex.length; c += 2) { bytes.push(parseInt(hex.substr(c, 2), 16)); } return bytes; }
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.