diff --git a/vendor/jooby/analog-gasi3.js b/vendor/jooby/analog-gasi3.js new file mode 100644 index 0000000000..4ed8f7a29f --- /dev/null +++ b/vendor/jooby/analog-gasi3.js @@ -0,0 +1,4212 @@ +// https://github.com/jooby-dev/jooby-codec/blob/main/src/analog/constants/hardwareTypes.ts +const config = { + // GASI3 + hardwareType: 3 +}; + +// helper +const decode = ( fromBytes, input ) => { + const data = {bytes: input.bytes}; + const decodeResult = fromBytes(input.bytes, config); + const errors = []; + + if ( decodeResult.error ) { + errors.push(decodeResult.error); + // there may be some partially decoded result + data.message = decodeResult.message; + } else { + data.message = decodeResult; + } + + return {data, errors}; +}; + +// will have encoder/decoder after init +let message; + + +/* + Get bytes from message. + + Input is an object with the following fields: + * data - object, must contain "commands" field + * fPort - downlink fPort + + Output must be an object with the following fields: + * bytes - byte array containing the downlink payload +*/ +function encodeDownlink ( input ) { + let bytes = message.downlink.toBytes(input.data.commands, config); + + return {bytes, fPort: 1}; +} + +/* + Get message from bytes. + + Input is an object with the following fields: + * bytes - byte array containing the uplink payload, e.g. [255, 230, 255, 0] + * fPort - uplink fPort + + Output must be an object with the following fields: + * data - object representing the decoded payload +*/ +function decodeUplink ( input ) { + return decode(message.uplink.fromBytes, input); +} + +/* + Get message from bytes. + + Input is an object with the following fields: + * bytes - byte array containing the downlink payload, e.g. [255, 230, 255, 0] + * fPort - downlink fPort + + Output must be an object with the following fields: + * data - object representing the decoded payload +*/ +function decodeDownlink ( input ) { + return decode(message.downlink.fromBytes, input); +} + + +//#region [autogenerated jooby-codec bundle from index.js] +(function () { + 'use strict'; + + const hexFormatOptions = { + separator: ' ', + prefix: '' + }; + + const INT8_SIZE = 1; + const INT16_SIZE = 2; + const INT24_SIZE = 3; + const INT32_SIZE = 4; + const { + log, + pow, + LN2 + } = Math; + const readFloat = (buffer, offset, isLittleEndian, mLen, bytes) => { + var e, + m, + eLen = bytes * 8 - mLen - 1, + eMax = (1 << eLen) - 1, + eBias = eMax >> 1, + nBits = -7, + i = isLittleEndian ? bytes - 1 : 0, + d = isLittleEndian ? -1 : 1, + s = buffer[offset + i]; + i += d; + e = s & (1 << -nBits) - 1; + s >>= -nBits; + nBits += eLen; + for (; nBits > 0; e = e * 0x100 + buffer[offset + i], i += d, nBits -= 8); + m = e & (1 << -nBits) - 1; + e >>= -nBits; + nBits += mLen; + for (; nBits > 0; m = m * 0x100 + buffer[offset + i], i += d, nBits -= 8); + if (e === 0) { + e = 1 - eBias; + } else if (e === eMax) { + return m ? NaN : s ? -Infinity : Infinity; + } else { + m = m + pow(2, mLen); + e = e - eBias; + } + return (s ? -1 : 1) * m * pow(2, e - mLen); + }; + const writeFloat = (buffer, offset, value, isLittleEndian, mLen, bytes) => { + var e, + m, + c, + eLen = bytes * 8 - mLen - 1, + eMax = (1 << eLen) - 1, + eBias = eMax >> 1, + rt = mLen === 23 ? pow(2, -24) - pow(2, -77) : 0, + i = isLittleEndian ? 0 : bytes - 1, + d = isLittleEndian ? 1 : -1, + s = value < 0 || value === 0 && 1 / value < 0 ? 1 : 0; + value < 0 && (value = -value); + if (value !== value || value === Infinity) { + m = value !== value ? 1 : 0; + e = eMax; + } else { + e = log(value) / LN2 | 0; + if (value * (c = pow(2, -e)) < 1) { + e--; + c *= 2; + } + if (e + eBias >= 1) { + value += rt / c; + } else { + value += rt * pow(2, 1 - eBias); + } + if (value * c >= 2) { + e++; + c /= 2; + } + if (e + eBias >= eMax) { + m = 0; + e = eMax; + } else if (e + eBias >= 1) { + m = (value * c - 1) * pow(2, mLen); + e = e + eBias; + } else { + m = value * pow(2, eBias - 1) * pow(2, mLen); + e = 0; + } + } + for (; mLen >= 8; buffer[offset + i] = m & 0xff, i += d, m /= 0x100, mLen -= 8); + e = e << mLen | m; + eLen += mLen; + for (; eLen > 0; buffer[offset + i] = e & 0xff, i += d, e /= 0x100, eLen -= 8); + buffer[offset + i - d] |= s * 0x80; + }; + const be2 = [1, 0]; + const be3 = [2, 1, 0]; + const be4 = [3, 2, 1, 0]; + const le2 = [0, 1]; + const le3 = [0, 1, 2]; + const le4 = [0, 1, 2, 3]; + const readUint8 = (buffer, offset) => buffer[offset]; + const readUint16 = (buffer, offset, isLittleEndian) => { + const order = isLittleEndian ? le2 : be2; + const b0 = buffer[offset + order[0]]; + const b1 = buffer[offset + order[1]] << 8; + return b0 | b1; + }; + const readUint24 = (buffer, offset, isLittleEndian) => { + const order = isLittleEndian ? le3 : be3; + const b0 = buffer[offset + order[0]]; + const b1 = buffer[offset + order[1]] << 8; + const b2 = buffer[offset + order[2]] << 16; + return b0 | b1 | b2; + }; + const readUint32 = (buffer, offset, isLittleEndian) => { + const order = isLittleEndian ? le4 : be4; + const b0 = buffer[offset + order[3]] * 0x1000000; + const b1 = buffer[offset + order[2]] * 0x10000; + const b2 = buffer[offset + order[1]] * 0x100; + const b3 = buffer[offset + order[0]]; + return b0 + b1 + b2 + b3; + }; + const writeUint8 = (buffer, offset, value) => { + buffer[offset] = value & 0xff; + }; + const writeUint16 = (buffer, offset, value, isLittleEndian) => { + const order = isLittleEndian ? le2 : be2; + buffer[offset + order[0]] = value & 0xff; + buffer[offset + order[1]] = value >>> 8 & 0xff; + }; + const writeUint24 = (buffer, offset, value, isLittleEndian) => { + const order = isLittleEndian ? le3 : be3; + buffer[offset + order[0]] = value & 0xff; + buffer[offset + order[1]] = value >>> 8 & 0xff; + buffer[offset + order[2]] = value >>> 16 & 0xff; + }; + const writeUint32 = (buffer, offset, value, isLittleEndian) => { + const order = isLittleEndian ? le4 : be4; + buffer[offset + order[0]] = value & 0xff; + buffer[offset + order[1]] = value >>> 8 & 0xff; + buffer[offset + order[2]] = value >>> 16 & 0xff; + buffer[offset + order[3]] = value >>> 24 & 0xff; + }; + function BinaryBuffer(dataOrLength) { + let isLittleEndian = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : true; + if (typeof dataOrLength === 'number') { + const bytes = new Array(dataOrLength).fill(0); + this.data = bytes; + } else { + this.data = dataOrLength; + } + this.offset = 0; + this.isLittleEndian = isLittleEndian; + } + BinaryBuffer.prototype = { + toUint8Array() { + return this.data; + }, + seek(position) { + if (position < 0 || position >= this.data.length) { + throw new Error('Invalid position.'); + } + this.offset = position; + }, + setInt8(value) { + writeUint8(this.data, this.offset, value < 0 ? value | 0x100 : value); + this.offset += INT8_SIZE; + }, + getInt8() { + const result = readUint8(this.data, this.offset); + this.offset += INT8_SIZE; + return result & 0x80 ? result ^ -256 : result; + }, + setUint8(value) { + writeUint8(this.data, this.offset, value); + this.offset += INT8_SIZE; + }, + getUint8() { + const result = readUint8(this.data, this.offset); + this.offset += INT8_SIZE; + return result; + }, + setInt16(value) { + let isLittleEndian = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : this.isLittleEndian; + writeUint16(this.data, this.offset, value < 0 ? value | 0x10000 : value, isLittleEndian); + this.offset += INT16_SIZE; + }, + getInt16() { + let isLittleEndian = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : this.isLittleEndian; + const result = readUint16(this.data, this.offset, isLittleEndian); + this.offset += INT16_SIZE; + return result & 0x8000 ? result ^ -65536 : result; + }, + setUint16(value) { + let isLittleEndian = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : this.isLittleEndian; + writeUint16(this.data, this.offset, value, isLittleEndian); + this.offset += INT16_SIZE; + }, + getUint16() { + let isLittleEndian = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : this.isLittleEndian; + const result = readUint16(this.data, this.offset, isLittleEndian); + this.offset += INT16_SIZE; + return result; + }, + setInt24(value) { + let isLittleEndian = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : this.isLittleEndian; + writeUint24(this.data, this.offset, value < 0 ? value | 0x1000000 : value, isLittleEndian); + this.offset += INT24_SIZE; + }, + getInt24() { + let isLittleEndian = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : this.isLittleEndian; + const result = readUint24(this.data, this.offset, isLittleEndian); + this.offset += INT24_SIZE; + return result & 0x800000 ? result ^ -16777216 : result; + }, + setUint24(value) { + let isLittleEndian = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : this.isLittleEndian; + writeUint24(this.data, this.offset, value, isLittleEndian); + this.offset += INT24_SIZE; + }, + getUint24() { + let isLittleEndian = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : this.isLittleEndian; + const result = readUint24(this.data, this.offset, isLittleEndian); + this.offset += INT24_SIZE; + return result; + }, + setInt32(value) { + let isLittleEndian = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : this.isLittleEndian; + writeUint32(this.data, this.offset, value < 0 ? value | 0x100000000 : value, isLittleEndian); + this.offset += INT32_SIZE; + }, + getInt32() { + let isLittleEndian = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : this.isLittleEndian; + const result = readUint32(this.data, this.offset, isLittleEndian); + this.offset += INT32_SIZE; + return result & 0x80000000 ? result ^ -4294967296 : result; + }, + setUint32(value) { + let isLittleEndian = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : this.isLittleEndian; + writeUint32(this.data, this.offset, value, isLittleEndian); + this.offset += INT32_SIZE; + }, + getUint32() { + let isLittleEndian = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : this.isLittleEndian; + const result = readUint32(this.data, this.offset, isLittleEndian); + this.offset += INT32_SIZE; + return result; + }, + setFloat32(value) { + let isLittleEndian = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : this.isLittleEndian; + writeFloat(this.data, this.offset, value, isLittleEndian, 23, 4); + this.offset += INT32_SIZE; + }, + getFloat32() { + let isLittleEndian = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : this.isLittleEndian; + const result = readFloat(this.data, this.offset, isLittleEndian, 23, 4); + this.offset += INT32_SIZE; + return result; + }, + setString(value) { + this.setUint8(value.length); + for (let index = 0; index < value.length; ++index) { + this.setUint8(value.charCodeAt(index)); + } + }, + getString() { + const size = this.getUint8(); + const endIndex = this.offset + size; + const chars = []; + while (this.offset < endIndex) { + chars.push(String.fromCharCode(this.getUint8())); + } + return chars.join(''); + }, + getBytesToOffset() { + let offset = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : this.offset; + return this.data.slice(0, offset); + }, + getBytesLeft() { + return this.getBytes(this.bytesLeft); + }, + getBytes(length) { + let offset = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : this.offset; + this.offset = offset + length; + return this.data.slice(offset, this.offset); + }, + setBytes(data) { + let offset = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : this.offset; + const bytes = this.data; + bytes.splice(offset, data.length, ...data); + this.data = bytes; + this.offset = offset + data.length; + } + }; + Object.defineProperties(BinaryBuffer.prototype, { + size: { + get() { + return this.data.length; + } + }, + isEmpty: { + get() { + if (this.offset > this.data.length) { + throw new Error(`current offset ${this.offset} is outside the bounds of the buffer`); + } + return this.data.length - this.offset === 0; + } + }, + bytesLeft: { + get() { + return this.data.length - this.offset; + } + }, + position: { + get() { + return this.offset; + } + } + }); + + const shortCommandMask = 0xe0; + const extraCommandMask = 0x1f; + const fromBytes$11 = data => { + if (data.length === 0) { + throw new Error('Invalid buffer size'); + } + const header = { + shortCode: data[0] & shortCommandMask, + extraCode: data[0] & extraCommandMask + }; + if (header.shortCode !== 0) { + return { + headerSize: 1, + commandId: data[0] & ~header.extraCode, + commandSize: header.extraCode + }; + } + if (header.extraCode === extraCommandMask) { + if (data.length < 3) { + throw new Error('Invalid buffer size'); + } + return { + headerSize: 3, + commandId: data[1] << 8 | extraCommandMask, + commandSize: data[2] + }; + } + if (data.length < 2) { + throw new Error('Invalid buffer size'); + } + return { + headerSize: 2, + commandId: header.extraCode, + commandSize: data[1] + }; + }; + const toBytes$12 = (commandId, commandSize) => { + if ((commandId & extraCommandMask) === 0) { + if (commandSize > extraCommandMask) { + throw new Error(`Wrong command id/size. Id: ${commandId}, size: ${commandSize}.`); + } + return [commandId | commandSize]; + } + if (commandId > extraCommandMask) { + return [extraCommandMask, commandId >> 8, commandSize]; + } + return [commandId, commandSize]; + }; + + const toBytes$11 = function (commandId) { + let commandData = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : []; + const headerData = toBytes$12(commandId, commandData.length); + return [...headerData, ...commandData]; + }; + + const setTime2000$1 = 0x02; + const setParameter$1 = 0x03; + const getParameter$1 = 0x04; + const getArchiveHours$1 = 0x05; + const getArchiveDays$1 = 0x06; + const getCurrent = 0x07; + const getTime2000 = 0x09; + const getArchiveEvents$1 = 0x0b; + const correctTime2000$1 = 0x0c; + const getStatus = 0x14; + const getCurrentMc = 0x18; + const softRestart$1 = 0x19; + const getArchiveHoursMc$1 = 0x1a; + const getArchiveDaysMc$1 = 0x1b; + const dataSegment$1 = 0x1e; + const getLmicInfo$1 = 0x21f; + const getBatteryStatus$1 = 0x51f; + const usWaterMeterCommand$1 = 0x71f; + const getExAbsArchiveHoursMc$1 = 0xc1f; + const getExAbsArchiveDaysMc$1 = 0xd1f; + const getExAbsCurrentMc = 0xf1f; + const writeImage$1 = 0x2a1f; + const verifyImage$1 = 0x2b1f; + const updateRun$1 = 0x2c1f; + const getArchiveHoursMcEx$1 = 0x301f; + const getChannelsStatus$1 = 0x321f; + const getChannelsTypes$1 = 0x331f; + + var downlinkIds = /*#__PURE__*/Object.freeze({ + __proto__: null, + correctTime2000: correctTime2000$1, + dataSegment: dataSegment$1, + getArchiveDays: getArchiveDays$1, + getArchiveDaysMc: getArchiveDaysMc$1, + getArchiveEvents: getArchiveEvents$1, + getArchiveHours: getArchiveHours$1, + getArchiveHoursMc: getArchiveHoursMc$1, + getArchiveHoursMcEx: getArchiveHoursMcEx$1, + getBatteryStatus: getBatteryStatus$1, + getChannelsStatus: getChannelsStatus$1, + getChannelsTypes: getChannelsTypes$1, + getCurrent: getCurrent, + getCurrentMc: getCurrentMc, + getExAbsArchiveDaysMc: getExAbsArchiveDaysMc$1, + getExAbsArchiveHoursMc: getExAbsArchiveHoursMc$1, + getExAbsCurrentMc: getExAbsCurrentMc, + getLmicInfo: getLmicInfo$1, + getParameter: getParameter$1, + getStatus: getStatus, + getTime2000: getTime2000, + setParameter: setParameter$1, + setTime2000: setTime2000$1, + softRestart: softRestart$1, + updateRun: updateRun$1, + usWaterMeterCommand: usWaterMeterCommand$1, + verifyImage: verifyImage$1, + writeImage: writeImage$1 + }); + + var invertObject = source => { + const target = {}; + for (const property in source) { + const value = source[property]; + target[value] = property; + } + return target; + }; + + var downlinkNames = invertObject(downlinkIds); + + const id$_ = correctTime2000$1; + downlinkNames[correctTime2000$1]; + const COMMAND_BODY_SIZE$w = 2; + const fromBytes$10 = data => { + if (data.length !== COMMAND_BODY_SIZE$w) { + throw new Error(`Wrong buffer size: ${data.length}.`); + } + const buffer = new BinaryBuffer(data, false); + const parameters = { + sequenceNumber: buffer.getUint8(), + seconds: buffer.getInt8() + }; + if (!buffer.isEmpty) { + throw new Error('BinaryBuffer is not empty.'); + } + return parameters; + }; + const toBytes$10 = parameters => { + const { + sequenceNumber, + seconds + } = parameters; + const buffer = new BinaryBuffer(COMMAND_BODY_SIZE$w, false); + buffer.setUint8(sequenceNumber); + buffer.setInt8(seconds); + return toBytes$11(id$_, buffer.data); + }; + + const fromObject = function () { + let bitMask = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : {}; + let booleanObject = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : {}; + let result = 0; + for (const name in booleanObject) { + if (name in bitMask && booleanObject[name]) { + result |= bitMask[name]; + } + } + return result; + }; + const toObject = function () { + let bitMask = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : {}; + let value = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : 0; + const result = {}; + for (const name in bitMask) { + result[name] = (value & bitMask[name]) !== 0; + } + return result; + }; + const extractBits = (value, bitsNumber, startIndex) => (1 << bitsNumber) - 1 & value >> startIndex - 1; + const fillBits = (value, bitsNumber, startIndex, valueToSet) => { + const mask = (1 << bitsNumber) - 1 << startIndex - 1; + let newValueToSet = valueToSet; + let result = value; + result &= ~mask; + newValueToSet <<= startIndex - 1; + result |= newValueToSet; + return result; + }; + + var getHexFromBytes = (function (bytes) { + let options = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : {}; + const { + separator, + prefix + } = Object.assign({}, hexFormatOptions, options); + return bytes.map(byte => `${prefix}${byte.toString(16).padStart(2, '0')}`).join(separator); + }); + + var getBytesFromHex = hex => { + let cleanHex = hex.trim(); + if (!cleanHex) { + return []; + } + cleanHex = cleanHex.replace(/0x/g, '').split(/\s+/).map(byte => byte.padStart(2, '0')).join(''); + if (cleanHex.length % 2 !== 0) { + cleanHex = `0${cleanHex}`; + } + const resultLength = cleanHex.length / 2; + const bytes = new Array(resultLength); + for (let index = 0; index < resultLength; index++) { + bytes[index] = parseInt(cleanHex.substring(index * 2, index * 2 + 2), 16); + } + return bytes; + }; + + var roundNumber = (function (value) { + let decimalPlaces = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : 4; + const places = Math.pow(10, decimalPlaces); + return Math.round(value * places * (1 + Number.EPSILON)) / places; + }); + + const INITIAL_YEAR_TIMESTAMP = 946684800000; + const MILLISECONDS_IN_SECONDS = 1000; + const getDateFromTime2000 = time2000 => new Date(INITIAL_YEAR_TIMESTAMP + time2000 * MILLISECONDS_IN_SECONDS); + const getTime2000FromDate = date => (date.getTime() - INITIAL_YEAR_TIMESTAMP) / MILLISECONDS_IN_SECONDS; + + const GASI1 = 1; + const GASI2 = 2; + const GASI3 = 3; + const NOVATOR = 4; + const IMP2EU = 5; + const IMP4EU = 6; + const MTXLORA = 7; + const IMP2AS = 8; + const IMP2IN = 9; + const IMP4IN = 10; + const ELIMP = 11; + const GASIC = 12; + const US_WATER = 13; + const NBIOT = 24; + + const REPORTING_DATA_INTERVAL = 1; + const DAY_CHECKOUT_HOUR = 4; + const REPORTING_DATA_TYPE = 5; + const PRIORITY_DATA_DELIVERY_TYPE = 8; + const ACTIVATION_METHOD = 9; + const BATTERY_DEPASSIVATION_INFO = 10; + const BATTERY_MINIMAL_LOAD_TIME = 11; + const CHANNELS_CONFIG = 13; + const RX2_CONFIG = 18; + const ABSOLUTE_DATA = 23; + const ABSOLUTE_DATA_ENABLE = 24; + const SERIAL_NUMBER = 25; + const GEOLOCATION = 26; + const EXTRA_FRAME_INTERVAL = 28; + const ABSOLUTE_DATA_MULTI_CHANNEL = 29; + const ABSOLUTE_DATA_ENABLE_MULTI_CHANNEL = 30; + const PULSE_CHANNELS_SCAN_CONFIG = 31; + const PULSE_CHANNELS_SET_CONFIG = 32; + const BATTERY_DEPASSIVATION_CONFIG = 33; + const MQTT_SESSION_CONFIG = 34; + const MQTT_BROKER_ADDRESS = 35; + const MQTT_SSL_ENABLE = 36; + const MQTT_TOPIC_PREFIX = 37; + const MQTT_DATA_RECEIVE_CONFIG = 38; + const MQTT_DATA_SEND_CONFIG = 39; + const NBIOT_SSL_CONFIG = 40; + const NBIOT_SSL_CACERT_WRITE = 41; + const NBIOT_SSL_CACERT_SET = 42; + const NBIOT_SSL_CLIENT_CERT_WRITE = 43; + const NBIOT_SSL_CLIENT_CERT_SET = 44; + const NBIOT_SSL_CLIENT_KEY_WRITE = 45; + const NBIOT_SSL_CLIENT_KEY_SET = 46; + const NBIOT_DEVICE_SOFTWARE_UPDATE = 47; + const NBIOT_MODULE_FIRMWARE_UPDATE = 48; + const REPORTING_DATA_CONFIG = 49; + const EVENTS_CONFIG = 50; + const NBIOT_MODULE_INFO = 51; + const NBIOT_BANDS = 52; + const NBIOT_APN = 53; + const NBIOT_LED_INDICATION = 54; + const NBIOT_SIM = 55; + const CHANNEL_TYPE = 56; + + var deviceParameters = /*#__PURE__*/Object.freeze({ + __proto__: null, + ABSOLUTE_DATA: ABSOLUTE_DATA, + ABSOLUTE_DATA_ENABLE: ABSOLUTE_DATA_ENABLE, + ABSOLUTE_DATA_ENABLE_MULTI_CHANNEL: ABSOLUTE_DATA_ENABLE_MULTI_CHANNEL, + ABSOLUTE_DATA_MULTI_CHANNEL: ABSOLUTE_DATA_MULTI_CHANNEL, + ACTIVATION_METHOD: ACTIVATION_METHOD, + BATTERY_DEPASSIVATION_CONFIG: BATTERY_DEPASSIVATION_CONFIG, + BATTERY_DEPASSIVATION_INFO: BATTERY_DEPASSIVATION_INFO, + BATTERY_MINIMAL_LOAD_TIME: BATTERY_MINIMAL_LOAD_TIME, + CHANNELS_CONFIG: CHANNELS_CONFIG, + CHANNEL_TYPE: CHANNEL_TYPE, + DAY_CHECKOUT_HOUR: DAY_CHECKOUT_HOUR, + EVENTS_CONFIG: EVENTS_CONFIG, + EXTRA_FRAME_INTERVAL: EXTRA_FRAME_INTERVAL, + GEOLOCATION: GEOLOCATION, + MQTT_BROKER_ADDRESS: MQTT_BROKER_ADDRESS, + MQTT_DATA_RECEIVE_CONFIG: MQTT_DATA_RECEIVE_CONFIG, + MQTT_DATA_SEND_CONFIG: MQTT_DATA_SEND_CONFIG, + MQTT_SESSION_CONFIG: MQTT_SESSION_CONFIG, + MQTT_SSL_ENABLE: MQTT_SSL_ENABLE, + MQTT_TOPIC_PREFIX: MQTT_TOPIC_PREFIX, + NBIOT_APN: NBIOT_APN, + NBIOT_BANDS: NBIOT_BANDS, + NBIOT_DEVICE_SOFTWARE_UPDATE: NBIOT_DEVICE_SOFTWARE_UPDATE, + NBIOT_LED_INDICATION: NBIOT_LED_INDICATION, + NBIOT_MODULE_FIRMWARE_UPDATE: NBIOT_MODULE_FIRMWARE_UPDATE, + NBIOT_MODULE_INFO: NBIOT_MODULE_INFO, + NBIOT_SIM: NBIOT_SIM, + NBIOT_SSL_CACERT_SET: NBIOT_SSL_CACERT_SET, + NBIOT_SSL_CACERT_WRITE: NBIOT_SSL_CACERT_WRITE, + NBIOT_SSL_CLIENT_CERT_SET: NBIOT_SSL_CLIENT_CERT_SET, + NBIOT_SSL_CLIENT_CERT_WRITE: NBIOT_SSL_CLIENT_CERT_WRITE, + NBIOT_SSL_CLIENT_KEY_SET: NBIOT_SSL_CLIENT_KEY_SET, + NBIOT_SSL_CLIENT_KEY_WRITE: NBIOT_SSL_CLIENT_KEY_WRITE, + NBIOT_SSL_CONFIG: NBIOT_SSL_CONFIG, + PRIORITY_DATA_DELIVERY_TYPE: PRIORITY_DATA_DELIVERY_TYPE, + PULSE_CHANNELS_SCAN_CONFIG: PULSE_CHANNELS_SCAN_CONFIG, + PULSE_CHANNELS_SET_CONFIG: PULSE_CHANNELS_SET_CONFIG, + REPORTING_DATA_CONFIG: REPORTING_DATA_CONFIG, + REPORTING_DATA_INTERVAL: REPORTING_DATA_INTERVAL, + REPORTING_DATA_TYPE: REPORTING_DATA_TYPE, + RX2_CONFIG: RX2_CONFIG, + SERIAL_NUMBER: SERIAL_NUMBER + }); + + var deviceParameterNames = invertObject(deviceParameters); + + const EMPTY_VALUE = 0xffffffff; + + const IDLE = 0; + const POWER_CHANNEL = 2; + const BINARY_SENSOR = 3; + const TEMPERATURE_SENSOR = 4; + + var channelTypes = /*#__PURE__*/Object.freeze({ + __proto__: null, + BINARY_SENSOR: BINARY_SENSOR, + IDLE: IDLE, + POWER_CHANNEL: POWER_CHANNEL, + TEMPERATURE_SENSOR: TEMPERATURE_SENSOR + }); + + const SF12B125 = 0; + const SF11B125 = 1; + const SF10B125 = 2; + const SF9B125 = 3; + const SF8B125 = 4; + const SF7B125 = 5; + const SF7B250 = 6; + + var rx2SpreadFactors = /*#__PURE__*/Object.freeze({ + __proto__: null, + SF10B125: SF10B125, + SF11B125: SF11B125, + SF12B125: SF12B125, + SF7B125: SF7B125, + SF7B250: SF7B250, + SF8B125: SF8B125, + SF9B125: SF9B125 + }); + + var spreadFactorNames = invertObject(rx2SpreadFactors); + + const INITIAL_YEAR = 2000; + const MONTH_BIT_SIZE = 4; + const DATE_BIT_SIZE = 5; + const YEAR_START_INDEX = 1; + const UNKNOWN_BATTERY_VOLTAGE = 4095; + const EXTEND_BIT_MASK = 0x80; + const LAST_BIT_INDEX = 7; + const DATA_SENDING_INTERVAL_SECONDS_COEFFICIENT = 600; + const DATA_SENDING_INTERVAL_RESERVED_BYTES = 3; + const PARAMETER_RX2_FREQUENCY_COEFFICIENT = 100; + const SERIAL_NUMBER_SIZE = 6; + const MAGNETIC_INFLUENCE_BIT_INDEX = 8; + const LEGACY_HOUR_COUNTER_SIZE = 2 + 4; + const LEGACY_HOUR_DIFF_SIZE = 2; + const GAS_HARDWARE_TYPES = [GASI2, GASI3, GASI1, GASIC, NBIOT]; + const TWO_CHANNELS_HARDWARE_TYPES = [IMP2AS, IMP2EU, IMP2IN, NOVATOR]; + const ELIMP_HARDWARE_TYPES = [ELIMP]; + const FOUR_CHANNELS_HARDWARE_TYPES = [IMP4EU, IMP4IN]; + const MTX_HARDWARE_TYPES = [MTXLORA]; + const TWO_BYTES_HARDWARE_TYPES = [...FOUR_CHANNELS_HARDWARE_TYPES, ...MTX_HARDWARE_TYPES]; + const gasBitMask = { + isBatteryLow: Math.pow(2, 0), + isMagneticInfluence: Math.pow(2, 1), + isButtonReleased: Math.pow(2, 2), + isConnectionLost: Math.pow(2, 3) + }; + const twoChannelBitMask = { + isBatteryLow: Math.pow(2, 0), + isConnectionLost: Math.pow(2, 3), + isFirstChannelInactive: Math.pow(2, 4), + isSecondChannelInactive: Math.pow(2, 5) + }; + const elimpBitMask = { + isConnectionLost: Math.pow(2, 3) + }; + const fourChannelBitMask = { + isBatteryLow: Math.pow(2, 0), + isConnectionLost: Math.pow(2, 3), + isFirstChannelInactive: Math.pow(2, 4), + isSecondChannelInactive: Math.pow(2, 5), + isThirdChannelInactive: Math.pow(2, 6), + isForthChannelInactive: Math.pow(2, 8) + }; + const mtxBitMask = { + isMeterCaseOpen: Math.pow(2, 0), + isMagneticInfluence: Math.pow(2, 1), + isParametersSetRemotely: Math.pow(2, 2), + isParametersSetLocally: Math.pow(2, 3), + isMeterProgramRestarted: Math.pow(2, 4), + isLockedOut: Math.pow(2, 5), + isTimeSet: Math.pow(2, 6), + isTimeCorrected: Math.pow(2, 7), + isMeterFailure: Math.pow(2, 8), + isMeterTerminalBoxOpen: Math.pow(2, 9), + isModuleCompartmentOpen: Math.pow(2, 10), + isTariffPlanChanged: Math.pow(2, 11), + isNewTariffPlanReceived: Math.pow(2, 12) + }; + const usWaterMeterEventBitMask = { + transportMode: 0x01, + frequencyOutput: 0x02, + reverseFlow: 0x04, + tamperBreak: 0x08, + leakage: 0x10, + pipeBreak: 0x20, + pipeEmpty: 0x40, + batteryDischarge: 0x80 + }; + const getChannelTypeSize = _ref => { + let { + type + } = _ref; + let size = 1; + switch (type) { + case IDLE: + case POWER_CHANNEL: + break; + case BINARY_SENSOR: + size += 2; + break; + case TEMPERATURE_SENSOR: + size += 5; + break; + } + return size; + }; + const parametersSizeMap = { + [REPORTING_DATA_INTERVAL]: 1 + 4, + [DAY_CHECKOUT_HOUR]: 1 + 1, + [REPORTING_DATA_TYPE]: 1 + 1, + [PRIORITY_DATA_DELIVERY_TYPE]: 1 + 1, + [ACTIVATION_METHOD]: 1 + 1, + [BATTERY_DEPASSIVATION_INFO]: 1 + 6, + [BATTERY_MINIMAL_LOAD_TIME]: 1 + 4, + [CHANNELS_CONFIG]: 1 + 1, + [RX2_CONFIG]: 1 + 4, + [ABSOLUTE_DATA]: 1 + 9, + [ABSOLUTE_DATA_ENABLE]: 1 + 1, + [SERIAL_NUMBER]: 1 + 6, + [GEOLOCATION]: 1 + 10, + [EXTRA_FRAME_INTERVAL]: 1 + 2, + [ABSOLUTE_DATA_MULTI_CHANNEL]: 1 + 10, + [ABSOLUTE_DATA_ENABLE_MULTI_CHANNEL]: 1 + 2, + [PULSE_CHANNELS_SCAN_CONFIG]: 1 + 3, + [PULSE_CHANNELS_SET_CONFIG]: 1 + 1, + [BATTERY_DEPASSIVATION_CONFIG]: 1 + 4, + [MQTT_SSL_ENABLE]: 1 + 1, + [MQTT_DATA_RECEIVE_CONFIG]: 1 + 3, + [MQTT_DATA_SEND_CONFIG]: 1 + 3, + [NBIOT_SSL_CONFIG]: 1 + 2, + [NBIOT_SSL_CACERT_SET]: 1 + 4, + [NBIOT_SSL_CLIENT_CERT_SET]: 1 + 4, + [NBIOT_SSL_CLIENT_KEY_SET]: 1 + 4, + [REPORTING_DATA_CONFIG]: 1 + 4, + [EVENTS_CONFIG]: 1 + 3, + [NBIOT_LED_INDICATION]: 1 + 2, + [NBIOT_SIM]: 1 + 3 + }; + const fourChannelsBitMask = { + channel1: Math.pow(2, 0), + channel2: Math.pow(2, 1), + channel3: Math.pow(2, 2), + channel4: Math.pow(2, 3) + }; + const getChannelsMaskFromNumber = value => { + const object = toObject(fourChannelsBitMask, value); + return { + channel1: object.channel1, + channel2: object.channel2, + channel3: object.channel3, + channel4: object.channel4 + }; + }; + const setChannelsMaskToNumber = channelsMask => { + const { + channel1, + channel2, + channel3, + channel4 + } = channelsMask; + return fromObject(fourChannelsBitMask, { + channel1, + channel2, + channel3, + channel4 + }); + }; + const getChannelsMask = buffer => getChannelsMaskFromNumber(buffer.getUint8()); + const setChannelsMask = (buffer, channelsMask) => buffer.setUint8(setChannelsMaskToNumber(channelsMask)); + const byteToPulseCoefficientMap = { + 128: 1, + 129: 5, + 130: 10, + 131: 100, + 132: 1000, + 133: 10000, + 134: 100000 + }; + const pulseCoefficientToByteMap = invertObject(byteToPulseCoefficientMap); + const isMSBSet = value => !!(value & 0x80); + const getNbiotSslWrite = buffer => ({ + size: buffer.getUint16(), + position: buffer.getUint16(), + chunk: buffer.getBytesLeft() + }); + const setNbiotSslWrite = (buffer, parameter) => { + if (parameter.size !== parameter.chunk.length) { + throw new Error('ssl chunk size parameter doesn\'t match actual ssl chunk size'); + } + buffer.setUint16(parameter.size); + buffer.setUint16(parameter.position); + buffer.setBytes(parameter.chunk); + }; + const getNbiotSslSet = buffer => ({ + crc32: buffer.getUint32() + }); + const setNbiotSslSet = (buffer, parameter) => { + buffer.setUint32(parameter.crc32); + }; + const deviceParameterConvertersMap = { + [REPORTING_DATA_INTERVAL]: { + get: buffer => { + buffer.seek(buffer.offset + DATA_SENDING_INTERVAL_RESERVED_BYTES); + return { + value: buffer.getUint8() * DATA_SENDING_INTERVAL_SECONDS_COEFFICIENT + }; + }, + set: (buffer, parameter) => { + buffer.seek(buffer.offset + DATA_SENDING_INTERVAL_RESERVED_BYTES); + buffer.setUint8(parameter.value / DATA_SENDING_INTERVAL_SECONDS_COEFFICIENT); + } + }, + [DAY_CHECKOUT_HOUR]: { + get: buffer => ({ + value: buffer.getUint8() + }), + set: (buffer, parameter) => { + buffer.setUint8(parameter.value); + } + }, + [REPORTING_DATA_TYPE]: { + get: buffer => ({ + type: buffer.getUint8() + }), + set: (buffer, parameter) => { + buffer.setUint8(parameter.type); + } + }, + [PRIORITY_DATA_DELIVERY_TYPE]: { + get: buffer => ({ + value: buffer.getUint8() + }), + set: (buffer, parameter) => { + buffer.setUint8(parameter.value); + } + }, + [ACTIVATION_METHOD]: { + get: buffer => ({ + type: buffer.getUint8() + }), + set: (buffer, parameter) => { + buffer.setUint8(parameter.type); + } + }, + [BATTERY_DEPASSIVATION_INFO]: { + get: buffer => ({ + loadTime: buffer.getUint16(), + internalResistance: buffer.getUint16(), + lowVoltage: buffer.getUint16() + }), + set: (buffer, parameter) => { + buffer.setUint16(parameter.loadTime); + buffer.setUint16(parameter.internalResistance); + buffer.setUint16(parameter.lowVoltage); + } + }, + [BATTERY_MINIMAL_LOAD_TIME]: { + get: buffer => ({ + value: buffer.getUint32() + }), + set: (buffer, parameter) => { + buffer.setUint32(parameter.value); + } + }, + [CHANNELS_CONFIG]: { + get: buffer => ({ + value: buffer.getUint8() + }), + set: (buffer, parameter) => { + if (parameter.value < 0 || parameter.value > 18) { + throw new Error('channels config must be between 0-18'); + } + buffer.setUint8(parameter.value); + } + }, + [RX2_CONFIG]: { + get: buffer => { + const spreadFactor = buffer.getUint8(); + const spreadFactorName = spreadFactorNames[spreadFactor]; + const frequency = buffer.getUint24() * PARAMETER_RX2_FREQUENCY_COEFFICIENT; + return { + spreadFactor, + spreadFactorName, + frequency + }; + }, + set: (buffer, parameter) => { + buffer.setUint8(parameter.spreadFactor); + buffer.setUint24(parameter.frequency / PARAMETER_RX2_FREQUENCY_COEFFICIENT); + } + }, + [ABSOLUTE_DATA]: { + get: buffer => ({ + meterValue: buffer.getUint32(), + pulseCoefficient: buffer.getPulseCoefficient(), + value: buffer.getUint32() + }), + set: (buffer, parameter) => { + buffer.setUint32(parameter.meterValue); + buffer.setPulseCoefficient(parameter.pulseCoefficient); + buffer.setUint32(parameter.value); + } + }, + [ABSOLUTE_DATA_ENABLE]: { + get: buffer => ({ + state: buffer.getUint8() + }), + set: (buffer, parameter) => { + buffer.setUint8(parameter.state); + } + }, + [SERIAL_NUMBER]: { + get: buffer => ({ + value: getHexFromBytes(buffer.getBytes(SERIAL_NUMBER_SIZE)) + }), + set: (buffer, parameter) => { + getBytesFromHex(parameter.value).forEach(byte => buffer.setUint8(byte)); + } + }, + [GEOLOCATION]: { + get: buffer => ({ + latitude: roundNumber(buffer.getFloat32()), + longitude: roundNumber(buffer.getFloat32()), + altitude: roundNumber(buffer.getUint16()) + }), + set: (buffer, parameter) => { + buffer.setFloat32(roundNumber(parameter.latitude)); + buffer.setFloat32(roundNumber(parameter.longitude)); + buffer.setUint16(roundNumber(parameter.altitude)); + } + }, + [EXTRA_FRAME_INTERVAL]: { + get: buffer => ({ + value: buffer.getUint16() + }), + set: (buffer, parameter) => { + buffer.setUint16(parameter.value); + } + }, + [ABSOLUTE_DATA_MULTI_CHANNEL]: { + get: buffer => ({ + channel: buffer.getChannelValue(), + meterValue: buffer.getUint32(), + pulseCoefficient: buffer.getPulseCoefficient(), + value: buffer.getUint32() + }), + set: (buffer, parameter) => { + buffer.setChannelValue(parameter.channel); + buffer.setUint32(parameter.meterValue); + buffer.setPulseCoefficient(parameter.pulseCoefficient); + buffer.setUint32(parameter.value); + } + }, + [ABSOLUTE_DATA_ENABLE_MULTI_CHANNEL]: { + get: buffer => ({ + channel: buffer.getChannelValue(), + state: buffer.getUint8() + }), + set: (buffer, parameter) => { + buffer.setChannelValue(parameter.channel); + buffer.setUint8(parameter.state); + } + }, + [PULSE_CHANNELS_SCAN_CONFIG]: { + get: buffer => ({ + channelList: buffer.getChannels(), + pullUpTime: buffer.getUint8(), + scanTime: buffer.getUint8() + }), + set: (buffer, parameter) => { + if (parameter.pullUpTime < 17) { + throw new Error('minimal value for pullUpTime - 17'); + } + if (parameter.scanTime < 15) { + throw new Error('minimal value for scanTime - 15'); + } + buffer.setChannels(parameter.channelList.map(index => ({ + index + }))); + buffer.setUint8(parameter.pullUpTime); + buffer.setUint8(parameter.scanTime); + } + }, + [PULSE_CHANNELS_SET_CONFIG]: { + get: getChannelsMask, + set: setChannelsMask + }, + [BATTERY_DEPASSIVATION_CONFIG]: { + get: buffer => ({ + resistanceStartThreshold: buffer.getUint16(), + resistanceStopThreshold: buffer.getUint16() + }), + set: (buffer, parameter) => { + buffer.setUint16(parameter.resistanceStartThreshold); + buffer.setUint16(parameter.resistanceStopThreshold); + } + }, + [MQTT_SESSION_CONFIG]: { + get: buffer => ({ + clientId: buffer.getString(), + username: buffer.getString(), + password: buffer.getString(), + cleanSession: buffer.getUint8() + }), + set: (buffer, parameter) => { + buffer.setString(parameter.clientId); + buffer.setString(parameter.username); + buffer.setString(parameter.password); + buffer.setUint8(parameter.cleanSession); + } + }, + [MQTT_BROKER_ADDRESS]: { + get: buffer => ({ + hostName: buffer.getString(), + port: buffer.getUint16() + }), + set: (buffer, parameter) => { + buffer.setString(parameter.hostName); + buffer.setUint16(parameter.port); + } + }, + [MQTT_SSL_ENABLE]: { + get: buffer => ({ + enable: buffer.getUint8() + }), + set: (buffer, parameter) => { + buffer.setUint8(parameter.enable); + } + }, + [MQTT_TOPIC_PREFIX]: { + get: buffer => ({ + topicPrefix: buffer.getString() + }), + set: (buffer, parameter) => { + buffer.setString(parameter.topicPrefix); + } + }, + [MQTT_DATA_RECEIVE_CONFIG]: { + get: buffer => ({ + qos: buffer.getUint8(), + count: buffer.getUint8(), + timeout: buffer.getUint8() + }), + set: (buffer, parameter) => { + buffer.setUint8(parameter.qos); + buffer.setUint8(parameter.count); + buffer.setUint8(parameter.timeout); + } + }, + [MQTT_DATA_SEND_CONFIG]: { + get: buffer => ({ + qos: buffer.getUint8(), + retain: buffer.getUint8(), + newestSendFirst: buffer.getUint8() + }), + set: (buffer, parameter) => { + buffer.setUint8(parameter.qos); + buffer.setUint8(parameter.retain); + buffer.setUint8(parameter.newestSendFirst); + } + }, + [NBIOT_SSL_CONFIG]: { + get: buffer => ({ + securityLevel: buffer.getUint8(), + version: buffer.getUint8() + }), + set: (buffer, parameter) => { + buffer.setUint8(parameter.securityLevel); + buffer.setUint8(parameter.version); + } + }, + [NBIOT_SSL_CACERT_WRITE]: { + get: getNbiotSslWrite, + set: setNbiotSslWrite + }, + [NBIOT_SSL_CACERT_SET]: { + get: getNbiotSslSet, + set: setNbiotSslSet + }, + [NBIOT_SSL_CLIENT_CERT_WRITE]: { + get: getNbiotSslWrite, + set: setNbiotSslWrite + }, + [NBIOT_SSL_CLIENT_CERT_SET]: { + get: getNbiotSslSet, + set: setNbiotSslSet + }, + [NBIOT_SSL_CLIENT_KEY_WRITE]: { + get: getNbiotSslWrite, + set: setNbiotSslWrite + }, + [NBIOT_SSL_CLIENT_KEY_SET]: { + get: getNbiotSslSet, + set: setNbiotSslSet + }, + [NBIOT_DEVICE_SOFTWARE_UPDATE]: { + get: buffer => ({ + softwareImageUrl: buffer.getString() + }), + set: (buffer, parameter) => { + buffer.setString(parameter.softwareImageUrl); + } + }, + [NBIOT_MODULE_FIRMWARE_UPDATE]: { + get: buffer => ({ + moduleFirmwareImageUrl: buffer.getString() + }), + set: (buffer, parameter) => { + buffer.setString(parameter.moduleFirmwareImageUrl); + } + }, + [REPORTING_DATA_CONFIG]: { + get: buffer => ({ + dataType: buffer.getUint8(), + hour: buffer.getUint8(), + minutes: buffer.getUint8(), + countToSend: buffer.getUint8() + }), + set: (buffer, parameter) => { + buffer.setUint8(parameter.dataType); + buffer.setUint8(parameter.hour); + buffer.setUint8(parameter.minutes); + buffer.setUint8(parameter.countToSend); + } + }, + [EVENTS_CONFIG]: { + get: buffer => ({ + eventId: buffer.getUint8(), + sendEvent: buffer.getUint8(), + saveEvent: buffer.getUint8() + }), + set: (buffer, parameter) => { + buffer.setUint8(parameter.eventId); + buffer.setUint8(parameter.sendEvent); + buffer.setUint8(parameter.saveEvent); + } + }, + [NBIOT_MODULE_INFO]: { + get: buffer => ({ + moduleInfo: buffer.getString() + }), + set: (buffer, parameter) => { + buffer.setString(parameter.moduleInfo); + } + }, + [NBIOT_BANDS]: { + get: buffer => { + const count = buffer.getUint8(); + const bands = []; + for (let index = 0; index < count; index++) { + bands.push(buffer.getUint8()); + } + return { + bands + }; + }, + set: (buffer, parameter) => { + buffer.setUint8(parameter.bands.length); + for (const band of parameter.bands) { + buffer.setUint8(band); + } + } + }, + [NBIOT_APN]: { + get: buffer => ({ + apn: buffer.getString() + }), + set: (buffer, parameter) => { + buffer.setString(parameter.apn); + } + }, + [NBIOT_LED_INDICATION]: { + get: buffer => ({ + enableLed: buffer.getUint8(), + enableNbiotNetworkLed: buffer.getUint8() + }), + set: (buffer, parameter) => { + buffer.setUint8(parameter.enableLed); + buffer.setUint8(parameter.enableNbiotNetworkLed); + } + }, + [NBIOT_SIM]: { + get: buffer => ({ + enable: buffer.getUint8(), + pin: buffer.getUint16() + }), + set: (buffer, parameter) => { + buffer.setUint8(parameter.enable); + buffer.setUint16(parameter.pin); + } + }, + [CHANNEL_TYPE]: { + get: buffer => buffer.getChannelType(), + set: (buffer, parameter) => buffer.setChannelType(parameter) + } + }; + const getEventStatusSize = hardwareType => TWO_BYTES_HARDWARE_TYPES.indexOf(hardwareType) !== -1 ? 2 : 1; + const getParameterSize = parameter => { + let size; + let data; + switch (parameter.id) { + case MQTT_SESSION_CONFIG: + data = parameter.data; + size = 1 + 1; + size += data.clientId.length + 1; + size += data.username.length + 1; + size += data.password.length + 1; + break; + case MQTT_BROKER_ADDRESS: + data = parameter.data; + size = 1 + 2; + size += data.hostName.length + 1; + break; + case MQTT_TOPIC_PREFIX: + data = parameter.data; + size = 1; + size += data.topicPrefix.length + 1; + break; + case NBIOT_SSL_CACERT_WRITE: + case NBIOT_SSL_CLIENT_CERT_WRITE: + case NBIOT_SSL_CLIENT_KEY_WRITE: + data = parameter.data; + size = 1 + 2 + 2; + size += data.chunk.length; + break; + case NBIOT_DEVICE_SOFTWARE_UPDATE: + data = parameter.data; + size = 1; + size += data.softwareImageUrl.length + 1; + break; + case NBIOT_MODULE_FIRMWARE_UPDATE: + data = parameter.data; + size = 1; + size += data.moduleFirmwareImageUrl.length + 1; + break; + case NBIOT_MODULE_INFO: + data = parameter.data; + size = 1 + 1 + data.moduleInfo.length; + break; + case NBIOT_BANDS: + data = parameter.data; + size = 1 + 1; + size += data.bands.length; + break; + case NBIOT_APN: + data = parameter.data; + size = 1 + 1 + data.apn.length; + break; + case CHANNEL_TYPE: + data = parameter.data; + size = 1 + getChannelTypeSize(data); + break; + default: + size = parametersSizeMap[parameter.id]; + } + if (size === undefined) { + throw new Error('unknown parameter id'); + } + return size; + }; + const getRequestParameterSize = parameter => { + let size; + switch (parameter.id) { + case ABSOLUTE_DATA_MULTI_CHANNEL: + case ABSOLUTE_DATA_ENABLE_MULTI_CHANNEL: + case REPORTING_DATA_CONFIG: + case EVENTS_CONFIG: + case CHANNEL_TYPE: + size = 2; + break; + default: + size = 1; + break; + } + return size; + }; + const getResponseParameterSize = parameter => { + let size; + switch (parameter.id) { + case MQTT_SESSION_CONFIG: + case NBIOT_SSL_CACERT_WRITE: + case NBIOT_SSL_CLIENT_CERT_WRITE: + case NBIOT_SSL_CLIENT_KEY_WRITE: + case NBIOT_SSL_CACERT_SET: + case NBIOT_SSL_CLIENT_CERT_SET: + case NBIOT_SSL_CLIENT_KEY_SET: + case NBIOT_DEVICE_SOFTWARE_UPDATE: + case NBIOT_MODULE_FIRMWARE_UPDATE: + size = 1; + break; + case MQTT_BROKER_ADDRESS: + case MQTT_TOPIC_PREFIX: + case NBIOT_MODULE_INFO: + case NBIOT_BANDS: + case NBIOT_APN: + case CHANNEL_TYPE: + size = getParameterSize(parameter); + break; + default: + size = parametersSizeMap[parameter.id]; + } + if (size === undefined) { + throw new Error('unknown parameter id'); + } + return size; + }; + function CommandBinaryBuffer(dataOrLength) { + let isLittleEndian = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : false; + BinaryBuffer.call(this, dataOrLength, isLittleEndian); + } + CommandBinaryBuffer.prototype = Object.create(BinaryBuffer.prototype); + CommandBinaryBuffer.prototype.constructor = CommandBinaryBuffer; + CommandBinaryBuffer.getMagneticInfluenceBit = byte => !!extractBits(byte, 1, MAGNETIC_INFLUENCE_BIT_INDEX); + CommandBinaryBuffer.setMagneticInfluenceBit = (byte, value) => fillBits(byte, 1, MAGNETIC_INFLUENCE_BIT_INDEX, +value); + CommandBinaryBuffer.getLegacyHourCounterSize = hourCounter => LEGACY_HOUR_COUNTER_SIZE + hourCounter.diff.length * LEGACY_HOUR_DIFF_SIZE; + CommandBinaryBuffer.prototype.getExtendedValue = function () { + let value = 0; + let isByteExtended = true; + let position = 0; + while (isByteExtended && this.offset <= this.data.length) { + const byte = this.getUint8(); + isByteExtended = !!(byte & EXTEND_BIT_MASK); + value += (byte & 0x7f) << 7 * position >>> 0; + ++position; + } + return value; + }; + CommandBinaryBuffer.prototype.setExtendedValue = function (value) { + if (value === 0) { + this.setUint8(0); + return; + } + const data = []; + let encodedValue = value; + while (encodedValue) { + data.push(EXTEND_BIT_MASK | encodedValue & 0x7f); + encodedValue >>>= 7; + } + const lastByte = data.pop(); + if (lastByte) { + data.push(lastByte & 0x7f); + } + data.forEach(extendedValue => this.setUint8(extendedValue)); + }; + CommandBinaryBuffer.prototype.getExtendedValueSize = function (bits) { + const extBits = Math.ceil(bits / 7); + const totalBits = bits + extBits; + const extBytes = Math.ceil(totalBits / 8); + return extBytes; + }; + CommandBinaryBuffer.prototype.getTime = function () { + return this.getUint32(); + }; + CommandBinaryBuffer.prototype.setTime = function (value) { + this.setUint32(value); + }; + CommandBinaryBuffer.prototype.getBatteryVoltage = function () { + const lowVoltageByte = this.getUint8(); + const lowAndHightVoltageByte = this.getUint8(); + const highVoltageByte = this.getUint8(); + let underLowLoad = lowVoltageByte << 4; + underLowLoad |= (lowAndHightVoltageByte & 0xf0) >> 4; + let underHighLoad = (lowAndHightVoltageByte & 0x0f) << 8 | highVoltageByte; + if (underHighLoad === UNKNOWN_BATTERY_VOLTAGE) { + underHighLoad = undefined; + } + if (underLowLoad === UNKNOWN_BATTERY_VOLTAGE) { + underLowLoad = undefined; + } + return { + underLowLoad, + underHighLoad + }; + }; + CommandBinaryBuffer.prototype.setBatteryVoltage = function (batteryVoltage) { + let { + underLowLoad, + underHighLoad + } = batteryVoltage; + if (underLowLoad === undefined) { + underLowLoad = UNKNOWN_BATTERY_VOLTAGE; + } + if (underHighLoad === undefined) { + underHighLoad = UNKNOWN_BATTERY_VOLTAGE; + } + const lowVoltageByte = underLowLoad >> 4 & 0xff; + const lowAndHighVoltageByte = (underLowLoad & 0x0f) << 4 | underHighLoad >> 8 & 0x0f; + const highVoltageByte = underHighLoad & 0xff; + [lowVoltageByte, lowAndHighVoltageByte, highVoltageByte].forEach(byte => this.setUint8(byte)); + }; + CommandBinaryBuffer.prototype.getLegacyCounterValue = function () { + return this.getUint24(); + }; + CommandBinaryBuffer.prototype.setLegacyCounterValue = function (value) { + this.setUint24(value); + }; + CommandBinaryBuffer.prototype.getLegacyCounter = function () { + let byte = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : this.getUint8(); + let isArchiveValue = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : false; + const value = this.getLegacyCounterValue(); + return { + isMagneticInfluence: CommandBinaryBuffer.getMagneticInfluenceBit(byte), + value: isArchiveValue && value === EMPTY_VALUE ? 0 : value + }; + }; + CommandBinaryBuffer.prototype.setLegacyCounter = function (counter) { + let byte = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : 0; + let isArchiveValue = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : false; + this.setUint8(CommandBinaryBuffer.setMagneticInfluenceBit(byte, counter.isMagneticInfluence)); + this.setLegacyCounterValue(isArchiveValue && counter.value === 0 ? EMPTY_VALUE : counter.value); + }; + CommandBinaryBuffer.prototype.getChannels = function () { + const channelList = []; + let extended = true; + let channelIndex = 1; + while (extended) { + const byte = this.getUint8(); + const bits = byte.toString(2).padStart(LAST_BIT_INDEX + 1, '0').split('').reverse(); + bits.forEach((bit, index) => { + const value = Number(bit); + if (index === LAST_BIT_INDEX) { + extended = !!value; + } else { + if (value) { + channelList.push(channelIndex); + } + ++channelIndex; + } + }); + } + return channelList; + }; + CommandBinaryBuffer.prototype.setChannels = function (channelList) { + if (channelList.length === 0) { + this.setUint8(0); + return; + } + channelList.sort((a, b) => a.index - b.index); + const maxChannel = Math.max(...channelList.map(_ref2 => { + let { + index + } = _ref2; + return index; + })); + const size = (maxChannel - maxChannel % 8) / 8; + const data = new Array(size + 1).fill(0); + let byte = 0; + data.forEach((_, byteIndex) => { + let channelIndex = byteIndex * LAST_BIT_INDEX + 1; + const maxChannelIndex = channelIndex + LAST_BIT_INDEX; + while (channelIndex < maxChannelIndex) { + const channel = channelList.find(item => item.index === channelIndex); + if (channel !== undefined) { + byte |= 1 << (channel.index - 1) % LAST_BIT_INDEX; + } + ++channelIndex; + } + if (data[byteIndex + 1] !== undefined) { + byte |= 1 << LAST_BIT_INDEX; + } + data[byteIndex] = byte; + byte = 0; + }); + data.forEach(value => this.setUint8(value)); + }; + CommandBinaryBuffer.prototype.getChannelValue = function () { + return this.getUint8() + 1; + }; + CommandBinaryBuffer.prototype.setChannelValue = function (value) { + if (value < 1) { + throw new Error('channel must be 1 or greater'); + } + this.setUint8(value - 1); + }; + CommandBinaryBuffer.prototype.getChannelsValuesWithHourDiff = function () { + let isArchiveValue = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : false; + const date = this.getDate(); + const { + hour, + hours + } = this.getHours(); + const channels = this.getChannels(); + const channelList = []; + date.setUTCHours(hour); + channels.forEach(channelIndex => { + const diff = []; + const value = this.getExtendedValue(); + for (let diffHour = 1; diffHour < hours; ++diffHour) { + diff.push(this.getExtendedValue()); + } + channelList.push({ + value: value === isArchiveValue && EMPTY_VALUE ? 0 : value, + diff, + index: channelIndex + }); + }); + return { + startTime2000: getTime2000FromDate(date), + hours, + channelList + }; + }; + CommandBinaryBuffer.prototype.setChannelsValuesWithHourDiff = function (hours, startTime2000, channelList) { + let isArchiveValue = arguments.length > 3 && arguments[3] !== undefined ? arguments[3] : false; + const date = getDateFromTime2000(startTime2000); + const hour = date.getUTCHours(); + this.setDate(date); + this.setHours(hour, hours); + this.setChannels(channelList); + channelList.forEach(_ref3 => { + let { + value, + diff + } = _ref3; + this.setExtendedValue(isArchiveValue && value === 0 ? EMPTY_VALUE : value); + diff.forEach(diffValue => this.setExtendedValue(diffValue)); + }); + }; + CommandBinaryBuffer.prototype.getHours = function () { + let byte = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : this.getUint8(); + if (byte === 0) { + return { + hours: 0, + hour: 0 + }; + } + const hours = ((byte & 0xe0) >> 5) + 1; + const hour = byte & 0x1f; + return { + hours, + hour + }; + }; + CommandBinaryBuffer.prototype.setHours = function (hour, hours) { + if (hour === 0 && hours === 0) { + this.setUint8(0); + return; + } + this.setUint8((hours - 1 & 0x07) << 5 | hour & 0x1f); + }; + CommandBinaryBuffer.prototype.getDate = function () { + const yearMonthByte = this.getUint8(); + const monthDateByte = this.getUint8(); + const year = yearMonthByte >> YEAR_START_INDEX; + const month = (yearMonthByte & 0x01) << MONTH_BIT_SIZE - YEAR_START_INDEX | monthDateByte >> DATE_BIT_SIZE; + const monthDay = monthDateByte & 0x1f; + return new Date(Date.UTC(year + INITIAL_YEAR, month - 1, monthDay, 0, 0, 0, 0)); + }; + CommandBinaryBuffer.prototype.setDate = function (dateOrTime) { + let date; + if (dateOrTime instanceof Date) { + date = dateOrTime; + } else { + date = getDateFromTime2000(dateOrTime); + } + const year = date.getUTCFullYear() - INITIAL_YEAR; + const month = date.getUTCMonth() + 1; + const day = date.getUTCDate(); + const yearMonthByte = year << YEAR_START_INDEX | month >> MONTH_BIT_SIZE - YEAR_START_INDEX; + const monthDateByte = (month & 0x07) << DATE_BIT_SIZE | day; + [yearMonthByte, monthDateByte].forEach(byte => this.setUint8(byte)); + }; + CommandBinaryBuffer.prototype.getPulseCoefficient = function () { + const pulseCoefficient = this.getUint8(); + if (isMSBSet(pulseCoefficient)) { + const value = byteToPulseCoefficientMap[pulseCoefficient]; + if (value) { + return value; + } + throw new Error('pulseCoefficient MSB is set, but value unknown'); + } + return pulseCoefficient; + }; + CommandBinaryBuffer.prototype.setPulseCoefficient = function (value) { + if (value in pulseCoefficientToByteMap) { + const byte = pulseCoefficientToByteMap[value]; + if (byte) { + this.setUint8(byte); + } else { + throw new Error('pulseCoefficient MSB is set, but value unknown'); + } + } else { + this.setUint8(value); + } + }; + CommandBinaryBuffer.prototype.getChannelsWithAbsoluteValues = function () { + const channels = this.getChannels(); + const channelList = []; + channels.forEach(channelIndex => { + channelList.push({ + pulseCoefficient: this.getPulseCoefficient(), + value: this.getExtendedValue(), + index: channelIndex + }); + }); + return channelList; + }; + CommandBinaryBuffer.prototype.setChannelsWithAbsoluteValues = function (channelList) { + this.setChannels(channelList); + channelList.forEach(_ref4 => { + let { + value, + pulseCoefficient + } = _ref4; + this.setPulseCoefficient(pulseCoefficient); + this.setExtendedValue(value); + }); + }; + CommandBinaryBuffer.prototype.getChannelsAbsoluteValuesWithHourDiff = function (hours) { + const channels = this.getChannels(); + const channelList = []; + channels.forEach(channelIndex => { + const pulseCoefficient = this.getPulseCoefficient(); + const value = this.getExtendedValue(); + const diff = []; + for (let hourIndex = 1; hourIndex < hours; ++hourIndex) { + diff.push(this.getExtendedValue()); + } + channelList.push({ + diff, + value, + pulseCoefficient, + index: channelIndex + }); + }); + return channelList; + }; + CommandBinaryBuffer.prototype.setChannelsAbsoluteValuesWithHourDiff = function (channelList) { + this.setChannels(channelList); + channelList.forEach(_ref5 => { + let { + value, + diff, + pulseCoefficient + } = _ref5; + this.setPulseCoefficient(pulseCoefficient); + this.setExtendedValue(value); + diff.forEach(diffValue => this.setExtendedValue(diffValue)); + }); + }; + CommandBinaryBuffer.prototype.getEventStatus = function (hardwareType) { + let status; + if (GAS_HARDWARE_TYPES.indexOf(hardwareType) !== -1) { + status = toObject(gasBitMask, this.getUint8()); + } else if (TWO_CHANNELS_HARDWARE_TYPES.indexOf(hardwareType) !== -1) { + status = toObject(twoChannelBitMask, this.getUint8()); + } else if (ELIMP_HARDWARE_TYPES.indexOf(hardwareType) !== -1) { + status = toObject(elimpBitMask, this.getUint8()); + } else if (FOUR_CHANNELS_HARDWARE_TYPES.indexOf(hardwareType) !== -1) { + status = toObject(fourChannelBitMask, this.getUint16(true)); + } else if (MTX_HARDWARE_TYPES.indexOf(hardwareType) !== -1) { + status = toObject(mtxBitMask, this.getUint16(true)); + } else if (hardwareType === US_WATER) { + const event = toObject(usWaterMeterEventBitMask, this.getUint8()); + status = { + event, + error: this.getUint8() + }; + } else { + throw new Error('wrong hardwareType'); + } + return status; + }; + CommandBinaryBuffer.prototype.setEventStatus = function (hardwareType, status) { + if (GAS_HARDWARE_TYPES.indexOf(hardwareType) !== -1) { + this.setUint8(fromObject(gasBitMask, status)); + } else if (TWO_CHANNELS_HARDWARE_TYPES.indexOf(hardwareType) !== -1) { + this.setUint8(fromObject(twoChannelBitMask, status)); + } else if (ELIMP_HARDWARE_TYPES.indexOf(hardwareType) !== -1) { + this.setUint8(fromObject(elimpBitMask, status)); + } else if (FOUR_CHANNELS_HARDWARE_TYPES.indexOf(hardwareType) !== -1) { + this.setUint16(fromObject(fourChannelBitMask, status) | 1 << 7, true); + } else if (MTX_HARDWARE_TYPES.indexOf(hardwareType) !== -1) { + this.setUint16(fromObject(mtxBitMask, status), true); + } else if (hardwareType === US_WATER) { + const data = status; + this.setUint8(fromObject(usWaterMeterEventBitMask, data.event)); + this.setUint8(data.error); + } else { + throw new Error('wrong hardwareType'); + } + }; + CommandBinaryBuffer.prototype.getParameter = function () { + const id = this.getUint8(); + const name = deviceParameterNames[id]; + if (!deviceParameterConvertersMap[id] || !deviceParameterConvertersMap[id].get) { + throw new Error(`parameter ${id} is not supported`); + } + const data = deviceParameterConvertersMap[id].get(this); + return { + id, + name, + data + }; + }; + CommandBinaryBuffer.prototype.setParameter = function (parameter) { + const { + id, + data + } = parameter; + if (!deviceParameterConvertersMap[id] || !deviceParameterConvertersMap[id].set) { + throw new Error(`parameter ${id} is not supported`); + } + this.setUint8(id); + deviceParameterConvertersMap[id].set(this, data); + }; + CommandBinaryBuffer.prototype.getRequestParameter = function () { + const id = this.getUint8(); + const name = deviceParameterNames[id]; + let data = null; + switch (id) { + case ABSOLUTE_DATA_ENABLE_MULTI_CHANNEL: + case ABSOLUTE_DATA_MULTI_CHANNEL: + case CHANNEL_TYPE: + data = { + channel: this.getChannelValue() + }; + break; + case REPORTING_DATA_CONFIG: + data = { + dataType: this.getUint8() + }; + break; + case EVENTS_CONFIG: + data = { + eventId: this.getUint8() + }; + break; + } + return { + id, + name, + data + }; + }; + CommandBinaryBuffer.prototype.setRequestParameter = function (parameter) { + const { + id, + data: parameterData + } = parameter; + let data; + this.setUint8(id); + switch (id) { + case ABSOLUTE_DATA_MULTI_CHANNEL: + case ABSOLUTE_DATA_ENABLE_MULTI_CHANNEL: + case CHANNEL_TYPE: + data = parameterData; + this.setChannelValue(data.channel); + break; + case REPORTING_DATA_CONFIG: + data = parameterData; + this.setUint8(data.dataType); + break; + case EVENTS_CONFIG: + data = parameterData; + this.setUint8(data.eventId); + break; + } + }; + CommandBinaryBuffer.prototype.getResponseParameter = function () { + const id = this.getUint8(); + const name = deviceParameterNames[id]; + let data; + if (!deviceParameterConvertersMap[id] || !deviceParameterConvertersMap[id].get) { + throw new Error(`parameter ${id} is not supported`); + } + switch (id) { + case MQTT_SESSION_CONFIG: + case NBIOT_SSL_CACERT_WRITE: + case NBIOT_SSL_CLIENT_CERT_WRITE: + case NBIOT_SSL_CLIENT_KEY_WRITE: + case NBIOT_SSL_CACERT_SET: + case NBIOT_SSL_CLIENT_CERT_SET: + case NBIOT_SSL_CLIENT_KEY_SET: + case NBIOT_DEVICE_SOFTWARE_UPDATE: + case NBIOT_MODULE_FIRMWARE_UPDATE: + data = null; + break; + default: + data = deviceParameterConvertersMap[id].get(this); + } + return { + id, + name, + data + }; + }; + CommandBinaryBuffer.prototype.setResponseParameter = function (parameter) { + const { + id, + data + } = parameter; + if (!deviceParameterConvertersMap[id] || !deviceParameterConvertersMap[id].set) { + throw new Error(`parameter ${id} is not supported`); + } + this.setUint8(id); + switch (id) { + case MQTT_SESSION_CONFIG: + case NBIOT_SSL_CACERT_WRITE: + case NBIOT_SSL_CLIENT_CERT_WRITE: + case NBIOT_SSL_CLIENT_KEY_WRITE: + case NBIOT_SSL_CACERT_SET: + case NBIOT_SSL_CLIENT_CERT_SET: + case NBIOT_SSL_CLIENT_KEY_SET: + case NBIOT_DEVICE_SOFTWARE_UPDATE: + case NBIOT_MODULE_FIRMWARE_UPDATE: + break; + default: + deviceParameterConvertersMap[id].set(this, data); + } + }; + CommandBinaryBuffer.prototype.getLegacyHourDiff = function () { + const stateWithValueByte = this.getUint8(); + const valueLowerByte = this.getUint8(); + return { + isMagneticInfluence: CommandBinaryBuffer.getMagneticInfluenceBit(stateWithValueByte), + value: (stateWithValueByte & 0x1f) << 8 | valueLowerByte + }; + }; + CommandBinaryBuffer.prototype.setLegacyHourDiff = function (diff) { + const bytes = [diff.value >> 8, diff.value & 0xff]; + bytes[0] = CommandBinaryBuffer.setMagneticInfluenceBit(bytes[0], diff.isMagneticInfluence); + bytes.forEach(byte => this.setUint8(byte)); + }; + CommandBinaryBuffer.prototype.getLegacyHourCounterWithDiff = function () { + let isArchiveValue = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : false; + const date = this.getDate(); + const byte = this.getUint8(); + const { + hour + } = this.getHours(byte); + const value = this.getLegacyCounterValue(); + const counter = { + isMagneticInfluence: CommandBinaryBuffer.getMagneticInfluenceBit(byte), + value: isArchiveValue && value === EMPTY_VALUE ? 0 : value + }; + const diff = []; + while (this.offset < this.data.length) { + diff.push(this.getLegacyHourDiff()); + } + date.setUTCHours(hour); + return { + startTime2000: getTime2000FromDate(date), + counter, + diff + }; + }; + CommandBinaryBuffer.prototype.setLegacyHourCounterWithDiff = function (hourCounter) { + let isArchiveValue = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : false; + const date = getDateFromTime2000(hourCounter.startTime2000); + const hour = date.getUTCHours(); + const { + value + } = hourCounter.counter; + this.setDate(date); + this.setHours(hour, 1); + this.seek(this.offset - 1); + const byte = this.getUint8(); + this.seek(this.offset - 1); + this.setUint8(CommandBinaryBuffer.setMagneticInfluenceBit(byte, hourCounter.counter.isMagneticInfluence)); + this.setLegacyCounterValue(isArchiveValue && value === 0 ? EMPTY_VALUE : value); + hourCounter.diff.forEach(diffItem => this.setLegacyHourDiff(diffItem)); + }; + CommandBinaryBuffer.prototype.getChannelsValuesWithHourDiffExtended = function () { + let isArchiveValue = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : false; + const date = this.getDate(); + const hour = this.getUint8(); + const hours = this.getUint8(); + const channels = this.getChannels(); + const channelList = []; + date.setUTCHours(hour); + channels.forEach(channelIndex => { + const diff = []; + const value = this.getExtendedValue(); + for (let diffHour = 0; diffHour < hours; ++diffHour) { + diff.push(this.getExtendedValue()); + } + channelList.push({ + value: value === isArchiveValue && EMPTY_VALUE ? 0 : value, + diff, + index: channelIndex + }); + }); + return { + startTime2000: getTime2000FromDate(date), + hour, + hours, + channelList + }; + }; + CommandBinaryBuffer.prototype.setChannelsValuesWithHourDiffExtended = function (parameters) { + let isArchiveValue = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : false; + const date = getDateFromTime2000(parameters.startTime2000); + this.setDate(date); + this.setUint8(parameters.hour); + this.setUint8(parameters.hours); + this.setChannels(parameters.channelList); + parameters.channelList.forEach(_ref6 => { + let { + value, + diff + } = _ref6; + this.setExtendedValue(isArchiveValue && value === 0 ? EMPTY_VALUE : value); + diff.forEach(diffValue => this.setExtendedValue(diffValue)); + }); + }; + CommandBinaryBuffer.prototype.getDataSegment = function () { + const segmentationSessionId = this.getUint8(); + const flag = this.getUint8(); + return { + segmentationSessionId, + segmentIndex: extractBits(flag, 3, 1), + segmentsNumber: extractBits(flag, 3, 5), + isLast: Boolean(extractBits(flag, 1, 8)), + data: this.getBytesLeft() + }; + }; + CommandBinaryBuffer.prototype.setDataSegment = function (parameters) { + let flag = fillBits(0, 3, 1, parameters.segmentIndex); + flag = fillBits(flag, 3, 5, parameters.segmentsNumber); + flag = fillBits(flag, 1, 8, +parameters.isLast); + this.setUint8(parameters.segmentationSessionId); + this.setUint8(flag); + this.setBytes(parameters.data); + }; + CommandBinaryBuffer.prototype.getBinarySensor = function () { + const activeStateTimeMs = this.getUint16(); + return { + activeStateTimeMs + }; + }; + CommandBinaryBuffer.prototype.setBinarySensor = function (parameters) { + this.setUint16(parameters.activeStateTimeMs); + }; + CommandBinaryBuffer.prototype.getTemperatureSensor = function () { + const measurementPeriod = this.getUint16(); + const hysteresisSec = this.getUint8(); + const highTemperatureThreshold = this.getInt8(); + const lowTemperatureThreshold = this.getInt8(); + return { + measurementPeriod, + hysteresisSec, + highTemperatureThreshold, + lowTemperatureThreshold + }; + }; + CommandBinaryBuffer.prototype.setTemperatureSensor = function (parameters) { + this.setInt16(parameters.measurementPeriod); + this.setInt8(parameters.hysteresisSec); + this.setInt8(parameters.highTemperatureThreshold); + this.setInt8(parameters.lowTemperatureThreshold); + }; + CommandBinaryBuffer.prototype.getChannelType = function () { + const channel = this.getChannelValue(); + const type = this.getUint8(); + let parameters = {}; + switch (type) { + case BINARY_SENSOR: + parameters = this.getBinarySensor(); + break; + case TEMPERATURE_SENSOR: + parameters = this.getTemperatureSensor(); + break; + } + return { + channel, + type, + parameters + }; + }; + CommandBinaryBuffer.prototype.setChannelType = function (_ref7) { + let { + type, + channel, + parameters + } = _ref7; + this.setChannelValue(channel); + this.setUint8(type); + switch (type) { + case BINARY_SENSOR: + this.setBinarySensor(parameters); + break; + case TEMPERATURE_SENSOR: + this.setTemperatureSensor(parameters); + break; + } + }; + + const id$Z = dataSegment$1; + downlinkNames[dataSegment$1]; + const COMMAND_BODY_MIN_SIZE$3 = 2; + const fromBytes$ = data => { + const buffer = new CommandBinaryBuffer(data); + return buffer.getDataSegment(); + }; + const toBytes$ = parameters => { + const buffer = new CommandBinaryBuffer(COMMAND_BODY_MIN_SIZE$3 + parameters.data.length); + buffer.setDataSegment(parameters); + return toBytes$11(id$Z, buffer.data); + }; + + const id$Y = getArchiveDays$1; + downlinkNames[getArchiveDays$1]; + const COMMAND_BODY_SIZE$v = 3; + const fromBytes$_ = data => { + if (data.length !== COMMAND_BODY_SIZE$v) { + throw new Error(`Wrong buffer size: ${data.length}.`); + } + const buffer = new CommandBinaryBuffer(data); + const date = buffer.getDate(); + const days = buffer.getUint8(); + if (!buffer.isEmpty) { + throw new Error('BinaryBuffer is not empty.'); + } + return { + startTime2000: getTime2000FromDate(date), + days + }; + }; + const toBytes$_ = parameters => { + const buffer = new CommandBinaryBuffer(COMMAND_BODY_SIZE$v); + const { + startTime2000, + days + } = parameters; + const date = getDateFromTime2000(startTime2000); + buffer.setDate(date); + buffer.setUint8(days); + return toBytes$11(id$Y, buffer.data); + }; + + const id$X = getArchiveDaysMc$1; + downlinkNames[getArchiveDaysMc$1]; + const COMMAND_BODY_SIZE$u = 4; + const fromBytes$Z = data => { + if (data.length !== COMMAND_BODY_SIZE$u) { + throw new Error(`Wrong buffer size: ${data.length}.`); + } + const buffer = new CommandBinaryBuffer(data); + const date = buffer.getDate(); + const channelList = buffer.getChannels(); + const days = buffer.getUint8(); + if (!buffer.isEmpty) { + throw new Error('BinaryBuffer is not empty.'); + } + return { + startTime2000: getTime2000FromDate(date), + days, + channelList + }; + }; + const toBytes$Z = parameters => { + const buffer = new CommandBinaryBuffer(COMMAND_BODY_SIZE$u); + const { + startTime2000, + days, + channelList + } = parameters; + const date = getDateFromTime2000(startTime2000); + buffer.setDate(date); + buffer.setChannels(channelList.map(index => ({ + index + }))); + buffer.setUint8(days); + return toBytes$11(id$X, buffer.data); + }; + + const id$W = getArchiveEvents$1; + downlinkNames[getArchiveEvents$1]; + const COMMAND_BODY_SIZE$t = 5; + const fromBytes$Y = data => { + if (data.length !== COMMAND_BODY_SIZE$t) { + throw new Error(`Wrong buffer size: ${data.length}.`); + } + const buffer = new CommandBinaryBuffer(data); + const startTime2000 = buffer.getTime(); + const events = buffer.getUint8(); + if (!buffer.isEmpty) { + throw new Error('BinaryBuffer is not empty.'); + } + return { + startTime2000, + events + }; + }; + const toBytes$Y = parameters => { + const { + startTime2000, + events + } = parameters; + const buffer = new CommandBinaryBuffer(COMMAND_BODY_SIZE$t); + buffer.setTime(startTime2000); + buffer.setUint8(events); + return toBytes$11(id$W, buffer.data); + }; + + const id$V = getArchiveHours$1; + downlinkNames[getArchiveHours$1]; + const COMMAND_BODY_SIZE$s = 4; + const fromBytes$X = data => { + if (data.length !== COMMAND_BODY_SIZE$s) { + throw new Error(`Wrong buffer size: ${data.length}.`); + } + const buffer = new CommandBinaryBuffer(data); + const date = buffer.getDate(); + const { + hour + } = buffer.getHours(); + const hours = buffer.getUint8(); + date.setUTCHours(hour); + if (!buffer.isEmpty) { + throw new Error('BinaryBuffer is not empty.'); + } + return { + startTime2000: getTime2000FromDate(date), + hours + }; + }; + const toBytes$X = parameters => { + const { + startTime2000, + hours + } = parameters; + const buffer = new CommandBinaryBuffer(COMMAND_BODY_SIZE$s); + const date = getDateFromTime2000(startTime2000); + const hour = date.getUTCHours(); + buffer.setDate(date); + buffer.setHours(hour, 1); + buffer.setUint8(hours); + return toBytes$11(id$V, buffer.data); + }; + + const id$U = getArchiveHoursMc$1; + downlinkNames[getArchiveHoursMc$1]; + const COMMAND_BODY_SIZE$r = 4; + const fromBytes$W = data => { + if (data.length !== COMMAND_BODY_SIZE$r) { + throw new Error(`Wrong buffer size: ${data.length}.`); + } + const buffer = new CommandBinaryBuffer(data); + const date = buffer.getDate(); + const { + hour, + hours + } = buffer.getHours(); + const channelList = buffer.getChannels(); + date.setUTCHours(hour); + if (!buffer.isEmpty) { + throw new Error('BinaryBuffer is not empty.'); + } + return { + startTime2000: getTime2000FromDate(date), + hours, + channelList + }; + }; + const toBytes$W = parameters => { + const buffer = new CommandBinaryBuffer(COMMAND_BODY_SIZE$r); + const { + hours, + startTime2000, + channelList + } = parameters; + const date = getDateFromTime2000(startTime2000); + const hour = date.getUTCHours(); + buffer.setDate(date); + buffer.setHours(hour, hours); + buffer.setChannels(channelList.map(index => ({ + index + }))); + return toBytes$11(id$U, buffer.data); + }; + + const id$T = getArchiveHoursMcEx$1; + downlinkNames[getArchiveHoursMcEx$1]; + const COMMAND_BODY_SIZE$q = 5; + const fromBytes$V = data => { + const buffer = new CommandBinaryBuffer(data); + const date = buffer.getDate(); + const hour = buffer.getUint8(); + const hours = buffer.getUint8(); + const channelList = buffer.getChannels(); + date.setUTCHours(hour); + if (!buffer.isEmpty) { + throw new Error('BinaryBuffer is not empty.'); + } + return { + startTime2000: getTime2000FromDate(date), + hour, + hours, + channelList + }; + }; + const toBytes$V = parameters => { + const buffer = new CommandBinaryBuffer(COMMAND_BODY_SIZE$q); + const { + channelList, + hour, + hours, + startTime2000 + } = parameters; + const date = getDateFromTime2000(startTime2000); + buffer.setDate(date); + buffer.setUint8(hour); + buffer.setUint8(hours); + buffer.setChannels(channelList.map(index => ({ + index + }))); + return toBytes$11(id$T, buffer.data); + }; + + const id$S = getBatteryStatus$1; + downlinkNames[getBatteryStatus$1]; + const COMMAND_BODY_SIZE$p = 0; + const fromBytes$U = data => { + if (data.length !== COMMAND_BODY_SIZE$p) { + throw new Error(`Wrong buffer size: ${data.length}.`); + } + return {}; + }; + const toBytes$U = () => toBytes$11(id$S); + + const id$R = getChannelsStatus$1; + downlinkNames[getChannelsStatus$1]; + const fromBytes$T = data => data.length === 0 ? {} : getChannelsMaskFromNumber(data[0]); + const toBytes$T = parameters => toBytes$11(id$R, Object.keys(parameters).length !== 0 ? [setChannelsMaskToNumber(parameters)] : []); + + const id$Q = getChannelsTypes$1; + downlinkNames[getChannelsTypes$1]; + const COMMAND_BODY_SIZE$o = 0; + const fromBytes$S = data => { + if (data.length !== COMMAND_BODY_SIZE$o) { + throw new Error(`Wrong buffer size: ${data.length}.`); + } + return {}; + }; + const toBytes$S = () => toBytes$11(id$Q); + + const id$P = getCurrent; + downlinkNames[getCurrent]; + const COMMAND_BODY_SIZE$n = 0; + const fromBytes$R = data => { + if (data.length !== COMMAND_BODY_SIZE$n) { + throw new Error(`Wrong buffer size: ${data.length}.`); + } + return {}; + }; + const toBytes$R = () => toBytes$11(id$P); + + const id$O = getCurrentMc; + downlinkNames[getCurrentMc]; + const COMMAND_BODY_SIZE$m = 0; + const fromBytes$Q = data => { + if (data.length !== COMMAND_BODY_SIZE$m) { + throw new Error(`Wrong buffer size: ${data.length}.`); + } + return {}; + }; + const toBytes$Q = () => toBytes$11(id$O); + + const id$N = getExAbsArchiveDaysMc$1; + downlinkNames[getExAbsArchiveDaysMc$1]; + const COMMAND_BODY_SIZE$l = 4; + const fromBytes$P = data => { + if (data.length !== COMMAND_BODY_SIZE$l) { + throw new Error(`Wrong buffer size: ${data.length}.`); + } + const buffer = new CommandBinaryBuffer(data); + const date = buffer.getDate(); + const channelList = buffer.getChannels(); + const days = buffer.getUint8(); + if (!buffer.isEmpty) { + throw new Error('BinaryBuffer is not empty.'); + } + return { + startTime2000: getTime2000FromDate(date), + days, + channelList + }; + }; + const toBytes$P = parameters => { + const buffer = new CommandBinaryBuffer(COMMAND_BODY_SIZE$l); + const { + startTime2000, + days, + channelList + } = parameters; + buffer.setDate(startTime2000); + buffer.setChannels(channelList.map(index => ({ + index + }))); + buffer.setUint8(days); + return toBytes$11(id$N, buffer.data); + }; + + const id$M = getExAbsArchiveHoursMc$1; + downlinkNames[getExAbsArchiveHoursMc$1]; + const COMMAND_BODY_SIZE$k = 4; + const fromBytes$O = data => { + const buffer = new CommandBinaryBuffer(data); + const date = buffer.getDate(); + const { + hour, + hours + } = buffer.getHours(); + const channelList = buffer.getChannels(); + date.setUTCHours(hour); + if (!buffer.isEmpty) { + throw new Error('BinaryBuffer is not empty.'); + } + return { + channelList, + hours, + startTime2000: getTime2000FromDate(date) + }; + }; + const toBytes$O = parameters => { + const buffer = new CommandBinaryBuffer(COMMAND_BODY_SIZE$k); + const { + startTime2000, + hours, + channelList + } = parameters; + const date = getDateFromTime2000(startTime2000); + const hour = date.getUTCHours(); + buffer.setDate(date); + buffer.setHours(hour, hours); + buffer.setChannels(channelList.map(index => ({ + index + }))); + return toBytes$11(id$M, buffer.data); + }; + + const id$L = getExAbsCurrentMc; + downlinkNames[getExAbsCurrentMc]; + const COMMAND_BODY_SIZE$j = 0; + const fromBytes$N = data => { + if (data.length !== COMMAND_BODY_SIZE$j) { + throw new Error(`Wrong buffer size: ${data.length}.`); + } + return {}; + }; + const toBytes$N = () => toBytes$11(id$L); + + const id$K = getLmicInfo$1; + downlinkNames[getLmicInfo$1]; + const COMMAND_BODY_SIZE$i = 0; + const fromBytes$M = data => { + if (data.length !== COMMAND_BODY_SIZE$i) { + throw new Error(`Wrong buffer size: ${data.length}.`); + } + return {}; + }; + const toBytes$M = () => toBytes$11(id$K); + + const id$J = getParameter$1; + downlinkNames[getParameter$1]; + const fromBytes$L = data => { + const buffer = new CommandBinaryBuffer(data); + return buffer.getRequestParameter(); + }; + const toBytes$L = parameters => { + const buffer = new CommandBinaryBuffer(getRequestParameterSize(parameters)); + buffer.setRequestParameter(parameters); + return toBytes$11(id$J, buffer.data); + }; + + const id$I = getStatus; + downlinkNames[getStatus]; + const COMMAND_BODY_SIZE$h = 0; + const fromBytes$K = data => { + if (data.length !== COMMAND_BODY_SIZE$h) { + throw new Error(`Wrong buffer size: ${data.length}.`); + } + return {}; + }; + const toBytes$K = () => toBytes$11(id$I); + + const id$H = getTime2000; + downlinkNames[getTime2000]; + const COMMAND_BODY_SIZE$g = 0; + const fromBytes$J = data => { + if (data.length !== COMMAND_BODY_SIZE$g) { + throw new Error(`Wrong buffer size: ${data.length}.`); + } + return {}; + }; + const toBytes$J = () => toBytes$11(id$H, []); + + const id$G = setParameter$1; + downlinkNames[setParameter$1]; + const fromBytes$I = data => { + const buffer = new CommandBinaryBuffer(data); + return buffer.getParameter(); + }; + const toBytes$I = parameters => { + const buffer = new CommandBinaryBuffer(getParameterSize(parameters)); + buffer.setParameter(parameters); + return toBytes$11(id$G, buffer.data); + }; + + const id$F = setTime2000$1; + downlinkNames[setTime2000$1]; + const COMMAND_BODY_SIZE$f = 5; + const fromBytes$H = data => { + if (data.length !== COMMAND_BODY_SIZE$f) { + throw new Error(`Wrong buffer size: ${data.length}.`); + } + const buffer = new BinaryBuffer(data, false); + const parameters = { + sequenceNumber: buffer.getUint8(), + seconds: buffer.getInt32() + }; + if (!buffer.isEmpty) { + throw new Error('BinaryBuffer is not empty.'); + } + return parameters; + }; + const toBytes$H = parameters => { + const { + sequenceNumber, + seconds + } = parameters; + const buffer = new BinaryBuffer(COMMAND_BODY_SIZE$f, false); + buffer.setUint8(sequenceNumber); + buffer.setInt32(seconds); + return toBytes$11(id$F, buffer.data); + }; + + const id$E = softRestart$1; + downlinkNames[softRestart$1]; + const COMMAND_BODY_SIZE$e = 0; + const fromBytes$G = data => { + if (data.length !== COMMAND_BODY_SIZE$e) { + throw new Error(`Wrong buffer size: ${data.length}.`); + } + return {}; + }; + const toBytes$G = () => toBytes$11(id$E); + + const id$D = updateRun$1; + downlinkNames[updateRun$1]; + const COMMAND_BODY_SIZE$d = 0; + const fromBytes$F = data => { + if (data.length !== COMMAND_BODY_SIZE$d) { + throw new Error(`Wrong buffer size: ${data.length}.`); + } + return {}; + }; + const toBytes$F = () => toBytes$11(id$D); + + const id$C = usWaterMeterCommand$1; + downlinkNames[usWaterMeterCommand$1]; + const fromBytes$E = data => { + const buffer = new CommandBinaryBuffer(data); + const length = buffer.getUint8(); + return { + length, + data: data.slice(1) + }; + }; + const toBytes$E = parameters => { + const { + data, + length + } = parameters; + const buffer = new CommandBinaryBuffer(length); + buffer.setUint8(length); + buffer.setBytes(data); + return toBytes$11(id$C, buffer.data); + }; + + const id$B = verifyImage$1; + downlinkNames[verifyImage$1]; + const COMMAND_BODY_SIZE$c = 0; + const fromBytes$D = data => { + if (data.length !== COMMAND_BODY_SIZE$c) { + throw new Error(`Wrong buffer size: ${data.length}.`); + } + return {}; + }; + const toBytes$D = () => toBytes$11(id$B); + + const id$A = writeImage$1; + downlinkNames[writeImage$1]; + const COMMAND_BODY_MIN_SIZE$2 = 4; + const fromBytes$C = data => { + if (data.length < COMMAND_BODY_MIN_SIZE$2) { + throw new Error(`Wrong buffer size: ${data.length}.`); + } + const buffer = new CommandBinaryBuffer(data); + const offset = buffer.getUint32(); + return { + offset, + data: data.slice(COMMAND_BODY_MIN_SIZE$2) + }; + }; + const toBytes$C = parameters => { + const buffer = new CommandBinaryBuffer(COMMAND_BODY_MIN_SIZE$2); + buffer.setUint32(parameters.offset); + buffer.setBytes(parameters.data); + return toBytes$11(id$A, buffer.data); + }; + + var calculateLrc = (function (data) { + let initialLrc = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : 0x55; + let lrc = initialLrc; + data.forEach(item => { + lrc ^= item; + }); + return lrc; + }); + + const HEADER_MAX_SIZE = 3; + const getFromBytes = (fromBytesMap, nameMap) => function () { + let bytes = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : []; + let config = arguments.length > 1 ? arguments[1] : undefined; + const commands = []; + const message = { + commands, + bytes, + lrc: { + received: undefined, + calculated: 0 + } + }; + let processedBytes = 0; + let receivedLrc; + let calculatedLrc; + if (!bytes.length) { + return message; + } + do { + const headerInfo = fromBytes$11(bytes.slice(processedBytes, processedBytes + HEADER_MAX_SIZE)); + const headerData = bytes.slice(processedBytes, processedBytes + headerInfo.headerSize); + const bodyData = bytes.slice(processedBytes + headerInfo.headerSize, processedBytes + headerInfo.headerSize + headerInfo.commandSize); + const command = { + id: headerInfo.commandId, + name: nameMap[headerInfo.commandId], + headerSize: headerInfo.headerSize, + bytes: [...headerData, ...bodyData] + }; + processedBytes = processedBytes + headerInfo.headerSize + headerInfo.commandSize; + if (config) { + command.config = config; + } + try { + if (!fromBytesMap[headerInfo.commandId]) { + throw new Error(`Unsupported command id: ${headerInfo.commandId}!`); + } + command.parameters = fromBytesMap[headerInfo.commandId](bodyData, config); + commands.push(command); + } catch (error) { + commands.push({ + command, + error: error.message + }); + } + } while (processedBytes < bytes.length - 1); + if (bytes.length - processedBytes === 1) { + receivedLrc = bytes[bytes.length - 1]; + calculatedLrc = calculateLrc(bytes.slice(0, -1)); + } else { + calculatedLrc = calculateLrc(bytes); + } + message.lrc.calculated = calculatedLrc; + message.lrc.received = receivedLrc; + if (receivedLrc === calculatedLrc) { + return message; + } + return { + message, + error: 'Mismatch LRC.' + }; + }; + const getToBytes = toBytesMap => commands => { + const commandBytes = commands.map(command => { + if ('id' in command) { + return toBytesMap[command.id](command.parameters || {}, command.config); + } + if ('command' in command) { + return command.command.bytes; + } + throw new Error('wrong command format'); + }); + const body = [].concat(...commandBytes); + return [...body, calculateLrc(body)]; + }; + const getToMessage = toBytesMap => commands => { + const commandsWithBytes = commands.map(command => { + if ('parameters' in command) { + return Object.assign({}, command, { + bytes: toBytesMap[command.id](command.parameters, command.config) + }); + } + throw new Error('wrong command format'); + }); + const commandBytes = commandsWithBytes.map(_ref => { + let { + bytes + } = _ref; + return bytes; + }); + const body = [].concat(...commandBytes); + const lrc = calculateLrc(body); + return { + commands: commandsWithBytes, + bytes: [...body, lrc], + lrc: { + received: lrc, + calculated: lrc + } + }; + }; + + const toBytesMap$1 = {}; + const fromBytesMap$1 = {}; + const nameMap$1 = downlinkNames; + const fromBytes$B = getFromBytes(fromBytesMap$1, nameMap$1); + const toBytes$B = getToBytes(toBytesMap$1); + const toMessage$1 = getToMessage(toBytesMap$1); + toBytesMap$1[id$_] = toBytes$10; + toBytesMap$1[id$Z] = toBytes$; + toBytesMap$1[id$Y] = toBytes$_; + toBytesMap$1[id$X] = toBytes$Z; + toBytesMap$1[id$W] = toBytes$Y; + toBytesMap$1[id$V] = toBytes$X; + toBytesMap$1[id$U] = toBytes$W; + toBytesMap$1[id$T] = toBytes$V; + toBytesMap$1[id$S] = toBytes$U; + toBytesMap$1[id$R] = toBytes$T; + toBytesMap$1[id$Q] = toBytes$S; + toBytesMap$1[id$P] = toBytes$R; + toBytesMap$1[id$O] = toBytes$Q; + toBytesMap$1[id$N] = toBytes$P; + toBytesMap$1[id$M] = toBytes$O; + toBytesMap$1[id$L] = toBytes$N; + toBytesMap$1[id$K] = toBytes$M; + toBytesMap$1[id$J] = toBytes$L; + toBytesMap$1[id$I] = toBytes$K; + toBytesMap$1[id$H] = toBytes$J; + toBytesMap$1[id$G] = toBytes$I; + toBytesMap$1[id$F] = toBytes$H; + toBytesMap$1[id$E] = toBytes$G; + toBytesMap$1[id$D] = toBytes$F; + toBytesMap$1[id$C] = toBytes$E; + toBytesMap$1[id$B] = toBytes$D; + toBytesMap$1[id$A] = toBytes$C; + fromBytesMap$1[id$_] = fromBytes$10; + fromBytesMap$1[id$Z] = fromBytes$; + fromBytesMap$1[id$Y] = fromBytes$_; + fromBytesMap$1[id$X] = fromBytes$Z; + fromBytesMap$1[id$W] = fromBytes$Y; + fromBytesMap$1[id$V] = fromBytes$X; + fromBytesMap$1[id$U] = fromBytes$W; + fromBytesMap$1[id$T] = fromBytes$V; + fromBytesMap$1[id$S] = fromBytes$U; + fromBytesMap$1[id$R] = fromBytes$T; + fromBytesMap$1[id$Q] = fromBytes$S; + fromBytesMap$1[id$P] = fromBytes$R; + fromBytesMap$1[id$O] = fromBytes$Q; + fromBytesMap$1[id$N] = fromBytes$P; + fromBytesMap$1[id$M] = fromBytes$O; + fromBytesMap$1[id$L] = fromBytes$N; + fromBytesMap$1[id$K] = fromBytes$M; + fromBytesMap$1[id$J] = fromBytes$L; + fromBytesMap$1[id$I] = fromBytes$K; + fromBytesMap$1[id$H] = fromBytes$J; + fromBytesMap$1[id$G] = fromBytes$I; + fromBytesMap$1[id$F] = fromBytes$H; + fromBytesMap$1[id$E] = fromBytes$G; + fromBytesMap$1[id$D] = fromBytes$F; + fromBytesMap$1[id$C] = fromBytes$E; + fromBytesMap$1[id$B] = fromBytes$D; + fromBytesMap$1[id$A] = fromBytes$C; + + var downlink = /*#__PURE__*/Object.freeze({ + __proto__: null, + fromBytes: fromBytes$B, + fromBytesMap: fromBytesMap$1, + nameMap: nameMap$1, + toBytes: toBytes$B, + toBytesMap: toBytesMap$1, + toMessage: toMessage$1 + }); + + const setTime2000 = 0x02; + const setParameter = 0x03; + const getParameter = 0x04; + const getArchiveHours = 0x05; + const getArchiveDays = 0x06; + const current = 0x07; + const time2000 = 0x09; + const getArchiveEvents = 0x0b; + const correctTime2000 = 0x0c; + const status = 0x14; + const newEvent = 0x15; + const dayMc = 0x16; + const hourMc = 0x17; + const currentMc = 0x18; + const softRestart = 0x19; + const getArchiveHoursMc = 0x1a; + const getArchiveDaysMc = 0x1b; + const dataSegment = 0x1e; + const day = 0x20; + const hour = 0x40; + const lastEvent = 0x60; + const getLmicInfo = 0x21f; + const getBatteryStatus = 0x51f; + const usWaterMeterCommand = 0x71f; + const exAbsHourMc = 0xa1f; + const exAbsDayMc = 0xb1f; + const getExAbsArchiveHoursMc = 0xc1f; + const getExAbsArchiveDaysMc = 0xd1f; + const exAbsCurrentMc = 0xf1f; + const usWaterMeterBatteryStatus = 0x141f; + const writeImage = 0x2a1f; + const verifyImage = 0x2b1f; + const updateRun = 0x2c1f; + const getArchiveHoursMcEx = 0x301f; + const hourMcEx = 0x311f; + const getChannelsStatus = 0x321f; + const getChannelsTypes = 0x331f; + + var uplinkIds = /*#__PURE__*/Object.freeze({ + __proto__: null, + correctTime2000: correctTime2000, + current: current, + currentMc: currentMc, + dataSegment: dataSegment, + day: day, + dayMc: dayMc, + exAbsCurrentMc: exAbsCurrentMc, + exAbsDayMc: exAbsDayMc, + exAbsHourMc: exAbsHourMc, + getArchiveDays: getArchiveDays, + getArchiveDaysMc: getArchiveDaysMc, + getArchiveEvents: getArchiveEvents, + getArchiveHours: getArchiveHours, + getArchiveHoursMc: getArchiveHoursMc, + getArchiveHoursMcEx: getArchiveHoursMcEx, + getBatteryStatus: getBatteryStatus, + getChannelsStatus: getChannelsStatus, + getChannelsTypes: getChannelsTypes, + getExAbsArchiveDaysMc: getExAbsArchiveDaysMc, + getExAbsArchiveHoursMc: getExAbsArchiveHoursMc, + getLmicInfo: getLmicInfo, + getParameter: getParameter, + hour: hour, + hourMc: hourMc, + hourMcEx: hourMcEx, + lastEvent: lastEvent, + newEvent: newEvent, + setParameter: setParameter, + setTime2000: setTime2000, + softRestart: softRestart, + status: status, + time2000: time2000, + updateRun: updateRun, + usWaterMeterBatteryStatus: usWaterMeterBatteryStatus, + usWaterMeterCommand: usWaterMeterCommand, + verifyImage: verifyImage, + writeImage: writeImage + }); + + var uplinkNames = invertObject(uplinkIds); + + const id$z = correctTime2000; + uplinkNames[correctTime2000]; + const COMMAND_BODY_SIZE$b = 1; + const fromBytes$A = data => { + if (data.length !== COMMAND_BODY_SIZE$b) { + throw new Error(`Wrong buffer size: ${data.length}.`); + } + const buffer = new BinaryBuffer(data, false); + const parameters = { + status: buffer.getUint8() + }; + if (!buffer.isEmpty) { + throw new Error('BinaryBuffer is not empty.'); + } + return parameters; + }; + const toBytes$A = parameters => { + const { + status + } = parameters; + const buffer = new BinaryBuffer(COMMAND_BODY_SIZE$b, false); + buffer.setUint8(status); + return toBytes$11(id$z, buffer.data); + }; + + const id$y = current; + uplinkNames[current]; + const COMMAND_BODY_MAX_SIZE$e = 4; + const fromBytes$z = data => { + if (data.length > COMMAND_BODY_MAX_SIZE$e) { + throw new Error(`Wrong buffer size: ${data.length}.`); + } + const buffer = new CommandBinaryBuffer(data); + return buffer.getLegacyCounter(); + }; + const toBytes$z = parameters => { + const buffer = new CommandBinaryBuffer(COMMAND_BODY_MAX_SIZE$e); + buffer.setLegacyCounter(parameters); + return toBytes$11(id$y, buffer.data); + }; + + const id$x = currentMc; + uplinkNames[currentMc]; + const COMMAND_BODY_MAX_SIZE$d = 37; + const fromBytes$y = data => { + if (data.length > COMMAND_BODY_MAX_SIZE$d) { + throw new Error(`Wrong buffer size: ${data.length}.`); + } + const parameters = { + channelList: [] + }; + const buffer = new CommandBinaryBuffer(data); + const channelList = buffer.getChannels(); + parameters.channelList = channelList.map(channelIndex => ({ + value: buffer.getExtendedValue(), + index: channelIndex + })); + return parameters; + }; + const toBytes$y = parameters => { + const buffer = new CommandBinaryBuffer(COMMAND_BODY_MAX_SIZE$d); + const { + channelList + } = parameters; + buffer.setChannels(channelList); + channelList.forEach(_ref => { + let { + value + } = _ref; + buffer.setExtendedValue(value); + }); + return toBytes$11(id$x, buffer.getBytesToOffset()); + }; + + const id$w = day; + uplinkNames[day]; + const COMMAND_BODY_SIZE$a = 6; + const fromBytes$x = data => { + const buffer = new CommandBinaryBuffer(data); + const date = buffer.getDate(); + const byte = buffer.getUint8(); + const { + hour + } = buffer.getHours(byte); + const isMagneticInfluence = CommandBinaryBuffer.getMagneticInfluenceBit(byte); + const value = buffer.getLegacyCounterValue(); + date.setUTCHours(hour); + return { + value, + isMagneticInfluence, + startTime2000: getTime2000FromDate(date) + }; + }; + const toBytes$x = parameters => { + const buffer = new CommandBinaryBuffer(COMMAND_BODY_SIZE$a); + const { + value, + isMagneticInfluence, + startTime2000 + } = parameters; + const date = getDateFromTime2000(startTime2000); + const hour = date.getUTCHours(); + buffer.setDate(date); + buffer.setHours(hour, 1); + buffer.seek(buffer.offset - 1); + const byte = buffer.getUint8(); + buffer.seek(buffer.offset - 1); + buffer.setUint8(CommandBinaryBuffer.setMagneticInfluenceBit(byte, isMagneticInfluence)); + buffer.setLegacyCounterValue(value); + return toBytes$11(id$w, buffer.getBytesToOffset()); + }; + + const id$v = dayMc; + uplinkNames[dayMc]; + const COMMAND_BODY_MAX_SIZE$c = 32; + const fromBytes$w = data => { + if (data.length > COMMAND_BODY_MAX_SIZE$c) { + throw new Error(`Wrong buffer size: ${data.length}.`); + } + const buffer = new CommandBinaryBuffer(data); + const date = buffer.getDate(); + const channels = buffer.getChannels(); + const channelList = channels.map(channelIndex => ({ + value: buffer.getExtendedValue(), + index: channelIndex + })); + return { + startTime2000: getTime2000FromDate(date), + channelList + }; + }; + const toBytes$w = parameters => { + const buffer = new CommandBinaryBuffer(COMMAND_BODY_MAX_SIZE$c); + const { + channelList, + startTime2000 + } = parameters; + buffer.setDate(startTime2000); + buffer.setChannels(channelList); + channelList.forEach(_ref => { + let { + value + } = _ref; + buffer.setExtendedValue(value); + }); + return toBytes$11(id$v, buffer.getBytesToOffset()); + }; + + const id$u = exAbsCurrentMc; + uplinkNames[exAbsCurrentMc]; + const COMMAND_BODY_MAX_SIZE$b = 87; + const fromBytes$v = data => { + const buffer = new CommandBinaryBuffer(data); + return { + channelList: buffer.getChannelsWithAbsoluteValues() + }; + }; + const toBytes$v = parameters => { + const buffer = new CommandBinaryBuffer(COMMAND_BODY_MAX_SIZE$b); + buffer.setChannelsWithAbsoluteValues(parameters.channelList); + return toBytes$11(id$u, buffer.getBytesToOffset()); + }; + + const id$t = exAbsDayMc; + uplinkNames[exAbsDayMc]; + const COMMAND_BODY_MAX_SIZE$a = 89; + const fromBytes$u = data => { + if (data.length > COMMAND_BODY_MAX_SIZE$a) { + throw new Error(`Wrong buffer size: ${data.length}.`); + } + const buffer = new CommandBinaryBuffer(data); + const date = buffer.getDate(); + const channelList = buffer.getChannelsWithAbsoluteValues(); + return { + startTime2000: getTime2000FromDate(date), + channelList + }; + }; + const toBytes$u = parameters => { + const buffer = new CommandBinaryBuffer(COMMAND_BODY_MAX_SIZE$a); + const { + startTime2000, + channelList + } = parameters; + buffer.setDate(startTime2000); + buffer.setChannelsWithAbsoluteValues(channelList); + return toBytes$11(id$t, buffer.getBytesToOffset()); + }; + + const id$s = exAbsHourMc; + uplinkNames[exAbsHourMc]; + const COMMAND_BODY_MAX_SIZE$9 = 168; + const fromBytes$t = data => { + if (data.length > COMMAND_BODY_MAX_SIZE$9) { + throw new Error(`Wrong buffer size: ${data.length}.`); + } + const buffer = new CommandBinaryBuffer(data); + const date = buffer.getDate(); + const { + hour, + hours + } = buffer.getHours(); + const channelList = buffer.getChannelsAbsoluteValuesWithHourDiff(hours); + date.setUTCHours(hour); + return { + startTime2000: getTime2000FromDate(date), + hours, + channelList + }; + }; + const toBytes$t = parameters => { + const buffer = new CommandBinaryBuffer(COMMAND_BODY_MAX_SIZE$9); + const { + startTime2000, + hours, + channelList + } = parameters; + const date = getDateFromTime2000(startTime2000); + const hour = date.getUTCHours(); + buffer.setDate(startTime2000); + buffer.setHours(hour, hours); + buffer.setChannelsAbsoluteValuesWithHourDiff(channelList); + return toBytes$11(id$s, buffer.getBytesToOffset()); + }; + + const id$r = getArchiveDays; + uplinkNames[getArchiveDays]; + const COMMAND_BODY_MIN_SIZE$1 = 2; + const DAY_COUNTER_SIZE = 4; + const fromBytes$s = data => { + const buffer = new CommandBinaryBuffer(data); + const date = buffer.getDate(); + const dayList = []; + while (buffer.offset < buffer.data.length) { + dayList.push(buffer.getLegacyCounter(undefined, true)); + } + return { + startTime2000: getTime2000FromDate(date), + dayList + }; + }; + const toBytes$s = parameters => { + const { + startTime2000, + dayList + } = parameters; + const buffer = new CommandBinaryBuffer(COMMAND_BODY_MIN_SIZE$1 + dayList.length * DAY_COUNTER_SIZE); + buffer.setDate(startTime2000); + dayList.forEach(dayCounter => buffer.setLegacyCounter(dayCounter, undefined, true)); + return toBytes$11(id$r, buffer.getBytesToOffset()); + }; + + const id$q = getArchiveDaysMc; + uplinkNames[getArchiveDaysMc]; + const COMMAND_BODY_MAX_SIZE$8 = 255; + const fromBytes$r = data => { + const buffer = new CommandBinaryBuffer(data); + const date = buffer.getDate(); + const channels = buffer.getChannels(); + const days = buffer.getUint8(); + const channelList = []; + channels.forEach(channelIndex => { + const dayList = []; + channelList.push({ + dayList, + index: channelIndex + }); + for (let day = 0; day < days; ++day) { + const value = buffer.getExtendedValue(); + dayList.push(value === EMPTY_VALUE ? 0 : value); + } + }); + return { + startTime2000: getTime2000FromDate(date), + days, + channelList + }; + }; + const toBytes$r = parameters => { + const buffer = new CommandBinaryBuffer(COMMAND_BODY_MAX_SIZE$8); + const { + startTime2000, + days, + channelList + } = parameters; + buffer.setDate(startTime2000); + buffer.setChannels(channelList); + buffer.setUint8(days); + channelList.forEach(_ref => { + let { + dayList + } = _ref; + dayList.forEach(value => { + buffer.setExtendedValue(value === 0 ? EMPTY_VALUE : value); + }); + }); + return toBytes$11(id$q, buffer.getBytesToOffset()); + }; + + const MAGNET_ON = 1; + const MAGNET_OFF = 2; + const ACTIVATE = 3; + const DEACTIVATE = 4; + const BATTERY_ALARM = 5; + const CAN_OFF = 6; + const INSERT = 7; + const REMOVE = 8; + const COUNTER_OVER = 9; + const SET_TIME = 10; + const ACTIVATE_MTX = 11; + const CONNECT = 12; + const DISCONNECT = 13; + const DEPASS_DONE = 14; + const OPTOLOW = 15; + const OPTOFLASH = 16; + const MTX = 17; + const JOIN_ACCEPT = 18; + const WATER_EVENT = 19; + const WATER_NO_RESPONSE = 20; + const OPTOSENSOR_ERROR = 21; + const BINARY_SENSOR_ON = 22; + const BINARY_SENSOR_OFF = 23; + const TEMPERATURE_SENSOR_HYSTERESIS = 24; + const TEMPERATURE_SENSOR_LOW_TEMPERATURE = 25; + const TEMPERATURE_SENSOR_HIGH_TEMPERATURE = 26; + + var events = /*#__PURE__*/Object.freeze({ + __proto__: null, + ACTIVATE: ACTIVATE, + ACTIVATE_MTX: ACTIVATE_MTX, + BATTERY_ALARM: BATTERY_ALARM, + BINARY_SENSOR_OFF: BINARY_SENSOR_OFF, + BINARY_SENSOR_ON: BINARY_SENSOR_ON, + CAN_OFF: CAN_OFF, + CONNECT: CONNECT, + COUNTER_OVER: COUNTER_OVER, + DEACTIVATE: DEACTIVATE, + DEPASS_DONE: DEPASS_DONE, + DISCONNECT: DISCONNECT, + INSERT: INSERT, + JOIN_ACCEPT: JOIN_ACCEPT, + MAGNET_OFF: MAGNET_OFF, + MAGNET_ON: MAGNET_ON, + MTX: MTX, + OPTOFLASH: OPTOFLASH, + OPTOLOW: OPTOLOW, + OPTOSENSOR_ERROR: OPTOSENSOR_ERROR, + REMOVE: REMOVE, + SET_TIME: SET_TIME, + TEMPERATURE_SENSOR_HIGH_TEMPERATURE: TEMPERATURE_SENSOR_HIGH_TEMPERATURE, + TEMPERATURE_SENSOR_HYSTERESIS: TEMPERATURE_SENSOR_HYSTERESIS, + TEMPERATURE_SENSOR_LOW_TEMPERATURE: TEMPERATURE_SENSOR_LOW_TEMPERATURE, + WATER_EVENT: WATER_EVENT, + WATER_NO_RESPONSE: WATER_NO_RESPONSE + }); + + var eventNames = invertObject(events); + + const id$p = getArchiveEvents; + uplinkNames[getArchiveEvents]; + const COMMAND_BODY_MIN_SIZE = 4 + 1 + 1; + const getEvent = buffer => { + const time2000 = buffer.getTime(); + const eventId = buffer.getUint8(); + const sequenceNumber = buffer.getUint8(); + return { + time2000, + id: eventId, + name: eventNames[eventId], + sequenceNumber + }; + }; + const setEvent = (buffer, event) => { + buffer.setTime(event.time2000); + buffer.setUint8(event.id); + buffer.setUint8(event.sequenceNumber); + }; + const fromBytes$q = data => { + const buffer = new CommandBinaryBuffer(data); + const eventList = []; + while (buffer.bytesLeft > 0) { + eventList.push(getEvent(buffer)); + } + return { + eventList + }; + }; + function toBytes$q(parameters) { + const { + eventList + } = parameters; + const buffer = new CommandBinaryBuffer(eventList.length * COMMAND_BODY_MIN_SIZE); + eventList.forEach(event => setEvent(buffer, event)); + return toBytes$11(id$p, buffer.data); + } + + const id$o = getArchiveHours; + uplinkNames[getArchiveHours]; + const fromBytes$p = data => { + const buffer = new CommandBinaryBuffer(data); + return buffer.getLegacyHourCounterWithDiff(true); + }; + const toBytes$p = parameters => { + const buffer = new CommandBinaryBuffer(CommandBinaryBuffer.getLegacyHourCounterSize(parameters)); + buffer.setLegacyHourCounterWithDiff(parameters, true); + return toBytes$11(id$o, buffer.getBytesToOffset()); + }; + + const id$n = getArchiveHoursMc; + uplinkNames[getArchiveHoursMc]; + const COMMAND_BODY_MAX_SIZE$7 = 164; + const fromBytes$o = data => { + if (data.length > COMMAND_BODY_MAX_SIZE$7) { + throw new Error(`Wrong buffer size: ${data.length}.`); + } + const buffer = new CommandBinaryBuffer(data); + return buffer.getChannelsValuesWithHourDiff(true); + }; + const toBytes$o = parameters => { + const buffer = new CommandBinaryBuffer(COMMAND_BODY_MAX_SIZE$7); + const { + hours, + startTime2000, + channelList + } = parameters; + buffer.setChannelsValuesWithHourDiff(hours, startTime2000, channelList, true); + return toBytes$11(id$n, buffer.getBytesToOffset()); + }; + + const id$m = getArchiveHoursMcEx; + uplinkNames[getArchiveHoursMcEx]; + const COMMAND_BODY_MAX_SIZE$6 = 255; + const fromBytes$n = data => { + if (data.length > COMMAND_BODY_MAX_SIZE$6) { + throw new Error(`Wrong buffer size: ${data.length}.`); + } + const buffer = new CommandBinaryBuffer(data); + return buffer.getChannelsValuesWithHourDiffExtended(true); + }; + const toBytes$n = parameters => { + const buffer = new CommandBinaryBuffer(COMMAND_BODY_MAX_SIZE$6); + buffer.setChannelsValuesWithHourDiffExtended(parameters, true); + return toBytes$11(id$m, buffer.getBytesToOffset()); + }; + + const id$l = getBatteryStatus; + uplinkNames[getBatteryStatus]; + const COMMAND_BODY_SIZE$9 = 11; + const fromBytes$m = data => { + const buffer = new CommandBinaryBuffer(data); + return { + voltageUnderLowLoad: buffer.getUint16(), + voltageUnderHighLoad: buffer.getUint16(), + internalResistance: buffer.getUint16(), + temperature: buffer.getUint8(), + remainingCapacity: buffer.getUint8(), + isLastDayOverconsumption: buffer.getUint8() === 1, + averageDailyOverconsumptionCounter: buffer.getUint16() + }; + }; + const toBytes$m = parameters => { + const buffer = new CommandBinaryBuffer(COMMAND_BODY_SIZE$9); + buffer.setUint16(parameters.voltageUnderLowLoad); + buffer.setUint16(parameters.voltageUnderHighLoad); + buffer.setUint16(parameters.internalResistance); + buffer.setUint8(parameters.temperature); + buffer.setUint8(parameters.remainingCapacity); + buffer.setUint8(parameters.isLastDayOverconsumption ? 1 : 0); + buffer.setUint16(parameters.averageDailyOverconsumptionCounter); + return toBytes$11(id$l, buffer.data); + }; + + var channelNames = invertObject(channelTypes); + + const id$k = getChannelsStatus; + uplinkNames[getChannelsStatus]; + const getBufferSize = channelsStatus => { + let size = 0; + for (let index = 0; index < channelsStatus.length; index++) { + size += 2; + switch (channelsStatus[index].type) { + case BINARY_SENSOR: + case TEMPERATURE_SENSOR: + size += 1; + break; + } + } + return size; + }; + const getBinarySensorStatus = buffer => ({ + state: buffer.getUint8() !== 0 + }); + const setBinarySensorStatus = (status, buffer) => { + buffer.setUint8(status.state ? 1 : 0); + }; + const getTemperatureSensorStatus = buffer => ({ + temperature: buffer.getInt8(), + time2000: buffer.getTime() + }); + const setTemperatureSensorStatus = (status, buffer) => { + buffer.setInt8(status.temperature); + buffer.setTime(status.time2000); + }; + const fromBytes$l = data => { + const buffer = new CommandBinaryBuffer(data); + const result = []; + while (buffer.bytesLeft !== 0) { + const type = buffer.getUint8(); + const channelStatus = { + type, + typeName: channelNames[type], + channel: buffer.getChannelValue() + }; + switch (channelStatus.type) { + case BINARY_SENSOR: + channelStatus.status = getBinarySensorStatus(buffer); + break; + case TEMPERATURE_SENSOR: + channelStatus.status = getTemperatureSensorStatus(buffer); + break; + default: + return result; + } + result.push(channelStatus); + } + return result; + }; + const toBytes$l = channelsStatus => { + const buffer = new CommandBinaryBuffer(getBufferSize(channelsStatus)); + for (let index = 0; index < channelsStatus.length; index++) { + const { + type, + channel, + status + } = channelsStatus[index]; + buffer.setUint8(type); + buffer.setChannelValue(channel); + switch (type) { + case BINARY_SENSOR: + setBinarySensorStatus(status, buffer); + break; + case TEMPERATURE_SENSOR: + setTemperatureSensorStatus(status, buffer); + break; + } + } + return toBytes$11(id$k, buffer.data); + }; + + const id$j = getChannelsTypes; + uplinkNames[getChannelsTypes]; + const fromBytes$k = data => ({ + channels: data.map(type => ({ + type, + typeName: channelNames[type] + })) + }); + const toBytes$k = _ref => { + let { + channels + } = _ref; + return toBytes$11(id$j, channels.map(channel => channel.type)); + }; + + const id$i = getExAbsArchiveDaysMc; + uplinkNames[getExAbsArchiveDaysMc]; + const COMMAND_BODY_MAX_SIZE$5 = 255; + const fromBytes$j = data => { + const buffer = new CommandBinaryBuffer(data); + const date = buffer.getDate(); + const channels = buffer.getChannels(); + const days = buffer.getUint8(); + const channelList = []; + channels.forEach(channelIndex => { + const dayList = []; + const pulseCoefficient = buffer.getPulseCoefficient(); + channelList.push({ + pulseCoefficient, + dayList, + index: channelIndex + }); + for (let day = 0; day < days; ++day) { + const value = buffer.getExtendedValue(); + dayList.push(value === EMPTY_VALUE ? 0 : value); + } + }); + return { + channelList, + days, + startTime2000: getTime2000FromDate(date) + }; + }; + const toBytes$j = parameters => { + const buffer = new CommandBinaryBuffer(COMMAND_BODY_MAX_SIZE$5); + const { + channelList, + startTime2000, + days + } = parameters; + buffer.setDate(startTime2000); + buffer.setChannels(channelList); + buffer.setUint8(days); + channelList.forEach(_ref => { + let { + pulseCoefficient, + dayList + } = _ref; + buffer.setPulseCoefficient(pulseCoefficient); + dayList.forEach(value => { + buffer.setExtendedValue(value === 0 ? EMPTY_VALUE : value); + }); + }); + return toBytes$11(id$i, buffer.getBytesToOffset()); + }; + + const id$h = getExAbsArchiveHoursMc; + uplinkNames[getExAbsArchiveHoursMc]; + const COMMAND_BODY_MAX_SIZE$4 = 164; + const fromBytes$i = data => { + const buffer = new CommandBinaryBuffer(data); + return buffer.getChannelsValuesWithHourDiff(true); + }; + const toBytes$i = parameters => { + const buffer = new CommandBinaryBuffer(COMMAND_BODY_MAX_SIZE$4); + buffer.setChannelsValuesWithHourDiff(parameters.hours, parameters.startTime2000, parameters.channelList, true); + return toBytes$11(id$h, buffer.getBytesToOffset()); + }; + + const id$g = getLmicInfo; + uplinkNames[getLmicInfo]; + const COMMAND_BODY_SIZE$8 = 2; + const lmicCapabilitiesBitMask = { + isMulticastSupported: 1 << 0, + isFragmentedDataSupported: 1 << 1 + }; + const fromBytes$h = data => { + if (data.length !== COMMAND_BODY_SIZE$8) { + throw new Error(`Wrong buffer size: ${data.length}.`); + } + const buffer = new BinaryBuffer(data); + const capabilities = toObject(lmicCapabilitiesBitMask, buffer.getUint8()); + const version = buffer.getUint8(); + if (!buffer.isEmpty) { + throw new Error('BinaryBuffer is not empty.'); + } + return { + capabilities, + version + }; + }; + const toBytes$h = parameters => { + const { + capabilities, + version + } = parameters; + const buffer = new BinaryBuffer(COMMAND_BODY_SIZE$8); + buffer.setUint8(fromObject(lmicCapabilitiesBitMask, capabilities)); + buffer.setUint8(version); + return toBytes$11(id$g, buffer.data); + }; + + const id$f = getParameter; + uplinkNames[getParameter]; + const fromBytes$g = data => { + const buffer = new CommandBinaryBuffer(data); + return buffer.getResponseParameter(); + }; + const toBytes$g = parameters => { + const buffer = new CommandBinaryBuffer(getResponseParameterSize(parameters)); + buffer.setResponseParameter(parameters); + return toBytes$11(id$f, buffer.data); + }; + + const id$e = hour; + uplinkNames[hour]; + const fromBytes$f = data => { + const buffer = new CommandBinaryBuffer(data); + return buffer.getLegacyHourCounterWithDiff(); + }; + const toBytes$f = parameters => { + const buffer = new CommandBinaryBuffer(CommandBinaryBuffer.getLegacyHourCounterSize(parameters)); + buffer.setLegacyHourCounterWithDiff(parameters); + return toBytes$11(id$e, buffer.getBytesToOffset()); + }; + + const id$d = hourMc; + uplinkNames[hourMc]; + const COMMAND_BODY_MAX_SIZE$3 = 164; + const fromBytes$e = data => { + if (data.length > COMMAND_BODY_MAX_SIZE$3) { + throw new Error(`Wrong buffer size: ${data.length}.`); + } + const buffer = new CommandBinaryBuffer(data); + return buffer.getChannelsValuesWithHourDiff(); + }; + const toBytes$e = parameters => { + const buffer = new CommandBinaryBuffer(COMMAND_BODY_MAX_SIZE$3); + const { + startTime2000, + hours, + channelList + } = parameters; + buffer.setChannelsValuesWithHourDiff(hours, startTime2000, channelList); + return toBytes$11(id$d, buffer.getBytesToOffset()); + }; + + const id$c = hourMcEx; + uplinkNames[hourMcEx]; + const COMMAND_BODY_MAX_SIZE$2 = 255; + const fromBytes$d = data => { + if (data.length > COMMAND_BODY_MAX_SIZE$2) { + throw new Error(`Wrong buffer size: ${data.length}.`); + } + const buffer = new CommandBinaryBuffer(data); + return buffer.getChannelsValuesWithHourDiffExtended(); + }; + const toBytes$d = parameters => { + const buffer = new CommandBinaryBuffer(COMMAND_BODY_MAX_SIZE$2); + buffer.setChannelsValuesWithHourDiffExtended(parameters); + return toBytes$11(id$c, buffer.getBytesToOffset()); + }; + + const id$b = lastEvent; + uplinkNames[lastEvent]; + const fromBytes$c = (data, config) => { + if (!config.hardwareType) { + throw new Error('hardwareType in config is mandatory'); + } + const buffer = new CommandBinaryBuffer(data); + const sequenceNumber = buffer.getUint8(); + const status = buffer.getEventStatus(config.hardwareType); + return { + sequenceNumber, + status + }; + }; + const toBytes$c = (parameters, config) => { + if (!config.hardwareType) { + throw new Error('hardwareType in config is mandatory'); + } + const buffer = new CommandBinaryBuffer(1 + getEventStatusSize(config.hardwareType)); + const { + sequenceNumber, + status + } = parameters; + buffer.setUint8(sequenceNumber); + buffer.setEventStatus(config.hardwareType, status); + return toBytes$11(id$b, buffer.data); + }; + + const id$a = newEvent; + uplinkNames[newEvent]; + const COMMAND_BODY_MAX_SIZE$1 = 14; + const MTX_ADDRESS_SIZE = 8; + const getVoltage = buffer => buffer.getUint16(); + const setVoltage = (buffer, value) => buffer.setUint16(value); + const getDeviceId = buffer => getHexFromBytes(buffer.getBytes(MTX_ADDRESS_SIZE)); + const setDeviceId = (buffer, value) => { + getBytesFromHex(value).forEach(byte => buffer.setUint8(byte)); + }; + const fromBytes$b = data => { + if (data.length > COMMAND_BODY_MAX_SIZE$1) { + throw new Error(`Wrong buffer size: ${data.length}.`); + } + const buffer = new CommandBinaryBuffer(data); + const eventId = buffer.getUint8(); + const eventName = eventNames[eventId]; + const sequenceNumber = buffer.getUint8(); + let eventData; + switch (eventId) { + case MAGNET_ON: + case MAGNET_OFF: + case ACTIVATE: + case DEACTIVATE: + case CAN_OFF: + case INSERT: + case REMOVE: + case COUNTER_OVER: + case OPTOLOW: + case OPTOFLASH: + case JOIN_ACCEPT: + eventData = { + time2000: buffer.getTime() + }; + break; + case BATTERY_ALARM: + eventData = { + voltage: getVoltage(buffer) + }; + break; + case ACTIVATE_MTX: + eventData = { + time2000: buffer.getTime(), + deviceId: getDeviceId(buffer) + }; + break; + case CONNECT: + case DISCONNECT: + eventData = { + channel: buffer.getUint8() + 1, + value: buffer.getExtendedValue() + }; + break; + case MTX: + eventData = { + status: buffer.getEventStatus(MTXLORA) + }; + break; + case BINARY_SENSOR_ON: + case BINARY_SENSOR_OFF: + eventData = { + time2000: buffer.getTime(), + channel: buffer.getChannelValue() + }; + break; + case TEMPERATURE_SENSOR_HYSTERESIS: + case TEMPERATURE_SENSOR_LOW_TEMPERATURE: + case TEMPERATURE_SENSOR_HIGH_TEMPERATURE: + eventData = { + time2000: buffer.getTime(), + channel: buffer.getChannelValue(), + temperature: buffer.getInt8() + }; + break; + default: + throw new Error(`Event ${id$a} is not supported`); + } + return { + id: eventId, + name: eventName, + sequenceNumber, + data: eventData + }; + }; + const toBytes$b = parameters => { + const buffer = new CommandBinaryBuffer(COMMAND_BODY_MAX_SIZE$1); + const { + id: eventId, + sequenceNumber, + data + } = parameters; + buffer.setUint8(eventId); + buffer.setUint8(sequenceNumber); + switch (eventId) { + case MAGNET_ON: + case MAGNET_OFF: + case ACTIVATE: + case DEACTIVATE: + case CAN_OFF: + case INSERT: + case REMOVE: + case COUNTER_OVER: + case OPTOLOW: + case OPTOFLASH: + case JOIN_ACCEPT: + buffer.setTime(data.time2000); + break; + case BATTERY_ALARM: + setVoltage(buffer, data.voltage); + break; + case ACTIVATE_MTX: + buffer.setTime(data.time2000); + setDeviceId(buffer, data.deviceId); + break; + case CONNECT: + case DISCONNECT: + buffer.setUint8(data.channel - 1); + buffer.setExtendedValue(data.value); + break; + case MTX: + buffer.setEventStatus(MTXLORA, data.status); + break; + case BINARY_SENSOR_ON: + case BINARY_SENSOR_OFF: + buffer.setTime(data.time2000); + buffer.setChannelValue(data.channel); + break; + case TEMPERATURE_SENSOR_HYSTERESIS: + case TEMPERATURE_SENSOR_LOW_TEMPERATURE: + case TEMPERATURE_SENSOR_HIGH_TEMPERATURE: + buffer.setTime(data.time2000); + buffer.setChannelValue(data.channel); + buffer.setInt8(data.temperature); + break; + default: + throw new Error(`Event ${id$a} is not supported`); + } + return toBytes$11(id$a, buffer.getBytesToOffset()); + }; + + const id$9 = setParameter; + uplinkNames[setParameter]; + const COMMAND_BODY_SIZE$7 = 2; + const fromBytes$a = data => { + if (data.length !== COMMAND_BODY_SIZE$7) { + throw new Error(`Wrong buffer size: ${data.length}.`); + } + const buffer = new CommandBinaryBuffer(data); + const parameters = { + id: buffer.getUint8(), + status: buffer.getUint8() + }; + if (!buffer.isEmpty) { + throw new Error('BinaryBuffer is not empty.'); + } + return parameters; + }; + const toBytes$a = parameters => { + const buffer = new CommandBinaryBuffer(COMMAND_BODY_SIZE$7); + buffer.setUint8(parameters.id); + buffer.setUint8(parameters.status); + return toBytes$11(id$9, buffer.data); + }; + + const id$8 = setTime2000; + uplinkNames[setTime2000]; + const COMMAND_BODY_SIZE$6 = 1; + const fromBytes$9 = data => { + if (data.length !== COMMAND_BODY_SIZE$6) { + throw new Error(`Wrong buffer size: ${data.length}.`); + } + const buffer = new BinaryBuffer(data, false); + const parameters = { + status: buffer.getUint8() + }; + if (!buffer.isEmpty) { + throw new Error('BinaryBuffer is not empty.'); + } + return parameters; + }; + const toBytes$9 = parameters => { + const { + status + } = parameters; + const buffer = new BinaryBuffer(COMMAND_BODY_SIZE$6, false); + buffer.setUint8(status); + return toBytes$11(id$8, buffer.data); + }; + + const id$7 = softRestart; + uplinkNames[softRestart]; + const COMMAND_BODY_SIZE$5 = 0; + const fromBytes$8 = data => { + if (data.length !== COMMAND_BODY_SIZE$5) { + throw new Error(`Wrong buffer size: ${data.length}.`); + } + return {}; + }; + const toBytes$8 = () => toBytes$11(id$7); + + const id$6 = status; + uplinkNames[status]; + const COMMAND_BODY_MAX_SIZE = 20; + const UNKNOWN_BATTERY_RESISTANCE = 65535; + const UNKNOWN_BATTERY_CAPACITY = 255; + const fromBytes$7 = bytes => { + const buffer = new CommandBinaryBuffer(bytes); + const software = { + type: buffer.getUint8(), + version: buffer.getUint8() + }; + const hardware = { + type: buffer.getUint8(), + version: buffer.getUint8() + }; + let data; + switch (hardware.type) { + case GASI1: + case GASI2: + case GASI3: + case NOVATOR: + case IMP2EU: + case IMP4EU: + case IMP2AS: + case IMP2IN: + case IMP4IN: + case GASIC: + case NBIOT: + { + const statusData = { + batteryVoltage: buffer.getBatteryVoltage(), + batteryInternalResistance: buffer.getUint16(), + temperature: buffer.getUint8(), + remainingBatteryCapacity: buffer.getUint8(), + lastEventSequenceNumber: buffer.getUint8() + }; + if (statusData.batteryInternalResistance === UNKNOWN_BATTERY_RESISTANCE) { + statusData.batteryInternalResistance = undefined; + } + if (statusData.remainingBatteryCapacity === UNKNOWN_BATTERY_CAPACITY) { + statusData.remainingBatteryCapacity = undefined; + } else if (statusData.remainingBatteryCapacity !== undefined) { + statusData.remainingBatteryCapacity = roundNumber(statusData.remainingBatteryCapacity * 100 / (UNKNOWN_BATTERY_CAPACITY - 1), 1); + } + if (!buffer.isEmpty) { + statusData.downlinkQuality = buffer.getUint8(); + } + data = statusData; + } + break; + case MTXLORA: + data = { + time2000: buffer.getUint32(), + resetReason: buffer.getUint8(), + rssiLastDownlinkFrame: buffer.getUint8(), + snrLastDownlinkFrame: buffer.getUint8(), + downlinkRequestsNumber: buffer.getUint8(), + downlinkFragmentsNumber: buffer.getUint8(), + uplinkResponsesNumber: buffer.getUint8(), + uplinkFragmentsNumber: buffer.getUint8(), + signalMarginToGateway: buffer.getUint8(), + signalMarginFromGateway: buffer.getUint8(), + detectedGatewaysNumber: buffer.getUint8(), + gatewayDownlinkErrorRate: buffer.getUint8(), + lastEventSequenceNumber: buffer.getUint8() + }; + break; + case ELIMP: + default: + throw new Error(`${id$6}: hardware type ${hardware.type} is not supported`); + } + return { + software, + hardware, + data + }; + }; + const toBytes$7 = parameters => { + const { + software, + hardware, + data + } = parameters; + const buffer = new CommandBinaryBuffer(COMMAND_BODY_MAX_SIZE); + buffer.setUint8(software.type); + buffer.setUint8(software.version); + buffer.setUint8(hardware.type); + buffer.setUint8(hardware.version); + switch (hardware.type) { + case GASI1: + case GASI2: + case GASI3: + case NOVATOR: + case IMP2EU: + case IMP4EU: + case IMP2AS: + case IMP2IN: + case IMP4IN: + case GASIC: + { + const statusData = data; + buffer.setBatteryVoltage(statusData.batteryVoltage); + if (statusData.batteryInternalResistance === undefined) { + buffer.setUint16(UNKNOWN_BATTERY_RESISTANCE); + } else { + buffer.setUint16(statusData.batteryInternalResistance); + } + buffer.setUint8(statusData.temperature); + if (statusData.remainingBatteryCapacity === undefined) { + buffer.setUint8(UNKNOWN_BATTERY_CAPACITY); + } else { + buffer.setUint8(roundNumber((UNKNOWN_BATTERY_CAPACITY - 1) * (statusData.remainingBatteryCapacity / 100), 0)); + } + buffer.setUint8(statusData.lastEventSequenceNumber); + if ('downlinkQuality' in statusData) { + buffer.setUint8(statusData.downlinkQuality); + } + } + break; + case MTXLORA: + { + const statusData = data; + buffer.setUint32(statusData.time2000); + buffer.setUint8(statusData.resetReason); + buffer.setUint8(statusData.rssiLastDownlinkFrame); + buffer.setUint8(statusData.snrLastDownlinkFrame); + buffer.setUint8(statusData.downlinkRequestsNumber); + buffer.setUint8(statusData.downlinkFragmentsNumber); + buffer.setUint8(statusData.uplinkResponsesNumber); + buffer.setUint8(statusData.uplinkFragmentsNumber); + buffer.setUint8(statusData.signalMarginToGateway); + buffer.setUint8(statusData.signalMarginFromGateway); + buffer.setUint8(statusData.detectedGatewaysNumber); + buffer.setUint8(statusData.gatewayDownlinkErrorRate); + buffer.setUint8(statusData.lastEventSequenceNumber); + } + break; + case ELIMP: + default: + throw new Error(`${id$6}: hardware type ${hardware.type} is not supported`); + } + return toBytes$11(id$6, buffer.getBytesToOffset()); + }; + + const id$5 = time2000; + uplinkNames[time2000]; + const COMMAND_BODY_SIZE$4 = 5; + const fromBytes$6 = data => { + if (data.length !== COMMAND_BODY_SIZE$4) { + throw new Error(`Wrong buffer size: ${data.length}.`); + } + const buffer = new CommandBinaryBuffer(data); + const parameters = { + sequenceNumber: buffer.getUint8(), + time2000: buffer.getTime() + }; + if (!buffer.isEmpty) { + throw new Error('BinaryBuffer is not empty.'); + } + return parameters; + }; + function toBytes$6(parameters) { + const { + sequenceNumber, + time2000 + } = parameters; + const buffer = new CommandBinaryBuffer(COMMAND_BODY_SIZE$4); + buffer.setUint8(sequenceNumber); + buffer.setTime(time2000); + return toBytes$11(id$5, buffer.data); + } + + const id$4 = updateRun; + uplinkNames[updateRun]; + const COMMAND_BODY_SIZE$3 = 0; + const fromBytes$5 = data => { + if (data.length !== COMMAND_BODY_SIZE$3) { + throw new Error(`Wrong buffer size: ${data.length}.`); + } + return {}; + }; + const toBytes$5 = () => toBytes$11(id$4); + + const id$3 = usWaterMeterBatteryStatus; + uplinkNames[usWaterMeterBatteryStatus]; + const COMMAND_BODY_SIZE$2 = 7; + const fromBytes$4 = data => { + const buffer = new CommandBinaryBuffer(data); + return { + voltage: buffer.getBatteryVoltage(), + internalResistance: buffer.getUint16(), + lastDepassivationTime: buffer.getUint16() + }; + }; + const toBytes$4 = parameters => { + const buffer = new CommandBinaryBuffer(COMMAND_BODY_SIZE$2); + buffer.setBatteryVoltage(parameters.voltage); + buffer.setUint16(parameters.internalResistance); + buffer.setUint16(parameters.lastDepassivationTime); + return toBytes$11(id$3, buffer.data); + }; + + const id$2 = usWaterMeterCommand; + uplinkNames[usWaterMeterCommand]; + const fromBytes$3 = data => { + const buffer = new CommandBinaryBuffer(data); + const length = buffer.getUint8(); + return { + length, + data: data.slice(1) + }; + }; + const toBytes$3 = parameters => { + const { + data, + length + } = parameters; + const buffer = new CommandBinaryBuffer(length); + buffer.setUint8(length); + buffer.setBytes(data); + return toBytes$11(id$2, buffer.data); + }; + + const id$1 = verifyImage; + uplinkNames[verifyImage]; + const COMMAND_BODY_SIZE$1 = 1; + const fromBytes$2 = data => { + if (data.length !== COMMAND_BODY_SIZE$1) { + throw new Error(`Wrong buffer size: ${data.length}.`); + } + const buffer = new CommandBinaryBuffer(data); + return { + status: buffer.getUint8() + }; + }; + const toBytes$2 = parameters => { + const buffer = new CommandBinaryBuffer(COMMAND_BODY_SIZE$1); + buffer.setUint8(parameters.status); + return toBytes$11(id$1, buffer.data); + }; + + const id = writeImage; + uplinkNames[writeImage]; + const COMMAND_BODY_SIZE = 5; + const fromBytes$1 = data => { + const buffer = new CommandBinaryBuffer(data); + return { + offset: buffer.getUint32(), + status: buffer.getUint8() + }; + }; + const toBytes$1 = parameters => { + const buffer = new CommandBinaryBuffer(COMMAND_BODY_SIZE); + buffer.setUint32(parameters.offset); + buffer.setUint8(parameters.status); + return toBytes$11(id, buffer.data); + }; + + const toBytesMap = {}; + const fromBytesMap = {}; + const nameMap = uplinkNames; + const fromBytes = getFromBytes(fromBytesMap, nameMap); + const toBytes = getToBytes(toBytesMap); + const toMessage = getToMessage(toBytesMap); + toBytesMap[id$z] = toBytes$A; + toBytesMap[id$y] = toBytes$z; + toBytesMap[id$x] = toBytes$y; + toBytesMap[id$Z] = toBytes$; + toBytesMap[id$w] = toBytes$x; + toBytesMap[id$v] = toBytes$w; + toBytesMap[id$u] = toBytes$v; + toBytesMap[id$t] = toBytes$u; + toBytesMap[id$s] = toBytes$t; + toBytesMap[id$r] = toBytes$s; + toBytesMap[id$q] = toBytes$r; + toBytesMap[id$p] = toBytes$q; + toBytesMap[id$o] = toBytes$p; + toBytesMap[id$n] = toBytes$o; + toBytesMap[id$m] = toBytes$n; + toBytesMap[id$l] = toBytes$m; + toBytesMap[id$k] = toBytes$l; + toBytesMap[id$j] = toBytes$k; + toBytesMap[id$i] = toBytes$j; + toBytesMap[id$h] = toBytes$i; + toBytesMap[id$g] = toBytes$h; + toBytesMap[id$f] = toBytes$g; + toBytesMap[id$e] = toBytes$f; + toBytesMap[id$d] = toBytes$e; + toBytesMap[id$c] = toBytes$d; + toBytesMap[id$b] = toBytes$c; + toBytesMap[id$a] = toBytes$b; + toBytesMap[id$9] = toBytes$a; + toBytesMap[id$8] = toBytes$9; + toBytesMap[id$7] = toBytes$8; + toBytesMap[id$6] = toBytes$7; + toBytesMap[id$5] = toBytes$6; + toBytesMap[id$4] = toBytes$5; + toBytesMap[id$3] = toBytes$4; + toBytesMap[id$2] = toBytes$3; + toBytesMap[id$1] = toBytes$2; + toBytesMap[id] = toBytes$1; + fromBytesMap[id$z] = fromBytes$A; + fromBytesMap[id$y] = fromBytes$z; + fromBytesMap[id$x] = fromBytes$y; + fromBytesMap[id$Z] = fromBytes$; + fromBytesMap[id$w] = fromBytes$x; + fromBytesMap[id$v] = fromBytes$w; + fromBytesMap[id$u] = fromBytes$v; + fromBytesMap[id$t] = fromBytes$u; + fromBytesMap[id$s] = fromBytes$t; + fromBytesMap[id$r] = fromBytes$s; + fromBytesMap[id$q] = fromBytes$r; + fromBytesMap[id$p] = fromBytes$q; + fromBytesMap[id$o] = fromBytes$p; + fromBytesMap[id$n] = fromBytes$o; + fromBytesMap[id$m] = fromBytes$n; + fromBytesMap[id$l] = fromBytes$m; + fromBytesMap[id$k] = fromBytes$l; + fromBytesMap[id$j] = fromBytes$k; + fromBytesMap[id$i] = fromBytes$j; + fromBytesMap[id$h] = fromBytes$i; + fromBytesMap[id$g] = fromBytes$h; + fromBytesMap[id$f] = fromBytes$g; + fromBytesMap[id$e] = fromBytes$f; + fromBytesMap[id$d] = fromBytes$e; + fromBytesMap[id$c] = fromBytes$d; + fromBytesMap[id$b] = fromBytes$c; + fromBytesMap[id$a] = fromBytes$b; + fromBytesMap[id$9] = fromBytes$a; + fromBytesMap[id$8] = fromBytes$9; + fromBytesMap[id$7] = fromBytes$8; + fromBytesMap[id$6] = fromBytes$7; + fromBytesMap[id$5] = fromBytes$6; + fromBytesMap[id$4] = fromBytes$5; + fromBytesMap[id$3] = fromBytes$4; + fromBytesMap[id$2] = fromBytes$3; + fromBytesMap[id$1] = fromBytes$2; + fromBytesMap[id] = fromBytes$1; + + var uplink = /*#__PURE__*/Object.freeze({ + __proto__: null, + fromBytes: fromBytes, + fromBytesMap: fromBytesMap, + nameMap: nameMap, + toBytes: toBytes, + toBytesMap: toBytesMap, + toMessage: toMessage + }); + + var analogMessage = /*#__PURE__*/Object.freeze({ + __proto__: null, + downlink: downlink, + uplink: uplink + }); + + // export + message = analogMessage; + +})(); +//#endregion diff --git a/vendor/jooby/analog-gasic.js b/vendor/jooby/analog-gasic.js new file mode 100644 index 0000000000..40489feaec --- /dev/null +++ b/vendor/jooby/analog-gasic.js @@ -0,0 +1,4212 @@ +// https://github.com/jooby-dev/jooby-codec/blob/main/src/analog/constants/hardwareTypes.ts +const config = { + // GASIC + hardwareType: 12 +}; + +// helper +const decode = ( fromBytes, input ) => { + const data = {bytes: input.bytes}; + const decodeResult = fromBytes(input.bytes, config); + const errors = []; + + if ( decodeResult.error ) { + errors.push(decodeResult.error); + // there may be some partially decoded result + data.message = decodeResult.message; + } else { + data.message = decodeResult; + } + + return {data, errors}; +}; + +// will have encoder/decoder after init +let message; + + +/* + Get bytes from message. + + Input is an object with the following fields: + * data - object, must contain "commands" field + * fPort - downlink fPort + + Output must be an object with the following fields: + * bytes - byte array containing the downlink payload +*/ +function encodeDownlink ( input ) { + let bytes = message.downlink.toBytes(input.data.commands, config); + + return {bytes, fPort: 1}; +} + +/* + Get message from bytes. + + Input is an object with the following fields: + * bytes - byte array containing the uplink payload, e.g. [255, 230, 255, 0] + * fPort - uplink fPort + + Output must be an object with the following fields: + * data - object representing the decoded payload +*/ +function decodeUplink ( input ) { + return decode(message.uplink.fromBytes, input); +} + +/* + Get message from bytes. + + Input is an object with the following fields: + * bytes - byte array containing the downlink payload, e.g. [255, 230, 255, 0] + * fPort - downlink fPort + + Output must be an object with the following fields: + * data - object representing the decoded payload +*/ +function decodeDownlink ( input ) { + return decode(message.downlink.fromBytes, input); +} + + +//#region [autogenerated jooby-codec bundle from index.js] +(function () { + 'use strict'; + + const hexFormatOptions = { + separator: ' ', + prefix: '' + }; + + const INT8_SIZE = 1; + const INT16_SIZE = 2; + const INT24_SIZE = 3; + const INT32_SIZE = 4; + const { + log, + pow, + LN2 + } = Math; + const readFloat = (buffer, offset, isLittleEndian, mLen, bytes) => { + var e, + m, + eLen = bytes * 8 - mLen - 1, + eMax = (1 << eLen) - 1, + eBias = eMax >> 1, + nBits = -7, + i = isLittleEndian ? bytes - 1 : 0, + d = isLittleEndian ? -1 : 1, + s = buffer[offset + i]; + i += d; + e = s & (1 << -nBits) - 1; + s >>= -nBits; + nBits += eLen; + for (; nBits > 0; e = e * 0x100 + buffer[offset + i], i += d, nBits -= 8); + m = e & (1 << -nBits) - 1; + e >>= -nBits; + nBits += mLen; + for (; nBits > 0; m = m * 0x100 + buffer[offset + i], i += d, nBits -= 8); + if (e === 0) { + e = 1 - eBias; + } else if (e === eMax) { + return m ? NaN : s ? -Infinity : Infinity; + } else { + m = m + pow(2, mLen); + e = e - eBias; + } + return (s ? -1 : 1) * m * pow(2, e - mLen); + }; + const writeFloat = (buffer, offset, value, isLittleEndian, mLen, bytes) => { + var e, + m, + c, + eLen = bytes * 8 - mLen - 1, + eMax = (1 << eLen) - 1, + eBias = eMax >> 1, + rt = mLen === 23 ? pow(2, -24) - pow(2, -77) : 0, + i = isLittleEndian ? 0 : bytes - 1, + d = isLittleEndian ? 1 : -1, + s = value < 0 || value === 0 && 1 / value < 0 ? 1 : 0; + value < 0 && (value = -value); + if (value !== value || value === Infinity) { + m = value !== value ? 1 : 0; + e = eMax; + } else { + e = log(value) / LN2 | 0; + if (value * (c = pow(2, -e)) < 1) { + e--; + c *= 2; + } + if (e + eBias >= 1) { + value += rt / c; + } else { + value += rt * pow(2, 1 - eBias); + } + if (value * c >= 2) { + e++; + c /= 2; + } + if (e + eBias >= eMax) { + m = 0; + e = eMax; + } else if (e + eBias >= 1) { + m = (value * c - 1) * pow(2, mLen); + e = e + eBias; + } else { + m = value * pow(2, eBias - 1) * pow(2, mLen); + e = 0; + } + } + for (; mLen >= 8; buffer[offset + i] = m & 0xff, i += d, m /= 0x100, mLen -= 8); + e = e << mLen | m; + eLen += mLen; + for (; eLen > 0; buffer[offset + i] = e & 0xff, i += d, e /= 0x100, eLen -= 8); + buffer[offset + i - d] |= s * 0x80; + }; + const be2 = [1, 0]; + const be3 = [2, 1, 0]; + const be4 = [3, 2, 1, 0]; + const le2 = [0, 1]; + const le3 = [0, 1, 2]; + const le4 = [0, 1, 2, 3]; + const readUint8 = (buffer, offset) => buffer[offset]; + const readUint16 = (buffer, offset, isLittleEndian) => { + const order = isLittleEndian ? le2 : be2; + const b0 = buffer[offset + order[0]]; + const b1 = buffer[offset + order[1]] << 8; + return b0 | b1; + }; + const readUint24 = (buffer, offset, isLittleEndian) => { + const order = isLittleEndian ? le3 : be3; + const b0 = buffer[offset + order[0]]; + const b1 = buffer[offset + order[1]] << 8; + const b2 = buffer[offset + order[2]] << 16; + return b0 | b1 | b2; + }; + const readUint32 = (buffer, offset, isLittleEndian) => { + const order = isLittleEndian ? le4 : be4; + const b0 = buffer[offset + order[3]] * 0x1000000; + const b1 = buffer[offset + order[2]] * 0x10000; + const b2 = buffer[offset + order[1]] * 0x100; + const b3 = buffer[offset + order[0]]; + return b0 + b1 + b2 + b3; + }; + const writeUint8 = (buffer, offset, value) => { + buffer[offset] = value & 0xff; + }; + const writeUint16 = (buffer, offset, value, isLittleEndian) => { + const order = isLittleEndian ? le2 : be2; + buffer[offset + order[0]] = value & 0xff; + buffer[offset + order[1]] = value >>> 8 & 0xff; + }; + const writeUint24 = (buffer, offset, value, isLittleEndian) => { + const order = isLittleEndian ? le3 : be3; + buffer[offset + order[0]] = value & 0xff; + buffer[offset + order[1]] = value >>> 8 & 0xff; + buffer[offset + order[2]] = value >>> 16 & 0xff; + }; + const writeUint32 = (buffer, offset, value, isLittleEndian) => { + const order = isLittleEndian ? le4 : be4; + buffer[offset + order[0]] = value & 0xff; + buffer[offset + order[1]] = value >>> 8 & 0xff; + buffer[offset + order[2]] = value >>> 16 & 0xff; + buffer[offset + order[3]] = value >>> 24 & 0xff; + }; + function BinaryBuffer(dataOrLength) { + let isLittleEndian = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : true; + if (typeof dataOrLength === 'number') { + const bytes = new Array(dataOrLength).fill(0); + this.data = bytes; + } else { + this.data = dataOrLength; + } + this.offset = 0; + this.isLittleEndian = isLittleEndian; + } + BinaryBuffer.prototype = { + toUint8Array() { + return this.data; + }, + seek(position) { + if (position < 0 || position >= this.data.length) { + throw new Error('Invalid position.'); + } + this.offset = position; + }, + setInt8(value) { + writeUint8(this.data, this.offset, value < 0 ? value | 0x100 : value); + this.offset += INT8_SIZE; + }, + getInt8() { + const result = readUint8(this.data, this.offset); + this.offset += INT8_SIZE; + return result & 0x80 ? result ^ -256 : result; + }, + setUint8(value) { + writeUint8(this.data, this.offset, value); + this.offset += INT8_SIZE; + }, + getUint8() { + const result = readUint8(this.data, this.offset); + this.offset += INT8_SIZE; + return result; + }, + setInt16(value) { + let isLittleEndian = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : this.isLittleEndian; + writeUint16(this.data, this.offset, value < 0 ? value | 0x10000 : value, isLittleEndian); + this.offset += INT16_SIZE; + }, + getInt16() { + let isLittleEndian = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : this.isLittleEndian; + const result = readUint16(this.data, this.offset, isLittleEndian); + this.offset += INT16_SIZE; + return result & 0x8000 ? result ^ -65536 : result; + }, + setUint16(value) { + let isLittleEndian = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : this.isLittleEndian; + writeUint16(this.data, this.offset, value, isLittleEndian); + this.offset += INT16_SIZE; + }, + getUint16() { + let isLittleEndian = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : this.isLittleEndian; + const result = readUint16(this.data, this.offset, isLittleEndian); + this.offset += INT16_SIZE; + return result; + }, + setInt24(value) { + let isLittleEndian = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : this.isLittleEndian; + writeUint24(this.data, this.offset, value < 0 ? value | 0x1000000 : value, isLittleEndian); + this.offset += INT24_SIZE; + }, + getInt24() { + let isLittleEndian = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : this.isLittleEndian; + const result = readUint24(this.data, this.offset, isLittleEndian); + this.offset += INT24_SIZE; + return result & 0x800000 ? result ^ -16777216 : result; + }, + setUint24(value) { + let isLittleEndian = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : this.isLittleEndian; + writeUint24(this.data, this.offset, value, isLittleEndian); + this.offset += INT24_SIZE; + }, + getUint24() { + let isLittleEndian = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : this.isLittleEndian; + const result = readUint24(this.data, this.offset, isLittleEndian); + this.offset += INT24_SIZE; + return result; + }, + setInt32(value) { + let isLittleEndian = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : this.isLittleEndian; + writeUint32(this.data, this.offset, value < 0 ? value | 0x100000000 : value, isLittleEndian); + this.offset += INT32_SIZE; + }, + getInt32() { + let isLittleEndian = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : this.isLittleEndian; + const result = readUint32(this.data, this.offset, isLittleEndian); + this.offset += INT32_SIZE; + return result & 0x80000000 ? result ^ -4294967296 : result; + }, + setUint32(value) { + let isLittleEndian = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : this.isLittleEndian; + writeUint32(this.data, this.offset, value, isLittleEndian); + this.offset += INT32_SIZE; + }, + getUint32() { + let isLittleEndian = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : this.isLittleEndian; + const result = readUint32(this.data, this.offset, isLittleEndian); + this.offset += INT32_SIZE; + return result; + }, + setFloat32(value) { + let isLittleEndian = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : this.isLittleEndian; + writeFloat(this.data, this.offset, value, isLittleEndian, 23, 4); + this.offset += INT32_SIZE; + }, + getFloat32() { + let isLittleEndian = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : this.isLittleEndian; + const result = readFloat(this.data, this.offset, isLittleEndian, 23, 4); + this.offset += INT32_SIZE; + return result; + }, + setString(value) { + this.setUint8(value.length); + for (let index = 0; index < value.length; ++index) { + this.setUint8(value.charCodeAt(index)); + } + }, + getString() { + const size = this.getUint8(); + const endIndex = this.offset + size; + const chars = []; + while (this.offset < endIndex) { + chars.push(String.fromCharCode(this.getUint8())); + } + return chars.join(''); + }, + getBytesToOffset() { + let offset = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : this.offset; + return this.data.slice(0, offset); + }, + getBytesLeft() { + return this.getBytes(this.bytesLeft); + }, + getBytes(length) { + let offset = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : this.offset; + this.offset = offset + length; + return this.data.slice(offset, this.offset); + }, + setBytes(data) { + let offset = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : this.offset; + const bytes = this.data; + bytes.splice(offset, data.length, ...data); + this.data = bytes; + this.offset = offset + data.length; + } + }; + Object.defineProperties(BinaryBuffer.prototype, { + size: { + get() { + return this.data.length; + } + }, + isEmpty: { + get() { + if (this.offset > this.data.length) { + throw new Error(`current offset ${this.offset} is outside the bounds of the buffer`); + } + return this.data.length - this.offset === 0; + } + }, + bytesLeft: { + get() { + return this.data.length - this.offset; + } + }, + position: { + get() { + return this.offset; + } + } + }); + + const shortCommandMask = 0xe0; + const extraCommandMask = 0x1f; + const fromBytes$11 = data => { + if (data.length === 0) { + throw new Error('Invalid buffer size'); + } + const header = { + shortCode: data[0] & shortCommandMask, + extraCode: data[0] & extraCommandMask + }; + if (header.shortCode !== 0) { + return { + headerSize: 1, + commandId: data[0] & ~header.extraCode, + commandSize: header.extraCode + }; + } + if (header.extraCode === extraCommandMask) { + if (data.length < 3) { + throw new Error('Invalid buffer size'); + } + return { + headerSize: 3, + commandId: data[1] << 8 | extraCommandMask, + commandSize: data[2] + }; + } + if (data.length < 2) { + throw new Error('Invalid buffer size'); + } + return { + headerSize: 2, + commandId: header.extraCode, + commandSize: data[1] + }; + }; + const toBytes$12 = (commandId, commandSize) => { + if ((commandId & extraCommandMask) === 0) { + if (commandSize > extraCommandMask) { + throw new Error(`Wrong command id/size. Id: ${commandId}, size: ${commandSize}.`); + } + return [commandId | commandSize]; + } + if (commandId > extraCommandMask) { + return [extraCommandMask, commandId >> 8, commandSize]; + } + return [commandId, commandSize]; + }; + + const toBytes$11 = function (commandId) { + let commandData = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : []; + const headerData = toBytes$12(commandId, commandData.length); + return [...headerData, ...commandData]; + }; + + const setTime2000$1 = 0x02; + const setParameter$1 = 0x03; + const getParameter$1 = 0x04; + const getArchiveHours$1 = 0x05; + const getArchiveDays$1 = 0x06; + const getCurrent = 0x07; + const getTime2000 = 0x09; + const getArchiveEvents$1 = 0x0b; + const correctTime2000$1 = 0x0c; + const getStatus = 0x14; + const getCurrentMc = 0x18; + const softRestart$1 = 0x19; + const getArchiveHoursMc$1 = 0x1a; + const getArchiveDaysMc$1 = 0x1b; + const dataSegment$1 = 0x1e; + const getLmicInfo$1 = 0x21f; + const getBatteryStatus$1 = 0x51f; + const usWaterMeterCommand$1 = 0x71f; + const getExAbsArchiveHoursMc$1 = 0xc1f; + const getExAbsArchiveDaysMc$1 = 0xd1f; + const getExAbsCurrentMc = 0xf1f; + const writeImage$1 = 0x2a1f; + const verifyImage$1 = 0x2b1f; + const updateRun$1 = 0x2c1f; + const getArchiveHoursMcEx$1 = 0x301f; + const getChannelsStatus$1 = 0x321f; + const getChannelsTypes$1 = 0x331f; + + var downlinkIds = /*#__PURE__*/Object.freeze({ + __proto__: null, + correctTime2000: correctTime2000$1, + dataSegment: dataSegment$1, + getArchiveDays: getArchiveDays$1, + getArchiveDaysMc: getArchiveDaysMc$1, + getArchiveEvents: getArchiveEvents$1, + getArchiveHours: getArchiveHours$1, + getArchiveHoursMc: getArchiveHoursMc$1, + getArchiveHoursMcEx: getArchiveHoursMcEx$1, + getBatteryStatus: getBatteryStatus$1, + getChannelsStatus: getChannelsStatus$1, + getChannelsTypes: getChannelsTypes$1, + getCurrent: getCurrent, + getCurrentMc: getCurrentMc, + getExAbsArchiveDaysMc: getExAbsArchiveDaysMc$1, + getExAbsArchiveHoursMc: getExAbsArchiveHoursMc$1, + getExAbsCurrentMc: getExAbsCurrentMc, + getLmicInfo: getLmicInfo$1, + getParameter: getParameter$1, + getStatus: getStatus, + getTime2000: getTime2000, + setParameter: setParameter$1, + setTime2000: setTime2000$1, + softRestart: softRestart$1, + updateRun: updateRun$1, + usWaterMeterCommand: usWaterMeterCommand$1, + verifyImage: verifyImage$1, + writeImage: writeImage$1 + }); + + var invertObject = source => { + const target = {}; + for (const property in source) { + const value = source[property]; + target[value] = property; + } + return target; + }; + + var downlinkNames = invertObject(downlinkIds); + + const id$_ = correctTime2000$1; + downlinkNames[correctTime2000$1]; + const COMMAND_BODY_SIZE$w = 2; + const fromBytes$10 = data => { + if (data.length !== COMMAND_BODY_SIZE$w) { + throw new Error(`Wrong buffer size: ${data.length}.`); + } + const buffer = new BinaryBuffer(data, false); + const parameters = { + sequenceNumber: buffer.getUint8(), + seconds: buffer.getInt8() + }; + if (!buffer.isEmpty) { + throw new Error('BinaryBuffer is not empty.'); + } + return parameters; + }; + const toBytes$10 = parameters => { + const { + sequenceNumber, + seconds + } = parameters; + const buffer = new BinaryBuffer(COMMAND_BODY_SIZE$w, false); + buffer.setUint8(sequenceNumber); + buffer.setInt8(seconds); + return toBytes$11(id$_, buffer.data); + }; + + const fromObject = function () { + let bitMask = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : {}; + let booleanObject = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : {}; + let result = 0; + for (const name in booleanObject) { + if (name in bitMask && booleanObject[name]) { + result |= bitMask[name]; + } + } + return result; + }; + const toObject = function () { + let bitMask = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : {}; + let value = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : 0; + const result = {}; + for (const name in bitMask) { + result[name] = (value & bitMask[name]) !== 0; + } + return result; + }; + const extractBits = (value, bitsNumber, startIndex) => (1 << bitsNumber) - 1 & value >> startIndex - 1; + const fillBits = (value, bitsNumber, startIndex, valueToSet) => { + const mask = (1 << bitsNumber) - 1 << startIndex - 1; + let newValueToSet = valueToSet; + let result = value; + result &= ~mask; + newValueToSet <<= startIndex - 1; + result |= newValueToSet; + return result; + }; + + var getHexFromBytes = (function (bytes) { + let options = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : {}; + const { + separator, + prefix + } = Object.assign({}, hexFormatOptions, options); + return bytes.map(byte => `${prefix}${byte.toString(16).padStart(2, '0')}`).join(separator); + }); + + var getBytesFromHex = hex => { + let cleanHex = hex.trim(); + if (!cleanHex) { + return []; + } + cleanHex = cleanHex.replace(/0x/g, '').split(/\s+/).map(byte => byte.padStart(2, '0')).join(''); + if (cleanHex.length % 2 !== 0) { + cleanHex = `0${cleanHex}`; + } + const resultLength = cleanHex.length / 2; + const bytes = new Array(resultLength); + for (let index = 0; index < resultLength; index++) { + bytes[index] = parseInt(cleanHex.substring(index * 2, index * 2 + 2), 16); + } + return bytes; + }; + + var roundNumber = (function (value) { + let decimalPlaces = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : 4; + const places = Math.pow(10, decimalPlaces); + return Math.round(value * places * (1 + Number.EPSILON)) / places; + }); + + const INITIAL_YEAR_TIMESTAMP = 946684800000; + const MILLISECONDS_IN_SECONDS = 1000; + const getDateFromTime2000 = time2000 => new Date(INITIAL_YEAR_TIMESTAMP + time2000 * MILLISECONDS_IN_SECONDS); + const getTime2000FromDate = date => (date.getTime() - INITIAL_YEAR_TIMESTAMP) / MILLISECONDS_IN_SECONDS; + + const GASI1 = 1; + const GASI2 = 2; + const GASI3 = 3; + const NOVATOR = 4; + const IMP2EU = 5; + const IMP4EU = 6; + const MTXLORA = 7; + const IMP2AS = 8; + const IMP2IN = 9; + const IMP4IN = 10; + const ELIMP = 11; + const GASIC = 12; + const US_WATER = 13; + const NBIOT = 24; + + const REPORTING_DATA_INTERVAL = 1; + const DAY_CHECKOUT_HOUR = 4; + const REPORTING_DATA_TYPE = 5; + const PRIORITY_DATA_DELIVERY_TYPE = 8; + const ACTIVATION_METHOD = 9; + const BATTERY_DEPASSIVATION_INFO = 10; + const BATTERY_MINIMAL_LOAD_TIME = 11; + const CHANNELS_CONFIG = 13; + const RX2_CONFIG = 18; + const ABSOLUTE_DATA = 23; + const ABSOLUTE_DATA_ENABLE = 24; + const SERIAL_NUMBER = 25; + const GEOLOCATION = 26; + const EXTRA_FRAME_INTERVAL = 28; + const ABSOLUTE_DATA_MULTI_CHANNEL = 29; + const ABSOLUTE_DATA_ENABLE_MULTI_CHANNEL = 30; + const PULSE_CHANNELS_SCAN_CONFIG = 31; + const PULSE_CHANNELS_SET_CONFIG = 32; + const BATTERY_DEPASSIVATION_CONFIG = 33; + const MQTT_SESSION_CONFIG = 34; + const MQTT_BROKER_ADDRESS = 35; + const MQTT_SSL_ENABLE = 36; + const MQTT_TOPIC_PREFIX = 37; + const MQTT_DATA_RECEIVE_CONFIG = 38; + const MQTT_DATA_SEND_CONFIG = 39; + const NBIOT_SSL_CONFIG = 40; + const NBIOT_SSL_CACERT_WRITE = 41; + const NBIOT_SSL_CACERT_SET = 42; + const NBIOT_SSL_CLIENT_CERT_WRITE = 43; + const NBIOT_SSL_CLIENT_CERT_SET = 44; + const NBIOT_SSL_CLIENT_KEY_WRITE = 45; + const NBIOT_SSL_CLIENT_KEY_SET = 46; + const NBIOT_DEVICE_SOFTWARE_UPDATE = 47; + const NBIOT_MODULE_FIRMWARE_UPDATE = 48; + const REPORTING_DATA_CONFIG = 49; + const EVENTS_CONFIG = 50; + const NBIOT_MODULE_INFO = 51; + const NBIOT_BANDS = 52; + const NBIOT_APN = 53; + const NBIOT_LED_INDICATION = 54; + const NBIOT_SIM = 55; + const CHANNEL_TYPE = 56; + + var deviceParameters = /*#__PURE__*/Object.freeze({ + __proto__: null, + ABSOLUTE_DATA: ABSOLUTE_DATA, + ABSOLUTE_DATA_ENABLE: ABSOLUTE_DATA_ENABLE, + ABSOLUTE_DATA_ENABLE_MULTI_CHANNEL: ABSOLUTE_DATA_ENABLE_MULTI_CHANNEL, + ABSOLUTE_DATA_MULTI_CHANNEL: ABSOLUTE_DATA_MULTI_CHANNEL, + ACTIVATION_METHOD: ACTIVATION_METHOD, + BATTERY_DEPASSIVATION_CONFIG: BATTERY_DEPASSIVATION_CONFIG, + BATTERY_DEPASSIVATION_INFO: BATTERY_DEPASSIVATION_INFO, + BATTERY_MINIMAL_LOAD_TIME: BATTERY_MINIMAL_LOAD_TIME, + CHANNELS_CONFIG: CHANNELS_CONFIG, + CHANNEL_TYPE: CHANNEL_TYPE, + DAY_CHECKOUT_HOUR: DAY_CHECKOUT_HOUR, + EVENTS_CONFIG: EVENTS_CONFIG, + EXTRA_FRAME_INTERVAL: EXTRA_FRAME_INTERVAL, + GEOLOCATION: GEOLOCATION, + MQTT_BROKER_ADDRESS: MQTT_BROKER_ADDRESS, + MQTT_DATA_RECEIVE_CONFIG: MQTT_DATA_RECEIVE_CONFIG, + MQTT_DATA_SEND_CONFIG: MQTT_DATA_SEND_CONFIG, + MQTT_SESSION_CONFIG: MQTT_SESSION_CONFIG, + MQTT_SSL_ENABLE: MQTT_SSL_ENABLE, + MQTT_TOPIC_PREFIX: MQTT_TOPIC_PREFIX, + NBIOT_APN: NBIOT_APN, + NBIOT_BANDS: NBIOT_BANDS, + NBIOT_DEVICE_SOFTWARE_UPDATE: NBIOT_DEVICE_SOFTWARE_UPDATE, + NBIOT_LED_INDICATION: NBIOT_LED_INDICATION, + NBIOT_MODULE_FIRMWARE_UPDATE: NBIOT_MODULE_FIRMWARE_UPDATE, + NBIOT_MODULE_INFO: NBIOT_MODULE_INFO, + NBIOT_SIM: NBIOT_SIM, + NBIOT_SSL_CACERT_SET: NBIOT_SSL_CACERT_SET, + NBIOT_SSL_CACERT_WRITE: NBIOT_SSL_CACERT_WRITE, + NBIOT_SSL_CLIENT_CERT_SET: NBIOT_SSL_CLIENT_CERT_SET, + NBIOT_SSL_CLIENT_CERT_WRITE: NBIOT_SSL_CLIENT_CERT_WRITE, + NBIOT_SSL_CLIENT_KEY_SET: NBIOT_SSL_CLIENT_KEY_SET, + NBIOT_SSL_CLIENT_KEY_WRITE: NBIOT_SSL_CLIENT_KEY_WRITE, + NBIOT_SSL_CONFIG: NBIOT_SSL_CONFIG, + PRIORITY_DATA_DELIVERY_TYPE: PRIORITY_DATA_DELIVERY_TYPE, + PULSE_CHANNELS_SCAN_CONFIG: PULSE_CHANNELS_SCAN_CONFIG, + PULSE_CHANNELS_SET_CONFIG: PULSE_CHANNELS_SET_CONFIG, + REPORTING_DATA_CONFIG: REPORTING_DATA_CONFIG, + REPORTING_DATA_INTERVAL: REPORTING_DATA_INTERVAL, + REPORTING_DATA_TYPE: REPORTING_DATA_TYPE, + RX2_CONFIG: RX2_CONFIG, + SERIAL_NUMBER: SERIAL_NUMBER + }); + + var deviceParameterNames = invertObject(deviceParameters); + + const EMPTY_VALUE = 0xffffffff; + + const IDLE = 0; + const POWER_CHANNEL = 2; + const BINARY_SENSOR = 3; + const TEMPERATURE_SENSOR = 4; + + var channelTypes = /*#__PURE__*/Object.freeze({ + __proto__: null, + BINARY_SENSOR: BINARY_SENSOR, + IDLE: IDLE, + POWER_CHANNEL: POWER_CHANNEL, + TEMPERATURE_SENSOR: TEMPERATURE_SENSOR + }); + + const SF12B125 = 0; + const SF11B125 = 1; + const SF10B125 = 2; + const SF9B125 = 3; + const SF8B125 = 4; + const SF7B125 = 5; + const SF7B250 = 6; + + var rx2SpreadFactors = /*#__PURE__*/Object.freeze({ + __proto__: null, + SF10B125: SF10B125, + SF11B125: SF11B125, + SF12B125: SF12B125, + SF7B125: SF7B125, + SF7B250: SF7B250, + SF8B125: SF8B125, + SF9B125: SF9B125 + }); + + var spreadFactorNames = invertObject(rx2SpreadFactors); + + const INITIAL_YEAR = 2000; + const MONTH_BIT_SIZE = 4; + const DATE_BIT_SIZE = 5; + const YEAR_START_INDEX = 1; + const UNKNOWN_BATTERY_VOLTAGE = 4095; + const EXTEND_BIT_MASK = 0x80; + const LAST_BIT_INDEX = 7; + const DATA_SENDING_INTERVAL_SECONDS_COEFFICIENT = 600; + const DATA_SENDING_INTERVAL_RESERVED_BYTES = 3; + const PARAMETER_RX2_FREQUENCY_COEFFICIENT = 100; + const SERIAL_NUMBER_SIZE = 6; + const MAGNETIC_INFLUENCE_BIT_INDEX = 8; + const LEGACY_HOUR_COUNTER_SIZE = 2 + 4; + const LEGACY_HOUR_DIFF_SIZE = 2; + const GAS_HARDWARE_TYPES = [GASI2, GASI3, GASI1, GASIC, NBIOT]; + const TWO_CHANNELS_HARDWARE_TYPES = [IMP2AS, IMP2EU, IMP2IN, NOVATOR]; + const ELIMP_HARDWARE_TYPES = [ELIMP]; + const FOUR_CHANNELS_HARDWARE_TYPES = [IMP4EU, IMP4IN]; + const MTX_HARDWARE_TYPES = [MTXLORA]; + const TWO_BYTES_HARDWARE_TYPES = [...FOUR_CHANNELS_HARDWARE_TYPES, ...MTX_HARDWARE_TYPES]; + const gasBitMask = { + isBatteryLow: Math.pow(2, 0), + isMagneticInfluence: Math.pow(2, 1), + isButtonReleased: Math.pow(2, 2), + isConnectionLost: Math.pow(2, 3) + }; + const twoChannelBitMask = { + isBatteryLow: Math.pow(2, 0), + isConnectionLost: Math.pow(2, 3), + isFirstChannelInactive: Math.pow(2, 4), + isSecondChannelInactive: Math.pow(2, 5) + }; + const elimpBitMask = { + isConnectionLost: Math.pow(2, 3) + }; + const fourChannelBitMask = { + isBatteryLow: Math.pow(2, 0), + isConnectionLost: Math.pow(2, 3), + isFirstChannelInactive: Math.pow(2, 4), + isSecondChannelInactive: Math.pow(2, 5), + isThirdChannelInactive: Math.pow(2, 6), + isForthChannelInactive: Math.pow(2, 8) + }; + const mtxBitMask = { + isMeterCaseOpen: Math.pow(2, 0), + isMagneticInfluence: Math.pow(2, 1), + isParametersSetRemotely: Math.pow(2, 2), + isParametersSetLocally: Math.pow(2, 3), + isMeterProgramRestarted: Math.pow(2, 4), + isLockedOut: Math.pow(2, 5), + isTimeSet: Math.pow(2, 6), + isTimeCorrected: Math.pow(2, 7), + isMeterFailure: Math.pow(2, 8), + isMeterTerminalBoxOpen: Math.pow(2, 9), + isModuleCompartmentOpen: Math.pow(2, 10), + isTariffPlanChanged: Math.pow(2, 11), + isNewTariffPlanReceived: Math.pow(2, 12) + }; + const usWaterMeterEventBitMask = { + transportMode: 0x01, + frequencyOutput: 0x02, + reverseFlow: 0x04, + tamperBreak: 0x08, + leakage: 0x10, + pipeBreak: 0x20, + pipeEmpty: 0x40, + batteryDischarge: 0x80 + }; + const getChannelTypeSize = _ref => { + let { + type + } = _ref; + let size = 1; + switch (type) { + case IDLE: + case POWER_CHANNEL: + break; + case BINARY_SENSOR: + size += 2; + break; + case TEMPERATURE_SENSOR: + size += 5; + break; + } + return size; + }; + const parametersSizeMap = { + [REPORTING_DATA_INTERVAL]: 1 + 4, + [DAY_CHECKOUT_HOUR]: 1 + 1, + [REPORTING_DATA_TYPE]: 1 + 1, + [PRIORITY_DATA_DELIVERY_TYPE]: 1 + 1, + [ACTIVATION_METHOD]: 1 + 1, + [BATTERY_DEPASSIVATION_INFO]: 1 + 6, + [BATTERY_MINIMAL_LOAD_TIME]: 1 + 4, + [CHANNELS_CONFIG]: 1 + 1, + [RX2_CONFIG]: 1 + 4, + [ABSOLUTE_DATA]: 1 + 9, + [ABSOLUTE_DATA_ENABLE]: 1 + 1, + [SERIAL_NUMBER]: 1 + 6, + [GEOLOCATION]: 1 + 10, + [EXTRA_FRAME_INTERVAL]: 1 + 2, + [ABSOLUTE_DATA_MULTI_CHANNEL]: 1 + 10, + [ABSOLUTE_DATA_ENABLE_MULTI_CHANNEL]: 1 + 2, + [PULSE_CHANNELS_SCAN_CONFIG]: 1 + 3, + [PULSE_CHANNELS_SET_CONFIG]: 1 + 1, + [BATTERY_DEPASSIVATION_CONFIG]: 1 + 4, + [MQTT_SSL_ENABLE]: 1 + 1, + [MQTT_DATA_RECEIVE_CONFIG]: 1 + 3, + [MQTT_DATA_SEND_CONFIG]: 1 + 3, + [NBIOT_SSL_CONFIG]: 1 + 2, + [NBIOT_SSL_CACERT_SET]: 1 + 4, + [NBIOT_SSL_CLIENT_CERT_SET]: 1 + 4, + [NBIOT_SSL_CLIENT_KEY_SET]: 1 + 4, + [REPORTING_DATA_CONFIG]: 1 + 4, + [EVENTS_CONFIG]: 1 + 3, + [NBIOT_LED_INDICATION]: 1 + 2, + [NBIOT_SIM]: 1 + 3 + }; + const fourChannelsBitMask = { + channel1: Math.pow(2, 0), + channel2: Math.pow(2, 1), + channel3: Math.pow(2, 2), + channel4: Math.pow(2, 3) + }; + const getChannelsMaskFromNumber = value => { + const object = toObject(fourChannelsBitMask, value); + return { + channel1: object.channel1, + channel2: object.channel2, + channel3: object.channel3, + channel4: object.channel4 + }; + }; + const setChannelsMaskToNumber = channelsMask => { + const { + channel1, + channel2, + channel3, + channel4 + } = channelsMask; + return fromObject(fourChannelsBitMask, { + channel1, + channel2, + channel3, + channel4 + }); + }; + const getChannelsMask = buffer => getChannelsMaskFromNumber(buffer.getUint8()); + const setChannelsMask = (buffer, channelsMask) => buffer.setUint8(setChannelsMaskToNumber(channelsMask)); + const byteToPulseCoefficientMap = { + 128: 1, + 129: 5, + 130: 10, + 131: 100, + 132: 1000, + 133: 10000, + 134: 100000 + }; + const pulseCoefficientToByteMap = invertObject(byteToPulseCoefficientMap); + const isMSBSet = value => !!(value & 0x80); + const getNbiotSslWrite = buffer => ({ + size: buffer.getUint16(), + position: buffer.getUint16(), + chunk: buffer.getBytesLeft() + }); + const setNbiotSslWrite = (buffer, parameter) => { + if (parameter.size !== parameter.chunk.length) { + throw new Error('ssl chunk size parameter doesn\'t match actual ssl chunk size'); + } + buffer.setUint16(parameter.size); + buffer.setUint16(parameter.position); + buffer.setBytes(parameter.chunk); + }; + const getNbiotSslSet = buffer => ({ + crc32: buffer.getUint32() + }); + const setNbiotSslSet = (buffer, parameter) => { + buffer.setUint32(parameter.crc32); + }; + const deviceParameterConvertersMap = { + [REPORTING_DATA_INTERVAL]: { + get: buffer => { + buffer.seek(buffer.offset + DATA_SENDING_INTERVAL_RESERVED_BYTES); + return { + value: buffer.getUint8() * DATA_SENDING_INTERVAL_SECONDS_COEFFICIENT + }; + }, + set: (buffer, parameter) => { + buffer.seek(buffer.offset + DATA_SENDING_INTERVAL_RESERVED_BYTES); + buffer.setUint8(parameter.value / DATA_SENDING_INTERVAL_SECONDS_COEFFICIENT); + } + }, + [DAY_CHECKOUT_HOUR]: { + get: buffer => ({ + value: buffer.getUint8() + }), + set: (buffer, parameter) => { + buffer.setUint8(parameter.value); + } + }, + [REPORTING_DATA_TYPE]: { + get: buffer => ({ + type: buffer.getUint8() + }), + set: (buffer, parameter) => { + buffer.setUint8(parameter.type); + } + }, + [PRIORITY_DATA_DELIVERY_TYPE]: { + get: buffer => ({ + value: buffer.getUint8() + }), + set: (buffer, parameter) => { + buffer.setUint8(parameter.value); + } + }, + [ACTIVATION_METHOD]: { + get: buffer => ({ + type: buffer.getUint8() + }), + set: (buffer, parameter) => { + buffer.setUint8(parameter.type); + } + }, + [BATTERY_DEPASSIVATION_INFO]: { + get: buffer => ({ + loadTime: buffer.getUint16(), + internalResistance: buffer.getUint16(), + lowVoltage: buffer.getUint16() + }), + set: (buffer, parameter) => { + buffer.setUint16(parameter.loadTime); + buffer.setUint16(parameter.internalResistance); + buffer.setUint16(parameter.lowVoltage); + } + }, + [BATTERY_MINIMAL_LOAD_TIME]: { + get: buffer => ({ + value: buffer.getUint32() + }), + set: (buffer, parameter) => { + buffer.setUint32(parameter.value); + } + }, + [CHANNELS_CONFIG]: { + get: buffer => ({ + value: buffer.getUint8() + }), + set: (buffer, parameter) => { + if (parameter.value < 0 || parameter.value > 18) { + throw new Error('channels config must be between 0-18'); + } + buffer.setUint8(parameter.value); + } + }, + [RX2_CONFIG]: { + get: buffer => { + const spreadFactor = buffer.getUint8(); + const spreadFactorName = spreadFactorNames[spreadFactor]; + const frequency = buffer.getUint24() * PARAMETER_RX2_FREQUENCY_COEFFICIENT; + return { + spreadFactor, + spreadFactorName, + frequency + }; + }, + set: (buffer, parameter) => { + buffer.setUint8(parameter.spreadFactor); + buffer.setUint24(parameter.frequency / PARAMETER_RX2_FREQUENCY_COEFFICIENT); + } + }, + [ABSOLUTE_DATA]: { + get: buffer => ({ + meterValue: buffer.getUint32(), + pulseCoefficient: buffer.getPulseCoefficient(), + value: buffer.getUint32() + }), + set: (buffer, parameter) => { + buffer.setUint32(parameter.meterValue); + buffer.setPulseCoefficient(parameter.pulseCoefficient); + buffer.setUint32(parameter.value); + } + }, + [ABSOLUTE_DATA_ENABLE]: { + get: buffer => ({ + state: buffer.getUint8() + }), + set: (buffer, parameter) => { + buffer.setUint8(parameter.state); + } + }, + [SERIAL_NUMBER]: { + get: buffer => ({ + value: getHexFromBytes(buffer.getBytes(SERIAL_NUMBER_SIZE)) + }), + set: (buffer, parameter) => { + getBytesFromHex(parameter.value).forEach(byte => buffer.setUint8(byte)); + } + }, + [GEOLOCATION]: { + get: buffer => ({ + latitude: roundNumber(buffer.getFloat32()), + longitude: roundNumber(buffer.getFloat32()), + altitude: roundNumber(buffer.getUint16()) + }), + set: (buffer, parameter) => { + buffer.setFloat32(roundNumber(parameter.latitude)); + buffer.setFloat32(roundNumber(parameter.longitude)); + buffer.setUint16(roundNumber(parameter.altitude)); + } + }, + [EXTRA_FRAME_INTERVAL]: { + get: buffer => ({ + value: buffer.getUint16() + }), + set: (buffer, parameter) => { + buffer.setUint16(parameter.value); + } + }, + [ABSOLUTE_DATA_MULTI_CHANNEL]: { + get: buffer => ({ + channel: buffer.getChannelValue(), + meterValue: buffer.getUint32(), + pulseCoefficient: buffer.getPulseCoefficient(), + value: buffer.getUint32() + }), + set: (buffer, parameter) => { + buffer.setChannelValue(parameter.channel); + buffer.setUint32(parameter.meterValue); + buffer.setPulseCoefficient(parameter.pulseCoefficient); + buffer.setUint32(parameter.value); + } + }, + [ABSOLUTE_DATA_ENABLE_MULTI_CHANNEL]: { + get: buffer => ({ + channel: buffer.getChannelValue(), + state: buffer.getUint8() + }), + set: (buffer, parameter) => { + buffer.setChannelValue(parameter.channel); + buffer.setUint8(parameter.state); + } + }, + [PULSE_CHANNELS_SCAN_CONFIG]: { + get: buffer => ({ + channelList: buffer.getChannels(), + pullUpTime: buffer.getUint8(), + scanTime: buffer.getUint8() + }), + set: (buffer, parameter) => { + if (parameter.pullUpTime < 17) { + throw new Error('minimal value for pullUpTime - 17'); + } + if (parameter.scanTime < 15) { + throw new Error('minimal value for scanTime - 15'); + } + buffer.setChannels(parameter.channelList.map(index => ({ + index + }))); + buffer.setUint8(parameter.pullUpTime); + buffer.setUint8(parameter.scanTime); + } + }, + [PULSE_CHANNELS_SET_CONFIG]: { + get: getChannelsMask, + set: setChannelsMask + }, + [BATTERY_DEPASSIVATION_CONFIG]: { + get: buffer => ({ + resistanceStartThreshold: buffer.getUint16(), + resistanceStopThreshold: buffer.getUint16() + }), + set: (buffer, parameter) => { + buffer.setUint16(parameter.resistanceStartThreshold); + buffer.setUint16(parameter.resistanceStopThreshold); + } + }, + [MQTT_SESSION_CONFIG]: { + get: buffer => ({ + clientId: buffer.getString(), + username: buffer.getString(), + password: buffer.getString(), + cleanSession: buffer.getUint8() + }), + set: (buffer, parameter) => { + buffer.setString(parameter.clientId); + buffer.setString(parameter.username); + buffer.setString(parameter.password); + buffer.setUint8(parameter.cleanSession); + } + }, + [MQTT_BROKER_ADDRESS]: { + get: buffer => ({ + hostName: buffer.getString(), + port: buffer.getUint16() + }), + set: (buffer, parameter) => { + buffer.setString(parameter.hostName); + buffer.setUint16(parameter.port); + } + }, + [MQTT_SSL_ENABLE]: { + get: buffer => ({ + enable: buffer.getUint8() + }), + set: (buffer, parameter) => { + buffer.setUint8(parameter.enable); + } + }, + [MQTT_TOPIC_PREFIX]: { + get: buffer => ({ + topicPrefix: buffer.getString() + }), + set: (buffer, parameter) => { + buffer.setString(parameter.topicPrefix); + } + }, + [MQTT_DATA_RECEIVE_CONFIG]: { + get: buffer => ({ + qos: buffer.getUint8(), + count: buffer.getUint8(), + timeout: buffer.getUint8() + }), + set: (buffer, parameter) => { + buffer.setUint8(parameter.qos); + buffer.setUint8(parameter.count); + buffer.setUint8(parameter.timeout); + } + }, + [MQTT_DATA_SEND_CONFIG]: { + get: buffer => ({ + qos: buffer.getUint8(), + retain: buffer.getUint8(), + newestSendFirst: buffer.getUint8() + }), + set: (buffer, parameter) => { + buffer.setUint8(parameter.qos); + buffer.setUint8(parameter.retain); + buffer.setUint8(parameter.newestSendFirst); + } + }, + [NBIOT_SSL_CONFIG]: { + get: buffer => ({ + securityLevel: buffer.getUint8(), + version: buffer.getUint8() + }), + set: (buffer, parameter) => { + buffer.setUint8(parameter.securityLevel); + buffer.setUint8(parameter.version); + } + }, + [NBIOT_SSL_CACERT_WRITE]: { + get: getNbiotSslWrite, + set: setNbiotSslWrite + }, + [NBIOT_SSL_CACERT_SET]: { + get: getNbiotSslSet, + set: setNbiotSslSet + }, + [NBIOT_SSL_CLIENT_CERT_WRITE]: { + get: getNbiotSslWrite, + set: setNbiotSslWrite + }, + [NBIOT_SSL_CLIENT_CERT_SET]: { + get: getNbiotSslSet, + set: setNbiotSslSet + }, + [NBIOT_SSL_CLIENT_KEY_WRITE]: { + get: getNbiotSslWrite, + set: setNbiotSslWrite + }, + [NBIOT_SSL_CLIENT_KEY_SET]: { + get: getNbiotSslSet, + set: setNbiotSslSet + }, + [NBIOT_DEVICE_SOFTWARE_UPDATE]: { + get: buffer => ({ + softwareImageUrl: buffer.getString() + }), + set: (buffer, parameter) => { + buffer.setString(parameter.softwareImageUrl); + } + }, + [NBIOT_MODULE_FIRMWARE_UPDATE]: { + get: buffer => ({ + moduleFirmwareImageUrl: buffer.getString() + }), + set: (buffer, parameter) => { + buffer.setString(parameter.moduleFirmwareImageUrl); + } + }, + [REPORTING_DATA_CONFIG]: { + get: buffer => ({ + dataType: buffer.getUint8(), + hour: buffer.getUint8(), + minutes: buffer.getUint8(), + countToSend: buffer.getUint8() + }), + set: (buffer, parameter) => { + buffer.setUint8(parameter.dataType); + buffer.setUint8(parameter.hour); + buffer.setUint8(parameter.minutes); + buffer.setUint8(parameter.countToSend); + } + }, + [EVENTS_CONFIG]: { + get: buffer => ({ + eventId: buffer.getUint8(), + sendEvent: buffer.getUint8(), + saveEvent: buffer.getUint8() + }), + set: (buffer, parameter) => { + buffer.setUint8(parameter.eventId); + buffer.setUint8(parameter.sendEvent); + buffer.setUint8(parameter.saveEvent); + } + }, + [NBIOT_MODULE_INFO]: { + get: buffer => ({ + moduleInfo: buffer.getString() + }), + set: (buffer, parameter) => { + buffer.setString(parameter.moduleInfo); + } + }, + [NBIOT_BANDS]: { + get: buffer => { + const count = buffer.getUint8(); + const bands = []; + for (let index = 0; index < count; index++) { + bands.push(buffer.getUint8()); + } + return { + bands + }; + }, + set: (buffer, parameter) => { + buffer.setUint8(parameter.bands.length); + for (const band of parameter.bands) { + buffer.setUint8(band); + } + } + }, + [NBIOT_APN]: { + get: buffer => ({ + apn: buffer.getString() + }), + set: (buffer, parameter) => { + buffer.setString(parameter.apn); + } + }, + [NBIOT_LED_INDICATION]: { + get: buffer => ({ + enableLed: buffer.getUint8(), + enableNbiotNetworkLed: buffer.getUint8() + }), + set: (buffer, parameter) => { + buffer.setUint8(parameter.enableLed); + buffer.setUint8(parameter.enableNbiotNetworkLed); + } + }, + [NBIOT_SIM]: { + get: buffer => ({ + enable: buffer.getUint8(), + pin: buffer.getUint16() + }), + set: (buffer, parameter) => { + buffer.setUint8(parameter.enable); + buffer.setUint16(parameter.pin); + } + }, + [CHANNEL_TYPE]: { + get: buffer => buffer.getChannelType(), + set: (buffer, parameter) => buffer.setChannelType(parameter) + } + }; + const getEventStatusSize = hardwareType => TWO_BYTES_HARDWARE_TYPES.indexOf(hardwareType) !== -1 ? 2 : 1; + const getParameterSize = parameter => { + let size; + let data; + switch (parameter.id) { + case MQTT_SESSION_CONFIG: + data = parameter.data; + size = 1 + 1; + size += data.clientId.length + 1; + size += data.username.length + 1; + size += data.password.length + 1; + break; + case MQTT_BROKER_ADDRESS: + data = parameter.data; + size = 1 + 2; + size += data.hostName.length + 1; + break; + case MQTT_TOPIC_PREFIX: + data = parameter.data; + size = 1; + size += data.topicPrefix.length + 1; + break; + case NBIOT_SSL_CACERT_WRITE: + case NBIOT_SSL_CLIENT_CERT_WRITE: + case NBIOT_SSL_CLIENT_KEY_WRITE: + data = parameter.data; + size = 1 + 2 + 2; + size += data.chunk.length; + break; + case NBIOT_DEVICE_SOFTWARE_UPDATE: + data = parameter.data; + size = 1; + size += data.softwareImageUrl.length + 1; + break; + case NBIOT_MODULE_FIRMWARE_UPDATE: + data = parameter.data; + size = 1; + size += data.moduleFirmwareImageUrl.length + 1; + break; + case NBIOT_MODULE_INFO: + data = parameter.data; + size = 1 + 1 + data.moduleInfo.length; + break; + case NBIOT_BANDS: + data = parameter.data; + size = 1 + 1; + size += data.bands.length; + break; + case NBIOT_APN: + data = parameter.data; + size = 1 + 1 + data.apn.length; + break; + case CHANNEL_TYPE: + data = parameter.data; + size = 1 + getChannelTypeSize(data); + break; + default: + size = parametersSizeMap[parameter.id]; + } + if (size === undefined) { + throw new Error('unknown parameter id'); + } + return size; + }; + const getRequestParameterSize = parameter => { + let size; + switch (parameter.id) { + case ABSOLUTE_DATA_MULTI_CHANNEL: + case ABSOLUTE_DATA_ENABLE_MULTI_CHANNEL: + case REPORTING_DATA_CONFIG: + case EVENTS_CONFIG: + case CHANNEL_TYPE: + size = 2; + break; + default: + size = 1; + break; + } + return size; + }; + const getResponseParameterSize = parameter => { + let size; + switch (parameter.id) { + case MQTT_SESSION_CONFIG: + case NBIOT_SSL_CACERT_WRITE: + case NBIOT_SSL_CLIENT_CERT_WRITE: + case NBIOT_SSL_CLIENT_KEY_WRITE: + case NBIOT_SSL_CACERT_SET: + case NBIOT_SSL_CLIENT_CERT_SET: + case NBIOT_SSL_CLIENT_KEY_SET: + case NBIOT_DEVICE_SOFTWARE_UPDATE: + case NBIOT_MODULE_FIRMWARE_UPDATE: + size = 1; + break; + case MQTT_BROKER_ADDRESS: + case MQTT_TOPIC_PREFIX: + case NBIOT_MODULE_INFO: + case NBIOT_BANDS: + case NBIOT_APN: + case CHANNEL_TYPE: + size = getParameterSize(parameter); + break; + default: + size = parametersSizeMap[parameter.id]; + } + if (size === undefined) { + throw new Error('unknown parameter id'); + } + return size; + }; + function CommandBinaryBuffer(dataOrLength) { + let isLittleEndian = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : false; + BinaryBuffer.call(this, dataOrLength, isLittleEndian); + } + CommandBinaryBuffer.prototype = Object.create(BinaryBuffer.prototype); + CommandBinaryBuffer.prototype.constructor = CommandBinaryBuffer; + CommandBinaryBuffer.getMagneticInfluenceBit = byte => !!extractBits(byte, 1, MAGNETIC_INFLUENCE_BIT_INDEX); + CommandBinaryBuffer.setMagneticInfluenceBit = (byte, value) => fillBits(byte, 1, MAGNETIC_INFLUENCE_BIT_INDEX, +value); + CommandBinaryBuffer.getLegacyHourCounterSize = hourCounter => LEGACY_HOUR_COUNTER_SIZE + hourCounter.diff.length * LEGACY_HOUR_DIFF_SIZE; + CommandBinaryBuffer.prototype.getExtendedValue = function () { + let value = 0; + let isByteExtended = true; + let position = 0; + while (isByteExtended && this.offset <= this.data.length) { + const byte = this.getUint8(); + isByteExtended = !!(byte & EXTEND_BIT_MASK); + value += (byte & 0x7f) << 7 * position >>> 0; + ++position; + } + return value; + }; + CommandBinaryBuffer.prototype.setExtendedValue = function (value) { + if (value === 0) { + this.setUint8(0); + return; + } + const data = []; + let encodedValue = value; + while (encodedValue) { + data.push(EXTEND_BIT_MASK | encodedValue & 0x7f); + encodedValue >>>= 7; + } + const lastByte = data.pop(); + if (lastByte) { + data.push(lastByte & 0x7f); + } + data.forEach(extendedValue => this.setUint8(extendedValue)); + }; + CommandBinaryBuffer.prototype.getExtendedValueSize = function (bits) { + const extBits = Math.ceil(bits / 7); + const totalBits = bits + extBits; + const extBytes = Math.ceil(totalBits / 8); + return extBytes; + }; + CommandBinaryBuffer.prototype.getTime = function () { + return this.getUint32(); + }; + CommandBinaryBuffer.prototype.setTime = function (value) { + this.setUint32(value); + }; + CommandBinaryBuffer.prototype.getBatteryVoltage = function () { + const lowVoltageByte = this.getUint8(); + const lowAndHightVoltageByte = this.getUint8(); + const highVoltageByte = this.getUint8(); + let underLowLoad = lowVoltageByte << 4; + underLowLoad |= (lowAndHightVoltageByte & 0xf0) >> 4; + let underHighLoad = (lowAndHightVoltageByte & 0x0f) << 8 | highVoltageByte; + if (underHighLoad === UNKNOWN_BATTERY_VOLTAGE) { + underHighLoad = undefined; + } + if (underLowLoad === UNKNOWN_BATTERY_VOLTAGE) { + underLowLoad = undefined; + } + return { + underLowLoad, + underHighLoad + }; + }; + CommandBinaryBuffer.prototype.setBatteryVoltage = function (batteryVoltage) { + let { + underLowLoad, + underHighLoad + } = batteryVoltage; + if (underLowLoad === undefined) { + underLowLoad = UNKNOWN_BATTERY_VOLTAGE; + } + if (underHighLoad === undefined) { + underHighLoad = UNKNOWN_BATTERY_VOLTAGE; + } + const lowVoltageByte = underLowLoad >> 4 & 0xff; + const lowAndHighVoltageByte = (underLowLoad & 0x0f) << 4 | underHighLoad >> 8 & 0x0f; + const highVoltageByte = underHighLoad & 0xff; + [lowVoltageByte, lowAndHighVoltageByte, highVoltageByte].forEach(byte => this.setUint8(byte)); + }; + CommandBinaryBuffer.prototype.getLegacyCounterValue = function () { + return this.getUint24(); + }; + CommandBinaryBuffer.prototype.setLegacyCounterValue = function (value) { + this.setUint24(value); + }; + CommandBinaryBuffer.prototype.getLegacyCounter = function () { + let byte = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : this.getUint8(); + let isArchiveValue = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : false; + const value = this.getLegacyCounterValue(); + return { + isMagneticInfluence: CommandBinaryBuffer.getMagneticInfluenceBit(byte), + value: isArchiveValue && value === EMPTY_VALUE ? 0 : value + }; + }; + CommandBinaryBuffer.prototype.setLegacyCounter = function (counter) { + let byte = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : 0; + let isArchiveValue = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : false; + this.setUint8(CommandBinaryBuffer.setMagneticInfluenceBit(byte, counter.isMagneticInfluence)); + this.setLegacyCounterValue(isArchiveValue && counter.value === 0 ? EMPTY_VALUE : counter.value); + }; + CommandBinaryBuffer.prototype.getChannels = function () { + const channelList = []; + let extended = true; + let channelIndex = 1; + while (extended) { + const byte = this.getUint8(); + const bits = byte.toString(2).padStart(LAST_BIT_INDEX + 1, '0').split('').reverse(); + bits.forEach((bit, index) => { + const value = Number(bit); + if (index === LAST_BIT_INDEX) { + extended = !!value; + } else { + if (value) { + channelList.push(channelIndex); + } + ++channelIndex; + } + }); + } + return channelList; + }; + CommandBinaryBuffer.prototype.setChannels = function (channelList) { + if (channelList.length === 0) { + this.setUint8(0); + return; + } + channelList.sort((a, b) => a.index - b.index); + const maxChannel = Math.max(...channelList.map(_ref2 => { + let { + index + } = _ref2; + return index; + })); + const size = (maxChannel - maxChannel % 8) / 8; + const data = new Array(size + 1).fill(0); + let byte = 0; + data.forEach((_, byteIndex) => { + let channelIndex = byteIndex * LAST_BIT_INDEX + 1; + const maxChannelIndex = channelIndex + LAST_BIT_INDEX; + while (channelIndex < maxChannelIndex) { + const channel = channelList.find(item => item.index === channelIndex); + if (channel !== undefined) { + byte |= 1 << (channel.index - 1) % LAST_BIT_INDEX; + } + ++channelIndex; + } + if (data[byteIndex + 1] !== undefined) { + byte |= 1 << LAST_BIT_INDEX; + } + data[byteIndex] = byte; + byte = 0; + }); + data.forEach(value => this.setUint8(value)); + }; + CommandBinaryBuffer.prototype.getChannelValue = function () { + return this.getUint8() + 1; + }; + CommandBinaryBuffer.prototype.setChannelValue = function (value) { + if (value < 1) { + throw new Error('channel must be 1 or greater'); + } + this.setUint8(value - 1); + }; + CommandBinaryBuffer.prototype.getChannelsValuesWithHourDiff = function () { + let isArchiveValue = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : false; + const date = this.getDate(); + const { + hour, + hours + } = this.getHours(); + const channels = this.getChannels(); + const channelList = []; + date.setUTCHours(hour); + channels.forEach(channelIndex => { + const diff = []; + const value = this.getExtendedValue(); + for (let diffHour = 1; diffHour < hours; ++diffHour) { + diff.push(this.getExtendedValue()); + } + channelList.push({ + value: value === isArchiveValue && EMPTY_VALUE ? 0 : value, + diff, + index: channelIndex + }); + }); + return { + startTime2000: getTime2000FromDate(date), + hours, + channelList + }; + }; + CommandBinaryBuffer.prototype.setChannelsValuesWithHourDiff = function (hours, startTime2000, channelList) { + let isArchiveValue = arguments.length > 3 && arguments[3] !== undefined ? arguments[3] : false; + const date = getDateFromTime2000(startTime2000); + const hour = date.getUTCHours(); + this.setDate(date); + this.setHours(hour, hours); + this.setChannels(channelList); + channelList.forEach(_ref3 => { + let { + value, + diff + } = _ref3; + this.setExtendedValue(isArchiveValue && value === 0 ? EMPTY_VALUE : value); + diff.forEach(diffValue => this.setExtendedValue(diffValue)); + }); + }; + CommandBinaryBuffer.prototype.getHours = function () { + let byte = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : this.getUint8(); + if (byte === 0) { + return { + hours: 0, + hour: 0 + }; + } + const hours = ((byte & 0xe0) >> 5) + 1; + const hour = byte & 0x1f; + return { + hours, + hour + }; + }; + CommandBinaryBuffer.prototype.setHours = function (hour, hours) { + if (hour === 0 && hours === 0) { + this.setUint8(0); + return; + } + this.setUint8((hours - 1 & 0x07) << 5 | hour & 0x1f); + }; + CommandBinaryBuffer.prototype.getDate = function () { + const yearMonthByte = this.getUint8(); + const monthDateByte = this.getUint8(); + const year = yearMonthByte >> YEAR_START_INDEX; + const month = (yearMonthByte & 0x01) << MONTH_BIT_SIZE - YEAR_START_INDEX | monthDateByte >> DATE_BIT_SIZE; + const monthDay = monthDateByte & 0x1f; + return new Date(Date.UTC(year + INITIAL_YEAR, month - 1, monthDay, 0, 0, 0, 0)); + }; + CommandBinaryBuffer.prototype.setDate = function (dateOrTime) { + let date; + if (dateOrTime instanceof Date) { + date = dateOrTime; + } else { + date = getDateFromTime2000(dateOrTime); + } + const year = date.getUTCFullYear() - INITIAL_YEAR; + const month = date.getUTCMonth() + 1; + const day = date.getUTCDate(); + const yearMonthByte = year << YEAR_START_INDEX | month >> MONTH_BIT_SIZE - YEAR_START_INDEX; + const monthDateByte = (month & 0x07) << DATE_BIT_SIZE | day; + [yearMonthByte, monthDateByte].forEach(byte => this.setUint8(byte)); + }; + CommandBinaryBuffer.prototype.getPulseCoefficient = function () { + const pulseCoefficient = this.getUint8(); + if (isMSBSet(pulseCoefficient)) { + const value = byteToPulseCoefficientMap[pulseCoefficient]; + if (value) { + return value; + } + throw new Error('pulseCoefficient MSB is set, but value unknown'); + } + return pulseCoefficient; + }; + CommandBinaryBuffer.prototype.setPulseCoefficient = function (value) { + if (value in pulseCoefficientToByteMap) { + const byte = pulseCoefficientToByteMap[value]; + if (byte) { + this.setUint8(byte); + } else { + throw new Error('pulseCoefficient MSB is set, but value unknown'); + } + } else { + this.setUint8(value); + } + }; + CommandBinaryBuffer.prototype.getChannelsWithAbsoluteValues = function () { + const channels = this.getChannels(); + const channelList = []; + channels.forEach(channelIndex => { + channelList.push({ + pulseCoefficient: this.getPulseCoefficient(), + value: this.getExtendedValue(), + index: channelIndex + }); + }); + return channelList; + }; + CommandBinaryBuffer.prototype.setChannelsWithAbsoluteValues = function (channelList) { + this.setChannels(channelList); + channelList.forEach(_ref4 => { + let { + value, + pulseCoefficient + } = _ref4; + this.setPulseCoefficient(pulseCoefficient); + this.setExtendedValue(value); + }); + }; + CommandBinaryBuffer.prototype.getChannelsAbsoluteValuesWithHourDiff = function (hours) { + const channels = this.getChannels(); + const channelList = []; + channels.forEach(channelIndex => { + const pulseCoefficient = this.getPulseCoefficient(); + const value = this.getExtendedValue(); + const diff = []; + for (let hourIndex = 1; hourIndex < hours; ++hourIndex) { + diff.push(this.getExtendedValue()); + } + channelList.push({ + diff, + value, + pulseCoefficient, + index: channelIndex + }); + }); + return channelList; + }; + CommandBinaryBuffer.prototype.setChannelsAbsoluteValuesWithHourDiff = function (channelList) { + this.setChannels(channelList); + channelList.forEach(_ref5 => { + let { + value, + diff, + pulseCoefficient + } = _ref5; + this.setPulseCoefficient(pulseCoefficient); + this.setExtendedValue(value); + diff.forEach(diffValue => this.setExtendedValue(diffValue)); + }); + }; + CommandBinaryBuffer.prototype.getEventStatus = function (hardwareType) { + let status; + if (GAS_HARDWARE_TYPES.indexOf(hardwareType) !== -1) { + status = toObject(gasBitMask, this.getUint8()); + } else if (TWO_CHANNELS_HARDWARE_TYPES.indexOf(hardwareType) !== -1) { + status = toObject(twoChannelBitMask, this.getUint8()); + } else if (ELIMP_HARDWARE_TYPES.indexOf(hardwareType) !== -1) { + status = toObject(elimpBitMask, this.getUint8()); + } else if (FOUR_CHANNELS_HARDWARE_TYPES.indexOf(hardwareType) !== -1) { + status = toObject(fourChannelBitMask, this.getUint16(true)); + } else if (MTX_HARDWARE_TYPES.indexOf(hardwareType) !== -1) { + status = toObject(mtxBitMask, this.getUint16(true)); + } else if (hardwareType === US_WATER) { + const event = toObject(usWaterMeterEventBitMask, this.getUint8()); + status = { + event, + error: this.getUint8() + }; + } else { + throw new Error('wrong hardwareType'); + } + return status; + }; + CommandBinaryBuffer.prototype.setEventStatus = function (hardwareType, status) { + if (GAS_HARDWARE_TYPES.indexOf(hardwareType) !== -1) { + this.setUint8(fromObject(gasBitMask, status)); + } else if (TWO_CHANNELS_HARDWARE_TYPES.indexOf(hardwareType) !== -1) { + this.setUint8(fromObject(twoChannelBitMask, status)); + } else if (ELIMP_HARDWARE_TYPES.indexOf(hardwareType) !== -1) { + this.setUint8(fromObject(elimpBitMask, status)); + } else if (FOUR_CHANNELS_HARDWARE_TYPES.indexOf(hardwareType) !== -1) { + this.setUint16(fromObject(fourChannelBitMask, status) | 1 << 7, true); + } else if (MTX_HARDWARE_TYPES.indexOf(hardwareType) !== -1) { + this.setUint16(fromObject(mtxBitMask, status), true); + } else if (hardwareType === US_WATER) { + const data = status; + this.setUint8(fromObject(usWaterMeterEventBitMask, data.event)); + this.setUint8(data.error); + } else { + throw new Error('wrong hardwareType'); + } + }; + CommandBinaryBuffer.prototype.getParameter = function () { + const id = this.getUint8(); + const name = deviceParameterNames[id]; + if (!deviceParameterConvertersMap[id] || !deviceParameterConvertersMap[id].get) { + throw new Error(`parameter ${id} is not supported`); + } + const data = deviceParameterConvertersMap[id].get(this); + return { + id, + name, + data + }; + }; + CommandBinaryBuffer.prototype.setParameter = function (parameter) { + const { + id, + data + } = parameter; + if (!deviceParameterConvertersMap[id] || !deviceParameterConvertersMap[id].set) { + throw new Error(`parameter ${id} is not supported`); + } + this.setUint8(id); + deviceParameterConvertersMap[id].set(this, data); + }; + CommandBinaryBuffer.prototype.getRequestParameter = function () { + const id = this.getUint8(); + const name = deviceParameterNames[id]; + let data = null; + switch (id) { + case ABSOLUTE_DATA_ENABLE_MULTI_CHANNEL: + case ABSOLUTE_DATA_MULTI_CHANNEL: + case CHANNEL_TYPE: + data = { + channel: this.getChannelValue() + }; + break; + case REPORTING_DATA_CONFIG: + data = { + dataType: this.getUint8() + }; + break; + case EVENTS_CONFIG: + data = { + eventId: this.getUint8() + }; + break; + } + return { + id, + name, + data + }; + }; + CommandBinaryBuffer.prototype.setRequestParameter = function (parameter) { + const { + id, + data: parameterData + } = parameter; + let data; + this.setUint8(id); + switch (id) { + case ABSOLUTE_DATA_MULTI_CHANNEL: + case ABSOLUTE_DATA_ENABLE_MULTI_CHANNEL: + case CHANNEL_TYPE: + data = parameterData; + this.setChannelValue(data.channel); + break; + case REPORTING_DATA_CONFIG: + data = parameterData; + this.setUint8(data.dataType); + break; + case EVENTS_CONFIG: + data = parameterData; + this.setUint8(data.eventId); + break; + } + }; + CommandBinaryBuffer.prototype.getResponseParameter = function () { + const id = this.getUint8(); + const name = deviceParameterNames[id]; + let data; + if (!deviceParameterConvertersMap[id] || !deviceParameterConvertersMap[id].get) { + throw new Error(`parameter ${id} is not supported`); + } + switch (id) { + case MQTT_SESSION_CONFIG: + case NBIOT_SSL_CACERT_WRITE: + case NBIOT_SSL_CLIENT_CERT_WRITE: + case NBIOT_SSL_CLIENT_KEY_WRITE: + case NBIOT_SSL_CACERT_SET: + case NBIOT_SSL_CLIENT_CERT_SET: + case NBIOT_SSL_CLIENT_KEY_SET: + case NBIOT_DEVICE_SOFTWARE_UPDATE: + case NBIOT_MODULE_FIRMWARE_UPDATE: + data = null; + break; + default: + data = deviceParameterConvertersMap[id].get(this); + } + return { + id, + name, + data + }; + }; + CommandBinaryBuffer.prototype.setResponseParameter = function (parameter) { + const { + id, + data + } = parameter; + if (!deviceParameterConvertersMap[id] || !deviceParameterConvertersMap[id].set) { + throw new Error(`parameter ${id} is not supported`); + } + this.setUint8(id); + switch (id) { + case MQTT_SESSION_CONFIG: + case NBIOT_SSL_CACERT_WRITE: + case NBIOT_SSL_CLIENT_CERT_WRITE: + case NBIOT_SSL_CLIENT_KEY_WRITE: + case NBIOT_SSL_CACERT_SET: + case NBIOT_SSL_CLIENT_CERT_SET: + case NBIOT_SSL_CLIENT_KEY_SET: + case NBIOT_DEVICE_SOFTWARE_UPDATE: + case NBIOT_MODULE_FIRMWARE_UPDATE: + break; + default: + deviceParameterConvertersMap[id].set(this, data); + } + }; + CommandBinaryBuffer.prototype.getLegacyHourDiff = function () { + const stateWithValueByte = this.getUint8(); + const valueLowerByte = this.getUint8(); + return { + isMagneticInfluence: CommandBinaryBuffer.getMagneticInfluenceBit(stateWithValueByte), + value: (stateWithValueByte & 0x1f) << 8 | valueLowerByte + }; + }; + CommandBinaryBuffer.prototype.setLegacyHourDiff = function (diff) { + const bytes = [diff.value >> 8, diff.value & 0xff]; + bytes[0] = CommandBinaryBuffer.setMagneticInfluenceBit(bytes[0], diff.isMagneticInfluence); + bytes.forEach(byte => this.setUint8(byte)); + }; + CommandBinaryBuffer.prototype.getLegacyHourCounterWithDiff = function () { + let isArchiveValue = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : false; + const date = this.getDate(); + const byte = this.getUint8(); + const { + hour + } = this.getHours(byte); + const value = this.getLegacyCounterValue(); + const counter = { + isMagneticInfluence: CommandBinaryBuffer.getMagneticInfluenceBit(byte), + value: isArchiveValue && value === EMPTY_VALUE ? 0 : value + }; + const diff = []; + while (this.offset < this.data.length) { + diff.push(this.getLegacyHourDiff()); + } + date.setUTCHours(hour); + return { + startTime2000: getTime2000FromDate(date), + counter, + diff + }; + }; + CommandBinaryBuffer.prototype.setLegacyHourCounterWithDiff = function (hourCounter) { + let isArchiveValue = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : false; + const date = getDateFromTime2000(hourCounter.startTime2000); + const hour = date.getUTCHours(); + const { + value + } = hourCounter.counter; + this.setDate(date); + this.setHours(hour, 1); + this.seek(this.offset - 1); + const byte = this.getUint8(); + this.seek(this.offset - 1); + this.setUint8(CommandBinaryBuffer.setMagneticInfluenceBit(byte, hourCounter.counter.isMagneticInfluence)); + this.setLegacyCounterValue(isArchiveValue && value === 0 ? EMPTY_VALUE : value); + hourCounter.diff.forEach(diffItem => this.setLegacyHourDiff(diffItem)); + }; + CommandBinaryBuffer.prototype.getChannelsValuesWithHourDiffExtended = function () { + let isArchiveValue = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : false; + const date = this.getDate(); + const hour = this.getUint8(); + const hours = this.getUint8(); + const channels = this.getChannels(); + const channelList = []; + date.setUTCHours(hour); + channels.forEach(channelIndex => { + const diff = []; + const value = this.getExtendedValue(); + for (let diffHour = 0; diffHour < hours; ++diffHour) { + diff.push(this.getExtendedValue()); + } + channelList.push({ + value: value === isArchiveValue && EMPTY_VALUE ? 0 : value, + diff, + index: channelIndex + }); + }); + return { + startTime2000: getTime2000FromDate(date), + hour, + hours, + channelList + }; + }; + CommandBinaryBuffer.prototype.setChannelsValuesWithHourDiffExtended = function (parameters) { + let isArchiveValue = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : false; + const date = getDateFromTime2000(parameters.startTime2000); + this.setDate(date); + this.setUint8(parameters.hour); + this.setUint8(parameters.hours); + this.setChannels(parameters.channelList); + parameters.channelList.forEach(_ref6 => { + let { + value, + diff + } = _ref6; + this.setExtendedValue(isArchiveValue && value === 0 ? EMPTY_VALUE : value); + diff.forEach(diffValue => this.setExtendedValue(diffValue)); + }); + }; + CommandBinaryBuffer.prototype.getDataSegment = function () { + const segmentationSessionId = this.getUint8(); + const flag = this.getUint8(); + return { + segmentationSessionId, + segmentIndex: extractBits(flag, 3, 1), + segmentsNumber: extractBits(flag, 3, 5), + isLast: Boolean(extractBits(flag, 1, 8)), + data: this.getBytesLeft() + }; + }; + CommandBinaryBuffer.prototype.setDataSegment = function (parameters) { + let flag = fillBits(0, 3, 1, parameters.segmentIndex); + flag = fillBits(flag, 3, 5, parameters.segmentsNumber); + flag = fillBits(flag, 1, 8, +parameters.isLast); + this.setUint8(parameters.segmentationSessionId); + this.setUint8(flag); + this.setBytes(parameters.data); + }; + CommandBinaryBuffer.prototype.getBinarySensor = function () { + const activeStateTimeMs = this.getUint16(); + return { + activeStateTimeMs + }; + }; + CommandBinaryBuffer.prototype.setBinarySensor = function (parameters) { + this.setUint16(parameters.activeStateTimeMs); + }; + CommandBinaryBuffer.prototype.getTemperatureSensor = function () { + const measurementPeriod = this.getUint16(); + const hysteresisSec = this.getUint8(); + const highTemperatureThreshold = this.getInt8(); + const lowTemperatureThreshold = this.getInt8(); + return { + measurementPeriod, + hysteresisSec, + highTemperatureThreshold, + lowTemperatureThreshold + }; + }; + CommandBinaryBuffer.prototype.setTemperatureSensor = function (parameters) { + this.setInt16(parameters.measurementPeriod); + this.setInt8(parameters.hysteresisSec); + this.setInt8(parameters.highTemperatureThreshold); + this.setInt8(parameters.lowTemperatureThreshold); + }; + CommandBinaryBuffer.prototype.getChannelType = function () { + const channel = this.getChannelValue(); + const type = this.getUint8(); + let parameters = {}; + switch (type) { + case BINARY_SENSOR: + parameters = this.getBinarySensor(); + break; + case TEMPERATURE_SENSOR: + parameters = this.getTemperatureSensor(); + break; + } + return { + channel, + type, + parameters + }; + }; + CommandBinaryBuffer.prototype.setChannelType = function (_ref7) { + let { + type, + channel, + parameters + } = _ref7; + this.setChannelValue(channel); + this.setUint8(type); + switch (type) { + case BINARY_SENSOR: + this.setBinarySensor(parameters); + break; + case TEMPERATURE_SENSOR: + this.setTemperatureSensor(parameters); + break; + } + }; + + const id$Z = dataSegment$1; + downlinkNames[dataSegment$1]; + const COMMAND_BODY_MIN_SIZE$3 = 2; + const fromBytes$ = data => { + const buffer = new CommandBinaryBuffer(data); + return buffer.getDataSegment(); + }; + const toBytes$ = parameters => { + const buffer = new CommandBinaryBuffer(COMMAND_BODY_MIN_SIZE$3 + parameters.data.length); + buffer.setDataSegment(parameters); + return toBytes$11(id$Z, buffer.data); + }; + + const id$Y = getArchiveDays$1; + downlinkNames[getArchiveDays$1]; + const COMMAND_BODY_SIZE$v = 3; + const fromBytes$_ = data => { + if (data.length !== COMMAND_BODY_SIZE$v) { + throw new Error(`Wrong buffer size: ${data.length}.`); + } + const buffer = new CommandBinaryBuffer(data); + const date = buffer.getDate(); + const days = buffer.getUint8(); + if (!buffer.isEmpty) { + throw new Error('BinaryBuffer is not empty.'); + } + return { + startTime2000: getTime2000FromDate(date), + days + }; + }; + const toBytes$_ = parameters => { + const buffer = new CommandBinaryBuffer(COMMAND_BODY_SIZE$v); + const { + startTime2000, + days + } = parameters; + const date = getDateFromTime2000(startTime2000); + buffer.setDate(date); + buffer.setUint8(days); + return toBytes$11(id$Y, buffer.data); + }; + + const id$X = getArchiveDaysMc$1; + downlinkNames[getArchiveDaysMc$1]; + const COMMAND_BODY_SIZE$u = 4; + const fromBytes$Z = data => { + if (data.length !== COMMAND_BODY_SIZE$u) { + throw new Error(`Wrong buffer size: ${data.length}.`); + } + const buffer = new CommandBinaryBuffer(data); + const date = buffer.getDate(); + const channelList = buffer.getChannels(); + const days = buffer.getUint8(); + if (!buffer.isEmpty) { + throw new Error('BinaryBuffer is not empty.'); + } + return { + startTime2000: getTime2000FromDate(date), + days, + channelList + }; + }; + const toBytes$Z = parameters => { + const buffer = new CommandBinaryBuffer(COMMAND_BODY_SIZE$u); + const { + startTime2000, + days, + channelList + } = parameters; + const date = getDateFromTime2000(startTime2000); + buffer.setDate(date); + buffer.setChannels(channelList.map(index => ({ + index + }))); + buffer.setUint8(days); + return toBytes$11(id$X, buffer.data); + }; + + const id$W = getArchiveEvents$1; + downlinkNames[getArchiveEvents$1]; + const COMMAND_BODY_SIZE$t = 5; + const fromBytes$Y = data => { + if (data.length !== COMMAND_BODY_SIZE$t) { + throw new Error(`Wrong buffer size: ${data.length}.`); + } + const buffer = new CommandBinaryBuffer(data); + const startTime2000 = buffer.getTime(); + const events = buffer.getUint8(); + if (!buffer.isEmpty) { + throw new Error('BinaryBuffer is not empty.'); + } + return { + startTime2000, + events + }; + }; + const toBytes$Y = parameters => { + const { + startTime2000, + events + } = parameters; + const buffer = new CommandBinaryBuffer(COMMAND_BODY_SIZE$t); + buffer.setTime(startTime2000); + buffer.setUint8(events); + return toBytes$11(id$W, buffer.data); + }; + + const id$V = getArchiveHours$1; + downlinkNames[getArchiveHours$1]; + const COMMAND_BODY_SIZE$s = 4; + const fromBytes$X = data => { + if (data.length !== COMMAND_BODY_SIZE$s) { + throw new Error(`Wrong buffer size: ${data.length}.`); + } + const buffer = new CommandBinaryBuffer(data); + const date = buffer.getDate(); + const { + hour + } = buffer.getHours(); + const hours = buffer.getUint8(); + date.setUTCHours(hour); + if (!buffer.isEmpty) { + throw new Error('BinaryBuffer is not empty.'); + } + return { + startTime2000: getTime2000FromDate(date), + hours + }; + }; + const toBytes$X = parameters => { + const { + startTime2000, + hours + } = parameters; + const buffer = new CommandBinaryBuffer(COMMAND_BODY_SIZE$s); + const date = getDateFromTime2000(startTime2000); + const hour = date.getUTCHours(); + buffer.setDate(date); + buffer.setHours(hour, 1); + buffer.setUint8(hours); + return toBytes$11(id$V, buffer.data); + }; + + const id$U = getArchiveHoursMc$1; + downlinkNames[getArchiveHoursMc$1]; + const COMMAND_BODY_SIZE$r = 4; + const fromBytes$W = data => { + if (data.length !== COMMAND_BODY_SIZE$r) { + throw new Error(`Wrong buffer size: ${data.length}.`); + } + const buffer = new CommandBinaryBuffer(data); + const date = buffer.getDate(); + const { + hour, + hours + } = buffer.getHours(); + const channelList = buffer.getChannels(); + date.setUTCHours(hour); + if (!buffer.isEmpty) { + throw new Error('BinaryBuffer is not empty.'); + } + return { + startTime2000: getTime2000FromDate(date), + hours, + channelList + }; + }; + const toBytes$W = parameters => { + const buffer = new CommandBinaryBuffer(COMMAND_BODY_SIZE$r); + const { + hours, + startTime2000, + channelList + } = parameters; + const date = getDateFromTime2000(startTime2000); + const hour = date.getUTCHours(); + buffer.setDate(date); + buffer.setHours(hour, hours); + buffer.setChannels(channelList.map(index => ({ + index + }))); + return toBytes$11(id$U, buffer.data); + }; + + const id$T = getArchiveHoursMcEx$1; + downlinkNames[getArchiveHoursMcEx$1]; + const COMMAND_BODY_SIZE$q = 5; + const fromBytes$V = data => { + const buffer = new CommandBinaryBuffer(data); + const date = buffer.getDate(); + const hour = buffer.getUint8(); + const hours = buffer.getUint8(); + const channelList = buffer.getChannels(); + date.setUTCHours(hour); + if (!buffer.isEmpty) { + throw new Error('BinaryBuffer is not empty.'); + } + return { + startTime2000: getTime2000FromDate(date), + hour, + hours, + channelList + }; + }; + const toBytes$V = parameters => { + const buffer = new CommandBinaryBuffer(COMMAND_BODY_SIZE$q); + const { + channelList, + hour, + hours, + startTime2000 + } = parameters; + const date = getDateFromTime2000(startTime2000); + buffer.setDate(date); + buffer.setUint8(hour); + buffer.setUint8(hours); + buffer.setChannels(channelList.map(index => ({ + index + }))); + return toBytes$11(id$T, buffer.data); + }; + + const id$S = getBatteryStatus$1; + downlinkNames[getBatteryStatus$1]; + const COMMAND_BODY_SIZE$p = 0; + const fromBytes$U = data => { + if (data.length !== COMMAND_BODY_SIZE$p) { + throw new Error(`Wrong buffer size: ${data.length}.`); + } + return {}; + }; + const toBytes$U = () => toBytes$11(id$S); + + const id$R = getChannelsStatus$1; + downlinkNames[getChannelsStatus$1]; + const fromBytes$T = data => data.length === 0 ? {} : getChannelsMaskFromNumber(data[0]); + const toBytes$T = parameters => toBytes$11(id$R, Object.keys(parameters).length !== 0 ? [setChannelsMaskToNumber(parameters)] : []); + + const id$Q = getChannelsTypes$1; + downlinkNames[getChannelsTypes$1]; + const COMMAND_BODY_SIZE$o = 0; + const fromBytes$S = data => { + if (data.length !== COMMAND_BODY_SIZE$o) { + throw new Error(`Wrong buffer size: ${data.length}.`); + } + return {}; + }; + const toBytes$S = () => toBytes$11(id$Q); + + const id$P = getCurrent; + downlinkNames[getCurrent]; + const COMMAND_BODY_SIZE$n = 0; + const fromBytes$R = data => { + if (data.length !== COMMAND_BODY_SIZE$n) { + throw new Error(`Wrong buffer size: ${data.length}.`); + } + return {}; + }; + const toBytes$R = () => toBytes$11(id$P); + + const id$O = getCurrentMc; + downlinkNames[getCurrentMc]; + const COMMAND_BODY_SIZE$m = 0; + const fromBytes$Q = data => { + if (data.length !== COMMAND_BODY_SIZE$m) { + throw new Error(`Wrong buffer size: ${data.length}.`); + } + return {}; + }; + const toBytes$Q = () => toBytes$11(id$O); + + const id$N = getExAbsArchiveDaysMc$1; + downlinkNames[getExAbsArchiveDaysMc$1]; + const COMMAND_BODY_SIZE$l = 4; + const fromBytes$P = data => { + if (data.length !== COMMAND_BODY_SIZE$l) { + throw new Error(`Wrong buffer size: ${data.length}.`); + } + const buffer = new CommandBinaryBuffer(data); + const date = buffer.getDate(); + const channelList = buffer.getChannels(); + const days = buffer.getUint8(); + if (!buffer.isEmpty) { + throw new Error('BinaryBuffer is not empty.'); + } + return { + startTime2000: getTime2000FromDate(date), + days, + channelList + }; + }; + const toBytes$P = parameters => { + const buffer = new CommandBinaryBuffer(COMMAND_BODY_SIZE$l); + const { + startTime2000, + days, + channelList + } = parameters; + buffer.setDate(startTime2000); + buffer.setChannels(channelList.map(index => ({ + index + }))); + buffer.setUint8(days); + return toBytes$11(id$N, buffer.data); + }; + + const id$M = getExAbsArchiveHoursMc$1; + downlinkNames[getExAbsArchiveHoursMc$1]; + const COMMAND_BODY_SIZE$k = 4; + const fromBytes$O = data => { + const buffer = new CommandBinaryBuffer(data); + const date = buffer.getDate(); + const { + hour, + hours + } = buffer.getHours(); + const channelList = buffer.getChannels(); + date.setUTCHours(hour); + if (!buffer.isEmpty) { + throw new Error('BinaryBuffer is not empty.'); + } + return { + channelList, + hours, + startTime2000: getTime2000FromDate(date) + }; + }; + const toBytes$O = parameters => { + const buffer = new CommandBinaryBuffer(COMMAND_BODY_SIZE$k); + const { + startTime2000, + hours, + channelList + } = parameters; + const date = getDateFromTime2000(startTime2000); + const hour = date.getUTCHours(); + buffer.setDate(date); + buffer.setHours(hour, hours); + buffer.setChannels(channelList.map(index => ({ + index + }))); + return toBytes$11(id$M, buffer.data); + }; + + const id$L = getExAbsCurrentMc; + downlinkNames[getExAbsCurrentMc]; + const COMMAND_BODY_SIZE$j = 0; + const fromBytes$N = data => { + if (data.length !== COMMAND_BODY_SIZE$j) { + throw new Error(`Wrong buffer size: ${data.length}.`); + } + return {}; + }; + const toBytes$N = () => toBytes$11(id$L); + + const id$K = getLmicInfo$1; + downlinkNames[getLmicInfo$1]; + const COMMAND_BODY_SIZE$i = 0; + const fromBytes$M = data => { + if (data.length !== COMMAND_BODY_SIZE$i) { + throw new Error(`Wrong buffer size: ${data.length}.`); + } + return {}; + }; + const toBytes$M = () => toBytes$11(id$K); + + const id$J = getParameter$1; + downlinkNames[getParameter$1]; + const fromBytes$L = data => { + const buffer = new CommandBinaryBuffer(data); + return buffer.getRequestParameter(); + }; + const toBytes$L = parameters => { + const buffer = new CommandBinaryBuffer(getRequestParameterSize(parameters)); + buffer.setRequestParameter(parameters); + return toBytes$11(id$J, buffer.data); + }; + + const id$I = getStatus; + downlinkNames[getStatus]; + const COMMAND_BODY_SIZE$h = 0; + const fromBytes$K = data => { + if (data.length !== COMMAND_BODY_SIZE$h) { + throw new Error(`Wrong buffer size: ${data.length}.`); + } + return {}; + }; + const toBytes$K = () => toBytes$11(id$I); + + const id$H = getTime2000; + downlinkNames[getTime2000]; + const COMMAND_BODY_SIZE$g = 0; + const fromBytes$J = data => { + if (data.length !== COMMAND_BODY_SIZE$g) { + throw new Error(`Wrong buffer size: ${data.length}.`); + } + return {}; + }; + const toBytes$J = () => toBytes$11(id$H, []); + + const id$G = setParameter$1; + downlinkNames[setParameter$1]; + const fromBytes$I = data => { + const buffer = new CommandBinaryBuffer(data); + return buffer.getParameter(); + }; + const toBytes$I = parameters => { + const buffer = new CommandBinaryBuffer(getParameterSize(parameters)); + buffer.setParameter(parameters); + return toBytes$11(id$G, buffer.data); + }; + + const id$F = setTime2000$1; + downlinkNames[setTime2000$1]; + const COMMAND_BODY_SIZE$f = 5; + const fromBytes$H = data => { + if (data.length !== COMMAND_BODY_SIZE$f) { + throw new Error(`Wrong buffer size: ${data.length}.`); + } + const buffer = new BinaryBuffer(data, false); + const parameters = { + sequenceNumber: buffer.getUint8(), + seconds: buffer.getInt32() + }; + if (!buffer.isEmpty) { + throw new Error('BinaryBuffer is not empty.'); + } + return parameters; + }; + const toBytes$H = parameters => { + const { + sequenceNumber, + seconds + } = parameters; + const buffer = new BinaryBuffer(COMMAND_BODY_SIZE$f, false); + buffer.setUint8(sequenceNumber); + buffer.setInt32(seconds); + return toBytes$11(id$F, buffer.data); + }; + + const id$E = softRestart$1; + downlinkNames[softRestart$1]; + const COMMAND_BODY_SIZE$e = 0; + const fromBytes$G = data => { + if (data.length !== COMMAND_BODY_SIZE$e) { + throw new Error(`Wrong buffer size: ${data.length}.`); + } + return {}; + }; + const toBytes$G = () => toBytes$11(id$E); + + const id$D = updateRun$1; + downlinkNames[updateRun$1]; + const COMMAND_BODY_SIZE$d = 0; + const fromBytes$F = data => { + if (data.length !== COMMAND_BODY_SIZE$d) { + throw new Error(`Wrong buffer size: ${data.length}.`); + } + return {}; + }; + const toBytes$F = () => toBytes$11(id$D); + + const id$C = usWaterMeterCommand$1; + downlinkNames[usWaterMeterCommand$1]; + const fromBytes$E = data => { + const buffer = new CommandBinaryBuffer(data); + const length = buffer.getUint8(); + return { + length, + data: data.slice(1) + }; + }; + const toBytes$E = parameters => { + const { + data, + length + } = parameters; + const buffer = new CommandBinaryBuffer(length); + buffer.setUint8(length); + buffer.setBytes(data); + return toBytes$11(id$C, buffer.data); + }; + + const id$B = verifyImage$1; + downlinkNames[verifyImage$1]; + const COMMAND_BODY_SIZE$c = 0; + const fromBytes$D = data => { + if (data.length !== COMMAND_BODY_SIZE$c) { + throw new Error(`Wrong buffer size: ${data.length}.`); + } + return {}; + }; + const toBytes$D = () => toBytes$11(id$B); + + const id$A = writeImage$1; + downlinkNames[writeImage$1]; + const COMMAND_BODY_MIN_SIZE$2 = 4; + const fromBytes$C = data => { + if (data.length < COMMAND_BODY_MIN_SIZE$2) { + throw new Error(`Wrong buffer size: ${data.length}.`); + } + const buffer = new CommandBinaryBuffer(data); + const offset = buffer.getUint32(); + return { + offset, + data: data.slice(COMMAND_BODY_MIN_SIZE$2) + }; + }; + const toBytes$C = parameters => { + const buffer = new CommandBinaryBuffer(COMMAND_BODY_MIN_SIZE$2); + buffer.setUint32(parameters.offset); + buffer.setBytes(parameters.data); + return toBytes$11(id$A, buffer.data); + }; + + var calculateLrc = (function (data) { + let initialLrc = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : 0x55; + let lrc = initialLrc; + data.forEach(item => { + lrc ^= item; + }); + return lrc; + }); + + const HEADER_MAX_SIZE = 3; + const getFromBytes = (fromBytesMap, nameMap) => function () { + let bytes = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : []; + let config = arguments.length > 1 ? arguments[1] : undefined; + const commands = []; + const message = { + commands, + bytes, + lrc: { + received: undefined, + calculated: 0 + } + }; + let processedBytes = 0; + let receivedLrc; + let calculatedLrc; + if (!bytes.length) { + return message; + } + do { + const headerInfo = fromBytes$11(bytes.slice(processedBytes, processedBytes + HEADER_MAX_SIZE)); + const headerData = bytes.slice(processedBytes, processedBytes + headerInfo.headerSize); + const bodyData = bytes.slice(processedBytes + headerInfo.headerSize, processedBytes + headerInfo.headerSize + headerInfo.commandSize); + const command = { + id: headerInfo.commandId, + name: nameMap[headerInfo.commandId], + headerSize: headerInfo.headerSize, + bytes: [...headerData, ...bodyData] + }; + processedBytes = processedBytes + headerInfo.headerSize + headerInfo.commandSize; + if (config) { + command.config = config; + } + try { + if (!fromBytesMap[headerInfo.commandId]) { + throw new Error(`Unsupported command id: ${headerInfo.commandId}!`); + } + command.parameters = fromBytesMap[headerInfo.commandId](bodyData, config); + commands.push(command); + } catch (error) { + commands.push({ + command, + error: error.message + }); + } + } while (processedBytes < bytes.length - 1); + if (bytes.length - processedBytes === 1) { + receivedLrc = bytes[bytes.length - 1]; + calculatedLrc = calculateLrc(bytes.slice(0, -1)); + } else { + calculatedLrc = calculateLrc(bytes); + } + message.lrc.calculated = calculatedLrc; + message.lrc.received = receivedLrc; + if (receivedLrc === calculatedLrc) { + return message; + } + return { + message, + error: 'Mismatch LRC.' + }; + }; + const getToBytes = toBytesMap => commands => { + const commandBytes = commands.map(command => { + if ('id' in command) { + return toBytesMap[command.id](command.parameters || {}, command.config); + } + if ('command' in command) { + return command.command.bytes; + } + throw new Error('wrong command format'); + }); + const body = [].concat(...commandBytes); + return [...body, calculateLrc(body)]; + }; + const getToMessage = toBytesMap => commands => { + const commandsWithBytes = commands.map(command => { + if ('parameters' in command) { + return Object.assign({}, command, { + bytes: toBytesMap[command.id](command.parameters, command.config) + }); + } + throw new Error('wrong command format'); + }); + const commandBytes = commandsWithBytes.map(_ref => { + let { + bytes + } = _ref; + return bytes; + }); + const body = [].concat(...commandBytes); + const lrc = calculateLrc(body); + return { + commands: commandsWithBytes, + bytes: [...body, lrc], + lrc: { + received: lrc, + calculated: lrc + } + }; + }; + + const toBytesMap$1 = {}; + const fromBytesMap$1 = {}; + const nameMap$1 = downlinkNames; + const fromBytes$B = getFromBytes(fromBytesMap$1, nameMap$1); + const toBytes$B = getToBytes(toBytesMap$1); + const toMessage$1 = getToMessage(toBytesMap$1); + toBytesMap$1[id$_] = toBytes$10; + toBytesMap$1[id$Z] = toBytes$; + toBytesMap$1[id$Y] = toBytes$_; + toBytesMap$1[id$X] = toBytes$Z; + toBytesMap$1[id$W] = toBytes$Y; + toBytesMap$1[id$V] = toBytes$X; + toBytesMap$1[id$U] = toBytes$W; + toBytesMap$1[id$T] = toBytes$V; + toBytesMap$1[id$S] = toBytes$U; + toBytesMap$1[id$R] = toBytes$T; + toBytesMap$1[id$Q] = toBytes$S; + toBytesMap$1[id$P] = toBytes$R; + toBytesMap$1[id$O] = toBytes$Q; + toBytesMap$1[id$N] = toBytes$P; + toBytesMap$1[id$M] = toBytes$O; + toBytesMap$1[id$L] = toBytes$N; + toBytesMap$1[id$K] = toBytes$M; + toBytesMap$1[id$J] = toBytes$L; + toBytesMap$1[id$I] = toBytes$K; + toBytesMap$1[id$H] = toBytes$J; + toBytesMap$1[id$G] = toBytes$I; + toBytesMap$1[id$F] = toBytes$H; + toBytesMap$1[id$E] = toBytes$G; + toBytesMap$1[id$D] = toBytes$F; + toBytesMap$1[id$C] = toBytes$E; + toBytesMap$1[id$B] = toBytes$D; + toBytesMap$1[id$A] = toBytes$C; + fromBytesMap$1[id$_] = fromBytes$10; + fromBytesMap$1[id$Z] = fromBytes$; + fromBytesMap$1[id$Y] = fromBytes$_; + fromBytesMap$1[id$X] = fromBytes$Z; + fromBytesMap$1[id$W] = fromBytes$Y; + fromBytesMap$1[id$V] = fromBytes$X; + fromBytesMap$1[id$U] = fromBytes$W; + fromBytesMap$1[id$T] = fromBytes$V; + fromBytesMap$1[id$S] = fromBytes$U; + fromBytesMap$1[id$R] = fromBytes$T; + fromBytesMap$1[id$Q] = fromBytes$S; + fromBytesMap$1[id$P] = fromBytes$R; + fromBytesMap$1[id$O] = fromBytes$Q; + fromBytesMap$1[id$N] = fromBytes$P; + fromBytesMap$1[id$M] = fromBytes$O; + fromBytesMap$1[id$L] = fromBytes$N; + fromBytesMap$1[id$K] = fromBytes$M; + fromBytesMap$1[id$J] = fromBytes$L; + fromBytesMap$1[id$I] = fromBytes$K; + fromBytesMap$1[id$H] = fromBytes$J; + fromBytesMap$1[id$G] = fromBytes$I; + fromBytesMap$1[id$F] = fromBytes$H; + fromBytesMap$1[id$E] = fromBytes$G; + fromBytesMap$1[id$D] = fromBytes$F; + fromBytesMap$1[id$C] = fromBytes$E; + fromBytesMap$1[id$B] = fromBytes$D; + fromBytesMap$1[id$A] = fromBytes$C; + + var downlink = /*#__PURE__*/Object.freeze({ + __proto__: null, + fromBytes: fromBytes$B, + fromBytesMap: fromBytesMap$1, + nameMap: nameMap$1, + toBytes: toBytes$B, + toBytesMap: toBytesMap$1, + toMessage: toMessage$1 + }); + + const setTime2000 = 0x02; + const setParameter = 0x03; + const getParameter = 0x04; + const getArchiveHours = 0x05; + const getArchiveDays = 0x06; + const current = 0x07; + const time2000 = 0x09; + const getArchiveEvents = 0x0b; + const correctTime2000 = 0x0c; + const status = 0x14; + const newEvent = 0x15; + const dayMc = 0x16; + const hourMc = 0x17; + const currentMc = 0x18; + const softRestart = 0x19; + const getArchiveHoursMc = 0x1a; + const getArchiveDaysMc = 0x1b; + const dataSegment = 0x1e; + const day = 0x20; + const hour = 0x40; + const lastEvent = 0x60; + const getLmicInfo = 0x21f; + const getBatteryStatus = 0x51f; + const usWaterMeterCommand = 0x71f; + const exAbsHourMc = 0xa1f; + const exAbsDayMc = 0xb1f; + const getExAbsArchiveHoursMc = 0xc1f; + const getExAbsArchiveDaysMc = 0xd1f; + const exAbsCurrentMc = 0xf1f; + const usWaterMeterBatteryStatus = 0x141f; + const writeImage = 0x2a1f; + const verifyImage = 0x2b1f; + const updateRun = 0x2c1f; + const getArchiveHoursMcEx = 0x301f; + const hourMcEx = 0x311f; + const getChannelsStatus = 0x321f; + const getChannelsTypes = 0x331f; + + var uplinkIds = /*#__PURE__*/Object.freeze({ + __proto__: null, + correctTime2000: correctTime2000, + current: current, + currentMc: currentMc, + dataSegment: dataSegment, + day: day, + dayMc: dayMc, + exAbsCurrentMc: exAbsCurrentMc, + exAbsDayMc: exAbsDayMc, + exAbsHourMc: exAbsHourMc, + getArchiveDays: getArchiveDays, + getArchiveDaysMc: getArchiveDaysMc, + getArchiveEvents: getArchiveEvents, + getArchiveHours: getArchiveHours, + getArchiveHoursMc: getArchiveHoursMc, + getArchiveHoursMcEx: getArchiveHoursMcEx, + getBatteryStatus: getBatteryStatus, + getChannelsStatus: getChannelsStatus, + getChannelsTypes: getChannelsTypes, + getExAbsArchiveDaysMc: getExAbsArchiveDaysMc, + getExAbsArchiveHoursMc: getExAbsArchiveHoursMc, + getLmicInfo: getLmicInfo, + getParameter: getParameter, + hour: hour, + hourMc: hourMc, + hourMcEx: hourMcEx, + lastEvent: lastEvent, + newEvent: newEvent, + setParameter: setParameter, + setTime2000: setTime2000, + softRestart: softRestart, + status: status, + time2000: time2000, + updateRun: updateRun, + usWaterMeterBatteryStatus: usWaterMeterBatteryStatus, + usWaterMeterCommand: usWaterMeterCommand, + verifyImage: verifyImage, + writeImage: writeImage + }); + + var uplinkNames = invertObject(uplinkIds); + + const id$z = correctTime2000; + uplinkNames[correctTime2000]; + const COMMAND_BODY_SIZE$b = 1; + const fromBytes$A = data => { + if (data.length !== COMMAND_BODY_SIZE$b) { + throw new Error(`Wrong buffer size: ${data.length}.`); + } + const buffer = new BinaryBuffer(data, false); + const parameters = { + status: buffer.getUint8() + }; + if (!buffer.isEmpty) { + throw new Error('BinaryBuffer is not empty.'); + } + return parameters; + }; + const toBytes$A = parameters => { + const { + status + } = parameters; + const buffer = new BinaryBuffer(COMMAND_BODY_SIZE$b, false); + buffer.setUint8(status); + return toBytes$11(id$z, buffer.data); + }; + + const id$y = current; + uplinkNames[current]; + const COMMAND_BODY_MAX_SIZE$e = 4; + const fromBytes$z = data => { + if (data.length > COMMAND_BODY_MAX_SIZE$e) { + throw new Error(`Wrong buffer size: ${data.length}.`); + } + const buffer = new CommandBinaryBuffer(data); + return buffer.getLegacyCounter(); + }; + const toBytes$z = parameters => { + const buffer = new CommandBinaryBuffer(COMMAND_BODY_MAX_SIZE$e); + buffer.setLegacyCounter(parameters); + return toBytes$11(id$y, buffer.data); + }; + + const id$x = currentMc; + uplinkNames[currentMc]; + const COMMAND_BODY_MAX_SIZE$d = 37; + const fromBytes$y = data => { + if (data.length > COMMAND_BODY_MAX_SIZE$d) { + throw new Error(`Wrong buffer size: ${data.length}.`); + } + const parameters = { + channelList: [] + }; + const buffer = new CommandBinaryBuffer(data); + const channelList = buffer.getChannels(); + parameters.channelList = channelList.map(channelIndex => ({ + value: buffer.getExtendedValue(), + index: channelIndex + })); + return parameters; + }; + const toBytes$y = parameters => { + const buffer = new CommandBinaryBuffer(COMMAND_BODY_MAX_SIZE$d); + const { + channelList + } = parameters; + buffer.setChannels(channelList); + channelList.forEach(_ref => { + let { + value + } = _ref; + buffer.setExtendedValue(value); + }); + return toBytes$11(id$x, buffer.getBytesToOffset()); + }; + + const id$w = day; + uplinkNames[day]; + const COMMAND_BODY_SIZE$a = 6; + const fromBytes$x = data => { + const buffer = new CommandBinaryBuffer(data); + const date = buffer.getDate(); + const byte = buffer.getUint8(); + const { + hour + } = buffer.getHours(byte); + const isMagneticInfluence = CommandBinaryBuffer.getMagneticInfluenceBit(byte); + const value = buffer.getLegacyCounterValue(); + date.setUTCHours(hour); + return { + value, + isMagneticInfluence, + startTime2000: getTime2000FromDate(date) + }; + }; + const toBytes$x = parameters => { + const buffer = new CommandBinaryBuffer(COMMAND_BODY_SIZE$a); + const { + value, + isMagneticInfluence, + startTime2000 + } = parameters; + const date = getDateFromTime2000(startTime2000); + const hour = date.getUTCHours(); + buffer.setDate(date); + buffer.setHours(hour, 1); + buffer.seek(buffer.offset - 1); + const byte = buffer.getUint8(); + buffer.seek(buffer.offset - 1); + buffer.setUint8(CommandBinaryBuffer.setMagneticInfluenceBit(byte, isMagneticInfluence)); + buffer.setLegacyCounterValue(value); + return toBytes$11(id$w, buffer.getBytesToOffset()); + }; + + const id$v = dayMc; + uplinkNames[dayMc]; + const COMMAND_BODY_MAX_SIZE$c = 32; + const fromBytes$w = data => { + if (data.length > COMMAND_BODY_MAX_SIZE$c) { + throw new Error(`Wrong buffer size: ${data.length}.`); + } + const buffer = new CommandBinaryBuffer(data); + const date = buffer.getDate(); + const channels = buffer.getChannels(); + const channelList = channels.map(channelIndex => ({ + value: buffer.getExtendedValue(), + index: channelIndex + })); + return { + startTime2000: getTime2000FromDate(date), + channelList + }; + }; + const toBytes$w = parameters => { + const buffer = new CommandBinaryBuffer(COMMAND_BODY_MAX_SIZE$c); + const { + channelList, + startTime2000 + } = parameters; + buffer.setDate(startTime2000); + buffer.setChannels(channelList); + channelList.forEach(_ref => { + let { + value + } = _ref; + buffer.setExtendedValue(value); + }); + return toBytes$11(id$v, buffer.getBytesToOffset()); + }; + + const id$u = exAbsCurrentMc; + uplinkNames[exAbsCurrentMc]; + const COMMAND_BODY_MAX_SIZE$b = 87; + const fromBytes$v = data => { + const buffer = new CommandBinaryBuffer(data); + return { + channelList: buffer.getChannelsWithAbsoluteValues() + }; + }; + const toBytes$v = parameters => { + const buffer = new CommandBinaryBuffer(COMMAND_BODY_MAX_SIZE$b); + buffer.setChannelsWithAbsoluteValues(parameters.channelList); + return toBytes$11(id$u, buffer.getBytesToOffset()); + }; + + const id$t = exAbsDayMc; + uplinkNames[exAbsDayMc]; + const COMMAND_BODY_MAX_SIZE$a = 89; + const fromBytes$u = data => { + if (data.length > COMMAND_BODY_MAX_SIZE$a) { + throw new Error(`Wrong buffer size: ${data.length}.`); + } + const buffer = new CommandBinaryBuffer(data); + const date = buffer.getDate(); + const channelList = buffer.getChannelsWithAbsoluteValues(); + return { + startTime2000: getTime2000FromDate(date), + channelList + }; + }; + const toBytes$u = parameters => { + const buffer = new CommandBinaryBuffer(COMMAND_BODY_MAX_SIZE$a); + const { + startTime2000, + channelList + } = parameters; + buffer.setDate(startTime2000); + buffer.setChannelsWithAbsoluteValues(channelList); + return toBytes$11(id$t, buffer.getBytesToOffset()); + }; + + const id$s = exAbsHourMc; + uplinkNames[exAbsHourMc]; + const COMMAND_BODY_MAX_SIZE$9 = 168; + const fromBytes$t = data => { + if (data.length > COMMAND_BODY_MAX_SIZE$9) { + throw new Error(`Wrong buffer size: ${data.length}.`); + } + const buffer = new CommandBinaryBuffer(data); + const date = buffer.getDate(); + const { + hour, + hours + } = buffer.getHours(); + const channelList = buffer.getChannelsAbsoluteValuesWithHourDiff(hours); + date.setUTCHours(hour); + return { + startTime2000: getTime2000FromDate(date), + hours, + channelList + }; + }; + const toBytes$t = parameters => { + const buffer = new CommandBinaryBuffer(COMMAND_BODY_MAX_SIZE$9); + const { + startTime2000, + hours, + channelList + } = parameters; + const date = getDateFromTime2000(startTime2000); + const hour = date.getUTCHours(); + buffer.setDate(startTime2000); + buffer.setHours(hour, hours); + buffer.setChannelsAbsoluteValuesWithHourDiff(channelList); + return toBytes$11(id$s, buffer.getBytesToOffset()); + }; + + const id$r = getArchiveDays; + uplinkNames[getArchiveDays]; + const COMMAND_BODY_MIN_SIZE$1 = 2; + const DAY_COUNTER_SIZE = 4; + const fromBytes$s = data => { + const buffer = new CommandBinaryBuffer(data); + const date = buffer.getDate(); + const dayList = []; + while (buffer.offset < buffer.data.length) { + dayList.push(buffer.getLegacyCounter(undefined, true)); + } + return { + startTime2000: getTime2000FromDate(date), + dayList + }; + }; + const toBytes$s = parameters => { + const { + startTime2000, + dayList + } = parameters; + const buffer = new CommandBinaryBuffer(COMMAND_BODY_MIN_SIZE$1 + dayList.length * DAY_COUNTER_SIZE); + buffer.setDate(startTime2000); + dayList.forEach(dayCounter => buffer.setLegacyCounter(dayCounter, undefined, true)); + return toBytes$11(id$r, buffer.getBytesToOffset()); + }; + + const id$q = getArchiveDaysMc; + uplinkNames[getArchiveDaysMc]; + const COMMAND_BODY_MAX_SIZE$8 = 255; + const fromBytes$r = data => { + const buffer = new CommandBinaryBuffer(data); + const date = buffer.getDate(); + const channels = buffer.getChannels(); + const days = buffer.getUint8(); + const channelList = []; + channels.forEach(channelIndex => { + const dayList = []; + channelList.push({ + dayList, + index: channelIndex + }); + for (let day = 0; day < days; ++day) { + const value = buffer.getExtendedValue(); + dayList.push(value === EMPTY_VALUE ? 0 : value); + } + }); + return { + startTime2000: getTime2000FromDate(date), + days, + channelList + }; + }; + const toBytes$r = parameters => { + const buffer = new CommandBinaryBuffer(COMMAND_BODY_MAX_SIZE$8); + const { + startTime2000, + days, + channelList + } = parameters; + buffer.setDate(startTime2000); + buffer.setChannels(channelList); + buffer.setUint8(days); + channelList.forEach(_ref => { + let { + dayList + } = _ref; + dayList.forEach(value => { + buffer.setExtendedValue(value === 0 ? EMPTY_VALUE : value); + }); + }); + return toBytes$11(id$q, buffer.getBytesToOffset()); + }; + + const MAGNET_ON = 1; + const MAGNET_OFF = 2; + const ACTIVATE = 3; + const DEACTIVATE = 4; + const BATTERY_ALARM = 5; + const CAN_OFF = 6; + const INSERT = 7; + const REMOVE = 8; + const COUNTER_OVER = 9; + const SET_TIME = 10; + const ACTIVATE_MTX = 11; + const CONNECT = 12; + const DISCONNECT = 13; + const DEPASS_DONE = 14; + const OPTOLOW = 15; + const OPTOFLASH = 16; + const MTX = 17; + const JOIN_ACCEPT = 18; + const WATER_EVENT = 19; + const WATER_NO_RESPONSE = 20; + const OPTOSENSOR_ERROR = 21; + const BINARY_SENSOR_ON = 22; + const BINARY_SENSOR_OFF = 23; + const TEMPERATURE_SENSOR_HYSTERESIS = 24; + const TEMPERATURE_SENSOR_LOW_TEMPERATURE = 25; + const TEMPERATURE_SENSOR_HIGH_TEMPERATURE = 26; + + var events = /*#__PURE__*/Object.freeze({ + __proto__: null, + ACTIVATE: ACTIVATE, + ACTIVATE_MTX: ACTIVATE_MTX, + BATTERY_ALARM: BATTERY_ALARM, + BINARY_SENSOR_OFF: BINARY_SENSOR_OFF, + BINARY_SENSOR_ON: BINARY_SENSOR_ON, + CAN_OFF: CAN_OFF, + CONNECT: CONNECT, + COUNTER_OVER: COUNTER_OVER, + DEACTIVATE: DEACTIVATE, + DEPASS_DONE: DEPASS_DONE, + DISCONNECT: DISCONNECT, + INSERT: INSERT, + JOIN_ACCEPT: JOIN_ACCEPT, + MAGNET_OFF: MAGNET_OFF, + MAGNET_ON: MAGNET_ON, + MTX: MTX, + OPTOFLASH: OPTOFLASH, + OPTOLOW: OPTOLOW, + OPTOSENSOR_ERROR: OPTOSENSOR_ERROR, + REMOVE: REMOVE, + SET_TIME: SET_TIME, + TEMPERATURE_SENSOR_HIGH_TEMPERATURE: TEMPERATURE_SENSOR_HIGH_TEMPERATURE, + TEMPERATURE_SENSOR_HYSTERESIS: TEMPERATURE_SENSOR_HYSTERESIS, + TEMPERATURE_SENSOR_LOW_TEMPERATURE: TEMPERATURE_SENSOR_LOW_TEMPERATURE, + WATER_EVENT: WATER_EVENT, + WATER_NO_RESPONSE: WATER_NO_RESPONSE + }); + + var eventNames = invertObject(events); + + const id$p = getArchiveEvents; + uplinkNames[getArchiveEvents]; + const COMMAND_BODY_MIN_SIZE = 4 + 1 + 1; + const getEvent = buffer => { + const time2000 = buffer.getTime(); + const eventId = buffer.getUint8(); + const sequenceNumber = buffer.getUint8(); + return { + time2000, + id: eventId, + name: eventNames[eventId], + sequenceNumber + }; + }; + const setEvent = (buffer, event) => { + buffer.setTime(event.time2000); + buffer.setUint8(event.id); + buffer.setUint8(event.sequenceNumber); + }; + const fromBytes$q = data => { + const buffer = new CommandBinaryBuffer(data); + const eventList = []; + while (buffer.bytesLeft > 0) { + eventList.push(getEvent(buffer)); + } + return { + eventList + }; + }; + function toBytes$q(parameters) { + const { + eventList + } = parameters; + const buffer = new CommandBinaryBuffer(eventList.length * COMMAND_BODY_MIN_SIZE); + eventList.forEach(event => setEvent(buffer, event)); + return toBytes$11(id$p, buffer.data); + } + + const id$o = getArchiveHours; + uplinkNames[getArchiveHours]; + const fromBytes$p = data => { + const buffer = new CommandBinaryBuffer(data); + return buffer.getLegacyHourCounterWithDiff(true); + }; + const toBytes$p = parameters => { + const buffer = new CommandBinaryBuffer(CommandBinaryBuffer.getLegacyHourCounterSize(parameters)); + buffer.setLegacyHourCounterWithDiff(parameters, true); + return toBytes$11(id$o, buffer.getBytesToOffset()); + }; + + const id$n = getArchiveHoursMc; + uplinkNames[getArchiveHoursMc]; + const COMMAND_BODY_MAX_SIZE$7 = 164; + const fromBytes$o = data => { + if (data.length > COMMAND_BODY_MAX_SIZE$7) { + throw new Error(`Wrong buffer size: ${data.length}.`); + } + const buffer = new CommandBinaryBuffer(data); + return buffer.getChannelsValuesWithHourDiff(true); + }; + const toBytes$o = parameters => { + const buffer = new CommandBinaryBuffer(COMMAND_BODY_MAX_SIZE$7); + const { + hours, + startTime2000, + channelList + } = parameters; + buffer.setChannelsValuesWithHourDiff(hours, startTime2000, channelList, true); + return toBytes$11(id$n, buffer.getBytesToOffset()); + }; + + const id$m = getArchiveHoursMcEx; + uplinkNames[getArchiveHoursMcEx]; + const COMMAND_BODY_MAX_SIZE$6 = 255; + const fromBytes$n = data => { + if (data.length > COMMAND_BODY_MAX_SIZE$6) { + throw new Error(`Wrong buffer size: ${data.length}.`); + } + const buffer = new CommandBinaryBuffer(data); + return buffer.getChannelsValuesWithHourDiffExtended(true); + }; + const toBytes$n = parameters => { + const buffer = new CommandBinaryBuffer(COMMAND_BODY_MAX_SIZE$6); + buffer.setChannelsValuesWithHourDiffExtended(parameters, true); + return toBytes$11(id$m, buffer.getBytesToOffset()); + }; + + const id$l = getBatteryStatus; + uplinkNames[getBatteryStatus]; + const COMMAND_BODY_SIZE$9 = 11; + const fromBytes$m = data => { + const buffer = new CommandBinaryBuffer(data); + return { + voltageUnderLowLoad: buffer.getUint16(), + voltageUnderHighLoad: buffer.getUint16(), + internalResistance: buffer.getUint16(), + temperature: buffer.getUint8(), + remainingCapacity: buffer.getUint8(), + isLastDayOverconsumption: buffer.getUint8() === 1, + averageDailyOverconsumptionCounter: buffer.getUint16() + }; + }; + const toBytes$m = parameters => { + const buffer = new CommandBinaryBuffer(COMMAND_BODY_SIZE$9); + buffer.setUint16(parameters.voltageUnderLowLoad); + buffer.setUint16(parameters.voltageUnderHighLoad); + buffer.setUint16(parameters.internalResistance); + buffer.setUint8(parameters.temperature); + buffer.setUint8(parameters.remainingCapacity); + buffer.setUint8(parameters.isLastDayOverconsumption ? 1 : 0); + buffer.setUint16(parameters.averageDailyOverconsumptionCounter); + return toBytes$11(id$l, buffer.data); + }; + + var channelNames = invertObject(channelTypes); + + const id$k = getChannelsStatus; + uplinkNames[getChannelsStatus]; + const getBufferSize = channelsStatus => { + let size = 0; + for (let index = 0; index < channelsStatus.length; index++) { + size += 2; + switch (channelsStatus[index].type) { + case BINARY_SENSOR: + case TEMPERATURE_SENSOR: + size += 1; + break; + } + } + return size; + }; + const getBinarySensorStatus = buffer => ({ + state: buffer.getUint8() !== 0 + }); + const setBinarySensorStatus = (status, buffer) => { + buffer.setUint8(status.state ? 1 : 0); + }; + const getTemperatureSensorStatus = buffer => ({ + temperature: buffer.getInt8(), + time2000: buffer.getTime() + }); + const setTemperatureSensorStatus = (status, buffer) => { + buffer.setInt8(status.temperature); + buffer.setTime(status.time2000); + }; + const fromBytes$l = data => { + const buffer = new CommandBinaryBuffer(data); + const result = []; + while (buffer.bytesLeft !== 0) { + const type = buffer.getUint8(); + const channelStatus = { + type, + typeName: channelNames[type], + channel: buffer.getChannelValue() + }; + switch (channelStatus.type) { + case BINARY_SENSOR: + channelStatus.status = getBinarySensorStatus(buffer); + break; + case TEMPERATURE_SENSOR: + channelStatus.status = getTemperatureSensorStatus(buffer); + break; + default: + return result; + } + result.push(channelStatus); + } + return result; + }; + const toBytes$l = channelsStatus => { + const buffer = new CommandBinaryBuffer(getBufferSize(channelsStatus)); + for (let index = 0; index < channelsStatus.length; index++) { + const { + type, + channel, + status + } = channelsStatus[index]; + buffer.setUint8(type); + buffer.setChannelValue(channel); + switch (type) { + case BINARY_SENSOR: + setBinarySensorStatus(status, buffer); + break; + case TEMPERATURE_SENSOR: + setTemperatureSensorStatus(status, buffer); + break; + } + } + return toBytes$11(id$k, buffer.data); + }; + + const id$j = getChannelsTypes; + uplinkNames[getChannelsTypes]; + const fromBytes$k = data => ({ + channels: data.map(type => ({ + type, + typeName: channelNames[type] + })) + }); + const toBytes$k = _ref => { + let { + channels + } = _ref; + return toBytes$11(id$j, channels.map(channel => channel.type)); + }; + + const id$i = getExAbsArchiveDaysMc; + uplinkNames[getExAbsArchiveDaysMc]; + const COMMAND_BODY_MAX_SIZE$5 = 255; + const fromBytes$j = data => { + const buffer = new CommandBinaryBuffer(data); + const date = buffer.getDate(); + const channels = buffer.getChannels(); + const days = buffer.getUint8(); + const channelList = []; + channels.forEach(channelIndex => { + const dayList = []; + const pulseCoefficient = buffer.getPulseCoefficient(); + channelList.push({ + pulseCoefficient, + dayList, + index: channelIndex + }); + for (let day = 0; day < days; ++day) { + const value = buffer.getExtendedValue(); + dayList.push(value === EMPTY_VALUE ? 0 : value); + } + }); + return { + channelList, + days, + startTime2000: getTime2000FromDate(date) + }; + }; + const toBytes$j = parameters => { + const buffer = new CommandBinaryBuffer(COMMAND_BODY_MAX_SIZE$5); + const { + channelList, + startTime2000, + days + } = parameters; + buffer.setDate(startTime2000); + buffer.setChannels(channelList); + buffer.setUint8(days); + channelList.forEach(_ref => { + let { + pulseCoefficient, + dayList + } = _ref; + buffer.setPulseCoefficient(pulseCoefficient); + dayList.forEach(value => { + buffer.setExtendedValue(value === 0 ? EMPTY_VALUE : value); + }); + }); + return toBytes$11(id$i, buffer.getBytesToOffset()); + }; + + const id$h = getExAbsArchiveHoursMc; + uplinkNames[getExAbsArchiveHoursMc]; + const COMMAND_BODY_MAX_SIZE$4 = 164; + const fromBytes$i = data => { + const buffer = new CommandBinaryBuffer(data); + return buffer.getChannelsValuesWithHourDiff(true); + }; + const toBytes$i = parameters => { + const buffer = new CommandBinaryBuffer(COMMAND_BODY_MAX_SIZE$4); + buffer.setChannelsValuesWithHourDiff(parameters.hours, parameters.startTime2000, parameters.channelList, true); + return toBytes$11(id$h, buffer.getBytesToOffset()); + }; + + const id$g = getLmicInfo; + uplinkNames[getLmicInfo]; + const COMMAND_BODY_SIZE$8 = 2; + const lmicCapabilitiesBitMask = { + isMulticastSupported: 1 << 0, + isFragmentedDataSupported: 1 << 1 + }; + const fromBytes$h = data => { + if (data.length !== COMMAND_BODY_SIZE$8) { + throw new Error(`Wrong buffer size: ${data.length}.`); + } + const buffer = new BinaryBuffer(data); + const capabilities = toObject(lmicCapabilitiesBitMask, buffer.getUint8()); + const version = buffer.getUint8(); + if (!buffer.isEmpty) { + throw new Error('BinaryBuffer is not empty.'); + } + return { + capabilities, + version + }; + }; + const toBytes$h = parameters => { + const { + capabilities, + version + } = parameters; + const buffer = new BinaryBuffer(COMMAND_BODY_SIZE$8); + buffer.setUint8(fromObject(lmicCapabilitiesBitMask, capabilities)); + buffer.setUint8(version); + return toBytes$11(id$g, buffer.data); + }; + + const id$f = getParameter; + uplinkNames[getParameter]; + const fromBytes$g = data => { + const buffer = new CommandBinaryBuffer(data); + return buffer.getResponseParameter(); + }; + const toBytes$g = parameters => { + const buffer = new CommandBinaryBuffer(getResponseParameterSize(parameters)); + buffer.setResponseParameter(parameters); + return toBytes$11(id$f, buffer.data); + }; + + const id$e = hour; + uplinkNames[hour]; + const fromBytes$f = data => { + const buffer = new CommandBinaryBuffer(data); + return buffer.getLegacyHourCounterWithDiff(); + }; + const toBytes$f = parameters => { + const buffer = new CommandBinaryBuffer(CommandBinaryBuffer.getLegacyHourCounterSize(parameters)); + buffer.setLegacyHourCounterWithDiff(parameters); + return toBytes$11(id$e, buffer.getBytesToOffset()); + }; + + const id$d = hourMc; + uplinkNames[hourMc]; + const COMMAND_BODY_MAX_SIZE$3 = 164; + const fromBytes$e = data => { + if (data.length > COMMAND_BODY_MAX_SIZE$3) { + throw new Error(`Wrong buffer size: ${data.length}.`); + } + const buffer = new CommandBinaryBuffer(data); + return buffer.getChannelsValuesWithHourDiff(); + }; + const toBytes$e = parameters => { + const buffer = new CommandBinaryBuffer(COMMAND_BODY_MAX_SIZE$3); + const { + startTime2000, + hours, + channelList + } = parameters; + buffer.setChannelsValuesWithHourDiff(hours, startTime2000, channelList); + return toBytes$11(id$d, buffer.getBytesToOffset()); + }; + + const id$c = hourMcEx; + uplinkNames[hourMcEx]; + const COMMAND_BODY_MAX_SIZE$2 = 255; + const fromBytes$d = data => { + if (data.length > COMMAND_BODY_MAX_SIZE$2) { + throw new Error(`Wrong buffer size: ${data.length}.`); + } + const buffer = new CommandBinaryBuffer(data); + return buffer.getChannelsValuesWithHourDiffExtended(); + }; + const toBytes$d = parameters => { + const buffer = new CommandBinaryBuffer(COMMAND_BODY_MAX_SIZE$2); + buffer.setChannelsValuesWithHourDiffExtended(parameters); + return toBytes$11(id$c, buffer.getBytesToOffset()); + }; + + const id$b = lastEvent; + uplinkNames[lastEvent]; + const fromBytes$c = (data, config) => { + if (!config.hardwareType) { + throw new Error('hardwareType in config is mandatory'); + } + const buffer = new CommandBinaryBuffer(data); + const sequenceNumber = buffer.getUint8(); + const status = buffer.getEventStatus(config.hardwareType); + return { + sequenceNumber, + status + }; + }; + const toBytes$c = (parameters, config) => { + if (!config.hardwareType) { + throw new Error('hardwareType in config is mandatory'); + } + const buffer = new CommandBinaryBuffer(1 + getEventStatusSize(config.hardwareType)); + const { + sequenceNumber, + status + } = parameters; + buffer.setUint8(sequenceNumber); + buffer.setEventStatus(config.hardwareType, status); + return toBytes$11(id$b, buffer.data); + }; + + const id$a = newEvent; + uplinkNames[newEvent]; + const COMMAND_BODY_MAX_SIZE$1 = 14; + const MTX_ADDRESS_SIZE = 8; + const getVoltage = buffer => buffer.getUint16(); + const setVoltage = (buffer, value) => buffer.setUint16(value); + const getDeviceId = buffer => getHexFromBytes(buffer.getBytes(MTX_ADDRESS_SIZE)); + const setDeviceId = (buffer, value) => { + getBytesFromHex(value).forEach(byte => buffer.setUint8(byte)); + }; + const fromBytes$b = data => { + if (data.length > COMMAND_BODY_MAX_SIZE$1) { + throw new Error(`Wrong buffer size: ${data.length}.`); + } + const buffer = new CommandBinaryBuffer(data); + const eventId = buffer.getUint8(); + const eventName = eventNames[eventId]; + const sequenceNumber = buffer.getUint8(); + let eventData; + switch (eventId) { + case MAGNET_ON: + case MAGNET_OFF: + case ACTIVATE: + case DEACTIVATE: + case CAN_OFF: + case INSERT: + case REMOVE: + case COUNTER_OVER: + case OPTOLOW: + case OPTOFLASH: + case JOIN_ACCEPT: + eventData = { + time2000: buffer.getTime() + }; + break; + case BATTERY_ALARM: + eventData = { + voltage: getVoltage(buffer) + }; + break; + case ACTIVATE_MTX: + eventData = { + time2000: buffer.getTime(), + deviceId: getDeviceId(buffer) + }; + break; + case CONNECT: + case DISCONNECT: + eventData = { + channel: buffer.getUint8() + 1, + value: buffer.getExtendedValue() + }; + break; + case MTX: + eventData = { + status: buffer.getEventStatus(MTXLORA) + }; + break; + case BINARY_SENSOR_ON: + case BINARY_SENSOR_OFF: + eventData = { + time2000: buffer.getTime(), + channel: buffer.getChannelValue() + }; + break; + case TEMPERATURE_SENSOR_HYSTERESIS: + case TEMPERATURE_SENSOR_LOW_TEMPERATURE: + case TEMPERATURE_SENSOR_HIGH_TEMPERATURE: + eventData = { + time2000: buffer.getTime(), + channel: buffer.getChannelValue(), + temperature: buffer.getInt8() + }; + break; + default: + throw new Error(`Event ${id$a} is not supported`); + } + return { + id: eventId, + name: eventName, + sequenceNumber, + data: eventData + }; + }; + const toBytes$b = parameters => { + const buffer = new CommandBinaryBuffer(COMMAND_BODY_MAX_SIZE$1); + const { + id: eventId, + sequenceNumber, + data + } = parameters; + buffer.setUint8(eventId); + buffer.setUint8(sequenceNumber); + switch (eventId) { + case MAGNET_ON: + case MAGNET_OFF: + case ACTIVATE: + case DEACTIVATE: + case CAN_OFF: + case INSERT: + case REMOVE: + case COUNTER_OVER: + case OPTOLOW: + case OPTOFLASH: + case JOIN_ACCEPT: + buffer.setTime(data.time2000); + break; + case BATTERY_ALARM: + setVoltage(buffer, data.voltage); + break; + case ACTIVATE_MTX: + buffer.setTime(data.time2000); + setDeviceId(buffer, data.deviceId); + break; + case CONNECT: + case DISCONNECT: + buffer.setUint8(data.channel - 1); + buffer.setExtendedValue(data.value); + break; + case MTX: + buffer.setEventStatus(MTXLORA, data.status); + break; + case BINARY_SENSOR_ON: + case BINARY_SENSOR_OFF: + buffer.setTime(data.time2000); + buffer.setChannelValue(data.channel); + break; + case TEMPERATURE_SENSOR_HYSTERESIS: + case TEMPERATURE_SENSOR_LOW_TEMPERATURE: + case TEMPERATURE_SENSOR_HIGH_TEMPERATURE: + buffer.setTime(data.time2000); + buffer.setChannelValue(data.channel); + buffer.setInt8(data.temperature); + break; + default: + throw new Error(`Event ${id$a} is not supported`); + } + return toBytes$11(id$a, buffer.getBytesToOffset()); + }; + + const id$9 = setParameter; + uplinkNames[setParameter]; + const COMMAND_BODY_SIZE$7 = 2; + const fromBytes$a = data => { + if (data.length !== COMMAND_BODY_SIZE$7) { + throw new Error(`Wrong buffer size: ${data.length}.`); + } + const buffer = new CommandBinaryBuffer(data); + const parameters = { + id: buffer.getUint8(), + status: buffer.getUint8() + }; + if (!buffer.isEmpty) { + throw new Error('BinaryBuffer is not empty.'); + } + return parameters; + }; + const toBytes$a = parameters => { + const buffer = new CommandBinaryBuffer(COMMAND_BODY_SIZE$7); + buffer.setUint8(parameters.id); + buffer.setUint8(parameters.status); + return toBytes$11(id$9, buffer.data); + }; + + const id$8 = setTime2000; + uplinkNames[setTime2000]; + const COMMAND_BODY_SIZE$6 = 1; + const fromBytes$9 = data => { + if (data.length !== COMMAND_BODY_SIZE$6) { + throw new Error(`Wrong buffer size: ${data.length}.`); + } + const buffer = new BinaryBuffer(data, false); + const parameters = { + status: buffer.getUint8() + }; + if (!buffer.isEmpty) { + throw new Error('BinaryBuffer is not empty.'); + } + return parameters; + }; + const toBytes$9 = parameters => { + const { + status + } = parameters; + const buffer = new BinaryBuffer(COMMAND_BODY_SIZE$6, false); + buffer.setUint8(status); + return toBytes$11(id$8, buffer.data); + }; + + const id$7 = softRestart; + uplinkNames[softRestart]; + const COMMAND_BODY_SIZE$5 = 0; + const fromBytes$8 = data => { + if (data.length !== COMMAND_BODY_SIZE$5) { + throw new Error(`Wrong buffer size: ${data.length}.`); + } + return {}; + }; + const toBytes$8 = () => toBytes$11(id$7); + + const id$6 = status; + uplinkNames[status]; + const COMMAND_BODY_MAX_SIZE = 20; + const UNKNOWN_BATTERY_RESISTANCE = 65535; + const UNKNOWN_BATTERY_CAPACITY = 255; + const fromBytes$7 = bytes => { + const buffer = new CommandBinaryBuffer(bytes); + const software = { + type: buffer.getUint8(), + version: buffer.getUint8() + }; + const hardware = { + type: buffer.getUint8(), + version: buffer.getUint8() + }; + let data; + switch (hardware.type) { + case GASI1: + case GASI2: + case GASI3: + case NOVATOR: + case IMP2EU: + case IMP4EU: + case IMP2AS: + case IMP2IN: + case IMP4IN: + case GASIC: + case NBIOT: + { + const statusData = { + batteryVoltage: buffer.getBatteryVoltage(), + batteryInternalResistance: buffer.getUint16(), + temperature: buffer.getUint8(), + remainingBatteryCapacity: buffer.getUint8(), + lastEventSequenceNumber: buffer.getUint8() + }; + if (statusData.batteryInternalResistance === UNKNOWN_BATTERY_RESISTANCE) { + statusData.batteryInternalResistance = undefined; + } + if (statusData.remainingBatteryCapacity === UNKNOWN_BATTERY_CAPACITY) { + statusData.remainingBatteryCapacity = undefined; + } else if (statusData.remainingBatteryCapacity !== undefined) { + statusData.remainingBatteryCapacity = roundNumber(statusData.remainingBatteryCapacity * 100 / (UNKNOWN_BATTERY_CAPACITY - 1), 1); + } + if (!buffer.isEmpty) { + statusData.downlinkQuality = buffer.getUint8(); + } + data = statusData; + } + break; + case MTXLORA: + data = { + time2000: buffer.getUint32(), + resetReason: buffer.getUint8(), + rssiLastDownlinkFrame: buffer.getUint8(), + snrLastDownlinkFrame: buffer.getUint8(), + downlinkRequestsNumber: buffer.getUint8(), + downlinkFragmentsNumber: buffer.getUint8(), + uplinkResponsesNumber: buffer.getUint8(), + uplinkFragmentsNumber: buffer.getUint8(), + signalMarginToGateway: buffer.getUint8(), + signalMarginFromGateway: buffer.getUint8(), + detectedGatewaysNumber: buffer.getUint8(), + gatewayDownlinkErrorRate: buffer.getUint8(), + lastEventSequenceNumber: buffer.getUint8() + }; + break; + case ELIMP: + default: + throw new Error(`${id$6}: hardware type ${hardware.type} is not supported`); + } + return { + software, + hardware, + data + }; + }; + const toBytes$7 = parameters => { + const { + software, + hardware, + data + } = parameters; + const buffer = new CommandBinaryBuffer(COMMAND_BODY_MAX_SIZE); + buffer.setUint8(software.type); + buffer.setUint8(software.version); + buffer.setUint8(hardware.type); + buffer.setUint8(hardware.version); + switch (hardware.type) { + case GASI1: + case GASI2: + case GASI3: + case NOVATOR: + case IMP2EU: + case IMP4EU: + case IMP2AS: + case IMP2IN: + case IMP4IN: + case GASIC: + { + const statusData = data; + buffer.setBatteryVoltage(statusData.batteryVoltage); + if (statusData.batteryInternalResistance === undefined) { + buffer.setUint16(UNKNOWN_BATTERY_RESISTANCE); + } else { + buffer.setUint16(statusData.batteryInternalResistance); + } + buffer.setUint8(statusData.temperature); + if (statusData.remainingBatteryCapacity === undefined) { + buffer.setUint8(UNKNOWN_BATTERY_CAPACITY); + } else { + buffer.setUint8(roundNumber((UNKNOWN_BATTERY_CAPACITY - 1) * (statusData.remainingBatteryCapacity / 100), 0)); + } + buffer.setUint8(statusData.lastEventSequenceNumber); + if ('downlinkQuality' in statusData) { + buffer.setUint8(statusData.downlinkQuality); + } + } + break; + case MTXLORA: + { + const statusData = data; + buffer.setUint32(statusData.time2000); + buffer.setUint8(statusData.resetReason); + buffer.setUint8(statusData.rssiLastDownlinkFrame); + buffer.setUint8(statusData.snrLastDownlinkFrame); + buffer.setUint8(statusData.downlinkRequestsNumber); + buffer.setUint8(statusData.downlinkFragmentsNumber); + buffer.setUint8(statusData.uplinkResponsesNumber); + buffer.setUint8(statusData.uplinkFragmentsNumber); + buffer.setUint8(statusData.signalMarginToGateway); + buffer.setUint8(statusData.signalMarginFromGateway); + buffer.setUint8(statusData.detectedGatewaysNumber); + buffer.setUint8(statusData.gatewayDownlinkErrorRate); + buffer.setUint8(statusData.lastEventSequenceNumber); + } + break; + case ELIMP: + default: + throw new Error(`${id$6}: hardware type ${hardware.type} is not supported`); + } + return toBytes$11(id$6, buffer.getBytesToOffset()); + }; + + const id$5 = time2000; + uplinkNames[time2000]; + const COMMAND_BODY_SIZE$4 = 5; + const fromBytes$6 = data => { + if (data.length !== COMMAND_BODY_SIZE$4) { + throw new Error(`Wrong buffer size: ${data.length}.`); + } + const buffer = new CommandBinaryBuffer(data); + const parameters = { + sequenceNumber: buffer.getUint8(), + time2000: buffer.getTime() + }; + if (!buffer.isEmpty) { + throw new Error('BinaryBuffer is not empty.'); + } + return parameters; + }; + function toBytes$6(parameters) { + const { + sequenceNumber, + time2000 + } = parameters; + const buffer = new CommandBinaryBuffer(COMMAND_BODY_SIZE$4); + buffer.setUint8(sequenceNumber); + buffer.setTime(time2000); + return toBytes$11(id$5, buffer.data); + } + + const id$4 = updateRun; + uplinkNames[updateRun]; + const COMMAND_BODY_SIZE$3 = 0; + const fromBytes$5 = data => { + if (data.length !== COMMAND_BODY_SIZE$3) { + throw new Error(`Wrong buffer size: ${data.length}.`); + } + return {}; + }; + const toBytes$5 = () => toBytes$11(id$4); + + const id$3 = usWaterMeterBatteryStatus; + uplinkNames[usWaterMeterBatteryStatus]; + const COMMAND_BODY_SIZE$2 = 7; + const fromBytes$4 = data => { + const buffer = new CommandBinaryBuffer(data); + return { + voltage: buffer.getBatteryVoltage(), + internalResistance: buffer.getUint16(), + lastDepassivationTime: buffer.getUint16() + }; + }; + const toBytes$4 = parameters => { + const buffer = new CommandBinaryBuffer(COMMAND_BODY_SIZE$2); + buffer.setBatteryVoltage(parameters.voltage); + buffer.setUint16(parameters.internalResistance); + buffer.setUint16(parameters.lastDepassivationTime); + return toBytes$11(id$3, buffer.data); + }; + + const id$2 = usWaterMeterCommand; + uplinkNames[usWaterMeterCommand]; + const fromBytes$3 = data => { + const buffer = new CommandBinaryBuffer(data); + const length = buffer.getUint8(); + return { + length, + data: data.slice(1) + }; + }; + const toBytes$3 = parameters => { + const { + data, + length + } = parameters; + const buffer = new CommandBinaryBuffer(length); + buffer.setUint8(length); + buffer.setBytes(data); + return toBytes$11(id$2, buffer.data); + }; + + const id$1 = verifyImage; + uplinkNames[verifyImage]; + const COMMAND_BODY_SIZE$1 = 1; + const fromBytes$2 = data => { + if (data.length !== COMMAND_BODY_SIZE$1) { + throw new Error(`Wrong buffer size: ${data.length}.`); + } + const buffer = new CommandBinaryBuffer(data); + return { + status: buffer.getUint8() + }; + }; + const toBytes$2 = parameters => { + const buffer = new CommandBinaryBuffer(COMMAND_BODY_SIZE$1); + buffer.setUint8(parameters.status); + return toBytes$11(id$1, buffer.data); + }; + + const id = writeImage; + uplinkNames[writeImage]; + const COMMAND_BODY_SIZE = 5; + const fromBytes$1 = data => { + const buffer = new CommandBinaryBuffer(data); + return { + offset: buffer.getUint32(), + status: buffer.getUint8() + }; + }; + const toBytes$1 = parameters => { + const buffer = new CommandBinaryBuffer(COMMAND_BODY_SIZE); + buffer.setUint32(parameters.offset); + buffer.setUint8(parameters.status); + return toBytes$11(id, buffer.data); + }; + + const toBytesMap = {}; + const fromBytesMap = {}; + const nameMap = uplinkNames; + const fromBytes = getFromBytes(fromBytesMap, nameMap); + const toBytes = getToBytes(toBytesMap); + const toMessage = getToMessage(toBytesMap); + toBytesMap[id$z] = toBytes$A; + toBytesMap[id$y] = toBytes$z; + toBytesMap[id$x] = toBytes$y; + toBytesMap[id$Z] = toBytes$; + toBytesMap[id$w] = toBytes$x; + toBytesMap[id$v] = toBytes$w; + toBytesMap[id$u] = toBytes$v; + toBytesMap[id$t] = toBytes$u; + toBytesMap[id$s] = toBytes$t; + toBytesMap[id$r] = toBytes$s; + toBytesMap[id$q] = toBytes$r; + toBytesMap[id$p] = toBytes$q; + toBytesMap[id$o] = toBytes$p; + toBytesMap[id$n] = toBytes$o; + toBytesMap[id$m] = toBytes$n; + toBytesMap[id$l] = toBytes$m; + toBytesMap[id$k] = toBytes$l; + toBytesMap[id$j] = toBytes$k; + toBytesMap[id$i] = toBytes$j; + toBytesMap[id$h] = toBytes$i; + toBytesMap[id$g] = toBytes$h; + toBytesMap[id$f] = toBytes$g; + toBytesMap[id$e] = toBytes$f; + toBytesMap[id$d] = toBytes$e; + toBytesMap[id$c] = toBytes$d; + toBytesMap[id$b] = toBytes$c; + toBytesMap[id$a] = toBytes$b; + toBytesMap[id$9] = toBytes$a; + toBytesMap[id$8] = toBytes$9; + toBytesMap[id$7] = toBytes$8; + toBytesMap[id$6] = toBytes$7; + toBytesMap[id$5] = toBytes$6; + toBytesMap[id$4] = toBytes$5; + toBytesMap[id$3] = toBytes$4; + toBytesMap[id$2] = toBytes$3; + toBytesMap[id$1] = toBytes$2; + toBytesMap[id] = toBytes$1; + fromBytesMap[id$z] = fromBytes$A; + fromBytesMap[id$y] = fromBytes$z; + fromBytesMap[id$x] = fromBytes$y; + fromBytesMap[id$Z] = fromBytes$; + fromBytesMap[id$w] = fromBytes$x; + fromBytesMap[id$v] = fromBytes$w; + fromBytesMap[id$u] = fromBytes$v; + fromBytesMap[id$t] = fromBytes$u; + fromBytesMap[id$s] = fromBytes$t; + fromBytesMap[id$r] = fromBytes$s; + fromBytesMap[id$q] = fromBytes$r; + fromBytesMap[id$p] = fromBytes$q; + fromBytesMap[id$o] = fromBytes$p; + fromBytesMap[id$n] = fromBytes$o; + fromBytesMap[id$m] = fromBytes$n; + fromBytesMap[id$l] = fromBytes$m; + fromBytesMap[id$k] = fromBytes$l; + fromBytesMap[id$j] = fromBytes$k; + fromBytesMap[id$i] = fromBytes$j; + fromBytesMap[id$h] = fromBytes$i; + fromBytesMap[id$g] = fromBytes$h; + fromBytesMap[id$f] = fromBytes$g; + fromBytesMap[id$e] = fromBytes$f; + fromBytesMap[id$d] = fromBytes$e; + fromBytesMap[id$c] = fromBytes$d; + fromBytesMap[id$b] = fromBytes$c; + fromBytesMap[id$a] = fromBytes$b; + fromBytesMap[id$9] = fromBytes$a; + fromBytesMap[id$8] = fromBytes$9; + fromBytesMap[id$7] = fromBytes$8; + fromBytesMap[id$6] = fromBytes$7; + fromBytesMap[id$5] = fromBytes$6; + fromBytesMap[id$4] = fromBytes$5; + fromBytesMap[id$3] = fromBytes$4; + fromBytesMap[id$2] = fromBytes$3; + fromBytesMap[id$1] = fromBytes$2; + fromBytesMap[id] = fromBytes$1; + + var uplink = /*#__PURE__*/Object.freeze({ + __proto__: null, + fromBytes: fromBytes, + fromBytesMap: fromBytesMap, + nameMap: nameMap, + toBytes: toBytes, + toBytesMap: toBytesMap, + toMessage: toMessage + }); + + var analogMessage = /*#__PURE__*/Object.freeze({ + __proto__: null, + downlink: downlink, + uplink: uplink + }); + + // export + message = analogMessage; + +})(); +//#endregion diff --git a/vendor/jooby/analog-imp4eu.js b/vendor/jooby/analog-imp4eu.js new file mode 100644 index 0000000000..5007d04e1d --- /dev/null +++ b/vendor/jooby/analog-imp4eu.js @@ -0,0 +1,4212 @@ +// https://github.com/jooby-dev/jooby-codec/blob/main/src/analog/constants/hardwareTypes.ts +const config = { + // IMP4EU + hardwareType: 6 +}; + +// helper +const decode = ( fromBytes, input ) => { + const data = {bytes: input.bytes}; + const decodeResult = fromBytes(input.bytes, config); + const errors = []; + + if ( decodeResult.error ) { + errors.push(decodeResult.error); + // there may be some partially decoded result + data.message = decodeResult.message; + } else { + data.message = decodeResult; + } + + return {data, errors}; +}; + +// will have encoder/decoder after init +let message; + + +/* + Get bytes from message. + + Input is an object with the following fields: + * data - object, must contain "commands" field + * fPort - downlink fPort + + Output must be an object with the following fields: + * bytes - byte array containing the downlink payload +*/ +function encodeDownlink ( input ) { + let bytes = message.downlink.toBytes(input.data.commands, config); + + return {bytes, fPort: 1}; +} + +/* + Get message from bytes. + + Input is an object with the following fields: + * bytes - byte array containing the uplink payload, e.g. [255, 230, 255, 0] + * fPort - uplink fPort + + Output must be an object with the following fields: + * data - object representing the decoded payload +*/ +function decodeUplink ( input ) { + return decode(message.uplink.fromBytes, input); +} + +/* + Get message from bytes. + + Input is an object with the following fields: + * bytes - byte array containing the downlink payload, e.g. [255, 230, 255, 0] + * fPort - downlink fPort + + Output must be an object with the following fields: + * data - object representing the decoded payload +*/ +function decodeDownlink ( input ) { + return decode(message.downlink.fromBytes, input); +} + + +//#region [autogenerated jooby-codec bundle from index.js] +(function () { + 'use strict'; + + const hexFormatOptions = { + separator: ' ', + prefix: '' + }; + + const INT8_SIZE = 1; + const INT16_SIZE = 2; + const INT24_SIZE = 3; + const INT32_SIZE = 4; + const { + log, + pow, + LN2 + } = Math; + const readFloat = (buffer, offset, isLittleEndian, mLen, bytes) => { + var e, + m, + eLen = bytes * 8 - mLen - 1, + eMax = (1 << eLen) - 1, + eBias = eMax >> 1, + nBits = -7, + i = isLittleEndian ? bytes - 1 : 0, + d = isLittleEndian ? -1 : 1, + s = buffer[offset + i]; + i += d; + e = s & (1 << -nBits) - 1; + s >>= -nBits; + nBits += eLen; + for (; nBits > 0; e = e * 0x100 + buffer[offset + i], i += d, nBits -= 8); + m = e & (1 << -nBits) - 1; + e >>= -nBits; + nBits += mLen; + for (; nBits > 0; m = m * 0x100 + buffer[offset + i], i += d, nBits -= 8); + if (e === 0) { + e = 1 - eBias; + } else if (e === eMax) { + return m ? NaN : s ? -Infinity : Infinity; + } else { + m = m + pow(2, mLen); + e = e - eBias; + } + return (s ? -1 : 1) * m * pow(2, e - mLen); + }; + const writeFloat = (buffer, offset, value, isLittleEndian, mLen, bytes) => { + var e, + m, + c, + eLen = bytes * 8 - mLen - 1, + eMax = (1 << eLen) - 1, + eBias = eMax >> 1, + rt = mLen === 23 ? pow(2, -24) - pow(2, -77) : 0, + i = isLittleEndian ? 0 : bytes - 1, + d = isLittleEndian ? 1 : -1, + s = value < 0 || value === 0 && 1 / value < 0 ? 1 : 0; + value < 0 && (value = -value); + if (value !== value || value === Infinity) { + m = value !== value ? 1 : 0; + e = eMax; + } else { + e = log(value) / LN2 | 0; + if (value * (c = pow(2, -e)) < 1) { + e--; + c *= 2; + } + if (e + eBias >= 1) { + value += rt / c; + } else { + value += rt * pow(2, 1 - eBias); + } + if (value * c >= 2) { + e++; + c /= 2; + } + if (e + eBias >= eMax) { + m = 0; + e = eMax; + } else if (e + eBias >= 1) { + m = (value * c - 1) * pow(2, mLen); + e = e + eBias; + } else { + m = value * pow(2, eBias - 1) * pow(2, mLen); + e = 0; + } + } + for (; mLen >= 8; buffer[offset + i] = m & 0xff, i += d, m /= 0x100, mLen -= 8); + e = e << mLen | m; + eLen += mLen; + for (; eLen > 0; buffer[offset + i] = e & 0xff, i += d, e /= 0x100, eLen -= 8); + buffer[offset + i - d] |= s * 0x80; + }; + const be2 = [1, 0]; + const be3 = [2, 1, 0]; + const be4 = [3, 2, 1, 0]; + const le2 = [0, 1]; + const le3 = [0, 1, 2]; + const le4 = [0, 1, 2, 3]; + const readUint8 = (buffer, offset) => buffer[offset]; + const readUint16 = (buffer, offset, isLittleEndian) => { + const order = isLittleEndian ? le2 : be2; + const b0 = buffer[offset + order[0]]; + const b1 = buffer[offset + order[1]] << 8; + return b0 | b1; + }; + const readUint24 = (buffer, offset, isLittleEndian) => { + const order = isLittleEndian ? le3 : be3; + const b0 = buffer[offset + order[0]]; + const b1 = buffer[offset + order[1]] << 8; + const b2 = buffer[offset + order[2]] << 16; + return b0 | b1 | b2; + }; + const readUint32 = (buffer, offset, isLittleEndian) => { + const order = isLittleEndian ? le4 : be4; + const b0 = buffer[offset + order[3]] * 0x1000000; + const b1 = buffer[offset + order[2]] * 0x10000; + const b2 = buffer[offset + order[1]] * 0x100; + const b3 = buffer[offset + order[0]]; + return b0 + b1 + b2 + b3; + }; + const writeUint8 = (buffer, offset, value) => { + buffer[offset] = value & 0xff; + }; + const writeUint16 = (buffer, offset, value, isLittleEndian) => { + const order = isLittleEndian ? le2 : be2; + buffer[offset + order[0]] = value & 0xff; + buffer[offset + order[1]] = value >>> 8 & 0xff; + }; + const writeUint24 = (buffer, offset, value, isLittleEndian) => { + const order = isLittleEndian ? le3 : be3; + buffer[offset + order[0]] = value & 0xff; + buffer[offset + order[1]] = value >>> 8 & 0xff; + buffer[offset + order[2]] = value >>> 16 & 0xff; + }; + const writeUint32 = (buffer, offset, value, isLittleEndian) => { + const order = isLittleEndian ? le4 : be4; + buffer[offset + order[0]] = value & 0xff; + buffer[offset + order[1]] = value >>> 8 & 0xff; + buffer[offset + order[2]] = value >>> 16 & 0xff; + buffer[offset + order[3]] = value >>> 24 & 0xff; + }; + function BinaryBuffer(dataOrLength) { + let isLittleEndian = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : true; + if (typeof dataOrLength === 'number') { + const bytes = new Array(dataOrLength).fill(0); + this.data = bytes; + } else { + this.data = dataOrLength; + } + this.offset = 0; + this.isLittleEndian = isLittleEndian; + } + BinaryBuffer.prototype = { + toUint8Array() { + return this.data; + }, + seek(position) { + if (position < 0 || position >= this.data.length) { + throw new Error('Invalid position.'); + } + this.offset = position; + }, + setInt8(value) { + writeUint8(this.data, this.offset, value < 0 ? value | 0x100 : value); + this.offset += INT8_SIZE; + }, + getInt8() { + const result = readUint8(this.data, this.offset); + this.offset += INT8_SIZE; + return result & 0x80 ? result ^ -256 : result; + }, + setUint8(value) { + writeUint8(this.data, this.offset, value); + this.offset += INT8_SIZE; + }, + getUint8() { + const result = readUint8(this.data, this.offset); + this.offset += INT8_SIZE; + return result; + }, + setInt16(value) { + let isLittleEndian = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : this.isLittleEndian; + writeUint16(this.data, this.offset, value < 0 ? value | 0x10000 : value, isLittleEndian); + this.offset += INT16_SIZE; + }, + getInt16() { + let isLittleEndian = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : this.isLittleEndian; + const result = readUint16(this.data, this.offset, isLittleEndian); + this.offset += INT16_SIZE; + return result & 0x8000 ? result ^ -65536 : result; + }, + setUint16(value) { + let isLittleEndian = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : this.isLittleEndian; + writeUint16(this.data, this.offset, value, isLittleEndian); + this.offset += INT16_SIZE; + }, + getUint16() { + let isLittleEndian = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : this.isLittleEndian; + const result = readUint16(this.data, this.offset, isLittleEndian); + this.offset += INT16_SIZE; + return result; + }, + setInt24(value) { + let isLittleEndian = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : this.isLittleEndian; + writeUint24(this.data, this.offset, value < 0 ? value | 0x1000000 : value, isLittleEndian); + this.offset += INT24_SIZE; + }, + getInt24() { + let isLittleEndian = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : this.isLittleEndian; + const result = readUint24(this.data, this.offset, isLittleEndian); + this.offset += INT24_SIZE; + return result & 0x800000 ? result ^ -16777216 : result; + }, + setUint24(value) { + let isLittleEndian = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : this.isLittleEndian; + writeUint24(this.data, this.offset, value, isLittleEndian); + this.offset += INT24_SIZE; + }, + getUint24() { + let isLittleEndian = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : this.isLittleEndian; + const result = readUint24(this.data, this.offset, isLittleEndian); + this.offset += INT24_SIZE; + return result; + }, + setInt32(value) { + let isLittleEndian = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : this.isLittleEndian; + writeUint32(this.data, this.offset, value < 0 ? value | 0x100000000 : value, isLittleEndian); + this.offset += INT32_SIZE; + }, + getInt32() { + let isLittleEndian = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : this.isLittleEndian; + const result = readUint32(this.data, this.offset, isLittleEndian); + this.offset += INT32_SIZE; + return result & 0x80000000 ? result ^ -4294967296 : result; + }, + setUint32(value) { + let isLittleEndian = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : this.isLittleEndian; + writeUint32(this.data, this.offset, value, isLittleEndian); + this.offset += INT32_SIZE; + }, + getUint32() { + let isLittleEndian = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : this.isLittleEndian; + const result = readUint32(this.data, this.offset, isLittleEndian); + this.offset += INT32_SIZE; + return result; + }, + setFloat32(value) { + let isLittleEndian = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : this.isLittleEndian; + writeFloat(this.data, this.offset, value, isLittleEndian, 23, 4); + this.offset += INT32_SIZE; + }, + getFloat32() { + let isLittleEndian = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : this.isLittleEndian; + const result = readFloat(this.data, this.offset, isLittleEndian, 23, 4); + this.offset += INT32_SIZE; + return result; + }, + setString(value) { + this.setUint8(value.length); + for (let index = 0; index < value.length; ++index) { + this.setUint8(value.charCodeAt(index)); + } + }, + getString() { + const size = this.getUint8(); + const endIndex = this.offset + size; + const chars = []; + while (this.offset < endIndex) { + chars.push(String.fromCharCode(this.getUint8())); + } + return chars.join(''); + }, + getBytesToOffset() { + let offset = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : this.offset; + return this.data.slice(0, offset); + }, + getBytesLeft() { + return this.getBytes(this.bytesLeft); + }, + getBytes(length) { + let offset = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : this.offset; + this.offset = offset + length; + return this.data.slice(offset, this.offset); + }, + setBytes(data) { + let offset = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : this.offset; + const bytes = this.data; + bytes.splice(offset, data.length, ...data); + this.data = bytes; + this.offset = offset + data.length; + } + }; + Object.defineProperties(BinaryBuffer.prototype, { + size: { + get() { + return this.data.length; + } + }, + isEmpty: { + get() { + if (this.offset > this.data.length) { + throw new Error(`current offset ${this.offset} is outside the bounds of the buffer`); + } + return this.data.length - this.offset === 0; + } + }, + bytesLeft: { + get() { + return this.data.length - this.offset; + } + }, + position: { + get() { + return this.offset; + } + } + }); + + const shortCommandMask = 0xe0; + const extraCommandMask = 0x1f; + const fromBytes$11 = data => { + if (data.length === 0) { + throw new Error('Invalid buffer size'); + } + const header = { + shortCode: data[0] & shortCommandMask, + extraCode: data[0] & extraCommandMask + }; + if (header.shortCode !== 0) { + return { + headerSize: 1, + commandId: data[0] & ~header.extraCode, + commandSize: header.extraCode + }; + } + if (header.extraCode === extraCommandMask) { + if (data.length < 3) { + throw new Error('Invalid buffer size'); + } + return { + headerSize: 3, + commandId: data[1] << 8 | extraCommandMask, + commandSize: data[2] + }; + } + if (data.length < 2) { + throw new Error('Invalid buffer size'); + } + return { + headerSize: 2, + commandId: header.extraCode, + commandSize: data[1] + }; + }; + const toBytes$12 = (commandId, commandSize) => { + if ((commandId & extraCommandMask) === 0) { + if (commandSize > extraCommandMask) { + throw new Error(`Wrong command id/size. Id: ${commandId}, size: ${commandSize}.`); + } + return [commandId | commandSize]; + } + if (commandId > extraCommandMask) { + return [extraCommandMask, commandId >> 8, commandSize]; + } + return [commandId, commandSize]; + }; + + const toBytes$11 = function (commandId) { + let commandData = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : []; + const headerData = toBytes$12(commandId, commandData.length); + return [...headerData, ...commandData]; + }; + + const setTime2000$1 = 0x02; + const setParameter$1 = 0x03; + const getParameter$1 = 0x04; + const getArchiveHours$1 = 0x05; + const getArchiveDays$1 = 0x06; + const getCurrent = 0x07; + const getTime2000 = 0x09; + const getArchiveEvents$1 = 0x0b; + const correctTime2000$1 = 0x0c; + const getStatus = 0x14; + const getCurrentMc = 0x18; + const softRestart$1 = 0x19; + const getArchiveHoursMc$1 = 0x1a; + const getArchiveDaysMc$1 = 0x1b; + const dataSegment$1 = 0x1e; + const getLmicInfo$1 = 0x21f; + const getBatteryStatus$1 = 0x51f; + const usWaterMeterCommand$1 = 0x71f; + const getExAbsArchiveHoursMc$1 = 0xc1f; + const getExAbsArchiveDaysMc$1 = 0xd1f; + const getExAbsCurrentMc = 0xf1f; + const writeImage$1 = 0x2a1f; + const verifyImage$1 = 0x2b1f; + const updateRun$1 = 0x2c1f; + const getArchiveHoursMcEx$1 = 0x301f; + const getChannelsStatus$1 = 0x321f; + const getChannelsTypes$1 = 0x331f; + + var downlinkIds = /*#__PURE__*/Object.freeze({ + __proto__: null, + correctTime2000: correctTime2000$1, + dataSegment: dataSegment$1, + getArchiveDays: getArchiveDays$1, + getArchiveDaysMc: getArchiveDaysMc$1, + getArchiveEvents: getArchiveEvents$1, + getArchiveHours: getArchiveHours$1, + getArchiveHoursMc: getArchiveHoursMc$1, + getArchiveHoursMcEx: getArchiveHoursMcEx$1, + getBatteryStatus: getBatteryStatus$1, + getChannelsStatus: getChannelsStatus$1, + getChannelsTypes: getChannelsTypes$1, + getCurrent: getCurrent, + getCurrentMc: getCurrentMc, + getExAbsArchiveDaysMc: getExAbsArchiveDaysMc$1, + getExAbsArchiveHoursMc: getExAbsArchiveHoursMc$1, + getExAbsCurrentMc: getExAbsCurrentMc, + getLmicInfo: getLmicInfo$1, + getParameter: getParameter$1, + getStatus: getStatus, + getTime2000: getTime2000, + setParameter: setParameter$1, + setTime2000: setTime2000$1, + softRestart: softRestart$1, + updateRun: updateRun$1, + usWaterMeterCommand: usWaterMeterCommand$1, + verifyImage: verifyImage$1, + writeImage: writeImage$1 + }); + + var invertObject = source => { + const target = {}; + for (const property in source) { + const value = source[property]; + target[value] = property; + } + return target; + }; + + var downlinkNames = invertObject(downlinkIds); + + const id$_ = correctTime2000$1; + downlinkNames[correctTime2000$1]; + const COMMAND_BODY_SIZE$w = 2; + const fromBytes$10 = data => { + if (data.length !== COMMAND_BODY_SIZE$w) { + throw new Error(`Wrong buffer size: ${data.length}.`); + } + const buffer = new BinaryBuffer(data, false); + const parameters = { + sequenceNumber: buffer.getUint8(), + seconds: buffer.getInt8() + }; + if (!buffer.isEmpty) { + throw new Error('BinaryBuffer is not empty.'); + } + return parameters; + }; + const toBytes$10 = parameters => { + const { + sequenceNumber, + seconds + } = parameters; + const buffer = new BinaryBuffer(COMMAND_BODY_SIZE$w, false); + buffer.setUint8(sequenceNumber); + buffer.setInt8(seconds); + return toBytes$11(id$_, buffer.data); + }; + + const fromObject = function () { + let bitMask = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : {}; + let booleanObject = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : {}; + let result = 0; + for (const name in booleanObject) { + if (name in bitMask && booleanObject[name]) { + result |= bitMask[name]; + } + } + return result; + }; + const toObject = function () { + let bitMask = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : {}; + let value = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : 0; + const result = {}; + for (const name in bitMask) { + result[name] = (value & bitMask[name]) !== 0; + } + return result; + }; + const extractBits = (value, bitsNumber, startIndex) => (1 << bitsNumber) - 1 & value >> startIndex - 1; + const fillBits = (value, bitsNumber, startIndex, valueToSet) => { + const mask = (1 << bitsNumber) - 1 << startIndex - 1; + let newValueToSet = valueToSet; + let result = value; + result &= ~mask; + newValueToSet <<= startIndex - 1; + result |= newValueToSet; + return result; + }; + + var getHexFromBytes = (function (bytes) { + let options = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : {}; + const { + separator, + prefix + } = Object.assign({}, hexFormatOptions, options); + return bytes.map(byte => `${prefix}${byte.toString(16).padStart(2, '0')}`).join(separator); + }); + + var getBytesFromHex = hex => { + let cleanHex = hex.trim(); + if (!cleanHex) { + return []; + } + cleanHex = cleanHex.replace(/0x/g, '').split(/\s+/).map(byte => byte.padStart(2, '0')).join(''); + if (cleanHex.length % 2 !== 0) { + cleanHex = `0${cleanHex}`; + } + const resultLength = cleanHex.length / 2; + const bytes = new Array(resultLength); + for (let index = 0; index < resultLength; index++) { + bytes[index] = parseInt(cleanHex.substring(index * 2, index * 2 + 2), 16); + } + return bytes; + }; + + var roundNumber = (function (value) { + let decimalPlaces = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : 4; + const places = Math.pow(10, decimalPlaces); + return Math.round(value * places * (1 + Number.EPSILON)) / places; + }); + + const INITIAL_YEAR_TIMESTAMP = 946684800000; + const MILLISECONDS_IN_SECONDS = 1000; + const getDateFromTime2000 = time2000 => new Date(INITIAL_YEAR_TIMESTAMP + time2000 * MILLISECONDS_IN_SECONDS); + const getTime2000FromDate = date => (date.getTime() - INITIAL_YEAR_TIMESTAMP) / MILLISECONDS_IN_SECONDS; + + const GASI1 = 1; + const GASI2 = 2; + const GASI3 = 3; + const NOVATOR = 4; + const IMP2EU = 5; + const IMP4EU = 6; + const MTXLORA = 7; + const IMP2AS = 8; + const IMP2IN = 9; + const IMP4IN = 10; + const ELIMP = 11; + const GASIC = 12; + const US_WATER = 13; + const NBIOT = 24; + + const REPORTING_DATA_INTERVAL = 1; + const DAY_CHECKOUT_HOUR = 4; + const REPORTING_DATA_TYPE = 5; + const PRIORITY_DATA_DELIVERY_TYPE = 8; + const ACTIVATION_METHOD = 9; + const BATTERY_DEPASSIVATION_INFO = 10; + const BATTERY_MINIMAL_LOAD_TIME = 11; + const CHANNELS_CONFIG = 13; + const RX2_CONFIG = 18; + const ABSOLUTE_DATA = 23; + const ABSOLUTE_DATA_ENABLE = 24; + const SERIAL_NUMBER = 25; + const GEOLOCATION = 26; + const EXTRA_FRAME_INTERVAL = 28; + const ABSOLUTE_DATA_MULTI_CHANNEL = 29; + const ABSOLUTE_DATA_ENABLE_MULTI_CHANNEL = 30; + const PULSE_CHANNELS_SCAN_CONFIG = 31; + const PULSE_CHANNELS_SET_CONFIG = 32; + const BATTERY_DEPASSIVATION_CONFIG = 33; + const MQTT_SESSION_CONFIG = 34; + const MQTT_BROKER_ADDRESS = 35; + const MQTT_SSL_ENABLE = 36; + const MQTT_TOPIC_PREFIX = 37; + const MQTT_DATA_RECEIVE_CONFIG = 38; + const MQTT_DATA_SEND_CONFIG = 39; + const NBIOT_SSL_CONFIG = 40; + const NBIOT_SSL_CACERT_WRITE = 41; + const NBIOT_SSL_CACERT_SET = 42; + const NBIOT_SSL_CLIENT_CERT_WRITE = 43; + const NBIOT_SSL_CLIENT_CERT_SET = 44; + const NBIOT_SSL_CLIENT_KEY_WRITE = 45; + const NBIOT_SSL_CLIENT_KEY_SET = 46; + const NBIOT_DEVICE_SOFTWARE_UPDATE = 47; + const NBIOT_MODULE_FIRMWARE_UPDATE = 48; + const REPORTING_DATA_CONFIG = 49; + const EVENTS_CONFIG = 50; + const NBIOT_MODULE_INFO = 51; + const NBIOT_BANDS = 52; + const NBIOT_APN = 53; + const NBIOT_LED_INDICATION = 54; + const NBIOT_SIM = 55; + const CHANNEL_TYPE = 56; + + var deviceParameters = /*#__PURE__*/Object.freeze({ + __proto__: null, + ABSOLUTE_DATA: ABSOLUTE_DATA, + ABSOLUTE_DATA_ENABLE: ABSOLUTE_DATA_ENABLE, + ABSOLUTE_DATA_ENABLE_MULTI_CHANNEL: ABSOLUTE_DATA_ENABLE_MULTI_CHANNEL, + ABSOLUTE_DATA_MULTI_CHANNEL: ABSOLUTE_DATA_MULTI_CHANNEL, + ACTIVATION_METHOD: ACTIVATION_METHOD, + BATTERY_DEPASSIVATION_CONFIG: BATTERY_DEPASSIVATION_CONFIG, + BATTERY_DEPASSIVATION_INFO: BATTERY_DEPASSIVATION_INFO, + BATTERY_MINIMAL_LOAD_TIME: BATTERY_MINIMAL_LOAD_TIME, + CHANNELS_CONFIG: CHANNELS_CONFIG, + CHANNEL_TYPE: CHANNEL_TYPE, + DAY_CHECKOUT_HOUR: DAY_CHECKOUT_HOUR, + EVENTS_CONFIG: EVENTS_CONFIG, + EXTRA_FRAME_INTERVAL: EXTRA_FRAME_INTERVAL, + GEOLOCATION: GEOLOCATION, + MQTT_BROKER_ADDRESS: MQTT_BROKER_ADDRESS, + MQTT_DATA_RECEIVE_CONFIG: MQTT_DATA_RECEIVE_CONFIG, + MQTT_DATA_SEND_CONFIG: MQTT_DATA_SEND_CONFIG, + MQTT_SESSION_CONFIG: MQTT_SESSION_CONFIG, + MQTT_SSL_ENABLE: MQTT_SSL_ENABLE, + MQTT_TOPIC_PREFIX: MQTT_TOPIC_PREFIX, + NBIOT_APN: NBIOT_APN, + NBIOT_BANDS: NBIOT_BANDS, + NBIOT_DEVICE_SOFTWARE_UPDATE: NBIOT_DEVICE_SOFTWARE_UPDATE, + NBIOT_LED_INDICATION: NBIOT_LED_INDICATION, + NBIOT_MODULE_FIRMWARE_UPDATE: NBIOT_MODULE_FIRMWARE_UPDATE, + NBIOT_MODULE_INFO: NBIOT_MODULE_INFO, + NBIOT_SIM: NBIOT_SIM, + NBIOT_SSL_CACERT_SET: NBIOT_SSL_CACERT_SET, + NBIOT_SSL_CACERT_WRITE: NBIOT_SSL_CACERT_WRITE, + NBIOT_SSL_CLIENT_CERT_SET: NBIOT_SSL_CLIENT_CERT_SET, + NBIOT_SSL_CLIENT_CERT_WRITE: NBIOT_SSL_CLIENT_CERT_WRITE, + NBIOT_SSL_CLIENT_KEY_SET: NBIOT_SSL_CLIENT_KEY_SET, + NBIOT_SSL_CLIENT_KEY_WRITE: NBIOT_SSL_CLIENT_KEY_WRITE, + NBIOT_SSL_CONFIG: NBIOT_SSL_CONFIG, + PRIORITY_DATA_DELIVERY_TYPE: PRIORITY_DATA_DELIVERY_TYPE, + PULSE_CHANNELS_SCAN_CONFIG: PULSE_CHANNELS_SCAN_CONFIG, + PULSE_CHANNELS_SET_CONFIG: PULSE_CHANNELS_SET_CONFIG, + REPORTING_DATA_CONFIG: REPORTING_DATA_CONFIG, + REPORTING_DATA_INTERVAL: REPORTING_DATA_INTERVAL, + REPORTING_DATA_TYPE: REPORTING_DATA_TYPE, + RX2_CONFIG: RX2_CONFIG, + SERIAL_NUMBER: SERIAL_NUMBER + }); + + var deviceParameterNames = invertObject(deviceParameters); + + const EMPTY_VALUE = 0xffffffff; + + const IDLE = 0; + const POWER_CHANNEL = 2; + const BINARY_SENSOR = 3; + const TEMPERATURE_SENSOR = 4; + + var channelTypes = /*#__PURE__*/Object.freeze({ + __proto__: null, + BINARY_SENSOR: BINARY_SENSOR, + IDLE: IDLE, + POWER_CHANNEL: POWER_CHANNEL, + TEMPERATURE_SENSOR: TEMPERATURE_SENSOR + }); + + const SF12B125 = 0; + const SF11B125 = 1; + const SF10B125 = 2; + const SF9B125 = 3; + const SF8B125 = 4; + const SF7B125 = 5; + const SF7B250 = 6; + + var rx2SpreadFactors = /*#__PURE__*/Object.freeze({ + __proto__: null, + SF10B125: SF10B125, + SF11B125: SF11B125, + SF12B125: SF12B125, + SF7B125: SF7B125, + SF7B250: SF7B250, + SF8B125: SF8B125, + SF9B125: SF9B125 + }); + + var spreadFactorNames = invertObject(rx2SpreadFactors); + + const INITIAL_YEAR = 2000; + const MONTH_BIT_SIZE = 4; + const DATE_BIT_SIZE = 5; + const YEAR_START_INDEX = 1; + const UNKNOWN_BATTERY_VOLTAGE = 4095; + const EXTEND_BIT_MASK = 0x80; + const LAST_BIT_INDEX = 7; + const DATA_SENDING_INTERVAL_SECONDS_COEFFICIENT = 600; + const DATA_SENDING_INTERVAL_RESERVED_BYTES = 3; + const PARAMETER_RX2_FREQUENCY_COEFFICIENT = 100; + const SERIAL_NUMBER_SIZE = 6; + const MAGNETIC_INFLUENCE_BIT_INDEX = 8; + const LEGACY_HOUR_COUNTER_SIZE = 2 + 4; + const LEGACY_HOUR_DIFF_SIZE = 2; + const GAS_HARDWARE_TYPES = [GASI2, GASI3, GASI1, GASIC, NBIOT]; + const TWO_CHANNELS_HARDWARE_TYPES = [IMP2AS, IMP2EU, IMP2IN, NOVATOR]; + const ELIMP_HARDWARE_TYPES = [ELIMP]; + const FOUR_CHANNELS_HARDWARE_TYPES = [IMP4EU, IMP4IN]; + const MTX_HARDWARE_TYPES = [MTXLORA]; + const TWO_BYTES_HARDWARE_TYPES = [...FOUR_CHANNELS_HARDWARE_TYPES, ...MTX_HARDWARE_TYPES]; + const gasBitMask = { + isBatteryLow: Math.pow(2, 0), + isMagneticInfluence: Math.pow(2, 1), + isButtonReleased: Math.pow(2, 2), + isConnectionLost: Math.pow(2, 3) + }; + const twoChannelBitMask = { + isBatteryLow: Math.pow(2, 0), + isConnectionLost: Math.pow(2, 3), + isFirstChannelInactive: Math.pow(2, 4), + isSecondChannelInactive: Math.pow(2, 5) + }; + const elimpBitMask = { + isConnectionLost: Math.pow(2, 3) + }; + const fourChannelBitMask = { + isBatteryLow: Math.pow(2, 0), + isConnectionLost: Math.pow(2, 3), + isFirstChannelInactive: Math.pow(2, 4), + isSecondChannelInactive: Math.pow(2, 5), + isThirdChannelInactive: Math.pow(2, 6), + isForthChannelInactive: Math.pow(2, 8) + }; + const mtxBitMask = { + isMeterCaseOpen: Math.pow(2, 0), + isMagneticInfluence: Math.pow(2, 1), + isParametersSetRemotely: Math.pow(2, 2), + isParametersSetLocally: Math.pow(2, 3), + isMeterProgramRestarted: Math.pow(2, 4), + isLockedOut: Math.pow(2, 5), + isTimeSet: Math.pow(2, 6), + isTimeCorrected: Math.pow(2, 7), + isMeterFailure: Math.pow(2, 8), + isMeterTerminalBoxOpen: Math.pow(2, 9), + isModuleCompartmentOpen: Math.pow(2, 10), + isTariffPlanChanged: Math.pow(2, 11), + isNewTariffPlanReceived: Math.pow(2, 12) + }; + const usWaterMeterEventBitMask = { + transportMode: 0x01, + frequencyOutput: 0x02, + reverseFlow: 0x04, + tamperBreak: 0x08, + leakage: 0x10, + pipeBreak: 0x20, + pipeEmpty: 0x40, + batteryDischarge: 0x80 + }; + const getChannelTypeSize = _ref => { + let { + type + } = _ref; + let size = 1; + switch (type) { + case IDLE: + case POWER_CHANNEL: + break; + case BINARY_SENSOR: + size += 2; + break; + case TEMPERATURE_SENSOR: + size += 5; + break; + } + return size; + }; + const parametersSizeMap = { + [REPORTING_DATA_INTERVAL]: 1 + 4, + [DAY_CHECKOUT_HOUR]: 1 + 1, + [REPORTING_DATA_TYPE]: 1 + 1, + [PRIORITY_DATA_DELIVERY_TYPE]: 1 + 1, + [ACTIVATION_METHOD]: 1 + 1, + [BATTERY_DEPASSIVATION_INFO]: 1 + 6, + [BATTERY_MINIMAL_LOAD_TIME]: 1 + 4, + [CHANNELS_CONFIG]: 1 + 1, + [RX2_CONFIG]: 1 + 4, + [ABSOLUTE_DATA]: 1 + 9, + [ABSOLUTE_DATA_ENABLE]: 1 + 1, + [SERIAL_NUMBER]: 1 + 6, + [GEOLOCATION]: 1 + 10, + [EXTRA_FRAME_INTERVAL]: 1 + 2, + [ABSOLUTE_DATA_MULTI_CHANNEL]: 1 + 10, + [ABSOLUTE_DATA_ENABLE_MULTI_CHANNEL]: 1 + 2, + [PULSE_CHANNELS_SCAN_CONFIG]: 1 + 3, + [PULSE_CHANNELS_SET_CONFIG]: 1 + 1, + [BATTERY_DEPASSIVATION_CONFIG]: 1 + 4, + [MQTT_SSL_ENABLE]: 1 + 1, + [MQTT_DATA_RECEIVE_CONFIG]: 1 + 3, + [MQTT_DATA_SEND_CONFIG]: 1 + 3, + [NBIOT_SSL_CONFIG]: 1 + 2, + [NBIOT_SSL_CACERT_SET]: 1 + 4, + [NBIOT_SSL_CLIENT_CERT_SET]: 1 + 4, + [NBIOT_SSL_CLIENT_KEY_SET]: 1 + 4, + [REPORTING_DATA_CONFIG]: 1 + 4, + [EVENTS_CONFIG]: 1 + 3, + [NBIOT_LED_INDICATION]: 1 + 2, + [NBIOT_SIM]: 1 + 3 + }; + const fourChannelsBitMask = { + channel1: Math.pow(2, 0), + channel2: Math.pow(2, 1), + channel3: Math.pow(2, 2), + channel4: Math.pow(2, 3) + }; + const getChannelsMaskFromNumber = value => { + const object = toObject(fourChannelsBitMask, value); + return { + channel1: object.channel1, + channel2: object.channel2, + channel3: object.channel3, + channel4: object.channel4 + }; + }; + const setChannelsMaskToNumber = channelsMask => { + const { + channel1, + channel2, + channel3, + channel4 + } = channelsMask; + return fromObject(fourChannelsBitMask, { + channel1, + channel2, + channel3, + channel4 + }); + }; + const getChannelsMask = buffer => getChannelsMaskFromNumber(buffer.getUint8()); + const setChannelsMask = (buffer, channelsMask) => buffer.setUint8(setChannelsMaskToNumber(channelsMask)); + const byteToPulseCoefficientMap = { + 128: 1, + 129: 5, + 130: 10, + 131: 100, + 132: 1000, + 133: 10000, + 134: 100000 + }; + const pulseCoefficientToByteMap = invertObject(byteToPulseCoefficientMap); + const isMSBSet = value => !!(value & 0x80); + const getNbiotSslWrite = buffer => ({ + size: buffer.getUint16(), + position: buffer.getUint16(), + chunk: buffer.getBytesLeft() + }); + const setNbiotSslWrite = (buffer, parameter) => { + if (parameter.size !== parameter.chunk.length) { + throw new Error('ssl chunk size parameter doesn\'t match actual ssl chunk size'); + } + buffer.setUint16(parameter.size); + buffer.setUint16(parameter.position); + buffer.setBytes(parameter.chunk); + }; + const getNbiotSslSet = buffer => ({ + crc32: buffer.getUint32() + }); + const setNbiotSslSet = (buffer, parameter) => { + buffer.setUint32(parameter.crc32); + }; + const deviceParameterConvertersMap = { + [REPORTING_DATA_INTERVAL]: { + get: buffer => { + buffer.seek(buffer.offset + DATA_SENDING_INTERVAL_RESERVED_BYTES); + return { + value: buffer.getUint8() * DATA_SENDING_INTERVAL_SECONDS_COEFFICIENT + }; + }, + set: (buffer, parameter) => { + buffer.seek(buffer.offset + DATA_SENDING_INTERVAL_RESERVED_BYTES); + buffer.setUint8(parameter.value / DATA_SENDING_INTERVAL_SECONDS_COEFFICIENT); + } + }, + [DAY_CHECKOUT_HOUR]: { + get: buffer => ({ + value: buffer.getUint8() + }), + set: (buffer, parameter) => { + buffer.setUint8(parameter.value); + } + }, + [REPORTING_DATA_TYPE]: { + get: buffer => ({ + type: buffer.getUint8() + }), + set: (buffer, parameter) => { + buffer.setUint8(parameter.type); + } + }, + [PRIORITY_DATA_DELIVERY_TYPE]: { + get: buffer => ({ + value: buffer.getUint8() + }), + set: (buffer, parameter) => { + buffer.setUint8(parameter.value); + } + }, + [ACTIVATION_METHOD]: { + get: buffer => ({ + type: buffer.getUint8() + }), + set: (buffer, parameter) => { + buffer.setUint8(parameter.type); + } + }, + [BATTERY_DEPASSIVATION_INFO]: { + get: buffer => ({ + loadTime: buffer.getUint16(), + internalResistance: buffer.getUint16(), + lowVoltage: buffer.getUint16() + }), + set: (buffer, parameter) => { + buffer.setUint16(parameter.loadTime); + buffer.setUint16(parameter.internalResistance); + buffer.setUint16(parameter.lowVoltage); + } + }, + [BATTERY_MINIMAL_LOAD_TIME]: { + get: buffer => ({ + value: buffer.getUint32() + }), + set: (buffer, parameter) => { + buffer.setUint32(parameter.value); + } + }, + [CHANNELS_CONFIG]: { + get: buffer => ({ + value: buffer.getUint8() + }), + set: (buffer, parameter) => { + if (parameter.value < 0 || parameter.value > 18) { + throw new Error('channels config must be between 0-18'); + } + buffer.setUint8(parameter.value); + } + }, + [RX2_CONFIG]: { + get: buffer => { + const spreadFactor = buffer.getUint8(); + const spreadFactorName = spreadFactorNames[spreadFactor]; + const frequency = buffer.getUint24() * PARAMETER_RX2_FREQUENCY_COEFFICIENT; + return { + spreadFactor, + spreadFactorName, + frequency + }; + }, + set: (buffer, parameter) => { + buffer.setUint8(parameter.spreadFactor); + buffer.setUint24(parameter.frequency / PARAMETER_RX2_FREQUENCY_COEFFICIENT); + } + }, + [ABSOLUTE_DATA]: { + get: buffer => ({ + meterValue: buffer.getUint32(), + pulseCoefficient: buffer.getPulseCoefficient(), + value: buffer.getUint32() + }), + set: (buffer, parameter) => { + buffer.setUint32(parameter.meterValue); + buffer.setPulseCoefficient(parameter.pulseCoefficient); + buffer.setUint32(parameter.value); + } + }, + [ABSOLUTE_DATA_ENABLE]: { + get: buffer => ({ + state: buffer.getUint8() + }), + set: (buffer, parameter) => { + buffer.setUint8(parameter.state); + } + }, + [SERIAL_NUMBER]: { + get: buffer => ({ + value: getHexFromBytes(buffer.getBytes(SERIAL_NUMBER_SIZE)) + }), + set: (buffer, parameter) => { + getBytesFromHex(parameter.value).forEach(byte => buffer.setUint8(byte)); + } + }, + [GEOLOCATION]: { + get: buffer => ({ + latitude: roundNumber(buffer.getFloat32()), + longitude: roundNumber(buffer.getFloat32()), + altitude: roundNumber(buffer.getUint16()) + }), + set: (buffer, parameter) => { + buffer.setFloat32(roundNumber(parameter.latitude)); + buffer.setFloat32(roundNumber(parameter.longitude)); + buffer.setUint16(roundNumber(parameter.altitude)); + } + }, + [EXTRA_FRAME_INTERVAL]: { + get: buffer => ({ + value: buffer.getUint16() + }), + set: (buffer, parameter) => { + buffer.setUint16(parameter.value); + } + }, + [ABSOLUTE_DATA_MULTI_CHANNEL]: { + get: buffer => ({ + channel: buffer.getChannelValue(), + meterValue: buffer.getUint32(), + pulseCoefficient: buffer.getPulseCoefficient(), + value: buffer.getUint32() + }), + set: (buffer, parameter) => { + buffer.setChannelValue(parameter.channel); + buffer.setUint32(parameter.meterValue); + buffer.setPulseCoefficient(parameter.pulseCoefficient); + buffer.setUint32(parameter.value); + } + }, + [ABSOLUTE_DATA_ENABLE_MULTI_CHANNEL]: { + get: buffer => ({ + channel: buffer.getChannelValue(), + state: buffer.getUint8() + }), + set: (buffer, parameter) => { + buffer.setChannelValue(parameter.channel); + buffer.setUint8(parameter.state); + } + }, + [PULSE_CHANNELS_SCAN_CONFIG]: { + get: buffer => ({ + channelList: buffer.getChannels(), + pullUpTime: buffer.getUint8(), + scanTime: buffer.getUint8() + }), + set: (buffer, parameter) => { + if (parameter.pullUpTime < 17) { + throw new Error('minimal value for pullUpTime - 17'); + } + if (parameter.scanTime < 15) { + throw new Error('minimal value for scanTime - 15'); + } + buffer.setChannels(parameter.channelList.map(index => ({ + index + }))); + buffer.setUint8(parameter.pullUpTime); + buffer.setUint8(parameter.scanTime); + } + }, + [PULSE_CHANNELS_SET_CONFIG]: { + get: getChannelsMask, + set: setChannelsMask + }, + [BATTERY_DEPASSIVATION_CONFIG]: { + get: buffer => ({ + resistanceStartThreshold: buffer.getUint16(), + resistanceStopThreshold: buffer.getUint16() + }), + set: (buffer, parameter) => { + buffer.setUint16(parameter.resistanceStartThreshold); + buffer.setUint16(parameter.resistanceStopThreshold); + } + }, + [MQTT_SESSION_CONFIG]: { + get: buffer => ({ + clientId: buffer.getString(), + username: buffer.getString(), + password: buffer.getString(), + cleanSession: buffer.getUint8() + }), + set: (buffer, parameter) => { + buffer.setString(parameter.clientId); + buffer.setString(parameter.username); + buffer.setString(parameter.password); + buffer.setUint8(parameter.cleanSession); + } + }, + [MQTT_BROKER_ADDRESS]: { + get: buffer => ({ + hostName: buffer.getString(), + port: buffer.getUint16() + }), + set: (buffer, parameter) => { + buffer.setString(parameter.hostName); + buffer.setUint16(parameter.port); + } + }, + [MQTT_SSL_ENABLE]: { + get: buffer => ({ + enable: buffer.getUint8() + }), + set: (buffer, parameter) => { + buffer.setUint8(parameter.enable); + } + }, + [MQTT_TOPIC_PREFIX]: { + get: buffer => ({ + topicPrefix: buffer.getString() + }), + set: (buffer, parameter) => { + buffer.setString(parameter.topicPrefix); + } + }, + [MQTT_DATA_RECEIVE_CONFIG]: { + get: buffer => ({ + qos: buffer.getUint8(), + count: buffer.getUint8(), + timeout: buffer.getUint8() + }), + set: (buffer, parameter) => { + buffer.setUint8(parameter.qos); + buffer.setUint8(parameter.count); + buffer.setUint8(parameter.timeout); + } + }, + [MQTT_DATA_SEND_CONFIG]: { + get: buffer => ({ + qos: buffer.getUint8(), + retain: buffer.getUint8(), + newestSendFirst: buffer.getUint8() + }), + set: (buffer, parameter) => { + buffer.setUint8(parameter.qos); + buffer.setUint8(parameter.retain); + buffer.setUint8(parameter.newestSendFirst); + } + }, + [NBIOT_SSL_CONFIG]: { + get: buffer => ({ + securityLevel: buffer.getUint8(), + version: buffer.getUint8() + }), + set: (buffer, parameter) => { + buffer.setUint8(parameter.securityLevel); + buffer.setUint8(parameter.version); + } + }, + [NBIOT_SSL_CACERT_WRITE]: { + get: getNbiotSslWrite, + set: setNbiotSslWrite + }, + [NBIOT_SSL_CACERT_SET]: { + get: getNbiotSslSet, + set: setNbiotSslSet + }, + [NBIOT_SSL_CLIENT_CERT_WRITE]: { + get: getNbiotSslWrite, + set: setNbiotSslWrite + }, + [NBIOT_SSL_CLIENT_CERT_SET]: { + get: getNbiotSslSet, + set: setNbiotSslSet + }, + [NBIOT_SSL_CLIENT_KEY_WRITE]: { + get: getNbiotSslWrite, + set: setNbiotSslWrite + }, + [NBIOT_SSL_CLIENT_KEY_SET]: { + get: getNbiotSslSet, + set: setNbiotSslSet + }, + [NBIOT_DEVICE_SOFTWARE_UPDATE]: { + get: buffer => ({ + softwareImageUrl: buffer.getString() + }), + set: (buffer, parameter) => { + buffer.setString(parameter.softwareImageUrl); + } + }, + [NBIOT_MODULE_FIRMWARE_UPDATE]: { + get: buffer => ({ + moduleFirmwareImageUrl: buffer.getString() + }), + set: (buffer, parameter) => { + buffer.setString(parameter.moduleFirmwareImageUrl); + } + }, + [REPORTING_DATA_CONFIG]: { + get: buffer => ({ + dataType: buffer.getUint8(), + hour: buffer.getUint8(), + minutes: buffer.getUint8(), + countToSend: buffer.getUint8() + }), + set: (buffer, parameter) => { + buffer.setUint8(parameter.dataType); + buffer.setUint8(parameter.hour); + buffer.setUint8(parameter.minutes); + buffer.setUint8(parameter.countToSend); + } + }, + [EVENTS_CONFIG]: { + get: buffer => ({ + eventId: buffer.getUint8(), + sendEvent: buffer.getUint8(), + saveEvent: buffer.getUint8() + }), + set: (buffer, parameter) => { + buffer.setUint8(parameter.eventId); + buffer.setUint8(parameter.sendEvent); + buffer.setUint8(parameter.saveEvent); + } + }, + [NBIOT_MODULE_INFO]: { + get: buffer => ({ + moduleInfo: buffer.getString() + }), + set: (buffer, parameter) => { + buffer.setString(parameter.moduleInfo); + } + }, + [NBIOT_BANDS]: { + get: buffer => { + const count = buffer.getUint8(); + const bands = []; + for (let index = 0; index < count; index++) { + bands.push(buffer.getUint8()); + } + return { + bands + }; + }, + set: (buffer, parameter) => { + buffer.setUint8(parameter.bands.length); + for (const band of parameter.bands) { + buffer.setUint8(band); + } + } + }, + [NBIOT_APN]: { + get: buffer => ({ + apn: buffer.getString() + }), + set: (buffer, parameter) => { + buffer.setString(parameter.apn); + } + }, + [NBIOT_LED_INDICATION]: { + get: buffer => ({ + enableLed: buffer.getUint8(), + enableNbiotNetworkLed: buffer.getUint8() + }), + set: (buffer, parameter) => { + buffer.setUint8(parameter.enableLed); + buffer.setUint8(parameter.enableNbiotNetworkLed); + } + }, + [NBIOT_SIM]: { + get: buffer => ({ + enable: buffer.getUint8(), + pin: buffer.getUint16() + }), + set: (buffer, parameter) => { + buffer.setUint8(parameter.enable); + buffer.setUint16(parameter.pin); + } + }, + [CHANNEL_TYPE]: { + get: buffer => buffer.getChannelType(), + set: (buffer, parameter) => buffer.setChannelType(parameter) + } + }; + const getEventStatusSize = hardwareType => TWO_BYTES_HARDWARE_TYPES.indexOf(hardwareType) !== -1 ? 2 : 1; + const getParameterSize = parameter => { + let size; + let data; + switch (parameter.id) { + case MQTT_SESSION_CONFIG: + data = parameter.data; + size = 1 + 1; + size += data.clientId.length + 1; + size += data.username.length + 1; + size += data.password.length + 1; + break; + case MQTT_BROKER_ADDRESS: + data = parameter.data; + size = 1 + 2; + size += data.hostName.length + 1; + break; + case MQTT_TOPIC_PREFIX: + data = parameter.data; + size = 1; + size += data.topicPrefix.length + 1; + break; + case NBIOT_SSL_CACERT_WRITE: + case NBIOT_SSL_CLIENT_CERT_WRITE: + case NBIOT_SSL_CLIENT_KEY_WRITE: + data = parameter.data; + size = 1 + 2 + 2; + size += data.chunk.length; + break; + case NBIOT_DEVICE_SOFTWARE_UPDATE: + data = parameter.data; + size = 1; + size += data.softwareImageUrl.length + 1; + break; + case NBIOT_MODULE_FIRMWARE_UPDATE: + data = parameter.data; + size = 1; + size += data.moduleFirmwareImageUrl.length + 1; + break; + case NBIOT_MODULE_INFO: + data = parameter.data; + size = 1 + 1 + data.moduleInfo.length; + break; + case NBIOT_BANDS: + data = parameter.data; + size = 1 + 1; + size += data.bands.length; + break; + case NBIOT_APN: + data = parameter.data; + size = 1 + 1 + data.apn.length; + break; + case CHANNEL_TYPE: + data = parameter.data; + size = 1 + getChannelTypeSize(data); + break; + default: + size = parametersSizeMap[parameter.id]; + } + if (size === undefined) { + throw new Error('unknown parameter id'); + } + return size; + }; + const getRequestParameterSize = parameter => { + let size; + switch (parameter.id) { + case ABSOLUTE_DATA_MULTI_CHANNEL: + case ABSOLUTE_DATA_ENABLE_MULTI_CHANNEL: + case REPORTING_DATA_CONFIG: + case EVENTS_CONFIG: + case CHANNEL_TYPE: + size = 2; + break; + default: + size = 1; + break; + } + return size; + }; + const getResponseParameterSize = parameter => { + let size; + switch (parameter.id) { + case MQTT_SESSION_CONFIG: + case NBIOT_SSL_CACERT_WRITE: + case NBIOT_SSL_CLIENT_CERT_WRITE: + case NBIOT_SSL_CLIENT_KEY_WRITE: + case NBIOT_SSL_CACERT_SET: + case NBIOT_SSL_CLIENT_CERT_SET: + case NBIOT_SSL_CLIENT_KEY_SET: + case NBIOT_DEVICE_SOFTWARE_UPDATE: + case NBIOT_MODULE_FIRMWARE_UPDATE: + size = 1; + break; + case MQTT_BROKER_ADDRESS: + case MQTT_TOPIC_PREFIX: + case NBIOT_MODULE_INFO: + case NBIOT_BANDS: + case NBIOT_APN: + case CHANNEL_TYPE: + size = getParameterSize(parameter); + break; + default: + size = parametersSizeMap[parameter.id]; + } + if (size === undefined) { + throw new Error('unknown parameter id'); + } + return size; + }; + function CommandBinaryBuffer(dataOrLength) { + let isLittleEndian = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : false; + BinaryBuffer.call(this, dataOrLength, isLittleEndian); + } + CommandBinaryBuffer.prototype = Object.create(BinaryBuffer.prototype); + CommandBinaryBuffer.prototype.constructor = CommandBinaryBuffer; + CommandBinaryBuffer.getMagneticInfluenceBit = byte => !!extractBits(byte, 1, MAGNETIC_INFLUENCE_BIT_INDEX); + CommandBinaryBuffer.setMagneticInfluenceBit = (byte, value) => fillBits(byte, 1, MAGNETIC_INFLUENCE_BIT_INDEX, +value); + CommandBinaryBuffer.getLegacyHourCounterSize = hourCounter => LEGACY_HOUR_COUNTER_SIZE + hourCounter.diff.length * LEGACY_HOUR_DIFF_SIZE; + CommandBinaryBuffer.prototype.getExtendedValue = function () { + let value = 0; + let isByteExtended = true; + let position = 0; + while (isByteExtended && this.offset <= this.data.length) { + const byte = this.getUint8(); + isByteExtended = !!(byte & EXTEND_BIT_MASK); + value += (byte & 0x7f) << 7 * position >>> 0; + ++position; + } + return value; + }; + CommandBinaryBuffer.prototype.setExtendedValue = function (value) { + if (value === 0) { + this.setUint8(0); + return; + } + const data = []; + let encodedValue = value; + while (encodedValue) { + data.push(EXTEND_BIT_MASK | encodedValue & 0x7f); + encodedValue >>>= 7; + } + const lastByte = data.pop(); + if (lastByte) { + data.push(lastByte & 0x7f); + } + data.forEach(extendedValue => this.setUint8(extendedValue)); + }; + CommandBinaryBuffer.prototype.getExtendedValueSize = function (bits) { + const extBits = Math.ceil(bits / 7); + const totalBits = bits + extBits; + const extBytes = Math.ceil(totalBits / 8); + return extBytes; + }; + CommandBinaryBuffer.prototype.getTime = function () { + return this.getUint32(); + }; + CommandBinaryBuffer.prototype.setTime = function (value) { + this.setUint32(value); + }; + CommandBinaryBuffer.prototype.getBatteryVoltage = function () { + const lowVoltageByte = this.getUint8(); + const lowAndHightVoltageByte = this.getUint8(); + const highVoltageByte = this.getUint8(); + let underLowLoad = lowVoltageByte << 4; + underLowLoad |= (lowAndHightVoltageByte & 0xf0) >> 4; + let underHighLoad = (lowAndHightVoltageByte & 0x0f) << 8 | highVoltageByte; + if (underHighLoad === UNKNOWN_BATTERY_VOLTAGE) { + underHighLoad = undefined; + } + if (underLowLoad === UNKNOWN_BATTERY_VOLTAGE) { + underLowLoad = undefined; + } + return { + underLowLoad, + underHighLoad + }; + }; + CommandBinaryBuffer.prototype.setBatteryVoltage = function (batteryVoltage) { + let { + underLowLoad, + underHighLoad + } = batteryVoltage; + if (underLowLoad === undefined) { + underLowLoad = UNKNOWN_BATTERY_VOLTAGE; + } + if (underHighLoad === undefined) { + underHighLoad = UNKNOWN_BATTERY_VOLTAGE; + } + const lowVoltageByte = underLowLoad >> 4 & 0xff; + const lowAndHighVoltageByte = (underLowLoad & 0x0f) << 4 | underHighLoad >> 8 & 0x0f; + const highVoltageByte = underHighLoad & 0xff; + [lowVoltageByte, lowAndHighVoltageByte, highVoltageByte].forEach(byte => this.setUint8(byte)); + }; + CommandBinaryBuffer.prototype.getLegacyCounterValue = function () { + return this.getUint24(); + }; + CommandBinaryBuffer.prototype.setLegacyCounterValue = function (value) { + this.setUint24(value); + }; + CommandBinaryBuffer.prototype.getLegacyCounter = function () { + let byte = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : this.getUint8(); + let isArchiveValue = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : false; + const value = this.getLegacyCounterValue(); + return { + isMagneticInfluence: CommandBinaryBuffer.getMagneticInfluenceBit(byte), + value: isArchiveValue && value === EMPTY_VALUE ? 0 : value + }; + }; + CommandBinaryBuffer.prototype.setLegacyCounter = function (counter) { + let byte = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : 0; + let isArchiveValue = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : false; + this.setUint8(CommandBinaryBuffer.setMagneticInfluenceBit(byte, counter.isMagneticInfluence)); + this.setLegacyCounterValue(isArchiveValue && counter.value === 0 ? EMPTY_VALUE : counter.value); + }; + CommandBinaryBuffer.prototype.getChannels = function () { + const channelList = []; + let extended = true; + let channelIndex = 1; + while (extended) { + const byte = this.getUint8(); + const bits = byte.toString(2).padStart(LAST_BIT_INDEX + 1, '0').split('').reverse(); + bits.forEach((bit, index) => { + const value = Number(bit); + if (index === LAST_BIT_INDEX) { + extended = !!value; + } else { + if (value) { + channelList.push(channelIndex); + } + ++channelIndex; + } + }); + } + return channelList; + }; + CommandBinaryBuffer.prototype.setChannels = function (channelList) { + if (channelList.length === 0) { + this.setUint8(0); + return; + } + channelList.sort((a, b) => a.index - b.index); + const maxChannel = Math.max(...channelList.map(_ref2 => { + let { + index + } = _ref2; + return index; + })); + const size = (maxChannel - maxChannel % 8) / 8; + const data = new Array(size + 1).fill(0); + let byte = 0; + data.forEach((_, byteIndex) => { + let channelIndex = byteIndex * LAST_BIT_INDEX + 1; + const maxChannelIndex = channelIndex + LAST_BIT_INDEX; + while (channelIndex < maxChannelIndex) { + const channel = channelList.find(item => item.index === channelIndex); + if (channel !== undefined) { + byte |= 1 << (channel.index - 1) % LAST_BIT_INDEX; + } + ++channelIndex; + } + if (data[byteIndex + 1] !== undefined) { + byte |= 1 << LAST_BIT_INDEX; + } + data[byteIndex] = byte; + byte = 0; + }); + data.forEach(value => this.setUint8(value)); + }; + CommandBinaryBuffer.prototype.getChannelValue = function () { + return this.getUint8() + 1; + }; + CommandBinaryBuffer.prototype.setChannelValue = function (value) { + if (value < 1) { + throw new Error('channel must be 1 or greater'); + } + this.setUint8(value - 1); + }; + CommandBinaryBuffer.prototype.getChannelsValuesWithHourDiff = function () { + let isArchiveValue = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : false; + const date = this.getDate(); + const { + hour, + hours + } = this.getHours(); + const channels = this.getChannels(); + const channelList = []; + date.setUTCHours(hour); + channels.forEach(channelIndex => { + const diff = []; + const value = this.getExtendedValue(); + for (let diffHour = 1; diffHour < hours; ++diffHour) { + diff.push(this.getExtendedValue()); + } + channelList.push({ + value: value === isArchiveValue && EMPTY_VALUE ? 0 : value, + diff, + index: channelIndex + }); + }); + return { + startTime2000: getTime2000FromDate(date), + hours, + channelList + }; + }; + CommandBinaryBuffer.prototype.setChannelsValuesWithHourDiff = function (hours, startTime2000, channelList) { + let isArchiveValue = arguments.length > 3 && arguments[3] !== undefined ? arguments[3] : false; + const date = getDateFromTime2000(startTime2000); + const hour = date.getUTCHours(); + this.setDate(date); + this.setHours(hour, hours); + this.setChannels(channelList); + channelList.forEach(_ref3 => { + let { + value, + diff + } = _ref3; + this.setExtendedValue(isArchiveValue && value === 0 ? EMPTY_VALUE : value); + diff.forEach(diffValue => this.setExtendedValue(diffValue)); + }); + }; + CommandBinaryBuffer.prototype.getHours = function () { + let byte = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : this.getUint8(); + if (byte === 0) { + return { + hours: 0, + hour: 0 + }; + } + const hours = ((byte & 0xe0) >> 5) + 1; + const hour = byte & 0x1f; + return { + hours, + hour + }; + }; + CommandBinaryBuffer.prototype.setHours = function (hour, hours) { + if (hour === 0 && hours === 0) { + this.setUint8(0); + return; + } + this.setUint8((hours - 1 & 0x07) << 5 | hour & 0x1f); + }; + CommandBinaryBuffer.prototype.getDate = function () { + const yearMonthByte = this.getUint8(); + const monthDateByte = this.getUint8(); + const year = yearMonthByte >> YEAR_START_INDEX; + const month = (yearMonthByte & 0x01) << MONTH_BIT_SIZE - YEAR_START_INDEX | monthDateByte >> DATE_BIT_SIZE; + const monthDay = monthDateByte & 0x1f; + return new Date(Date.UTC(year + INITIAL_YEAR, month - 1, monthDay, 0, 0, 0, 0)); + }; + CommandBinaryBuffer.prototype.setDate = function (dateOrTime) { + let date; + if (dateOrTime instanceof Date) { + date = dateOrTime; + } else { + date = getDateFromTime2000(dateOrTime); + } + const year = date.getUTCFullYear() - INITIAL_YEAR; + const month = date.getUTCMonth() + 1; + const day = date.getUTCDate(); + const yearMonthByte = year << YEAR_START_INDEX | month >> MONTH_BIT_SIZE - YEAR_START_INDEX; + const monthDateByte = (month & 0x07) << DATE_BIT_SIZE | day; + [yearMonthByte, monthDateByte].forEach(byte => this.setUint8(byte)); + }; + CommandBinaryBuffer.prototype.getPulseCoefficient = function () { + const pulseCoefficient = this.getUint8(); + if (isMSBSet(pulseCoefficient)) { + const value = byteToPulseCoefficientMap[pulseCoefficient]; + if (value) { + return value; + } + throw new Error('pulseCoefficient MSB is set, but value unknown'); + } + return pulseCoefficient; + }; + CommandBinaryBuffer.prototype.setPulseCoefficient = function (value) { + if (value in pulseCoefficientToByteMap) { + const byte = pulseCoefficientToByteMap[value]; + if (byte) { + this.setUint8(byte); + } else { + throw new Error('pulseCoefficient MSB is set, but value unknown'); + } + } else { + this.setUint8(value); + } + }; + CommandBinaryBuffer.prototype.getChannelsWithAbsoluteValues = function () { + const channels = this.getChannels(); + const channelList = []; + channels.forEach(channelIndex => { + channelList.push({ + pulseCoefficient: this.getPulseCoefficient(), + value: this.getExtendedValue(), + index: channelIndex + }); + }); + return channelList; + }; + CommandBinaryBuffer.prototype.setChannelsWithAbsoluteValues = function (channelList) { + this.setChannels(channelList); + channelList.forEach(_ref4 => { + let { + value, + pulseCoefficient + } = _ref4; + this.setPulseCoefficient(pulseCoefficient); + this.setExtendedValue(value); + }); + }; + CommandBinaryBuffer.prototype.getChannelsAbsoluteValuesWithHourDiff = function (hours) { + const channels = this.getChannels(); + const channelList = []; + channels.forEach(channelIndex => { + const pulseCoefficient = this.getPulseCoefficient(); + const value = this.getExtendedValue(); + const diff = []; + for (let hourIndex = 1; hourIndex < hours; ++hourIndex) { + diff.push(this.getExtendedValue()); + } + channelList.push({ + diff, + value, + pulseCoefficient, + index: channelIndex + }); + }); + return channelList; + }; + CommandBinaryBuffer.prototype.setChannelsAbsoluteValuesWithHourDiff = function (channelList) { + this.setChannels(channelList); + channelList.forEach(_ref5 => { + let { + value, + diff, + pulseCoefficient + } = _ref5; + this.setPulseCoefficient(pulseCoefficient); + this.setExtendedValue(value); + diff.forEach(diffValue => this.setExtendedValue(diffValue)); + }); + }; + CommandBinaryBuffer.prototype.getEventStatus = function (hardwareType) { + let status; + if (GAS_HARDWARE_TYPES.indexOf(hardwareType) !== -1) { + status = toObject(gasBitMask, this.getUint8()); + } else if (TWO_CHANNELS_HARDWARE_TYPES.indexOf(hardwareType) !== -1) { + status = toObject(twoChannelBitMask, this.getUint8()); + } else if (ELIMP_HARDWARE_TYPES.indexOf(hardwareType) !== -1) { + status = toObject(elimpBitMask, this.getUint8()); + } else if (FOUR_CHANNELS_HARDWARE_TYPES.indexOf(hardwareType) !== -1) { + status = toObject(fourChannelBitMask, this.getUint16(true)); + } else if (MTX_HARDWARE_TYPES.indexOf(hardwareType) !== -1) { + status = toObject(mtxBitMask, this.getUint16(true)); + } else if (hardwareType === US_WATER) { + const event = toObject(usWaterMeterEventBitMask, this.getUint8()); + status = { + event, + error: this.getUint8() + }; + } else { + throw new Error('wrong hardwareType'); + } + return status; + }; + CommandBinaryBuffer.prototype.setEventStatus = function (hardwareType, status) { + if (GAS_HARDWARE_TYPES.indexOf(hardwareType) !== -1) { + this.setUint8(fromObject(gasBitMask, status)); + } else if (TWO_CHANNELS_HARDWARE_TYPES.indexOf(hardwareType) !== -1) { + this.setUint8(fromObject(twoChannelBitMask, status)); + } else if (ELIMP_HARDWARE_TYPES.indexOf(hardwareType) !== -1) { + this.setUint8(fromObject(elimpBitMask, status)); + } else if (FOUR_CHANNELS_HARDWARE_TYPES.indexOf(hardwareType) !== -1) { + this.setUint16(fromObject(fourChannelBitMask, status) | 1 << 7, true); + } else if (MTX_HARDWARE_TYPES.indexOf(hardwareType) !== -1) { + this.setUint16(fromObject(mtxBitMask, status), true); + } else if (hardwareType === US_WATER) { + const data = status; + this.setUint8(fromObject(usWaterMeterEventBitMask, data.event)); + this.setUint8(data.error); + } else { + throw new Error('wrong hardwareType'); + } + }; + CommandBinaryBuffer.prototype.getParameter = function () { + const id = this.getUint8(); + const name = deviceParameterNames[id]; + if (!deviceParameterConvertersMap[id] || !deviceParameterConvertersMap[id].get) { + throw new Error(`parameter ${id} is not supported`); + } + const data = deviceParameterConvertersMap[id].get(this); + return { + id, + name, + data + }; + }; + CommandBinaryBuffer.prototype.setParameter = function (parameter) { + const { + id, + data + } = parameter; + if (!deviceParameterConvertersMap[id] || !deviceParameterConvertersMap[id].set) { + throw new Error(`parameter ${id} is not supported`); + } + this.setUint8(id); + deviceParameterConvertersMap[id].set(this, data); + }; + CommandBinaryBuffer.prototype.getRequestParameter = function () { + const id = this.getUint8(); + const name = deviceParameterNames[id]; + let data = null; + switch (id) { + case ABSOLUTE_DATA_ENABLE_MULTI_CHANNEL: + case ABSOLUTE_DATA_MULTI_CHANNEL: + case CHANNEL_TYPE: + data = { + channel: this.getChannelValue() + }; + break; + case REPORTING_DATA_CONFIG: + data = { + dataType: this.getUint8() + }; + break; + case EVENTS_CONFIG: + data = { + eventId: this.getUint8() + }; + break; + } + return { + id, + name, + data + }; + }; + CommandBinaryBuffer.prototype.setRequestParameter = function (parameter) { + const { + id, + data: parameterData + } = parameter; + let data; + this.setUint8(id); + switch (id) { + case ABSOLUTE_DATA_MULTI_CHANNEL: + case ABSOLUTE_DATA_ENABLE_MULTI_CHANNEL: + case CHANNEL_TYPE: + data = parameterData; + this.setChannelValue(data.channel); + break; + case REPORTING_DATA_CONFIG: + data = parameterData; + this.setUint8(data.dataType); + break; + case EVENTS_CONFIG: + data = parameterData; + this.setUint8(data.eventId); + break; + } + }; + CommandBinaryBuffer.prototype.getResponseParameter = function () { + const id = this.getUint8(); + const name = deviceParameterNames[id]; + let data; + if (!deviceParameterConvertersMap[id] || !deviceParameterConvertersMap[id].get) { + throw new Error(`parameter ${id} is not supported`); + } + switch (id) { + case MQTT_SESSION_CONFIG: + case NBIOT_SSL_CACERT_WRITE: + case NBIOT_SSL_CLIENT_CERT_WRITE: + case NBIOT_SSL_CLIENT_KEY_WRITE: + case NBIOT_SSL_CACERT_SET: + case NBIOT_SSL_CLIENT_CERT_SET: + case NBIOT_SSL_CLIENT_KEY_SET: + case NBIOT_DEVICE_SOFTWARE_UPDATE: + case NBIOT_MODULE_FIRMWARE_UPDATE: + data = null; + break; + default: + data = deviceParameterConvertersMap[id].get(this); + } + return { + id, + name, + data + }; + }; + CommandBinaryBuffer.prototype.setResponseParameter = function (parameter) { + const { + id, + data + } = parameter; + if (!deviceParameterConvertersMap[id] || !deviceParameterConvertersMap[id].set) { + throw new Error(`parameter ${id} is not supported`); + } + this.setUint8(id); + switch (id) { + case MQTT_SESSION_CONFIG: + case NBIOT_SSL_CACERT_WRITE: + case NBIOT_SSL_CLIENT_CERT_WRITE: + case NBIOT_SSL_CLIENT_KEY_WRITE: + case NBIOT_SSL_CACERT_SET: + case NBIOT_SSL_CLIENT_CERT_SET: + case NBIOT_SSL_CLIENT_KEY_SET: + case NBIOT_DEVICE_SOFTWARE_UPDATE: + case NBIOT_MODULE_FIRMWARE_UPDATE: + break; + default: + deviceParameterConvertersMap[id].set(this, data); + } + }; + CommandBinaryBuffer.prototype.getLegacyHourDiff = function () { + const stateWithValueByte = this.getUint8(); + const valueLowerByte = this.getUint8(); + return { + isMagneticInfluence: CommandBinaryBuffer.getMagneticInfluenceBit(stateWithValueByte), + value: (stateWithValueByte & 0x1f) << 8 | valueLowerByte + }; + }; + CommandBinaryBuffer.prototype.setLegacyHourDiff = function (diff) { + const bytes = [diff.value >> 8, diff.value & 0xff]; + bytes[0] = CommandBinaryBuffer.setMagneticInfluenceBit(bytes[0], diff.isMagneticInfluence); + bytes.forEach(byte => this.setUint8(byte)); + }; + CommandBinaryBuffer.prototype.getLegacyHourCounterWithDiff = function () { + let isArchiveValue = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : false; + const date = this.getDate(); + const byte = this.getUint8(); + const { + hour + } = this.getHours(byte); + const value = this.getLegacyCounterValue(); + const counter = { + isMagneticInfluence: CommandBinaryBuffer.getMagneticInfluenceBit(byte), + value: isArchiveValue && value === EMPTY_VALUE ? 0 : value + }; + const diff = []; + while (this.offset < this.data.length) { + diff.push(this.getLegacyHourDiff()); + } + date.setUTCHours(hour); + return { + startTime2000: getTime2000FromDate(date), + counter, + diff + }; + }; + CommandBinaryBuffer.prototype.setLegacyHourCounterWithDiff = function (hourCounter) { + let isArchiveValue = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : false; + const date = getDateFromTime2000(hourCounter.startTime2000); + const hour = date.getUTCHours(); + const { + value + } = hourCounter.counter; + this.setDate(date); + this.setHours(hour, 1); + this.seek(this.offset - 1); + const byte = this.getUint8(); + this.seek(this.offset - 1); + this.setUint8(CommandBinaryBuffer.setMagneticInfluenceBit(byte, hourCounter.counter.isMagneticInfluence)); + this.setLegacyCounterValue(isArchiveValue && value === 0 ? EMPTY_VALUE : value); + hourCounter.diff.forEach(diffItem => this.setLegacyHourDiff(diffItem)); + }; + CommandBinaryBuffer.prototype.getChannelsValuesWithHourDiffExtended = function () { + let isArchiveValue = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : false; + const date = this.getDate(); + const hour = this.getUint8(); + const hours = this.getUint8(); + const channels = this.getChannels(); + const channelList = []; + date.setUTCHours(hour); + channels.forEach(channelIndex => { + const diff = []; + const value = this.getExtendedValue(); + for (let diffHour = 0; diffHour < hours; ++diffHour) { + diff.push(this.getExtendedValue()); + } + channelList.push({ + value: value === isArchiveValue && EMPTY_VALUE ? 0 : value, + diff, + index: channelIndex + }); + }); + return { + startTime2000: getTime2000FromDate(date), + hour, + hours, + channelList + }; + }; + CommandBinaryBuffer.prototype.setChannelsValuesWithHourDiffExtended = function (parameters) { + let isArchiveValue = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : false; + const date = getDateFromTime2000(parameters.startTime2000); + this.setDate(date); + this.setUint8(parameters.hour); + this.setUint8(parameters.hours); + this.setChannels(parameters.channelList); + parameters.channelList.forEach(_ref6 => { + let { + value, + diff + } = _ref6; + this.setExtendedValue(isArchiveValue && value === 0 ? EMPTY_VALUE : value); + diff.forEach(diffValue => this.setExtendedValue(diffValue)); + }); + }; + CommandBinaryBuffer.prototype.getDataSegment = function () { + const segmentationSessionId = this.getUint8(); + const flag = this.getUint8(); + return { + segmentationSessionId, + segmentIndex: extractBits(flag, 3, 1), + segmentsNumber: extractBits(flag, 3, 5), + isLast: Boolean(extractBits(flag, 1, 8)), + data: this.getBytesLeft() + }; + }; + CommandBinaryBuffer.prototype.setDataSegment = function (parameters) { + let flag = fillBits(0, 3, 1, parameters.segmentIndex); + flag = fillBits(flag, 3, 5, parameters.segmentsNumber); + flag = fillBits(flag, 1, 8, +parameters.isLast); + this.setUint8(parameters.segmentationSessionId); + this.setUint8(flag); + this.setBytes(parameters.data); + }; + CommandBinaryBuffer.prototype.getBinarySensor = function () { + const activeStateTimeMs = this.getUint16(); + return { + activeStateTimeMs + }; + }; + CommandBinaryBuffer.prototype.setBinarySensor = function (parameters) { + this.setUint16(parameters.activeStateTimeMs); + }; + CommandBinaryBuffer.prototype.getTemperatureSensor = function () { + const measurementPeriod = this.getUint16(); + const hysteresisSec = this.getUint8(); + const highTemperatureThreshold = this.getInt8(); + const lowTemperatureThreshold = this.getInt8(); + return { + measurementPeriod, + hysteresisSec, + highTemperatureThreshold, + lowTemperatureThreshold + }; + }; + CommandBinaryBuffer.prototype.setTemperatureSensor = function (parameters) { + this.setInt16(parameters.measurementPeriod); + this.setInt8(parameters.hysteresisSec); + this.setInt8(parameters.highTemperatureThreshold); + this.setInt8(parameters.lowTemperatureThreshold); + }; + CommandBinaryBuffer.prototype.getChannelType = function () { + const channel = this.getChannelValue(); + const type = this.getUint8(); + let parameters = {}; + switch (type) { + case BINARY_SENSOR: + parameters = this.getBinarySensor(); + break; + case TEMPERATURE_SENSOR: + parameters = this.getTemperatureSensor(); + break; + } + return { + channel, + type, + parameters + }; + }; + CommandBinaryBuffer.prototype.setChannelType = function (_ref7) { + let { + type, + channel, + parameters + } = _ref7; + this.setChannelValue(channel); + this.setUint8(type); + switch (type) { + case BINARY_SENSOR: + this.setBinarySensor(parameters); + break; + case TEMPERATURE_SENSOR: + this.setTemperatureSensor(parameters); + break; + } + }; + + const id$Z = dataSegment$1; + downlinkNames[dataSegment$1]; + const COMMAND_BODY_MIN_SIZE$3 = 2; + const fromBytes$ = data => { + const buffer = new CommandBinaryBuffer(data); + return buffer.getDataSegment(); + }; + const toBytes$ = parameters => { + const buffer = new CommandBinaryBuffer(COMMAND_BODY_MIN_SIZE$3 + parameters.data.length); + buffer.setDataSegment(parameters); + return toBytes$11(id$Z, buffer.data); + }; + + const id$Y = getArchiveDays$1; + downlinkNames[getArchiveDays$1]; + const COMMAND_BODY_SIZE$v = 3; + const fromBytes$_ = data => { + if (data.length !== COMMAND_BODY_SIZE$v) { + throw new Error(`Wrong buffer size: ${data.length}.`); + } + const buffer = new CommandBinaryBuffer(data); + const date = buffer.getDate(); + const days = buffer.getUint8(); + if (!buffer.isEmpty) { + throw new Error('BinaryBuffer is not empty.'); + } + return { + startTime2000: getTime2000FromDate(date), + days + }; + }; + const toBytes$_ = parameters => { + const buffer = new CommandBinaryBuffer(COMMAND_BODY_SIZE$v); + const { + startTime2000, + days + } = parameters; + const date = getDateFromTime2000(startTime2000); + buffer.setDate(date); + buffer.setUint8(days); + return toBytes$11(id$Y, buffer.data); + }; + + const id$X = getArchiveDaysMc$1; + downlinkNames[getArchiveDaysMc$1]; + const COMMAND_BODY_SIZE$u = 4; + const fromBytes$Z = data => { + if (data.length !== COMMAND_BODY_SIZE$u) { + throw new Error(`Wrong buffer size: ${data.length}.`); + } + const buffer = new CommandBinaryBuffer(data); + const date = buffer.getDate(); + const channelList = buffer.getChannels(); + const days = buffer.getUint8(); + if (!buffer.isEmpty) { + throw new Error('BinaryBuffer is not empty.'); + } + return { + startTime2000: getTime2000FromDate(date), + days, + channelList + }; + }; + const toBytes$Z = parameters => { + const buffer = new CommandBinaryBuffer(COMMAND_BODY_SIZE$u); + const { + startTime2000, + days, + channelList + } = parameters; + const date = getDateFromTime2000(startTime2000); + buffer.setDate(date); + buffer.setChannels(channelList.map(index => ({ + index + }))); + buffer.setUint8(days); + return toBytes$11(id$X, buffer.data); + }; + + const id$W = getArchiveEvents$1; + downlinkNames[getArchiveEvents$1]; + const COMMAND_BODY_SIZE$t = 5; + const fromBytes$Y = data => { + if (data.length !== COMMAND_BODY_SIZE$t) { + throw new Error(`Wrong buffer size: ${data.length}.`); + } + const buffer = new CommandBinaryBuffer(data); + const startTime2000 = buffer.getTime(); + const events = buffer.getUint8(); + if (!buffer.isEmpty) { + throw new Error('BinaryBuffer is not empty.'); + } + return { + startTime2000, + events + }; + }; + const toBytes$Y = parameters => { + const { + startTime2000, + events + } = parameters; + const buffer = new CommandBinaryBuffer(COMMAND_BODY_SIZE$t); + buffer.setTime(startTime2000); + buffer.setUint8(events); + return toBytes$11(id$W, buffer.data); + }; + + const id$V = getArchiveHours$1; + downlinkNames[getArchiveHours$1]; + const COMMAND_BODY_SIZE$s = 4; + const fromBytes$X = data => { + if (data.length !== COMMAND_BODY_SIZE$s) { + throw new Error(`Wrong buffer size: ${data.length}.`); + } + const buffer = new CommandBinaryBuffer(data); + const date = buffer.getDate(); + const { + hour + } = buffer.getHours(); + const hours = buffer.getUint8(); + date.setUTCHours(hour); + if (!buffer.isEmpty) { + throw new Error('BinaryBuffer is not empty.'); + } + return { + startTime2000: getTime2000FromDate(date), + hours + }; + }; + const toBytes$X = parameters => { + const { + startTime2000, + hours + } = parameters; + const buffer = new CommandBinaryBuffer(COMMAND_BODY_SIZE$s); + const date = getDateFromTime2000(startTime2000); + const hour = date.getUTCHours(); + buffer.setDate(date); + buffer.setHours(hour, 1); + buffer.setUint8(hours); + return toBytes$11(id$V, buffer.data); + }; + + const id$U = getArchiveHoursMc$1; + downlinkNames[getArchiveHoursMc$1]; + const COMMAND_BODY_SIZE$r = 4; + const fromBytes$W = data => { + if (data.length !== COMMAND_BODY_SIZE$r) { + throw new Error(`Wrong buffer size: ${data.length}.`); + } + const buffer = new CommandBinaryBuffer(data); + const date = buffer.getDate(); + const { + hour, + hours + } = buffer.getHours(); + const channelList = buffer.getChannels(); + date.setUTCHours(hour); + if (!buffer.isEmpty) { + throw new Error('BinaryBuffer is not empty.'); + } + return { + startTime2000: getTime2000FromDate(date), + hours, + channelList + }; + }; + const toBytes$W = parameters => { + const buffer = new CommandBinaryBuffer(COMMAND_BODY_SIZE$r); + const { + hours, + startTime2000, + channelList + } = parameters; + const date = getDateFromTime2000(startTime2000); + const hour = date.getUTCHours(); + buffer.setDate(date); + buffer.setHours(hour, hours); + buffer.setChannels(channelList.map(index => ({ + index + }))); + return toBytes$11(id$U, buffer.data); + }; + + const id$T = getArchiveHoursMcEx$1; + downlinkNames[getArchiveHoursMcEx$1]; + const COMMAND_BODY_SIZE$q = 5; + const fromBytes$V = data => { + const buffer = new CommandBinaryBuffer(data); + const date = buffer.getDate(); + const hour = buffer.getUint8(); + const hours = buffer.getUint8(); + const channelList = buffer.getChannels(); + date.setUTCHours(hour); + if (!buffer.isEmpty) { + throw new Error('BinaryBuffer is not empty.'); + } + return { + startTime2000: getTime2000FromDate(date), + hour, + hours, + channelList + }; + }; + const toBytes$V = parameters => { + const buffer = new CommandBinaryBuffer(COMMAND_BODY_SIZE$q); + const { + channelList, + hour, + hours, + startTime2000 + } = parameters; + const date = getDateFromTime2000(startTime2000); + buffer.setDate(date); + buffer.setUint8(hour); + buffer.setUint8(hours); + buffer.setChannels(channelList.map(index => ({ + index + }))); + return toBytes$11(id$T, buffer.data); + }; + + const id$S = getBatteryStatus$1; + downlinkNames[getBatteryStatus$1]; + const COMMAND_BODY_SIZE$p = 0; + const fromBytes$U = data => { + if (data.length !== COMMAND_BODY_SIZE$p) { + throw new Error(`Wrong buffer size: ${data.length}.`); + } + return {}; + }; + const toBytes$U = () => toBytes$11(id$S); + + const id$R = getChannelsStatus$1; + downlinkNames[getChannelsStatus$1]; + const fromBytes$T = data => data.length === 0 ? {} : getChannelsMaskFromNumber(data[0]); + const toBytes$T = parameters => toBytes$11(id$R, Object.keys(parameters).length !== 0 ? [setChannelsMaskToNumber(parameters)] : []); + + const id$Q = getChannelsTypes$1; + downlinkNames[getChannelsTypes$1]; + const COMMAND_BODY_SIZE$o = 0; + const fromBytes$S = data => { + if (data.length !== COMMAND_BODY_SIZE$o) { + throw new Error(`Wrong buffer size: ${data.length}.`); + } + return {}; + }; + const toBytes$S = () => toBytes$11(id$Q); + + const id$P = getCurrent; + downlinkNames[getCurrent]; + const COMMAND_BODY_SIZE$n = 0; + const fromBytes$R = data => { + if (data.length !== COMMAND_BODY_SIZE$n) { + throw new Error(`Wrong buffer size: ${data.length}.`); + } + return {}; + }; + const toBytes$R = () => toBytes$11(id$P); + + const id$O = getCurrentMc; + downlinkNames[getCurrentMc]; + const COMMAND_BODY_SIZE$m = 0; + const fromBytes$Q = data => { + if (data.length !== COMMAND_BODY_SIZE$m) { + throw new Error(`Wrong buffer size: ${data.length}.`); + } + return {}; + }; + const toBytes$Q = () => toBytes$11(id$O); + + const id$N = getExAbsArchiveDaysMc$1; + downlinkNames[getExAbsArchiveDaysMc$1]; + const COMMAND_BODY_SIZE$l = 4; + const fromBytes$P = data => { + if (data.length !== COMMAND_BODY_SIZE$l) { + throw new Error(`Wrong buffer size: ${data.length}.`); + } + const buffer = new CommandBinaryBuffer(data); + const date = buffer.getDate(); + const channelList = buffer.getChannels(); + const days = buffer.getUint8(); + if (!buffer.isEmpty) { + throw new Error('BinaryBuffer is not empty.'); + } + return { + startTime2000: getTime2000FromDate(date), + days, + channelList + }; + }; + const toBytes$P = parameters => { + const buffer = new CommandBinaryBuffer(COMMAND_BODY_SIZE$l); + const { + startTime2000, + days, + channelList + } = parameters; + buffer.setDate(startTime2000); + buffer.setChannels(channelList.map(index => ({ + index + }))); + buffer.setUint8(days); + return toBytes$11(id$N, buffer.data); + }; + + const id$M = getExAbsArchiveHoursMc$1; + downlinkNames[getExAbsArchiveHoursMc$1]; + const COMMAND_BODY_SIZE$k = 4; + const fromBytes$O = data => { + const buffer = new CommandBinaryBuffer(data); + const date = buffer.getDate(); + const { + hour, + hours + } = buffer.getHours(); + const channelList = buffer.getChannels(); + date.setUTCHours(hour); + if (!buffer.isEmpty) { + throw new Error('BinaryBuffer is not empty.'); + } + return { + channelList, + hours, + startTime2000: getTime2000FromDate(date) + }; + }; + const toBytes$O = parameters => { + const buffer = new CommandBinaryBuffer(COMMAND_BODY_SIZE$k); + const { + startTime2000, + hours, + channelList + } = parameters; + const date = getDateFromTime2000(startTime2000); + const hour = date.getUTCHours(); + buffer.setDate(date); + buffer.setHours(hour, hours); + buffer.setChannels(channelList.map(index => ({ + index + }))); + return toBytes$11(id$M, buffer.data); + }; + + const id$L = getExAbsCurrentMc; + downlinkNames[getExAbsCurrentMc]; + const COMMAND_BODY_SIZE$j = 0; + const fromBytes$N = data => { + if (data.length !== COMMAND_BODY_SIZE$j) { + throw new Error(`Wrong buffer size: ${data.length}.`); + } + return {}; + }; + const toBytes$N = () => toBytes$11(id$L); + + const id$K = getLmicInfo$1; + downlinkNames[getLmicInfo$1]; + const COMMAND_BODY_SIZE$i = 0; + const fromBytes$M = data => { + if (data.length !== COMMAND_BODY_SIZE$i) { + throw new Error(`Wrong buffer size: ${data.length}.`); + } + return {}; + }; + const toBytes$M = () => toBytes$11(id$K); + + const id$J = getParameter$1; + downlinkNames[getParameter$1]; + const fromBytes$L = data => { + const buffer = new CommandBinaryBuffer(data); + return buffer.getRequestParameter(); + }; + const toBytes$L = parameters => { + const buffer = new CommandBinaryBuffer(getRequestParameterSize(parameters)); + buffer.setRequestParameter(parameters); + return toBytes$11(id$J, buffer.data); + }; + + const id$I = getStatus; + downlinkNames[getStatus]; + const COMMAND_BODY_SIZE$h = 0; + const fromBytes$K = data => { + if (data.length !== COMMAND_BODY_SIZE$h) { + throw new Error(`Wrong buffer size: ${data.length}.`); + } + return {}; + }; + const toBytes$K = () => toBytes$11(id$I); + + const id$H = getTime2000; + downlinkNames[getTime2000]; + const COMMAND_BODY_SIZE$g = 0; + const fromBytes$J = data => { + if (data.length !== COMMAND_BODY_SIZE$g) { + throw new Error(`Wrong buffer size: ${data.length}.`); + } + return {}; + }; + const toBytes$J = () => toBytes$11(id$H, []); + + const id$G = setParameter$1; + downlinkNames[setParameter$1]; + const fromBytes$I = data => { + const buffer = new CommandBinaryBuffer(data); + return buffer.getParameter(); + }; + const toBytes$I = parameters => { + const buffer = new CommandBinaryBuffer(getParameterSize(parameters)); + buffer.setParameter(parameters); + return toBytes$11(id$G, buffer.data); + }; + + const id$F = setTime2000$1; + downlinkNames[setTime2000$1]; + const COMMAND_BODY_SIZE$f = 5; + const fromBytes$H = data => { + if (data.length !== COMMAND_BODY_SIZE$f) { + throw new Error(`Wrong buffer size: ${data.length}.`); + } + const buffer = new BinaryBuffer(data, false); + const parameters = { + sequenceNumber: buffer.getUint8(), + seconds: buffer.getInt32() + }; + if (!buffer.isEmpty) { + throw new Error('BinaryBuffer is not empty.'); + } + return parameters; + }; + const toBytes$H = parameters => { + const { + sequenceNumber, + seconds + } = parameters; + const buffer = new BinaryBuffer(COMMAND_BODY_SIZE$f, false); + buffer.setUint8(sequenceNumber); + buffer.setInt32(seconds); + return toBytes$11(id$F, buffer.data); + }; + + const id$E = softRestart$1; + downlinkNames[softRestart$1]; + const COMMAND_BODY_SIZE$e = 0; + const fromBytes$G = data => { + if (data.length !== COMMAND_BODY_SIZE$e) { + throw new Error(`Wrong buffer size: ${data.length}.`); + } + return {}; + }; + const toBytes$G = () => toBytes$11(id$E); + + const id$D = updateRun$1; + downlinkNames[updateRun$1]; + const COMMAND_BODY_SIZE$d = 0; + const fromBytes$F = data => { + if (data.length !== COMMAND_BODY_SIZE$d) { + throw new Error(`Wrong buffer size: ${data.length}.`); + } + return {}; + }; + const toBytes$F = () => toBytes$11(id$D); + + const id$C = usWaterMeterCommand$1; + downlinkNames[usWaterMeterCommand$1]; + const fromBytes$E = data => { + const buffer = new CommandBinaryBuffer(data); + const length = buffer.getUint8(); + return { + length, + data: data.slice(1) + }; + }; + const toBytes$E = parameters => { + const { + data, + length + } = parameters; + const buffer = new CommandBinaryBuffer(length); + buffer.setUint8(length); + buffer.setBytes(data); + return toBytes$11(id$C, buffer.data); + }; + + const id$B = verifyImage$1; + downlinkNames[verifyImage$1]; + const COMMAND_BODY_SIZE$c = 0; + const fromBytes$D = data => { + if (data.length !== COMMAND_BODY_SIZE$c) { + throw new Error(`Wrong buffer size: ${data.length}.`); + } + return {}; + }; + const toBytes$D = () => toBytes$11(id$B); + + const id$A = writeImage$1; + downlinkNames[writeImage$1]; + const COMMAND_BODY_MIN_SIZE$2 = 4; + const fromBytes$C = data => { + if (data.length < COMMAND_BODY_MIN_SIZE$2) { + throw new Error(`Wrong buffer size: ${data.length}.`); + } + const buffer = new CommandBinaryBuffer(data); + const offset = buffer.getUint32(); + return { + offset, + data: data.slice(COMMAND_BODY_MIN_SIZE$2) + }; + }; + const toBytes$C = parameters => { + const buffer = new CommandBinaryBuffer(COMMAND_BODY_MIN_SIZE$2); + buffer.setUint32(parameters.offset); + buffer.setBytes(parameters.data); + return toBytes$11(id$A, buffer.data); + }; + + var calculateLrc = (function (data) { + let initialLrc = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : 0x55; + let lrc = initialLrc; + data.forEach(item => { + lrc ^= item; + }); + return lrc; + }); + + const HEADER_MAX_SIZE = 3; + const getFromBytes = (fromBytesMap, nameMap) => function () { + let bytes = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : []; + let config = arguments.length > 1 ? arguments[1] : undefined; + const commands = []; + const message = { + commands, + bytes, + lrc: { + received: undefined, + calculated: 0 + } + }; + let processedBytes = 0; + let receivedLrc; + let calculatedLrc; + if (!bytes.length) { + return message; + } + do { + const headerInfo = fromBytes$11(bytes.slice(processedBytes, processedBytes + HEADER_MAX_SIZE)); + const headerData = bytes.slice(processedBytes, processedBytes + headerInfo.headerSize); + const bodyData = bytes.slice(processedBytes + headerInfo.headerSize, processedBytes + headerInfo.headerSize + headerInfo.commandSize); + const command = { + id: headerInfo.commandId, + name: nameMap[headerInfo.commandId], + headerSize: headerInfo.headerSize, + bytes: [...headerData, ...bodyData] + }; + processedBytes = processedBytes + headerInfo.headerSize + headerInfo.commandSize; + if (config) { + command.config = config; + } + try { + if (!fromBytesMap[headerInfo.commandId]) { + throw new Error(`Unsupported command id: ${headerInfo.commandId}!`); + } + command.parameters = fromBytesMap[headerInfo.commandId](bodyData, config); + commands.push(command); + } catch (error) { + commands.push({ + command, + error: error.message + }); + } + } while (processedBytes < bytes.length - 1); + if (bytes.length - processedBytes === 1) { + receivedLrc = bytes[bytes.length - 1]; + calculatedLrc = calculateLrc(bytes.slice(0, -1)); + } else { + calculatedLrc = calculateLrc(bytes); + } + message.lrc.calculated = calculatedLrc; + message.lrc.received = receivedLrc; + if (receivedLrc === calculatedLrc) { + return message; + } + return { + message, + error: 'Mismatch LRC.' + }; + }; + const getToBytes = toBytesMap => commands => { + const commandBytes = commands.map(command => { + if ('id' in command) { + return toBytesMap[command.id](command.parameters || {}, command.config); + } + if ('command' in command) { + return command.command.bytes; + } + throw new Error('wrong command format'); + }); + const body = [].concat(...commandBytes); + return [...body, calculateLrc(body)]; + }; + const getToMessage = toBytesMap => commands => { + const commandsWithBytes = commands.map(command => { + if ('parameters' in command) { + return Object.assign({}, command, { + bytes: toBytesMap[command.id](command.parameters, command.config) + }); + } + throw new Error('wrong command format'); + }); + const commandBytes = commandsWithBytes.map(_ref => { + let { + bytes + } = _ref; + return bytes; + }); + const body = [].concat(...commandBytes); + const lrc = calculateLrc(body); + return { + commands: commandsWithBytes, + bytes: [...body, lrc], + lrc: { + received: lrc, + calculated: lrc + } + }; + }; + + const toBytesMap$1 = {}; + const fromBytesMap$1 = {}; + const nameMap$1 = downlinkNames; + const fromBytes$B = getFromBytes(fromBytesMap$1, nameMap$1); + const toBytes$B = getToBytes(toBytesMap$1); + const toMessage$1 = getToMessage(toBytesMap$1); + toBytesMap$1[id$_] = toBytes$10; + toBytesMap$1[id$Z] = toBytes$; + toBytesMap$1[id$Y] = toBytes$_; + toBytesMap$1[id$X] = toBytes$Z; + toBytesMap$1[id$W] = toBytes$Y; + toBytesMap$1[id$V] = toBytes$X; + toBytesMap$1[id$U] = toBytes$W; + toBytesMap$1[id$T] = toBytes$V; + toBytesMap$1[id$S] = toBytes$U; + toBytesMap$1[id$R] = toBytes$T; + toBytesMap$1[id$Q] = toBytes$S; + toBytesMap$1[id$P] = toBytes$R; + toBytesMap$1[id$O] = toBytes$Q; + toBytesMap$1[id$N] = toBytes$P; + toBytesMap$1[id$M] = toBytes$O; + toBytesMap$1[id$L] = toBytes$N; + toBytesMap$1[id$K] = toBytes$M; + toBytesMap$1[id$J] = toBytes$L; + toBytesMap$1[id$I] = toBytes$K; + toBytesMap$1[id$H] = toBytes$J; + toBytesMap$1[id$G] = toBytes$I; + toBytesMap$1[id$F] = toBytes$H; + toBytesMap$1[id$E] = toBytes$G; + toBytesMap$1[id$D] = toBytes$F; + toBytesMap$1[id$C] = toBytes$E; + toBytesMap$1[id$B] = toBytes$D; + toBytesMap$1[id$A] = toBytes$C; + fromBytesMap$1[id$_] = fromBytes$10; + fromBytesMap$1[id$Z] = fromBytes$; + fromBytesMap$1[id$Y] = fromBytes$_; + fromBytesMap$1[id$X] = fromBytes$Z; + fromBytesMap$1[id$W] = fromBytes$Y; + fromBytesMap$1[id$V] = fromBytes$X; + fromBytesMap$1[id$U] = fromBytes$W; + fromBytesMap$1[id$T] = fromBytes$V; + fromBytesMap$1[id$S] = fromBytes$U; + fromBytesMap$1[id$R] = fromBytes$T; + fromBytesMap$1[id$Q] = fromBytes$S; + fromBytesMap$1[id$P] = fromBytes$R; + fromBytesMap$1[id$O] = fromBytes$Q; + fromBytesMap$1[id$N] = fromBytes$P; + fromBytesMap$1[id$M] = fromBytes$O; + fromBytesMap$1[id$L] = fromBytes$N; + fromBytesMap$1[id$K] = fromBytes$M; + fromBytesMap$1[id$J] = fromBytes$L; + fromBytesMap$1[id$I] = fromBytes$K; + fromBytesMap$1[id$H] = fromBytes$J; + fromBytesMap$1[id$G] = fromBytes$I; + fromBytesMap$1[id$F] = fromBytes$H; + fromBytesMap$1[id$E] = fromBytes$G; + fromBytesMap$1[id$D] = fromBytes$F; + fromBytesMap$1[id$C] = fromBytes$E; + fromBytesMap$1[id$B] = fromBytes$D; + fromBytesMap$1[id$A] = fromBytes$C; + + var downlink = /*#__PURE__*/Object.freeze({ + __proto__: null, + fromBytes: fromBytes$B, + fromBytesMap: fromBytesMap$1, + nameMap: nameMap$1, + toBytes: toBytes$B, + toBytesMap: toBytesMap$1, + toMessage: toMessage$1 + }); + + const setTime2000 = 0x02; + const setParameter = 0x03; + const getParameter = 0x04; + const getArchiveHours = 0x05; + const getArchiveDays = 0x06; + const current = 0x07; + const time2000 = 0x09; + const getArchiveEvents = 0x0b; + const correctTime2000 = 0x0c; + const status = 0x14; + const newEvent = 0x15; + const dayMc = 0x16; + const hourMc = 0x17; + const currentMc = 0x18; + const softRestart = 0x19; + const getArchiveHoursMc = 0x1a; + const getArchiveDaysMc = 0x1b; + const dataSegment = 0x1e; + const day = 0x20; + const hour = 0x40; + const lastEvent = 0x60; + const getLmicInfo = 0x21f; + const getBatteryStatus = 0x51f; + const usWaterMeterCommand = 0x71f; + const exAbsHourMc = 0xa1f; + const exAbsDayMc = 0xb1f; + const getExAbsArchiveHoursMc = 0xc1f; + const getExAbsArchiveDaysMc = 0xd1f; + const exAbsCurrentMc = 0xf1f; + const usWaterMeterBatteryStatus = 0x141f; + const writeImage = 0x2a1f; + const verifyImage = 0x2b1f; + const updateRun = 0x2c1f; + const getArchiveHoursMcEx = 0x301f; + const hourMcEx = 0x311f; + const getChannelsStatus = 0x321f; + const getChannelsTypes = 0x331f; + + var uplinkIds = /*#__PURE__*/Object.freeze({ + __proto__: null, + correctTime2000: correctTime2000, + current: current, + currentMc: currentMc, + dataSegment: dataSegment, + day: day, + dayMc: dayMc, + exAbsCurrentMc: exAbsCurrentMc, + exAbsDayMc: exAbsDayMc, + exAbsHourMc: exAbsHourMc, + getArchiveDays: getArchiveDays, + getArchiveDaysMc: getArchiveDaysMc, + getArchiveEvents: getArchiveEvents, + getArchiveHours: getArchiveHours, + getArchiveHoursMc: getArchiveHoursMc, + getArchiveHoursMcEx: getArchiveHoursMcEx, + getBatteryStatus: getBatteryStatus, + getChannelsStatus: getChannelsStatus, + getChannelsTypes: getChannelsTypes, + getExAbsArchiveDaysMc: getExAbsArchiveDaysMc, + getExAbsArchiveHoursMc: getExAbsArchiveHoursMc, + getLmicInfo: getLmicInfo, + getParameter: getParameter, + hour: hour, + hourMc: hourMc, + hourMcEx: hourMcEx, + lastEvent: lastEvent, + newEvent: newEvent, + setParameter: setParameter, + setTime2000: setTime2000, + softRestart: softRestart, + status: status, + time2000: time2000, + updateRun: updateRun, + usWaterMeterBatteryStatus: usWaterMeterBatteryStatus, + usWaterMeterCommand: usWaterMeterCommand, + verifyImage: verifyImage, + writeImage: writeImage + }); + + var uplinkNames = invertObject(uplinkIds); + + const id$z = correctTime2000; + uplinkNames[correctTime2000]; + const COMMAND_BODY_SIZE$b = 1; + const fromBytes$A = data => { + if (data.length !== COMMAND_BODY_SIZE$b) { + throw new Error(`Wrong buffer size: ${data.length}.`); + } + const buffer = new BinaryBuffer(data, false); + const parameters = { + status: buffer.getUint8() + }; + if (!buffer.isEmpty) { + throw new Error('BinaryBuffer is not empty.'); + } + return parameters; + }; + const toBytes$A = parameters => { + const { + status + } = parameters; + const buffer = new BinaryBuffer(COMMAND_BODY_SIZE$b, false); + buffer.setUint8(status); + return toBytes$11(id$z, buffer.data); + }; + + const id$y = current; + uplinkNames[current]; + const COMMAND_BODY_MAX_SIZE$e = 4; + const fromBytes$z = data => { + if (data.length > COMMAND_BODY_MAX_SIZE$e) { + throw new Error(`Wrong buffer size: ${data.length}.`); + } + const buffer = new CommandBinaryBuffer(data); + return buffer.getLegacyCounter(); + }; + const toBytes$z = parameters => { + const buffer = new CommandBinaryBuffer(COMMAND_BODY_MAX_SIZE$e); + buffer.setLegacyCounter(parameters); + return toBytes$11(id$y, buffer.data); + }; + + const id$x = currentMc; + uplinkNames[currentMc]; + const COMMAND_BODY_MAX_SIZE$d = 37; + const fromBytes$y = data => { + if (data.length > COMMAND_BODY_MAX_SIZE$d) { + throw new Error(`Wrong buffer size: ${data.length}.`); + } + const parameters = { + channelList: [] + }; + const buffer = new CommandBinaryBuffer(data); + const channelList = buffer.getChannels(); + parameters.channelList = channelList.map(channelIndex => ({ + value: buffer.getExtendedValue(), + index: channelIndex + })); + return parameters; + }; + const toBytes$y = parameters => { + const buffer = new CommandBinaryBuffer(COMMAND_BODY_MAX_SIZE$d); + const { + channelList + } = parameters; + buffer.setChannels(channelList); + channelList.forEach(_ref => { + let { + value + } = _ref; + buffer.setExtendedValue(value); + }); + return toBytes$11(id$x, buffer.getBytesToOffset()); + }; + + const id$w = day; + uplinkNames[day]; + const COMMAND_BODY_SIZE$a = 6; + const fromBytes$x = data => { + const buffer = new CommandBinaryBuffer(data); + const date = buffer.getDate(); + const byte = buffer.getUint8(); + const { + hour + } = buffer.getHours(byte); + const isMagneticInfluence = CommandBinaryBuffer.getMagneticInfluenceBit(byte); + const value = buffer.getLegacyCounterValue(); + date.setUTCHours(hour); + return { + value, + isMagneticInfluence, + startTime2000: getTime2000FromDate(date) + }; + }; + const toBytes$x = parameters => { + const buffer = new CommandBinaryBuffer(COMMAND_BODY_SIZE$a); + const { + value, + isMagneticInfluence, + startTime2000 + } = parameters; + const date = getDateFromTime2000(startTime2000); + const hour = date.getUTCHours(); + buffer.setDate(date); + buffer.setHours(hour, 1); + buffer.seek(buffer.offset - 1); + const byte = buffer.getUint8(); + buffer.seek(buffer.offset - 1); + buffer.setUint8(CommandBinaryBuffer.setMagneticInfluenceBit(byte, isMagneticInfluence)); + buffer.setLegacyCounterValue(value); + return toBytes$11(id$w, buffer.getBytesToOffset()); + }; + + const id$v = dayMc; + uplinkNames[dayMc]; + const COMMAND_BODY_MAX_SIZE$c = 32; + const fromBytes$w = data => { + if (data.length > COMMAND_BODY_MAX_SIZE$c) { + throw new Error(`Wrong buffer size: ${data.length}.`); + } + const buffer = new CommandBinaryBuffer(data); + const date = buffer.getDate(); + const channels = buffer.getChannels(); + const channelList = channels.map(channelIndex => ({ + value: buffer.getExtendedValue(), + index: channelIndex + })); + return { + startTime2000: getTime2000FromDate(date), + channelList + }; + }; + const toBytes$w = parameters => { + const buffer = new CommandBinaryBuffer(COMMAND_BODY_MAX_SIZE$c); + const { + channelList, + startTime2000 + } = parameters; + buffer.setDate(startTime2000); + buffer.setChannels(channelList); + channelList.forEach(_ref => { + let { + value + } = _ref; + buffer.setExtendedValue(value); + }); + return toBytes$11(id$v, buffer.getBytesToOffset()); + }; + + const id$u = exAbsCurrentMc; + uplinkNames[exAbsCurrentMc]; + const COMMAND_BODY_MAX_SIZE$b = 87; + const fromBytes$v = data => { + const buffer = new CommandBinaryBuffer(data); + return { + channelList: buffer.getChannelsWithAbsoluteValues() + }; + }; + const toBytes$v = parameters => { + const buffer = new CommandBinaryBuffer(COMMAND_BODY_MAX_SIZE$b); + buffer.setChannelsWithAbsoluteValues(parameters.channelList); + return toBytes$11(id$u, buffer.getBytesToOffset()); + }; + + const id$t = exAbsDayMc; + uplinkNames[exAbsDayMc]; + const COMMAND_BODY_MAX_SIZE$a = 89; + const fromBytes$u = data => { + if (data.length > COMMAND_BODY_MAX_SIZE$a) { + throw new Error(`Wrong buffer size: ${data.length}.`); + } + const buffer = new CommandBinaryBuffer(data); + const date = buffer.getDate(); + const channelList = buffer.getChannelsWithAbsoluteValues(); + return { + startTime2000: getTime2000FromDate(date), + channelList + }; + }; + const toBytes$u = parameters => { + const buffer = new CommandBinaryBuffer(COMMAND_BODY_MAX_SIZE$a); + const { + startTime2000, + channelList + } = parameters; + buffer.setDate(startTime2000); + buffer.setChannelsWithAbsoluteValues(channelList); + return toBytes$11(id$t, buffer.getBytesToOffset()); + }; + + const id$s = exAbsHourMc; + uplinkNames[exAbsHourMc]; + const COMMAND_BODY_MAX_SIZE$9 = 168; + const fromBytes$t = data => { + if (data.length > COMMAND_BODY_MAX_SIZE$9) { + throw new Error(`Wrong buffer size: ${data.length}.`); + } + const buffer = new CommandBinaryBuffer(data); + const date = buffer.getDate(); + const { + hour, + hours + } = buffer.getHours(); + const channelList = buffer.getChannelsAbsoluteValuesWithHourDiff(hours); + date.setUTCHours(hour); + return { + startTime2000: getTime2000FromDate(date), + hours, + channelList + }; + }; + const toBytes$t = parameters => { + const buffer = new CommandBinaryBuffer(COMMAND_BODY_MAX_SIZE$9); + const { + startTime2000, + hours, + channelList + } = parameters; + const date = getDateFromTime2000(startTime2000); + const hour = date.getUTCHours(); + buffer.setDate(startTime2000); + buffer.setHours(hour, hours); + buffer.setChannelsAbsoluteValuesWithHourDiff(channelList); + return toBytes$11(id$s, buffer.getBytesToOffset()); + }; + + const id$r = getArchiveDays; + uplinkNames[getArchiveDays]; + const COMMAND_BODY_MIN_SIZE$1 = 2; + const DAY_COUNTER_SIZE = 4; + const fromBytes$s = data => { + const buffer = new CommandBinaryBuffer(data); + const date = buffer.getDate(); + const dayList = []; + while (buffer.offset < buffer.data.length) { + dayList.push(buffer.getLegacyCounter(undefined, true)); + } + return { + startTime2000: getTime2000FromDate(date), + dayList + }; + }; + const toBytes$s = parameters => { + const { + startTime2000, + dayList + } = parameters; + const buffer = new CommandBinaryBuffer(COMMAND_BODY_MIN_SIZE$1 + dayList.length * DAY_COUNTER_SIZE); + buffer.setDate(startTime2000); + dayList.forEach(dayCounter => buffer.setLegacyCounter(dayCounter, undefined, true)); + return toBytes$11(id$r, buffer.getBytesToOffset()); + }; + + const id$q = getArchiveDaysMc; + uplinkNames[getArchiveDaysMc]; + const COMMAND_BODY_MAX_SIZE$8 = 255; + const fromBytes$r = data => { + const buffer = new CommandBinaryBuffer(data); + const date = buffer.getDate(); + const channels = buffer.getChannels(); + const days = buffer.getUint8(); + const channelList = []; + channels.forEach(channelIndex => { + const dayList = []; + channelList.push({ + dayList, + index: channelIndex + }); + for (let day = 0; day < days; ++day) { + const value = buffer.getExtendedValue(); + dayList.push(value === EMPTY_VALUE ? 0 : value); + } + }); + return { + startTime2000: getTime2000FromDate(date), + days, + channelList + }; + }; + const toBytes$r = parameters => { + const buffer = new CommandBinaryBuffer(COMMAND_BODY_MAX_SIZE$8); + const { + startTime2000, + days, + channelList + } = parameters; + buffer.setDate(startTime2000); + buffer.setChannels(channelList); + buffer.setUint8(days); + channelList.forEach(_ref => { + let { + dayList + } = _ref; + dayList.forEach(value => { + buffer.setExtendedValue(value === 0 ? EMPTY_VALUE : value); + }); + }); + return toBytes$11(id$q, buffer.getBytesToOffset()); + }; + + const MAGNET_ON = 1; + const MAGNET_OFF = 2; + const ACTIVATE = 3; + const DEACTIVATE = 4; + const BATTERY_ALARM = 5; + const CAN_OFF = 6; + const INSERT = 7; + const REMOVE = 8; + const COUNTER_OVER = 9; + const SET_TIME = 10; + const ACTIVATE_MTX = 11; + const CONNECT = 12; + const DISCONNECT = 13; + const DEPASS_DONE = 14; + const OPTOLOW = 15; + const OPTOFLASH = 16; + const MTX = 17; + const JOIN_ACCEPT = 18; + const WATER_EVENT = 19; + const WATER_NO_RESPONSE = 20; + const OPTOSENSOR_ERROR = 21; + const BINARY_SENSOR_ON = 22; + const BINARY_SENSOR_OFF = 23; + const TEMPERATURE_SENSOR_HYSTERESIS = 24; + const TEMPERATURE_SENSOR_LOW_TEMPERATURE = 25; + const TEMPERATURE_SENSOR_HIGH_TEMPERATURE = 26; + + var events = /*#__PURE__*/Object.freeze({ + __proto__: null, + ACTIVATE: ACTIVATE, + ACTIVATE_MTX: ACTIVATE_MTX, + BATTERY_ALARM: BATTERY_ALARM, + BINARY_SENSOR_OFF: BINARY_SENSOR_OFF, + BINARY_SENSOR_ON: BINARY_SENSOR_ON, + CAN_OFF: CAN_OFF, + CONNECT: CONNECT, + COUNTER_OVER: COUNTER_OVER, + DEACTIVATE: DEACTIVATE, + DEPASS_DONE: DEPASS_DONE, + DISCONNECT: DISCONNECT, + INSERT: INSERT, + JOIN_ACCEPT: JOIN_ACCEPT, + MAGNET_OFF: MAGNET_OFF, + MAGNET_ON: MAGNET_ON, + MTX: MTX, + OPTOFLASH: OPTOFLASH, + OPTOLOW: OPTOLOW, + OPTOSENSOR_ERROR: OPTOSENSOR_ERROR, + REMOVE: REMOVE, + SET_TIME: SET_TIME, + TEMPERATURE_SENSOR_HIGH_TEMPERATURE: TEMPERATURE_SENSOR_HIGH_TEMPERATURE, + TEMPERATURE_SENSOR_HYSTERESIS: TEMPERATURE_SENSOR_HYSTERESIS, + TEMPERATURE_SENSOR_LOW_TEMPERATURE: TEMPERATURE_SENSOR_LOW_TEMPERATURE, + WATER_EVENT: WATER_EVENT, + WATER_NO_RESPONSE: WATER_NO_RESPONSE + }); + + var eventNames = invertObject(events); + + const id$p = getArchiveEvents; + uplinkNames[getArchiveEvents]; + const COMMAND_BODY_MIN_SIZE = 4 + 1 + 1; + const getEvent = buffer => { + const time2000 = buffer.getTime(); + const eventId = buffer.getUint8(); + const sequenceNumber = buffer.getUint8(); + return { + time2000, + id: eventId, + name: eventNames[eventId], + sequenceNumber + }; + }; + const setEvent = (buffer, event) => { + buffer.setTime(event.time2000); + buffer.setUint8(event.id); + buffer.setUint8(event.sequenceNumber); + }; + const fromBytes$q = data => { + const buffer = new CommandBinaryBuffer(data); + const eventList = []; + while (buffer.bytesLeft > 0) { + eventList.push(getEvent(buffer)); + } + return { + eventList + }; + }; + function toBytes$q(parameters) { + const { + eventList + } = parameters; + const buffer = new CommandBinaryBuffer(eventList.length * COMMAND_BODY_MIN_SIZE); + eventList.forEach(event => setEvent(buffer, event)); + return toBytes$11(id$p, buffer.data); + } + + const id$o = getArchiveHours; + uplinkNames[getArchiveHours]; + const fromBytes$p = data => { + const buffer = new CommandBinaryBuffer(data); + return buffer.getLegacyHourCounterWithDiff(true); + }; + const toBytes$p = parameters => { + const buffer = new CommandBinaryBuffer(CommandBinaryBuffer.getLegacyHourCounterSize(parameters)); + buffer.setLegacyHourCounterWithDiff(parameters, true); + return toBytes$11(id$o, buffer.getBytesToOffset()); + }; + + const id$n = getArchiveHoursMc; + uplinkNames[getArchiveHoursMc]; + const COMMAND_BODY_MAX_SIZE$7 = 164; + const fromBytes$o = data => { + if (data.length > COMMAND_BODY_MAX_SIZE$7) { + throw new Error(`Wrong buffer size: ${data.length}.`); + } + const buffer = new CommandBinaryBuffer(data); + return buffer.getChannelsValuesWithHourDiff(true); + }; + const toBytes$o = parameters => { + const buffer = new CommandBinaryBuffer(COMMAND_BODY_MAX_SIZE$7); + const { + hours, + startTime2000, + channelList + } = parameters; + buffer.setChannelsValuesWithHourDiff(hours, startTime2000, channelList, true); + return toBytes$11(id$n, buffer.getBytesToOffset()); + }; + + const id$m = getArchiveHoursMcEx; + uplinkNames[getArchiveHoursMcEx]; + const COMMAND_BODY_MAX_SIZE$6 = 255; + const fromBytes$n = data => { + if (data.length > COMMAND_BODY_MAX_SIZE$6) { + throw new Error(`Wrong buffer size: ${data.length}.`); + } + const buffer = new CommandBinaryBuffer(data); + return buffer.getChannelsValuesWithHourDiffExtended(true); + }; + const toBytes$n = parameters => { + const buffer = new CommandBinaryBuffer(COMMAND_BODY_MAX_SIZE$6); + buffer.setChannelsValuesWithHourDiffExtended(parameters, true); + return toBytes$11(id$m, buffer.getBytesToOffset()); + }; + + const id$l = getBatteryStatus; + uplinkNames[getBatteryStatus]; + const COMMAND_BODY_SIZE$9 = 11; + const fromBytes$m = data => { + const buffer = new CommandBinaryBuffer(data); + return { + voltageUnderLowLoad: buffer.getUint16(), + voltageUnderHighLoad: buffer.getUint16(), + internalResistance: buffer.getUint16(), + temperature: buffer.getUint8(), + remainingCapacity: buffer.getUint8(), + isLastDayOverconsumption: buffer.getUint8() === 1, + averageDailyOverconsumptionCounter: buffer.getUint16() + }; + }; + const toBytes$m = parameters => { + const buffer = new CommandBinaryBuffer(COMMAND_BODY_SIZE$9); + buffer.setUint16(parameters.voltageUnderLowLoad); + buffer.setUint16(parameters.voltageUnderHighLoad); + buffer.setUint16(parameters.internalResistance); + buffer.setUint8(parameters.temperature); + buffer.setUint8(parameters.remainingCapacity); + buffer.setUint8(parameters.isLastDayOverconsumption ? 1 : 0); + buffer.setUint16(parameters.averageDailyOverconsumptionCounter); + return toBytes$11(id$l, buffer.data); + }; + + var channelNames = invertObject(channelTypes); + + const id$k = getChannelsStatus; + uplinkNames[getChannelsStatus]; + const getBufferSize = channelsStatus => { + let size = 0; + for (let index = 0; index < channelsStatus.length; index++) { + size += 2; + switch (channelsStatus[index].type) { + case BINARY_SENSOR: + case TEMPERATURE_SENSOR: + size += 1; + break; + } + } + return size; + }; + const getBinarySensorStatus = buffer => ({ + state: buffer.getUint8() !== 0 + }); + const setBinarySensorStatus = (status, buffer) => { + buffer.setUint8(status.state ? 1 : 0); + }; + const getTemperatureSensorStatus = buffer => ({ + temperature: buffer.getInt8(), + time2000: buffer.getTime() + }); + const setTemperatureSensorStatus = (status, buffer) => { + buffer.setInt8(status.temperature); + buffer.setTime(status.time2000); + }; + const fromBytes$l = data => { + const buffer = new CommandBinaryBuffer(data); + const result = []; + while (buffer.bytesLeft !== 0) { + const type = buffer.getUint8(); + const channelStatus = { + type, + typeName: channelNames[type], + channel: buffer.getChannelValue() + }; + switch (channelStatus.type) { + case BINARY_SENSOR: + channelStatus.status = getBinarySensorStatus(buffer); + break; + case TEMPERATURE_SENSOR: + channelStatus.status = getTemperatureSensorStatus(buffer); + break; + default: + return result; + } + result.push(channelStatus); + } + return result; + }; + const toBytes$l = channelsStatus => { + const buffer = new CommandBinaryBuffer(getBufferSize(channelsStatus)); + for (let index = 0; index < channelsStatus.length; index++) { + const { + type, + channel, + status + } = channelsStatus[index]; + buffer.setUint8(type); + buffer.setChannelValue(channel); + switch (type) { + case BINARY_SENSOR: + setBinarySensorStatus(status, buffer); + break; + case TEMPERATURE_SENSOR: + setTemperatureSensorStatus(status, buffer); + break; + } + } + return toBytes$11(id$k, buffer.data); + }; + + const id$j = getChannelsTypes; + uplinkNames[getChannelsTypes]; + const fromBytes$k = data => ({ + channels: data.map(type => ({ + type, + typeName: channelNames[type] + })) + }); + const toBytes$k = _ref => { + let { + channels + } = _ref; + return toBytes$11(id$j, channels.map(channel => channel.type)); + }; + + const id$i = getExAbsArchiveDaysMc; + uplinkNames[getExAbsArchiveDaysMc]; + const COMMAND_BODY_MAX_SIZE$5 = 255; + const fromBytes$j = data => { + const buffer = new CommandBinaryBuffer(data); + const date = buffer.getDate(); + const channels = buffer.getChannels(); + const days = buffer.getUint8(); + const channelList = []; + channels.forEach(channelIndex => { + const dayList = []; + const pulseCoefficient = buffer.getPulseCoefficient(); + channelList.push({ + pulseCoefficient, + dayList, + index: channelIndex + }); + for (let day = 0; day < days; ++day) { + const value = buffer.getExtendedValue(); + dayList.push(value === EMPTY_VALUE ? 0 : value); + } + }); + return { + channelList, + days, + startTime2000: getTime2000FromDate(date) + }; + }; + const toBytes$j = parameters => { + const buffer = new CommandBinaryBuffer(COMMAND_BODY_MAX_SIZE$5); + const { + channelList, + startTime2000, + days + } = parameters; + buffer.setDate(startTime2000); + buffer.setChannels(channelList); + buffer.setUint8(days); + channelList.forEach(_ref => { + let { + pulseCoefficient, + dayList + } = _ref; + buffer.setPulseCoefficient(pulseCoefficient); + dayList.forEach(value => { + buffer.setExtendedValue(value === 0 ? EMPTY_VALUE : value); + }); + }); + return toBytes$11(id$i, buffer.getBytesToOffset()); + }; + + const id$h = getExAbsArchiveHoursMc; + uplinkNames[getExAbsArchiveHoursMc]; + const COMMAND_BODY_MAX_SIZE$4 = 164; + const fromBytes$i = data => { + const buffer = new CommandBinaryBuffer(data); + return buffer.getChannelsValuesWithHourDiff(true); + }; + const toBytes$i = parameters => { + const buffer = new CommandBinaryBuffer(COMMAND_BODY_MAX_SIZE$4); + buffer.setChannelsValuesWithHourDiff(parameters.hours, parameters.startTime2000, parameters.channelList, true); + return toBytes$11(id$h, buffer.getBytesToOffset()); + }; + + const id$g = getLmicInfo; + uplinkNames[getLmicInfo]; + const COMMAND_BODY_SIZE$8 = 2; + const lmicCapabilitiesBitMask = { + isMulticastSupported: 1 << 0, + isFragmentedDataSupported: 1 << 1 + }; + const fromBytes$h = data => { + if (data.length !== COMMAND_BODY_SIZE$8) { + throw new Error(`Wrong buffer size: ${data.length}.`); + } + const buffer = new BinaryBuffer(data); + const capabilities = toObject(lmicCapabilitiesBitMask, buffer.getUint8()); + const version = buffer.getUint8(); + if (!buffer.isEmpty) { + throw new Error('BinaryBuffer is not empty.'); + } + return { + capabilities, + version + }; + }; + const toBytes$h = parameters => { + const { + capabilities, + version + } = parameters; + const buffer = new BinaryBuffer(COMMAND_BODY_SIZE$8); + buffer.setUint8(fromObject(lmicCapabilitiesBitMask, capabilities)); + buffer.setUint8(version); + return toBytes$11(id$g, buffer.data); + }; + + const id$f = getParameter; + uplinkNames[getParameter]; + const fromBytes$g = data => { + const buffer = new CommandBinaryBuffer(data); + return buffer.getResponseParameter(); + }; + const toBytes$g = parameters => { + const buffer = new CommandBinaryBuffer(getResponseParameterSize(parameters)); + buffer.setResponseParameter(parameters); + return toBytes$11(id$f, buffer.data); + }; + + const id$e = hour; + uplinkNames[hour]; + const fromBytes$f = data => { + const buffer = new CommandBinaryBuffer(data); + return buffer.getLegacyHourCounterWithDiff(); + }; + const toBytes$f = parameters => { + const buffer = new CommandBinaryBuffer(CommandBinaryBuffer.getLegacyHourCounterSize(parameters)); + buffer.setLegacyHourCounterWithDiff(parameters); + return toBytes$11(id$e, buffer.getBytesToOffset()); + }; + + const id$d = hourMc; + uplinkNames[hourMc]; + const COMMAND_BODY_MAX_SIZE$3 = 164; + const fromBytes$e = data => { + if (data.length > COMMAND_BODY_MAX_SIZE$3) { + throw new Error(`Wrong buffer size: ${data.length}.`); + } + const buffer = new CommandBinaryBuffer(data); + return buffer.getChannelsValuesWithHourDiff(); + }; + const toBytes$e = parameters => { + const buffer = new CommandBinaryBuffer(COMMAND_BODY_MAX_SIZE$3); + const { + startTime2000, + hours, + channelList + } = parameters; + buffer.setChannelsValuesWithHourDiff(hours, startTime2000, channelList); + return toBytes$11(id$d, buffer.getBytesToOffset()); + }; + + const id$c = hourMcEx; + uplinkNames[hourMcEx]; + const COMMAND_BODY_MAX_SIZE$2 = 255; + const fromBytes$d = data => { + if (data.length > COMMAND_BODY_MAX_SIZE$2) { + throw new Error(`Wrong buffer size: ${data.length}.`); + } + const buffer = new CommandBinaryBuffer(data); + return buffer.getChannelsValuesWithHourDiffExtended(); + }; + const toBytes$d = parameters => { + const buffer = new CommandBinaryBuffer(COMMAND_BODY_MAX_SIZE$2); + buffer.setChannelsValuesWithHourDiffExtended(parameters); + return toBytes$11(id$c, buffer.getBytesToOffset()); + }; + + const id$b = lastEvent; + uplinkNames[lastEvent]; + const fromBytes$c = (data, config) => { + if (!config.hardwareType) { + throw new Error('hardwareType in config is mandatory'); + } + const buffer = new CommandBinaryBuffer(data); + const sequenceNumber = buffer.getUint8(); + const status = buffer.getEventStatus(config.hardwareType); + return { + sequenceNumber, + status + }; + }; + const toBytes$c = (parameters, config) => { + if (!config.hardwareType) { + throw new Error('hardwareType in config is mandatory'); + } + const buffer = new CommandBinaryBuffer(1 + getEventStatusSize(config.hardwareType)); + const { + sequenceNumber, + status + } = parameters; + buffer.setUint8(sequenceNumber); + buffer.setEventStatus(config.hardwareType, status); + return toBytes$11(id$b, buffer.data); + }; + + const id$a = newEvent; + uplinkNames[newEvent]; + const COMMAND_BODY_MAX_SIZE$1 = 14; + const MTX_ADDRESS_SIZE = 8; + const getVoltage = buffer => buffer.getUint16(); + const setVoltage = (buffer, value) => buffer.setUint16(value); + const getDeviceId = buffer => getHexFromBytes(buffer.getBytes(MTX_ADDRESS_SIZE)); + const setDeviceId = (buffer, value) => { + getBytesFromHex(value).forEach(byte => buffer.setUint8(byte)); + }; + const fromBytes$b = data => { + if (data.length > COMMAND_BODY_MAX_SIZE$1) { + throw new Error(`Wrong buffer size: ${data.length}.`); + } + const buffer = new CommandBinaryBuffer(data); + const eventId = buffer.getUint8(); + const eventName = eventNames[eventId]; + const sequenceNumber = buffer.getUint8(); + let eventData; + switch (eventId) { + case MAGNET_ON: + case MAGNET_OFF: + case ACTIVATE: + case DEACTIVATE: + case CAN_OFF: + case INSERT: + case REMOVE: + case COUNTER_OVER: + case OPTOLOW: + case OPTOFLASH: + case JOIN_ACCEPT: + eventData = { + time2000: buffer.getTime() + }; + break; + case BATTERY_ALARM: + eventData = { + voltage: getVoltage(buffer) + }; + break; + case ACTIVATE_MTX: + eventData = { + time2000: buffer.getTime(), + deviceId: getDeviceId(buffer) + }; + break; + case CONNECT: + case DISCONNECT: + eventData = { + channel: buffer.getUint8() + 1, + value: buffer.getExtendedValue() + }; + break; + case MTX: + eventData = { + status: buffer.getEventStatus(MTXLORA) + }; + break; + case BINARY_SENSOR_ON: + case BINARY_SENSOR_OFF: + eventData = { + time2000: buffer.getTime(), + channel: buffer.getChannelValue() + }; + break; + case TEMPERATURE_SENSOR_HYSTERESIS: + case TEMPERATURE_SENSOR_LOW_TEMPERATURE: + case TEMPERATURE_SENSOR_HIGH_TEMPERATURE: + eventData = { + time2000: buffer.getTime(), + channel: buffer.getChannelValue(), + temperature: buffer.getInt8() + }; + break; + default: + throw new Error(`Event ${id$a} is not supported`); + } + return { + id: eventId, + name: eventName, + sequenceNumber, + data: eventData + }; + }; + const toBytes$b = parameters => { + const buffer = new CommandBinaryBuffer(COMMAND_BODY_MAX_SIZE$1); + const { + id: eventId, + sequenceNumber, + data + } = parameters; + buffer.setUint8(eventId); + buffer.setUint8(sequenceNumber); + switch (eventId) { + case MAGNET_ON: + case MAGNET_OFF: + case ACTIVATE: + case DEACTIVATE: + case CAN_OFF: + case INSERT: + case REMOVE: + case COUNTER_OVER: + case OPTOLOW: + case OPTOFLASH: + case JOIN_ACCEPT: + buffer.setTime(data.time2000); + break; + case BATTERY_ALARM: + setVoltage(buffer, data.voltage); + break; + case ACTIVATE_MTX: + buffer.setTime(data.time2000); + setDeviceId(buffer, data.deviceId); + break; + case CONNECT: + case DISCONNECT: + buffer.setUint8(data.channel - 1); + buffer.setExtendedValue(data.value); + break; + case MTX: + buffer.setEventStatus(MTXLORA, data.status); + break; + case BINARY_SENSOR_ON: + case BINARY_SENSOR_OFF: + buffer.setTime(data.time2000); + buffer.setChannelValue(data.channel); + break; + case TEMPERATURE_SENSOR_HYSTERESIS: + case TEMPERATURE_SENSOR_LOW_TEMPERATURE: + case TEMPERATURE_SENSOR_HIGH_TEMPERATURE: + buffer.setTime(data.time2000); + buffer.setChannelValue(data.channel); + buffer.setInt8(data.temperature); + break; + default: + throw new Error(`Event ${id$a} is not supported`); + } + return toBytes$11(id$a, buffer.getBytesToOffset()); + }; + + const id$9 = setParameter; + uplinkNames[setParameter]; + const COMMAND_BODY_SIZE$7 = 2; + const fromBytes$a = data => { + if (data.length !== COMMAND_BODY_SIZE$7) { + throw new Error(`Wrong buffer size: ${data.length}.`); + } + const buffer = new CommandBinaryBuffer(data); + const parameters = { + id: buffer.getUint8(), + status: buffer.getUint8() + }; + if (!buffer.isEmpty) { + throw new Error('BinaryBuffer is not empty.'); + } + return parameters; + }; + const toBytes$a = parameters => { + const buffer = new CommandBinaryBuffer(COMMAND_BODY_SIZE$7); + buffer.setUint8(parameters.id); + buffer.setUint8(parameters.status); + return toBytes$11(id$9, buffer.data); + }; + + const id$8 = setTime2000; + uplinkNames[setTime2000]; + const COMMAND_BODY_SIZE$6 = 1; + const fromBytes$9 = data => { + if (data.length !== COMMAND_BODY_SIZE$6) { + throw new Error(`Wrong buffer size: ${data.length}.`); + } + const buffer = new BinaryBuffer(data, false); + const parameters = { + status: buffer.getUint8() + }; + if (!buffer.isEmpty) { + throw new Error('BinaryBuffer is not empty.'); + } + return parameters; + }; + const toBytes$9 = parameters => { + const { + status + } = parameters; + const buffer = new BinaryBuffer(COMMAND_BODY_SIZE$6, false); + buffer.setUint8(status); + return toBytes$11(id$8, buffer.data); + }; + + const id$7 = softRestart; + uplinkNames[softRestart]; + const COMMAND_BODY_SIZE$5 = 0; + const fromBytes$8 = data => { + if (data.length !== COMMAND_BODY_SIZE$5) { + throw new Error(`Wrong buffer size: ${data.length}.`); + } + return {}; + }; + const toBytes$8 = () => toBytes$11(id$7); + + const id$6 = status; + uplinkNames[status]; + const COMMAND_BODY_MAX_SIZE = 20; + const UNKNOWN_BATTERY_RESISTANCE = 65535; + const UNKNOWN_BATTERY_CAPACITY = 255; + const fromBytes$7 = bytes => { + const buffer = new CommandBinaryBuffer(bytes); + const software = { + type: buffer.getUint8(), + version: buffer.getUint8() + }; + const hardware = { + type: buffer.getUint8(), + version: buffer.getUint8() + }; + let data; + switch (hardware.type) { + case GASI1: + case GASI2: + case GASI3: + case NOVATOR: + case IMP2EU: + case IMP4EU: + case IMP2AS: + case IMP2IN: + case IMP4IN: + case GASIC: + case NBIOT: + { + const statusData = { + batteryVoltage: buffer.getBatteryVoltage(), + batteryInternalResistance: buffer.getUint16(), + temperature: buffer.getUint8(), + remainingBatteryCapacity: buffer.getUint8(), + lastEventSequenceNumber: buffer.getUint8() + }; + if (statusData.batteryInternalResistance === UNKNOWN_BATTERY_RESISTANCE) { + statusData.batteryInternalResistance = undefined; + } + if (statusData.remainingBatteryCapacity === UNKNOWN_BATTERY_CAPACITY) { + statusData.remainingBatteryCapacity = undefined; + } else if (statusData.remainingBatteryCapacity !== undefined) { + statusData.remainingBatteryCapacity = roundNumber(statusData.remainingBatteryCapacity * 100 / (UNKNOWN_BATTERY_CAPACITY - 1), 1); + } + if (!buffer.isEmpty) { + statusData.downlinkQuality = buffer.getUint8(); + } + data = statusData; + } + break; + case MTXLORA: + data = { + time2000: buffer.getUint32(), + resetReason: buffer.getUint8(), + rssiLastDownlinkFrame: buffer.getUint8(), + snrLastDownlinkFrame: buffer.getUint8(), + downlinkRequestsNumber: buffer.getUint8(), + downlinkFragmentsNumber: buffer.getUint8(), + uplinkResponsesNumber: buffer.getUint8(), + uplinkFragmentsNumber: buffer.getUint8(), + signalMarginToGateway: buffer.getUint8(), + signalMarginFromGateway: buffer.getUint8(), + detectedGatewaysNumber: buffer.getUint8(), + gatewayDownlinkErrorRate: buffer.getUint8(), + lastEventSequenceNumber: buffer.getUint8() + }; + break; + case ELIMP: + default: + throw new Error(`${id$6}: hardware type ${hardware.type} is not supported`); + } + return { + software, + hardware, + data + }; + }; + const toBytes$7 = parameters => { + const { + software, + hardware, + data + } = parameters; + const buffer = new CommandBinaryBuffer(COMMAND_BODY_MAX_SIZE); + buffer.setUint8(software.type); + buffer.setUint8(software.version); + buffer.setUint8(hardware.type); + buffer.setUint8(hardware.version); + switch (hardware.type) { + case GASI1: + case GASI2: + case GASI3: + case NOVATOR: + case IMP2EU: + case IMP4EU: + case IMP2AS: + case IMP2IN: + case IMP4IN: + case GASIC: + { + const statusData = data; + buffer.setBatteryVoltage(statusData.batteryVoltage); + if (statusData.batteryInternalResistance === undefined) { + buffer.setUint16(UNKNOWN_BATTERY_RESISTANCE); + } else { + buffer.setUint16(statusData.batteryInternalResistance); + } + buffer.setUint8(statusData.temperature); + if (statusData.remainingBatteryCapacity === undefined) { + buffer.setUint8(UNKNOWN_BATTERY_CAPACITY); + } else { + buffer.setUint8(roundNumber((UNKNOWN_BATTERY_CAPACITY - 1) * (statusData.remainingBatteryCapacity / 100), 0)); + } + buffer.setUint8(statusData.lastEventSequenceNumber); + if ('downlinkQuality' in statusData) { + buffer.setUint8(statusData.downlinkQuality); + } + } + break; + case MTXLORA: + { + const statusData = data; + buffer.setUint32(statusData.time2000); + buffer.setUint8(statusData.resetReason); + buffer.setUint8(statusData.rssiLastDownlinkFrame); + buffer.setUint8(statusData.snrLastDownlinkFrame); + buffer.setUint8(statusData.downlinkRequestsNumber); + buffer.setUint8(statusData.downlinkFragmentsNumber); + buffer.setUint8(statusData.uplinkResponsesNumber); + buffer.setUint8(statusData.uplinkFragmentsNumber); + buffer.setUint8(statusData.signalMarginToGateway); + buffer.setUint8(statusData.signalMarginFromGateway); + buffer.setUint8(statusData.detectedGatewaysNumber); + buffer.setUint8(statusData.gatewayDownlinkErrorRate); + buffer.setUint8(statusData.lastEventSequenceNumber); + } + break; + case ELIMP: + default: + throw new Error(`${id$6}: hardware type ${hardware.type} is not supported`); + } + return toBytes$11(id$6, buffer.getBytesToOffset()); + }; + + const id$5 = time2000; + uplinkNames[time2000]; + const COMMAND_BODY_SIZE$4 = 5; + const fromBytes$6 = data => { + if (data.length !== COMMAND_BODY_SIZE$4) { + throw new Error(`Wrong buffer size: ${data.length}.`); + } + const buffer = new CommandBinaryBuffer(data); + const parameters = { + sequenceNumber: buffer.getUint8(), + time2000: buffer.getTime() + }; + if (!buffer.isEmpty) { + throw new Error('BinaryBuffer is not empty.'); + } + return parameters; + }; + function toBytes$6(parameters) { + const { + sequenceNumber, + time2000 + } = parameters; + const buffer = new CommandBinaryBuffer(COMMAND_BODY_SIZE$4); + buffer.setUint8(sequenceNumber); + buffer.setTime(time2000); + return toBytes$11(id$5, buffer.data); + } + + const id$4 = updateRun; + uplinkNames[updateRun]; + const COMMAND_BODY_SIZE$3 = 0; + const fromBytes$5 = data => { + if (data.length !== COMMAND_BODY_SIZE$3) { + throw new Error(`Wrong buffer size: ${data.length}.`); + } + return {}; + }; + const toBytes$5 = () => toBytes$11(id$4); + + const id$3 = usWaterMeterBatteryStatus; + uplinkNames[usWaterMeterBatteryStatus]; + const COMMAND_BODY_SIZE$2 = 7; + const fromBytes$4 = data => { + const buffer = new CommandBinaryBuffer(data); + return { + voltage: buffer.getBatteryVoltage(), + internalResistance: buffer.getUint16(), + lastDepassivationTime: buffer.getUint16() + }; + }; + const toBytes$4 = parameters => { + const buffer = new CommandBinaryBuffer(COMMAND_BODY_SIZE$2); + buffer.setBatteryVoltage(parameters.voltage); + buffer.setUint16(parameters.internalResistance); + buffer.setUint16(parameters.lastDepassivationTime); + return toBytes$11(id$3, buffer.data); + }; + + const id$2 = usWaterMeterCommand; + uplinkNames[usWaterMeterCommand]; + const fromBytes$3 = data => { + const buffer = new CommandBinaryBuffer(data); + const length = buffer.getUint8(); + return { + length, + data: data.slice(1) + }; + }; + const toBytes$3 = parameters => { + const { + data, + length + } = parameters; + const buffer = new CommandBinaryBuffer(length); + buffer.setUint8(length); + buffer.setBytes(data); + return toBytes$11(id$2, buffer.data); + }; + + const id$1 = verifyImage; + uplinkNames[verifyImage]; + const COMMAND_BODY_SIZE$1 = 1; + const fromBytes$2 = data => { + if (data.length !== COMMAND_BODY_SIZE$1) { + throw new Error(`Wrong buffer size: ${data.length}.`); + } + const buffer = new CommandBinaryBuffer(data); + return { + status: buffer.getUint8() + }; + }; + const toBytes$2 = parameters => { + const buffer = new CommandBinaryBuffer(COMMAND_BODY_SIZE$1); + buffer.setUint8(parameters.status); + return toBytes$11(id$1, buffer.data); + }; + + const id = writeImage; + uplinkNames[writeImage]; + const COMMAND_BODY_SIZE = 5; + const fromBytes$1 = data => { + const buffer = new CommandBinaryBuffer(data); + return { + offset: buffer.getUint32(), + status: buffer.getUint8() + }; + }; + const toBytes$1 = parameters => { + const buffer = new CommandBinaryBuffer(COMMAND_BODY_SIZE); + buffer.setUint32(parameters.offset); + buffer.setUint8(parameters.status); + return toBytes$11(id, buffer.data); + }; + + const toBytesMap = {}; + const fromBytesMap = {}; + const nameMap = uplinkNames; + const fromBytes = getFromBytes(fromBytesMap, nameMap); + const toBytes = getToBytes(toBytesMap); + const toMessage = getToMessage(toBytesMap); + toBytesMap[id$z] = toBytes$A; + toBytesMap[id$y] = toBytes$z; + toBytesMap[id$x] = toBytes$y; + toBytesMap[id$Z] = toBytes$; + toBytesMap[id$w] = toBytes$x; + toBytesMap[id$v] = toBytes$w; + toBytesMap[id$u] = toBytes$v; + toBytesMap[id$t] = toBytes$u; + toBytesMap[id$s] = toBytes$t; + toBytesMap[id$r] = toBytes$s; + toBytesMap[id$q] = toBytes$r; + toBytesMap[id$p] = toBytes$q; + toBytesMap[id$o] = toBytes$p; + toBytesMap[id$n] = toBytes$o; + toBytesMap[id$m] = toBytes$n; + toBytesMap[id$l] = toBytes$m; + toBytesMap[id$k] = toBytes$l; + toBytesMap[id$j] = toBytes$k; + toBytesMap[id$i] = toBytes$j; + toBytesMap[id$h] = toBytes$i; + toBytesMap[id$g] = toBytes$h; + toBytesMap[id$f] = toBytes$g; + toBytesMap[id$e] = toBytes$f; + toBytesMap[id$d] = toBytes$e; + toBytesMap[id$c] = toBytes$d; + toBytesMap[id$b] = toBytes$c; + toBytesMap[id$a] = toBytes$b; + toBytesMap[id$9] = toBytes$a; + toBytesMap[id$8] = toBytes$9; + toBytesMap[id$7] = toBytes$8; + toBytesMap[id$6] = toBytes$7; + toBytesMap[id$5] = toBytes$6; + toBytesMap[id$4] = toBytes$5; + toBytesMap[id$3] = toBytes$4; + toBytesMap[id$2] = toBytes$3; + toBytesMap[id$1] = toBytes$2; + toBytesMap[id] = toBytes$1; + fromBytesMap[id$z] = fromBytes$A; + fromBytesMap[id$y] = fromBytes$z; + fromBytesMap[id$x] = fromBytes$y; + fromBytesMap[id$Z] = fromBytes$; + fromBytesMap[id$w] = fromBytes$x; + fromBytesMap[id$v] = fromBytes$w; + fromBytesMap[id$u] = fromBytes$v; + fromBytesMap[id$t] = fromBytes$u; + fromBytesMap[id$s] = fromBytes$t; + fromBytesMap[id$r] = fromBytes$s; + fromBytesMap[id$q] = fromBytes$r; + fromBytesMap[id$p] = fromBytes$q; + fromBytesMap[id$o] = fromBytes$p; + fromBytesMap[id$n] = fromBytes$o; + fromBytesMap[id$m] = fromBytes$n; + fromBytesMap[id$l] = fromBytes$m; + fromBytesMap[id$k] = fromBytes$l; + fromBytesMap[id$j] = fromBytes$k; + fromBytesMap[id$i] = fromBytes$j; + fromBytesMap[id$h] = fromBytes$i; + fromBytesMap[id$g] = fromBytes$h; + fromBytesMap[id$f] = fromBytes$g; + fromBytesMap[id$e] = fromBytes$f; + fromBytesMap[id$d] = fromBytes$e; + fromBytesMap[id$c] = fromBytes$d; + fromBytesMap[id$b] = fromBytes$c; + fromBytesMap[id$a] = fromBytes$b; + fromBytesMap[id$9] = fromBytes$a; + fromBytesMap[id$8] = fromBytes$9; + fromBytesMap[id$7] = fromBytes$8; + fromBytesMap[id$6] = fromBytes$7; + fromBytesMap[id$5] = fromBytes$6; + fromBytesMap[id$4] = fromBytes$5; + fromBytesMap[id$3] = fromBytes$4; + fromBytesMap[id$2] = fromBytes$3; + fromBytesMap[id$1] = fromBytes$2; + fromBytesMap[id] = fromBytes$1; + + var uplink = /*#__PURE__*/Object.freeze({ + __proto__: null, + fromBytes: fromBytes, + fromBytesMap: fromBytesMap, + nameMap: nameMap, + toBytes: toBytes, + toBytesMap: toBytesMap, + toMessage: toMessage + }); + + var analogMessage = /*#__PURE__*/Object.freeze({ + __proto__: null, + downlink: downlink, + uplink: uplink + }); + + // export + message = analogMessage; + +})(); +//#endregion diff --git a/vendor/jooby/ephir-rms-gmel10-codec.yaml b/vendor/jooby/ephir-rms-gmel10-codec.yaml new file mode 100644 index 0000000000..8682172e06 --- /dev/null +++ b/vendor/jooby/ephir-rms-gmel10-codec.yaml @@ -0,0 +1,2 @@ +uplinkDecoder: + fileName: analog-gasic.js diff --git a/vendor/jooby/ephir-rms-gmel10-profile-eu868.yaml b/vendor/jooby/ephir-rms-gmel10-profile-eu868.yaml new file mode 100644 index 0000000000..f788a4473f --- /dev/null +++ b/vendor/jooby/ephir-rms-gmel10-profile-eu868.yaml @@ -0,0 +1,49 @@ +# LoRaWAN MAC version: 1.0, 1.0.1, 1.0.2, 1.0.3, 1.0.4 or 1.1 +macVersion: '1.0.2' + +# LoRaWAN Regional Parameters version. Values depend on the LoRaWAN version: +# 1.0: TS001-1.0 +# 1.0.1: TS001-1.0.1 +# 1.0.2: RP001-1.0.2 or RP001-1.0.2-RevB +# 1.0.3: RP001-1.0.3-RevA +# 1.0.4: RP002-1.0.0, RP002-1.0.1, RP002-1.0.2, RP002-1.0.3 or RP002-1.0.4 +# 1.1: RP001-1.1-RevA or RP001-1.1-RevB +regionalParametersVersion: 'RP001-1.0.2-RevB' + +# Whether the end device supports join (OTAA) or not (ABP) +supportsJoin: true +# If your device is an ABP device (supportsJoin is false), uncomment the following fields: +# RX1 delay +#rx1Delay: 5 +# RX1 data rate offset +#rx1DataRateOffset: 0 +# RX2 data rate index +#rx2DataRateIndex: 0 +# RX2 frequency (MHz) +#rx2Frequency: 869.525 +# Factory preset frequencies (MHz) +#factoryPresetFrequencies: [868.1, 868.3, 868.5, 867.1, 867.3, 867.5, 867.7, 867.9] + +# Maximum EIRP +maxEIRP: 14 + +# Whether the end device supports 32-bit frame counters +supports32bitFCnt: false + +# Whether the end device supports class B +supportsClassB: false +# If your device supports class B, uncomment the following fields: +# Maximum delay for the end device to answer a MAC request or confirmed downlink frame (seconds) +#classBTimeout: 60 +# Ping slot period (seconds) +#pingSlotPeriod: 128 +# Ping slot data rate index +#pingSlotDataRateIndex: 0 +# Ping slot frequency (MHz). Set to 0 if the band supports ping slot frequency hopping. +#pingSlotFrequency: 869.525 + +# Whether the end device supports class C +supportsClassC: false +# If your device supports class C, uncomment the following fields: +# Maximum delay for the end device to answer a MAC request or confirmed downlink frame (seconds) +#classCTimeout: 60 diff --git a/vendor/jooby/ephir-rms-gmel10.png b/vendor/jooby/ephir-rms-gmel10.png new file mode 100644 index 0000000000..a2b3cce250 Binary files /dev/null and b/vendor/jooby/ephir-rms-gmel10.png differ diff --git a/vendor/jooby/ephir-rms-gmel10.yaml b/vendor/jooby/ephir-rms-gmel10.yaml new file mode 100644 index 0000000000..359d963631 --- /dev/null +++ b/vendor/jooby/ephir-rms-gmel10.yaml @@ -0,0 +1,67 @@ +name: ephir-rms-gmel10 +description: Jooby EPHIR RMS LoRaWAN GMEL10 100 EU KT 304862 + +# Hardware versions (optional) +hardwareVersions: + - version: '1.0' + numeric: 1 + +# Firmware versions (at least one is mandatory) +firmwareVersions: + - # Firmware version + version: '1.0' + numeric: 1 + # Supported hardware versions (optional) + hardwareVersions: + - '1.0' # Must refer to hardwareVersions declared above + # LoRaWAN Device Profiles per region + # Supported regions: EU863-870, US902-928, AU915-928, AS923, CN779-787, EU433, CN470-510, KR920-923, IN865-867, RU864-870 + profiles: + EU863-870: + id: ephir-rms-gmel10-profile-eu868 + lorawanCertified: false + codec: ephir-rms-gmel10-codec + +# Sensors that this device features (optional) +# Valid values are: +# 4-20 ma, accelerometer, altitude, analog input, auxiliary, barometer, battery, button, bvoc, co, co2, conductivity, +# current, digital input, dissolved oxygen, distance, dust, energy, gps, gyroscope, h2s, humidity, iaq, level, light, +# lightning, link, magnetometer, moisture, motion, no, no2, o3, particulate matter, ph, pir, pm2.5, pm10, potentiometer, +# power, precipitation, pressure, proximity, pulse count, pulse frequency, radar, rainfall, rssi, smart valve, snr, so2, +# solar radiation, sound, strain, surface temperature, temperature, tilt, time, tvoc, uv, vapor pressure, velocity, +# vibration, voltage, water potential, water, weight, wifi ssid, wind direction, wind speed. +sensors: + - battery + - analog input + - pulse count + +# Dimensions in mm (optional) +# Use width, height, length and/or diameter +dimensions: + width: 92 + length: 61 + height: 34 + +# Weight in grams (optional) +weight: 42 + +# Battery information (optional) +battery: + replaceable: false + +# Operating conditions (optional) +operatingConditions: + # Temperature (Celsius) + temperature: + min: -30 + max: 85 + +# IP rating (optional) +ipCode: IP50 + +# Product and data sheet URLs (optional) +productURL: https://jooby.eu/rdc/jooby-ephir-rms-100/ +dataSheetURL: https://jooby.eu/wp-content/uploads/2023/09/20230526_Jooby_RDC_Datasheet_RM_Elster_EN_web-3.pdf + +photos: + main: ephir-rms-gmel10.png diff --git a/vendor/jooby/ephir-rms-gmme10-codec.yaml b/vendor/jooby/ephir-rms-gmme10-codec.yaml new file mode 100644 index 0000000000..29d3e381c4 --- /dev/null +++ b/vendor/jooby/ephir-rms-gmme10-codec.yaml @@ -0,0 +1,2 @@ +uplinkDecoder: + fileName: analog-gasi3.js diff --git a/vendor/jooby/ephir-rms-gmme10-profile-eu868.yaml b/vendor/jooby/ephir-rms-gmme10-profile-eu868.yaml new file mode 100644 index 0000000000..f788a4473f --- /dev/null +++ b/vendor/jooby/ephir-rms-gmme10-profile-eu868.yaml @@ -0,0 +1,49 @@ +# LoRaWAN MAC version: 1.0, 1.0.1, 1.0.2, 1.0.3, 1.0.4 or 1.1 +macVersion: '1.0.2' + +# LoRaWAN Regional Parameters version. Values depend on the LoRaWAN version: +# 1.0: TS001-1.0 +# 1.0.1: TS001-1.0.1 +# 1.0.2: RP001-1.0.2 or RP001-1.0.2-RevB +# 1.0.3: RP001-1.0.3-RevA +# 1.0.4: RP002-1.0.0, RP002-1.0.1, RP002-1.0.2, RP002-1.0.3 or RP002-1.0.4 +# 1.1: RP001-1.1-RevA or RP001-1.1-RevB +regionalParametersVersion: 'RP001-1.0.2-RevB' + +# Whether the end device supports join (OTAA) or not (ABP) +supportsJoin: true +# If your device is an ABP device (supportsJoin is false), uncomment the following fields: +# RX1 delay +#rx1Delay: 5 +# RX1 data rate offset +#rx1DataRateOffset: 0 +# RX2 data rate index +#rx2DataRateIndex: 0 +# RX2 frequency (MHz) +#rx2Frequency: 869.525 +# Factory preset frequencies (MHz) +#factoryPresetFrequencies: [868.1, 868.3, 868.5, 867.1, 867.3, 867.5, 867.7, 867.9] + +# Maximum EIRP +maxEIRP: 14 + +# Whether the end device supports 32-bit frame counters +supports32bitFCnt: false + +# Whether the end device supports class B +supportsClassB: false +# If your device supports class B, uncomment the following fields: +# Maximum delay for the end device to answer a MAC request or confirmed downlink frame (seconds) +#classBTimeout: 60 +# Ping slot period (seconds) +#pingSlotPeriod: 128 +# Ping slot data rate index +#pingSlotDataRateIndex: 0 +# Ping slot frequency (MHz). Set to 0 if the band supports ping slot frequency hopping. +#pingSlotFrequency: 869.525 + +# Whether the end device supports class C +supportsClassC: false +# If your device supports class C, uncomment the following fields: +# Maximum delay for the end device to answer a MAC request or confirmed downlink frame (seconds) +#classCTimeout: 60 diff --git a/vendor/jooby/ephir-rms-gmme10.png b/vendor/jooby/ephir-rms-gmme10.png new file mode 100644 index 0000000000..5219b06b53 Binary files /dev/null and b/vendor/jooby/ephir-rms-gmme10.png differ diff --git a/vendor/jooby/ephir-rms-gmme10.yaml b/vendor/jooby/ephir-rms-gmme10.yaml new file mode 100644 index 0000000000..d8dae17bed --- /dev/null +++ b/vendor/jooby/ephir-rms-gmme10.yaml @@ -0,0 +1,67 @@ +name: ephir-rms-gmme10 +description: Jooby EPHIR RMS LoRaWAN GMME10 103 EU КТ 304866 + +# Hardware versions (optional) +hardwareVersions: + - version: '1.0' + numeric: 1 + +# Firmware versions (at least one is mandatory) +firmwareVersions: + - # Firmware version + version: '1.0' + numeric: 1 + # Supported hardware versions (optional) + hardwareVersions: + - '1.0' # Must refer to hardwareVersions declared above + # LoRaWAN Device Profiles per region + # Supported regions: EU863-870, US902-928, AU915-928, AS923, CN779-787, EU433, CN470-510, KR920-923, IN865-867, RU864-870 + profiles: + EU863-870: + id: ephir-rms-gmme10-profile-eu868 + lorawanCertified: false + codec: ephir-rms-gmme10-codec + +# Sensors that this device features (optional) +# Valid values are: +# 4-20 ma, accelerometer, altitude, analog input, auxiliary, barometer, battery, button, bvoc, co, co2, conductivity, +# current, digital input, dissolved oxygen, distance, dust, energy, gps, gyroscope, h2s, humidity, iaq, level, light, +# lightning, link, magnetometer, moisture, motion, no, no2, o3, particulate matter, ph, pir, pm2.5, pm10, potentiometer, +# power, precipitation, pressure, proximity, pulse count, pulse frequency, radar, rainfall, rssi, smart valve, snr, so2, +# solar radiation, sound, strain, surface temperature, temperature, tilt, time, tvoc, uv, vapor pressure, velocity, +# vibration, voltage, water potential, water, weight, wifi ssid, wind direction, wind speed. +sensors: + - battery + - analog input + - pulse count + +# Dimensions in mm (optional) +# Use width, height, length and/or diameter +dimensions: + width: 102 + length: 56 + height: 37 + +# Weight in grams (optional) +weight: 48 + +# Battery information (optional) +battery: + replaceable: false + +# Operating conditions (optional) +operatingConditions: + # Temperature (Celsius) + temperature: + min: -30 + max: 85 + +# IP rating (optional) +ipCode: IP50 + +# Product and data sheet URLs (optional) +productURL: https://jooby.eu/rdc/jooby-ephir-rms-103/ +dataSheetURL: https://jooby.eu/wp-content/uploads/2023/09/20230526_Jooby_RDC_Datasheet_RM_METRIX_EN_web-4.pdf + +photos: + main: ephir-rms-gmme10.png diff --git a/vendor/jooby/ephir-rms-gmsg10-codec.yaml b/vendor/jooby/ephir-rms-gmsg10-codec.yaml new file mode 100644 index 0000000000..29d3e381c4 --- /dev/null +++ b/vendor/jooby/ephir-rms-gmsg10-codec.yaml @@ -0,0 +1,2 @@ +uplinkDecoder: + fileName: analog-gasi3.js diff --git a/vendor/jooby/ephir-rms-gmsg10-profile-eu868.yaml b/vendor/jooby/ephir-rms-gmsg10-profile-eu868.yaml new file mode 100644 index 0000000000..f788a4473f --- /dev/null +++ b/vendor/jooby/ephir-rms-gmsg10-profile-eu868.yaml @@ -0,0 +1,49 @@ +# LoRaWAN MAC version: 1.0, 1.0.1, 1.0.2, 1.0.3, 1.0.4 or 1.1 +macVersion: '1.0.2' + +# LoRaWAN Regional Parameters version. Values depend on the LoRaWAN version: +# 1.0: TS001-1.0 +# 1.0.1: TS001-1.0.1 +# 1.0.2: RP001-1.0.2 or RP001-1.0.2-RevB +# 1.0.3: RP001-1.0.3-RevA +# 1.0.4: RP002-1.0.0, RP002-1.0.1, RP002-1.0.2, RP002-1.0.3 or RP002-1.0.4 +# 1.1: RP001-1.1-RevA or RP001-1.1-RevB +regionalParametersVersion: 'RP001-1.0.2-RevB' + +# Whether the end device supports join (OTAA) or not (ABP) +supportsJoin: true +# If your device is an ABP device (supportsJoin is false), uncomment the following fields: +# RX1 delay +#rx1Delay: 5 +# RX1 data rate offset +#rx1DataRateOffset: 0 +# RX2 data rate index +#rx2DataRateIndex: 0 +# RX2 frequency (MHz) +#rx2Frequency: 869.525 +# Factory preset frequencies (MHz) +#factoryPresetFrequencies: [868.1, 868.3, 868.5, 867.1, 867.3, 867.5, 867.7, 867.9] + +# Maximum EIRP +maxEIRP: 14 + +# Whether the end device supports 32-bit frame counters +supports32bitFCnt: false + +# Whether the end device supports class B +supportsClassB: false +# If your device supports class B, uncomment the following fields: +# Maximum delay for the end device to answer a MAC request or confirmed downlink frame (seconds) +#classBTimeout: 60 +# Ping slot period (seconds) +#pingSlotPeriod: 128 +# Ping slot data rate index +#pingSlotDataRateIndex: 0 +# Ping slot frequency (MHz). Set to 0 if the band supports ping slot frequency hopping. +#pingSlotFrequency: 869.525 + +# Whether the end device supports class C +supportsClassC: false +# If your device supports class C, uncomment the following fields: +# Maximum delay for the end device to answer a MAC request or confirmed downlink frame (seconds) +#classCTimeout: 60 diff --git a/vendor/jooby/ephir-rms-gmsg10.png b/vendor/jooby/ephir-rms-gmsg10.png new file mode 100644 index 0000000000..e91fb5c27c Binary files /dev/null and b/vendor/jooby/ephir-rms-gmsg10.png differ diff --git a/vendor/jooby/ephir-rms-gmsg10.yaml b/vendor/jooby/ephir-rms-gmsg10.yaml new file mode 100644 index 0000000000..c7aff6753b --- /dev/null +++ b/vendor/jooby/ephir-rms-gmsg10.yaml @@ -0,0 +1,67 @@ +name: ephir-rms-gmsg10 +description: Jooby EPHIR RMS LoRaWAN GMSG10 105 EU KT 304870 + +# Hardware versions (optional) +hardwareVersions: + - version: '1.0' + numeric: 1 + +# Firmware versions (at least one is mandatory) +firmwareVersions: + - # Firmware version + version: '1.0' + numeric: 1 + # Supported hardware versions (optional) + hardwareVersions: + - '1.0' # Must refer to hardwareVersions declared above + # LoRaWAN Device Profiles per region + # Supported regions: EU863-870, US902-928, AU915-928, AS923, CN779-787, EU433, CN470-510, KR920-923, IN865-867, RU864-870 + profiles: + EU863-870: + id: ephir-rms-gmsg10-profile-eu868 + lorawanCertified: false + codec: ephir-rms-gmsg10-codec + +# Sensors that this device features (optional) +# Valid values are: +# 4-20 ma, accelerometer, altitude, analog input, auxiliary, barometer, battery, button, bvoc, co, co2, conductivity, +# current, digital input, dissolved oxygen, distance, dust, energy, gps, gyroscope, h2s, humidity, iaq, level, light, +# lightning, link, magnetometer, moisture, motion, no, no2, o3, particulate matter, ph, pir, pm2.5, pm10, potentiometer, +# power, precipitation, pressure, proximity, pulse count, pulse frequency, radar, rainfall, rssi, smart valve, snr, so2, +# solar radiation, sound, strain, surface temperature, temperature, tilt, time, tvoc, uv, vapor pressure, velocity, +# vibration, voltage, water potential, water, weight, wifi ssid, wind direction, wind speed. +sensors: + - battery + - analog input + - pulse count + +# Dimensions in mm (optional) +# Use width, height, length and/or diameter +dimensions: + width: 97 + length: 45 + height: 32 + +# Weight in grams (optional) +weight: 50 + +# Battery information (optional) +battery: + replaceable: false + +# Operating conditions (optional) +operatingConditions: + # Temperature (Celsius) + temperature: + min: -30 + max: 85 + +# IP rating (optional) +ipCode: IP50 + +# Product and data sheet URLs (optional) +productURL: https://jooby.eu/rdc/jooby-ephir-rms-105/ +dataSheetURL: https://jooby.eu/wp-content/uploads/2023/09/20230322_Jooby_RDC_Datasheet_RM_Samgaz_EN_web-3.pdf + +photos: + main: ephir-rms-gmsg10.png diff --git a/vendor/jooby/index.yaml b/vendor/jooby/index.yaml index 90ebbe58c1..57f3d6f2f9 100644 --- a/vendor/jooby/index.yaml +++ b/vendor/jooby/index.yaml @@ -1,2 +1,6 @@ endDevices: + - ephir-rms-gmel10 + - ephir-rms-gmme10 + - ephir-rms-gmsg10 - mtx1 + - omni-rm-4pu204eu diff --git a/vendor/jooby/mtx1.js b/vendor/jooby/mtx1.js index 4ef57146f3..2f744a212d 100644 --- a/vendor/jooby/mtx1.js +++ b/vendor/jooby/mtx1.js @@ -263,7 +263,7 @@ function decodeDownlink ( input ) { getInt8() { const result = readUint8(this.data, this.offset); this.offset += INT8_SIZE; - return result & 0x80 ? result ^ -0x100 : result; + return result & 0x80 ? result ^ -256 : result; }, setUint8(value) { writeUint8(this.data, this.offset, value); @@ -283,7 +283,7 @@ function decodeDownlink ( input ) { let isLittleEndian = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : this.isLittleEndian; const result = readUint16(this.data, this.offset, isLittleEndian); this.offset += INT16_SIZE; - return result & 0x8000 ? result ^ -0x10000 : result; + return result & 0x8000 ? result ^ -65536 : result; }, setUint16(value) { let isLittleEndian = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : this.isLittleEndian; @@ -305,7 +305,7 @@ function decodeDownlink ( input ) { let isLittleEndian = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : this.isLittleEndian; const result = readUint24(this.data, this.offset, isLittleEndian); this.offset += INT24_SIZE; - return result & 0x800000 ? result ^ -0x1000000 : result; + return result & 0x800000 ? result ^ -16777216 : result; }, setUint24(value) { let isLittleEndian = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : this.isLittleEndian; @@ -327,7 +327,7 @@ function decodeDownlink ( input ) { let isLittleEndian = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : this.isLittleEndian; const result = readUint32(this.data, this.offset, isLittleEndian); this.offset += INT32_SIZE; - return result & 0x80000000 ? result ^ -0x100000000 : result; + return result & 0x80000000 ? result ^ -4294967296 : result; }, setUint32(value) { let isLittleEndian = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : this.isLittleEndian; diff --git a/vendor/jooby/omni-rm-4pu204eu-codec.yaml b/vendor/jooby/omni-rm-4pu204eu-codec.yaml new file mode 100644 index 0000000000..34860592a4 --- /dev/null +++ b/vendor/jooby/omni-rm-4pu204eu-codec.yaml @@ -0,0 +1,2 @@ +uplinkDecoder: + fileName: analog-imp4eu.js diff --git a/vendor/jooby/omni-rm-4pu204eu-profile-eu868.yaml b/vendor/jooby/omni-rm-4pu204eu-profile-eu868.yaml new file mode 100644 index 0000000000..f788a4473f --- /dev/null +++ b/vendor/jooby/omni-rm-4pu204eu-profile-eu868.yaml @@ -0,0 +1,49 @@ +# LoRaWAN MAC version: 1.0, 1.0.1, 1.0.2, 1.0.3, 1.0.4 or 1.1 +macVersion: '1.0.2' + +# LoRaWAN Regional Parameters version. Values depend on the LoRaWAN version: +# 1.0: TS001-1.0 +# 1.0.1: TS001-1.0.1 +# 1.0.2: RP001-1.0.2 or RP001-1.0.2-RevB +# 1.0.3: RP001-1.0.3-RevA +# 1.0.4: RP002-1.0.0, RP002-1.0.1, RP002-1.0.2, RP002-1.0.3 or RP002-1.0.4 +# 1.1: RP001-1.1-RevA or RP001-1.1-RevB +regionalParametersVersion: 'RP001-1.0.2-RevB' + +# Whether the end device supports join (OTAA) or not (ABP) +supportsJoin: true +# If your device is an ABP device (supportsJoin is false), uncomment the following fields: +# RX1 delay +#rx1Delay: 5 +# RX1 data rate offset +#rx1DataRateOffset: 0 +# RX2 data rate index +#rx2DataRateIndex: 0 +# RX2 frequency (MHz) +#rx2Frequency: 869.525 +# Factory preset frequencies (MHz) +#factoryPresetFrequencies: [868.1, 868.3, 868.5, 867.1, 867.3, 867.5, 867.7, 867.9] + +# Maximum EIRP +maxEIRP: 14 + +# Whether the end device supports 32-bit frame counters +supports32bitFCnt: false + +# Whether the end device supports class B +supportsClassB: false +# If your device supports class B, uncomment the following fields: +# Maximum delay for the end device to answer a MAC request or confirmed downlink frame (seconds) +#classBTimeout: 60 +# Ping slot period (seconds) +#pingSlotPeriod: 128 +# Ping slot data rate index +#pingSlotDataRateIndex: 0 +# Ping slot frequency (MHz). Set to 0 if the band supports ping slot frequency hopping. +#pingSlotFrequency: 869.525 + +# Whether the end device supports class C +supportsClassC: false +# If your device supports class C, uncomment the following fields: +# Maximum delay for the end device to answer a MAC request or confirmed downlink frame (seconds) +#classCTimeout: 60 diff --git a/vendor/jooby/omni-rm-4pu204eu.png b/vendor/jooby/omni-rm-4pu204eu.png new file mode 100644 index 0000000000..e5903ca104 Binary files /dev/null and b/vendor/jooby/omni-rm-4pu204eu.png differ diff --git a/vendor/jooby/omni-rm-4pu204eu.yaml b/vendor/jooby/omni-rm-4pu204eu.yaml new file mode 100644 index 0000000000..657e8ed6ee --- /dev/null +++ b/vendor/jooby/omni-rm-4pu204eu.yaml @@ -0,0 +1,67 @@ +name: omni-rm-4pu204eu +description: Jooby OMNI RM 4PU204EU KT 304935 + +# Hardware versions (optional) +hardwareVersions: + - version: '1.0' + numeric: 1 + +# Firmware versions (at least one is mandatory) +firmwareVersions: + - # Firmware version + version: '1.0' + numeric: 1 + # Supported hardware versions (optional) + hardwareVersions: + - '1.0' # Must refer to hardwareVersions declared above + # LoRaWAN Device Profiles per region + # Supported regions: EU863-870, US902-928, AU915-928, AS923, CN779-787, EU433, CN470-510, KR920-923, IN865-867, RU864-870 + profiles: + EU863-870: + id: omni-rm-4pu204eu-profile-eu868 + lorawanCertified: false + codec: omni-rm-4pu204eu-codec + +# Sensors that this device features (optional) +# Valid values are: +# 4-20 ma, accelerometer, altitude, analog input, auxiliary, barometer, battery, button, bvoc, co, co2, conductivity, +# current, digital input, dissolved oxygen, distance, dust, energy, gps, gyroscope, h2s, humidity, iaq, level, light, +# lightning, link, magnetometer, moisture, motion, no, no2, o3, particulate matter, ph, pir, pm2.5, pm10, potentiometer, +# power, precipitation, pressure, proximity, pulse count, pulse frequency, radar, rainfall, rssi, smart valve, snr, so2, +# solar radiation, sound, strain, surface temperature, temperature, tilt, time, tvoc, uv, vapor pressure, velocity, +# vibration, voltage, water potential, water, weight, wifi ssid, wind direction, wind speed. +sensors: + - battery + - analog input + - pulse count + +# Dimensions in mm (optional) +# Use width, height, length and/or diameter +dimensions: + width: 140 + length: 70 + height: 50 + +# Weight in grams (optional) +weight: 205 + +# Battery information (optional) +battery: + replaceable: false + +# Operating conditions (optional) +operatingConditions: + # Temperature (Celsius) + temperature: + min: -30 + max: 85 + +# IP rating (optional) +ipCode: IP65 + +# Product and data sheet URLs (optional) +productURL: https://jooby.eu/rdc/jooby-omni-rm-4pu-204/ +dataSheetURL: https://jooby.eu/wp-content/uploads/2023/10/EN_Datasheet_JOOBY-OMNI-RM-LoRaWAN-4PU-200_204_205-EU-1-2.pdf + +photos: + main: omni-rm-4pu204eu.png