UNPKG

@ncd-io/node-red-enterprise-sensors

Version:

You can install this library through the Palette Manager in Node-Red's UI.

1,389 lines (1,347 loc) 530 kB
const events = require('events'); const Queue = require('promise-queue'); globalDevices = {}; module.exports = class WirelessSensor{ constructor(digi){ this.mac; this.digi = digi; this.send = digi.send; this._emitter = new events.EventEmitter(); this.sensor_pool = {}; this.sensor_types = sensor_types(this); this.queue = new Queue(1); //route info and link quality objects this.mesh_map = {}; this.link_quality = {}; this.query_pool = {}; this.payloadType = { '122': 'power_up', '124': 'config_ack', '125': 'config_error', '127': 'sensor_data' }; var that = this; function receiver(frame){ try{ that.parse(frame); }catch(e){ console.log(frame); console.log('unable to parse frame'); console.log(e); } } function routeReceiver(frame){ that.parse_route_information_packet(frame); } function linkQualtiyReceiver(frame){ that.parse_link_quality_packet(frame); } this.digi.on('receive_packet', receiver); this.digi.on('explicit_rx_indicator', linkQualtiyReceiver); this.digi.on('route_information_packet', routeReceiver); this.on('close', () => { //console.log('removing listener'); this.digi._emitter.removeListener('receive_packet', receiver); this.digi._emitter.removeListener('explicit_rx_indicator',linkQualtiyReceiver); this.digi._emitter.removeListener('route_information_packet',routeReceiver); }); } send_control(type, mac, msg){ if(this.sensor_types[type] && typeof this.sensor_types[type].control != 'undefined'){ return this.control_send(mac, [249, ...this.sensor_types[type].control(msg)]); }else{ return new Promise((f,r)=>{r('Unknown sensor type');}); } } send_arbitrary(mac, data){ return this.control_send(mac,msg); } close(cb){ this._emitter.emit('close'); this.digi.close(); } parse_route_information_packet(frame){ var destination = frame.destination_mac; var route_array = this.mesh_map[destination]; var index = this.query_pool[destination]; //This is the route packet from the modem if(frame.source_mac == frame.responder_mac){ //Add Gateway MAC as first element of array. route_array[0] = frame.source_mac; //Add Receiver MAC as second item in array route_array[1] = frame.receiver_mac; if(frame.receiver_mac == frame.destination_mac){ //if receiver is the sensor then connection is direct from gateway to receiver so emit route info var msg_obj = {}; msg_obj.route = route_array; msg_obj.timestamp = Date.now(); this._emitter.emit("route_info",msg_obj); } }else{ //This is the final route packet if(frame.receiver_mac == destination){ route_array.push(frame.receiver_mac); var msg_obj = {}; msg_obj.route = route_array; msg_obj.timestamp = Date.now(); this._emitter.emit("route_info",msg_obj); delete this.query_pool[frame.destination_mac]; }else{ // This is an intermediate packet if(frame.responder_mac == route_array[this.query_pool[destination]]){ route_array.push(frame.receiver_mac); } } } //increment mesh hops index this.query_pool[destination]++; } parse_link_quality_packet(frame){ console.log("parse_link_quality_packet: "+frame); var msg_obj = {}; msg_obj.source_address = frame.source_mac; msg_obj.destination = toMac(frame.data.slice(0,8)); msg_obj.payload_size = msbLsb(frame.data[8],frame.data[9]); msg_obj.iterations = msbLsb(frame.data[10], frame.data[11]); msg_obj.successful_iterations = msbLsb(frame.data[12],frame.data[13]); msg_obj.retries = msbLsb(frame.data[14],frame.data[15]); msg_obj.result = frame.data[16] == 0 ? "success":"failed" msg_obj.max_allowed_retries = frame.data[17]; msg_obj.max_rssi = 0 - frame.data[18]; msg_obj.min_rssi = 0 - frame.data[19]; msg_obj.avg_rssi = 0 - frame.data[20]; msg_obj.timestamp = Date.now(); this._emitter.emit("link_info",msg_obj); } parse(frame){ // NOTE this must be above the type selection to prevent rs-485 data from triggering other functionality. if(globalDevices.hasOwnProperty(frame.mac) && globalDevices[frame.mac].hasOwnProperty('bridge') && globalDevices[frame.mac].bridge){ // if(type === undefined && globalDevices.hasOwnProperty(frame.mac) && globalDevices[frame.mac].hasOwnProperty('bridge') && globalDevices[frame.mac].bridge){ let query_data = { addr: frame.mac, payload: frame.data, } if(globalDevices[frame.mac].hasOwnProperty('command_queue') && globalDevices[frame.mac].command_queue.length != 0){ if(globalDevices[frame.mac].command_queue[0].hasOwnProperty('command')){ query_data.command = globalDevices[frame.mac].command_queue[0].command; } if(globalDevices[frame.mac].command_queue[0].hasOwnProperty('meta')){ query_data.meta = globalDevices[frame.mac].command_queue[0].meta; } this._emitter.emit('converter_ack-'+frame.mac, query_data); return; } // } } var type = this.payloadType[frame.data[0]]; if(typeof this[type] == 'function'){ var data = this[type](frame.data.slice(1), frame); if(typeof data == 'undefined'){ return; } data.type = type; data.addr = frame.mac; data.received = Date.now(); data.original = frame; var is_new = typeof this.sensor_pool[frame.mac] == 'undefined'; var new_mode = is_new; var mode = (type == 'power_up') ? data.mode : ((type == 'sensor_data') ? 'RUN' : ((type == 'config_ack') ? 'ACK' : 'PGM')); if(mode == 'ACK'){ if(data.data.length == 37){ this._emitter.emit('manifest_received', data); } } // #OTF var otf_devices = [4,12,21,23,26,32,33,39,44,45,48,52,53,56,58,74,76,78,79,80,81,82,84,88,89,90,91,97,98,101,102,103,105,106,107,108,109,110,111,112,114,117,118,119,120,121,122,123,124,180,181,202,217,211,270,519,520,521,531,535,536,537,538,539,540,541,542,543,1010,1011]; var device_type = msbLsb(frame.data[6], frame.data[7]); // var device_type = frame.data[7]; if(mode == "RUN"){ if(frame.data[9] == 70 && frame.data[10] == 76 && frame.data[11] == 89) { var broadcast_otf_devices = [101,102,202]; mode = "FLY"; } if(frame.data[9] == 85 && frame.data[10] == 80 && frame.data[11] == 84 && frame.data[12] == 72 && frame.data[13] == 87 && frame.data[14] == 82 && frame.data[15] == 78) { mode = "UPTHWRN"; } } if(mode == 'ACK'){ data.firmware_version = frame.data[5]; if(data.firmware_version == 0){ data.sensor_type = frame.data[3]; }else{ data.sensor_type = msbLsb(frame.data[3], frame.data[4]); } if(data.sensor_type == 0){ data.sensor_type = msbLsb(frame.data[3], frame.data[4]); } if(frame.data[7] == 79 && frame.data[8] == 84 && frame.data[9] == 78){ mode = "OTN"; } else if(frame.data[7] == 79 && frame.data[8] == 84 && frame.data[9] == 70){ mode = "OTF"; } } // If it is not a new sensor if(!is_new){ // If mode == RUN and type is not 'power_up' don't send RUN // sensor_data emitter sets status of UI anyay if(mode == 'RUN' && type != 'power_up'){ new_mode = false; } else if(mode == 'RUN' && type == 'power_up'){ new_mode = true; }else{ new_mode = this.sensor_pool[frame.mac].mode != mode; } }; this.sensor_pool[frame.mac] = { mac: frame.mac, type: data.sensor_type, nodeId: data.nodeId, mode: mode, // data: data, lastHeard: data.received }; if(mode === 'FLY' && frame.data.length > 12 && typeof this.sensor_types[data.sensor_type].parse_fly == 'function'){ try{ this.sensor_pool[frame.mac].reported_config = this.sensor_types[data.sensor_type].parse_fly(frame.data); } catch(error) { console.log('Error detect in parse_fly initiated by FLY message'); console.log(error); this.sensor_pool[frame.mac].reported_config = "Error parsing reported config. See log for details." } }else if(mode === 'OTF' && frame.data.length > 12 && typeof this.sensor_types[data.sensor_type].parse_fly == 'function'){ // restructure and add dead bytes to match FLY message so we only need one parser. // If we ever need to add any of the additional information of this packet we will need to rebuild to match try{ frame.data.splice(2,0,frame.data[5],0); this.sensor_pool[frame.mac].reported_config = this.sensor_types[data.sensor_type].parse_fly(frame.data); } catch(error){ console.log('Error detect in parse_fly initiated by OTF message'); console.log(error); this.sensor_pool[frame.mac].reported_config = "Error parsing reported config. See log for details." } }else if(mode === 'ACK'){ this.sensor_pool[frame.mac].status = data.result; if(data.data.length){ if(data.sensor_type == 110 || data.sensor_type == 111 || data.sensor_type == 112 || data.sensor_type == 114 || data.sensor_type == 543){ if(data.data[0] == 77 && data.data[1] == 79 && data.data[2] == 70 && data.data[3] == 70 && data.data[4] == 0){ this.sensor_pool[frame.mac].mode = 'MOFF'; } } this.sensor_pool[frame.mac].data = data.data; }; } var that = this; if(is_new){ that._emitter.emit('found_sensor', that.sensor_pool[frame.mac]); } // mode === 'ACK' check added to allow multiple configs through front end gateway input if(new_mode || mode === 'ACK'){ // If RSSI is not enabled send stored values, if it is, request the RSSI and temporarily append it. if(typeof frame.rssi == 'undefined'){ that._emitter.emit('sensor_mode', that.sensor_pool[frame.mac]); that._emitter.emit('sensor_mode-'+frame.mac, that.sensor_pool[frame.mac]); }else{ frame.rssi.then((v) => { let sensor_pool_rssi = that.sensor_pool[frame.mac]; sensor_pool_rssi.rssi = v.data[0]; that._emitter.emit('sensor_mode', sensor_pool_rssi); that._emitter.emit('sensor_mode-'+frame.mac, sensor_pool_rssi); }).catch(console.log); } } if(mode != 'FLY' && mode !='UPTHWRN'){ var send_events = function(){ that._emitter.emit(type, data); that._emitter.emit(type+'-'+data.sensor_type, data); that._emitter.emit(type+'-'+frame.mac, data); // MARK FLY CONFIG DATA }; if(typeof frame.rssi == 'undefined') send_events(); else frame.rssi.then((v) => { data.rssi = v.data[0]; send_events(); }).catch(console.log); } }else{ this._emitter.emit(frame.type+'-'+frame.mac.toUpperCase(), data); var data = {}; data.addr = frame.mac; data.data = frame.data; this._emitter.emit(frame.type+'-'+'unknown_device', data); } } power_up(payload){ return { nodeId: payload[0], sensor_type: msbLsb(payload[2], payload[3]), mode: String.fromCharCode(...payload.slice(6, 9)) }; } config_ack(payload){ if((msbLsb(payload[2], payload[3])) == 28){ payload[5] = payload[6]; } return { nodeId: payload[0], counter: payload[1], sensor_type: msbLsb(payload[2], payload[3]), result: payload[5], data: payload.slice(6) }; }; config_error(payload){ var errors = [ 'Unknown', 'Invalid Command', 'Sensor Type Mismatch', 'Node ID Mismatch', 'Apply change command failed', 'Invalid API Packet Command Response Received After Apply Change Command', 'Write command failed', 'Invalid API Packet Command Response Received After Write Command', 'Parameter Change Command Failed', 'Invalid Parameter Change Command Response Received After Write Command', 'Invalid/Incomplete Packet Received', 'Unknown', 'Unknown', 'Unknown', 'Unknown', 'Invalid Parameter for Setup/Saving' ]; return { nodeId: payload[0], sensor_type: msbLsb(payload[2], payload[3]), error: payload[6], error_message: errors[payload[6]], last_sent: this.digi.lastSent }; } sensor_data(payload, frame){ let sensor_type = msbLsb(payload[5], payload[6]); let battery_percent = ((msbLsb(payload[2], payload[3]) * 0.361) - 269.66).toFixed(2); let voltage = (msbLsb(payload[2], payload[3]) * 0.00322).toFixed(2); if(sensor_type == 110 || sensor_type == 111 || sensor_type == 112 || sensor_type == 114 || sensor_type == 543){ const vMin = 2.5; const vMax = 3.3; if (voltage >= vMax){ battery_percent = '100'; } else if (voltage <= vMin){ battery_percent = '0'; } else { const scale = 5.0; // tuning factor for steepness const percent = 100 * (1 - Math.exp(-scale * (voltage - vMin))); battery_percent = (Math.min(100, Math.max(0, percent))).toFixed(2); } } var parsed = { nodeId: payload[0], firmware: payload[1], battery: voltage, // battery_percent: (msbLsb(payload[2], payload[3]) * 0.537 - 449.9).toFixed(2), battery_percent: battery_percent, counter: payload[4], sensor_type: sensor_type }; // #OTF var otf_devices = [4,12,21,23,26,32,33,39,44,45,48,52,53,56,58,74,76,78,79,80,81,82,84,88,89,90,91,97,98,101,102,103,105,106,107,108,109,110,111,112,114,117,118,119,120,121,122,123,124,180,181,202,211,217,270,519,520,521,531,535,536,537,538,539,540,541,542,543,1010,1011]; if(otf_devices.includes(parsed.sensor_type)){ // If the message says FLY and there is not FLY timer in progress. if(payload[8] == 70 && payload[9] == 76 && payload[10] == 89) { parsed.payload = "Fly command"; return parsed; } } if(frame.data[9] == 85 && frame.data[10] == 80 && frame.data[11] == 84 && frame.data[12] == 72 && frame.data[13] == 87 && frame.data[14] == 82 && frame.data[15] == 78) { parsed.payload = "Upthwrn command"; return parsed; } // Sensor type 515 has a unique OTF that is indicated by a reserve byte value with MSb of 1 if(parsed.sensor_type == 515){ // MSb of reserve byte indicates sub-unit/ct firmware. parsed.ct_firmware = payload[7] >> 4; // If first bit in reserve is 1 AND current bank equals total banks if(payload[7] & 1 && payload[8] == payload[9]){ this._emitter.emit('set_destination_address'+frame.mac, frame.mac); this._emitter.emit('set_destination_address'+parsed.sensor_type, frame.mac); parsed.otf_515 = true; } else{ parsed.otf_515 = false; } } if(parsed.sensor_type == 101){ // If the message says FLY and there is not FLY timer in progress. // if(payload[8] == 70 && payload[9] == 76 && payload[10] == 89 && !this.hasOwnProperty('fly_101_in_progress')) { // this.fly_101_in_progress = true; // setTimeout(() => {this.config_set_rtc_101('00:00:00:00:00:00:FF:FF')}, 1000); // return; // } var deviceAddr = frame.mac; var firmware = payload[1]; var hour = payload[11]; var minute = payload[12]; if(firmware == 0){ var expected_packets = payload[15]; var current_packet = payload[16]; var sdata_start = 17; } else{ // Added external temp in firmware 1 inserted at item 15 var expected_packets = payload[17]; var current_packet = payload[18]; var sdata_start = 19; } if(globalDevices.hasOwnProperty(deviceAddr)){ // if a packet is already stored with the same packet ID, or if packet ID is 1, or if current packet ID is not one more than last packet ID if(current_packet == 1 && expected_packets != 1) { if(current_packet in globalDevices[deviceAddr].data || !(((current_packet&127)-1) in globalDevices[deviceAddr].data)) { console.log('bad packet breakdown, deleting stream. Current packet:'); console.log(current_packet); console.log('Total Expected Packets:'); console.log(expected_packets); // console.log(current_packet in globalDevices[deviceAddr].data); // console.log(!(((current_packet&127)-1) in globalDevices[deviceAddr].data)); // console.log(typeof current_packet in globalDevices[deviceAddr].data); if(this.hasOwnProperty('failure_no')){ this.failure_no = this.failure_no + 1; } else{ this.failure_no = 1; } if(this.hasOwnProperty('failure_no')){ console.log('####falure no'); console.log(this.failure_no); } // console.log(globalDevices[deviceAddr].data); delete globalDevices[deviceAddr]; if(current_packet != 1){ return; } else{ this.build_101_data(payload, deviceAddr, hour, minute, sdata_start, current_packet, firmware); return; } } } if(expected_packets == 1){ this.build_101_data(payload, deviceAddr, hour, minute, sdata_start, current_packet, firmware); } else{ // console.log('------'); // console.log(current_packet); // console.log(expected_packets); // console.log(Object.keys(globalDevices[deviceAddr].data).length); globalDevices[deviceAddr].data[current_packet] = payload.slice(sdata_start); } // Date Folder // CSV File date_macaddress.csv // Configuration // sensor wakes up even if not in config mode // time update needs to be sent as broadcast // sensors stay awake for two seconds // sensor request for current time has the word fly in it. // create functions node to split data out for graphing (group by x,y,x). // Function node to allow graphing // Auto Configure including time when fly request received // Try new fft - DOES NOT WORK. It is expecting a serial input from a particular device // Create Account on NCD so Bhaskar can tag in posts about added config functionality // Clever way to parse dependent on x/y/z axis enable if(Object.keys(globalDevices[deviceAddr].data).length == expected_packets){ var raw_data = new Array(); for(const packet in globalDevices[deviceAddr].data){ raw_data = raw_data.concat(globalDevices[deviceAddr].data[packet]); } var label = 0; // var fft = { // data: new Array() // // test: new Array() // }; var fft = new Array(); var fft_concat = {}; var en_axis_data = {}; switch (globalDevices[deviceAddr].en_axis){ case 1: en_axis_data.x_offset = 0; en_axis_data.increment = 2; break; case 2: en_axis_data.y_offset = 0; en_axis_data.increment = 2; break; case 3: en_axis_data.x_offset = 0; en_axis_data.y_offset = 2; en_axis_data.increment = 4; break; case 4: en_axis_data.z_offset = 0; en_axis_data.increment = 2; break; case 5: en_axis_data.x_offset = 0; en_axis_data.z_offset = 2; en_axis_data.increment = 4; break; case 6: en_axis_data.y_offset = 0; en_axis_data.z_offset = 2; en_axis_data.increment = 4; break; case 7: en_axis_data.x_offset = 0; en_axis_data.y_offset = 2; en_axis_data.z_offset = 4; en_axis_data.increment = 6; break; default: en_axis_data.increment = 0; } var fsr_mult = 0.000305185; var fsr_text = ""; switch(globalDevices[deviceAddr].fsr){ case 0: fsr_mult = 0.000305185; break; case 1: fsr_mult = 0.00061037; break; case 2: fsr_mult = 0.0012207; break; } switch(globalDevices[deviceAddr].fsr){ case 0: fsr_text = "10g"; break; case 1: fsr_text = "20g"; break; case 2: fsr_text = "40g"; break; } for(var i = 0; i < raw_data.length; i+=en_axis_data.increment){ label++; // var fft_data = { // time_id: globalDevices[deviceAddr].hour +':'+ globalDevices[deviceAddr].minute, // reading: label, // odr: globalDevices[deviceAddr].odr, // temperature: globalDevices[deviceAddr].temperature, // en_axis: globalDevices[deviceAddr].en_axis, // mac_address: deviceAddr, // } // var fft_data = {}; fft_concat[label] = {}; if('x_offset' in en_axis_data){ fft_concat[label].x = parseFloat((signInt(((raw_data[i+en_axis_data.x_offset]<<8)+(raw_data[i+en_axis_data.x_offset+1])), 16)*fsr_mult).toFixed(5)); } if('y_offset' in en_axis_data){ fft_concat[label].y = parseFloat((signInt(((raw_data[i+en_axis_data.y_offset]<<8)+(raw_data[i+en_axis_data.y_offset+1])), 16)*fsr_mult).toFixed(5)); } if('z_offset' in en_axis_data){ fft_concat[label].z = parseFloat((signInt(((raw_data[i+en_axis_data.z_offset]<<8)+(raw_data[i+en_axis_data.z_offset+1])), 16)*fsr_mult).toFixed(5)); } } var fft_concat_obj = { time_id: globalDevices[deviceAddr].hour +':'+ globalDevices[deviceAddr].minute, mac_address: deviceAddr, en_axis: globalDevices[deviceAddr].en_axis, odr: globalDevices[deviceAddr].odr, device_temp: globalDevices[deviceAddr].device_temp, fsr: globalDevices[deviceAddr].fsr, data: fft_concat }; if(firmware > 0){ fft_concat_obj.probe_temp = globalDevices[deviceAddr].probe_temp; } parsed.sensor_data = fft_concat_obj; parsed.raw_packets = globalDevices[deviceAddr].data; parsed.raw_data = raw_data; delete globalDevices[deviceAddr]; if(this.hasOwnProperty('failure_no')){ console.log('####falure no'); console.log(this.failure_no); } return parsed; } else{ return; } }else{ this.build_101_data(payload, deviceAddr, hour, minute, sdata_start, current_packet, firmware); return; } } if(parsed.sensor_type == 102){ // If the message says FLY and there is not FLY timer in progress. // if(payload[8] == 70 && payload[9] == 76 && payload[10] == 89 && !this.hasOwnProperty('fly_101_in_progress')) { // this.fly_101_in_progress = true; // this.sensor_pool[frame.mac].mode = "FLY"; // this._emitter.emit('sensor_mode-'+frame.mac, this.sensor_pool[frame.mac]); // // setTimeout(() => {this.config_set_rtc_101('00:00:00:00:00:00:FF:FF')}, 1000); // setTimeout(() => {this.config_set_rtc_101(frame.mac)}, 1000); // // return; // } var deviceAddr = frame.mac; var firmware = payload[1]; var hour = payload[9]; var minute = payload[10]; var expected_packets = payload[15]; var current_packet = payload[16]; var sdata_start = 17; if(globalDevices.hasOwnProperty(deviceAddr) || expected_packets == 1){ // if(expected_packets == 1){ // this.build_102_data(payload, deviceAddr, hour, minute, sdata_start, current_packet, firmware); // } // if a packet is already stored with the same packet ID, // or if packet ID is 1, // or if current packet ID is not one more than last packet ID if(current_packet == 1 && expected_packets != 1) { if(current_packet in globalDevices[deviceAddr].data || !(((current_packet&127)-1) in globalDevices[deviceAddr].data)) { console.log('bad packet breakdown, deleting stream. Current packet:'); console.log(current_packet); console.log('Total Expected Packets:'); console.log(expected_packets); // console.log(current_packet in globalDevices[deviceAddr].data && current_packet == 1 && expected_packets != 1); // console.log(current_packet == 1); // console.log(!((current_packet-1) in globalDevices[deviceAddr].data)); if(this.hasOwnProperty('failure_no')){ this.failure_no = this.failure_no + 1; } else{ this.failure_no = 1; } if(this.hasOwnProperty('failure_no')){ console.log('####falure no'); console.log(this.failure_no); } delete globalDevices[deviceAddr]; if(current_packet != 1){ return; } else{ this.build_102_data(payload, deviceAddr, hour, minute, sdata_start, current_packet, firmware); return; } } } if(expected_packets == 1){ this.build_102_data(payload, deviceAddr, hour, minute, sdata_start, current_packet, firmware); } else{ globalDevices[deviceAddr].data[current_packet] = payload.slice(sdata_start); } if(Object.keys(globalDevices[deviceAddr].data).length == expected_packets){ var raw_data = new Array(); for(const packet in globalDevices[deviceAddr].data){ raw_data = raw_data.concat(globalDevices[deviceAddr].data[packet]); } var label = 0; // var fft = { // data: new Array() // // test: new Array() // }; var fft = new Array(); var fft_concat = {}; for(var i = 0; i < raw_data.length; i+=2){ label++; fft_concat[label] = {'v': parseFloat((signInt(((raw_data[i]<<8)+(raw_data[i+1])), 16)*.00322).toFixed(5))}; } var fft_concat_obj = { time_id: globalDevices[deviceAddr].hour +':'+ globalDevices[deviceAddr].minute, mac_address: deviceAddr, // en_axis: globalDevices[deviceAddr].en_axis, odr: globalDevices[deviceAddr].odr, device_temp: globalDevices[deviceAddr].device_temp, probe_temp: globalDevices[deviceAddr].probe_temp, data: fft_concat }; parsed.sensor_data = fft_concat_obj; // parsed.sensor_data = fft; parsed.raw_packets = globalDevices[deviceAddr].data; parsed.raw_data = raw_data; // var data = globalDevices[deviceAddr]; delete globalDevices[deviceAddr]; if(this.hasOwnProperty('failure_no')){ console.log('####falure no'); console.log(this.failure_no); } return parsed; } else{ return; } }else{ this.build_102_data(payload, deviceAddr, hour, minute, sdata_start, current_packet, firmware); return; } } if(payload.length == 179){ if(msbLsb(payload[2], payload[3]) == 40){ delete parsed.firmware; delete parsed.battery; delete parsed.battery_percent; delete parsed.counter; // parsed.frame_id = payload[1]; parsed.sensor_type = msbLsb(payload[2], payload[3]); var odr; switch(payload[4]){ case 5: odr = 400; break; case 6: odr = 800; break; case 7: odr = 1600; break; case 12: odr = 3200; break; case 13: odr = 6400; break; case 14: odr = 12800; break; case 15: odr = 25600; break; default: odr = 0; } // parsed.sensor_data = {data_type: 'FFT', data: payload.slice(5)}; var deviceAddr = frame.mac; if(deviceAddr in globalDevices){ globalDevices[deviceAddr] = globalDevices[deviceAddr].concat(payload.slice(5)); if(globalDevices[deviceAddr].length == 2088){ var label = 1; var fft = {}; fft['odr'] = odr; fft['data_type'] = 'FFT'; for(var i = 0; i < 2064; i+=6){ var xLabel = 'x'+label; var yLabel = 'y'+label; var zLabel = 'z'+label; label++; fft[xLabel] = ((globalDevices[deviceAddr][i]<<8)+(globalDevices[deviceAddr][i+1]&255))/2048; fft[yLabel] = ((globalDevices[deviceAddr][i+2]<<8)+(globalDevices[deviceAddr][i+3]&255))/2048; fft[zLabel] = ((globalDevices[deviceAddr][i+4]<<8)+(globalDevices[deviceAddr][i+5]&255))/2048; } parsed.sensor_data = fft; parsed.sensor_data.xbee_data = globalDevices[deviceAddr]; delete globalDevices[deviceAddr]; return parsed; }else{ return; } }else{ globalDevices[deviceAddr] = payload.slice(5); return; } } }else{ if(typeof this.sensor_types[parsed.sensor_type] == 'undefined'){ parsed.sensor_data = { type: 'unknown', data: payload.slice(8) }; // #OTF }else if(parsed.sensor_type == 21 || parsed.sensor_type == 33 || parsed.sensor_type == 80 || parsed.sensor_type == 81 || parsed.sensor_type == 82 || parsed.sensor_type == 84 || parsed.sensor_type == 97 || parsed.sensor_type == 98 || parsed.sensor_type == 103 || parsed.sensor_type == 110 || parsed.sensor_type == 111 || parsed.sensor_type == 112 || parsed.sensor_type == 114 || parsed.sensor_type == 117 || parsed.sensor_type == 180 || parsed.sensor_type == 181 || parsed.sensor_type == 202 || parsed.sensor_type == 515 || parsed.sensor_type == 519 || parsed.sensor_type == 531 || parsed.sensor_type == 537 || parsed.sensor_type == 538 || parsed.sensor_type == 543){ parsed.sensor_data = this.sensor_types[parsed.sensor_type].parse(payload, parsed, frame.mac); if(!parsed.sensor_data){ return; } parsed.sensor_name = this.sensor_types[parsed.sensor_type].name; } else{ parsed.sensor_data = this.sensor_types[parsed.sensor_type].parse(payload.slice(8), payload); parsed.sensor_name = this.sensor_types[parsed.sensor_type].name; } } return parsed; } firmware_set_to_ota_mode(sensor_mac){ console.log('firmware_set_to_ota_mode'); var packet = [245, 56, 0, 0, 0]; return this.config_send(sensor_mac, packet, {}, 5000); // return this.config_send(sensor_mac, packet); } // TODO no code basis firmware_exit_ota_mode(sensor_mac){ console.log('firmware_exit_ota_mode'); var packet = [245, 57, 0, 0, 0]; return this.config_send(sensor_mac, packet); } firmware_request_manifest(sensor_mac){ console.log('firmware_request_manifest'); var packet = [245, 60, 0, 0, 0]; return this.config_send(sensor_mac, packet, {}, 1500, 500); } firmware_send_manifest(sensor_mac, manifest){ console.log('firmware_send_manifest'); // sensor_mac = "00:00:00:00:00:00:ff:ff"; let packet = [245, 58, 0, 0, 0].concat(Array.prototype.slice.call(manifest)); return this.config_send(sensor_mac, packet, {}, 1500, 500); } firmware_send_manifest_v13(sensor_mac, manifest){ console.log('firmware_send_manifest_v13'); // sensor_mac = "00:00:00:00:00:00:ff:ff"; let packet = [245, 58, 0, 0, 0].concat(Array.prototype.slice.call(manifest)); return this.firmware_send_v13(sensor_mac, packet, {}, 7000, 140, true); } firmware_send_chunk(sensor_mac, offset, chunk){ console.log('firmware_send_chunk'); // sensor_mac = "00:00:00:00:00:00:ff:ff"; let packet = [245, 59, 0, 0, 0].concat(offset, Array.prototype.slice.call(chunk)); // console.log(packet); return this.config_send(sensor_mac, packet); } firmware_request_last_segment(sensor_mac){ console.log('firmware_request_last_segment'); let packet = [245, 61, 0, 0, 0]; // console.log(packet); return this.config_send(sensor_mac, packet); } config_reboot_sensor(sensor_mac){ console.log('config_reboot_sensor: '+sensor_mac) var packet = [247, 64, 0, 0, 0]; return this.config_send(sensor_mac, packet); } config_set_broadcast(sensor_mac){ return config_set_destination(sensor_mac, 0x0000FFFF); } config_set_destination(sensor_mac, modem_mac){ var packet = [247, 3, 0, 0, 0]; var bytes = int2Bytes(modem_mac, 4); packet.push(...bytes); return this.config_send(sensor_mac, packet); } config_set_id_delay(sensor_mac, node_id, delay_s){ var packet = [247, 2, 0, 0, 0, node_id]; var delay_b = int2Bytes(delay_s, 3); packet.push(...delay_b); return this.config_send(sensor_mac, packet); } config_set_power(sensor_mac, pwr){ var packet = [247, 4, 0, 0, 0, pwr]; return this.config_send(sensor_mac, packet); } config_set_pan_id(sensor_mac, pan_id){ var packet = [247, 5, 0, 0, 0]; packet.push(...int2Bytes(pan_id, 2)); return this.config_send(sensor_mac, packet); } config_set_retries(sensor_mac, retries){ var packet = [247, 6, 0, 0, 0, retries]; return this.config_send(sensor_mac, packet); } config_set_change_detection(sensor_mac, enabled, perc, interval){ console.log('config_set_change_detection_ch1'); if(!perc) perc = 0; if(!interval) interval = 0; var packet = [247, 7, 0, 0, 0, enabled, perc, interval >> 16, (interval >> 8) & 255, interval & 255]; return this.config_send(sensor_mac, packet); } config_set_change_detection_ch2(sensor_mac, enabled, perc, interval){ console.log('config_set_change_detection_ch2'); if(!perc) perc = 0; if(!interval) interval = 0; var packet = [247, 8, 0, 0, 0, enabled, perc, interval >> 16, (interval >> 8) & 255, interval & 255]; return this.config_send(sensor_mac, packet); } config_set_change_detection_ch3(sensor_mac, enabled, perc, interval){ console.log('config_set_change_detection_ch3'); if(!perc) perc = 0; if(!interval) interval = 0; var packet = [247, 9, 0, 0, 0, enabled, perc, interval >> 16, (interval >> 8) & 255, interval & 255]; return this.config_send(sensor_mac, packet); } config_set_bp_altitude(sensor_mac, alt){ var packet = [244, 1, 0, 0, 0, alt >> 8, alt & 255]; return this.config_send(sensor_mac, packet); } config_set_bp_pressure(sensor_mac, press){ var packet = [244, 4, 0, 0, 0, press >> 8, press & 255]; return this.config_send(sensor_mac, packet); } config_set_bp_temp_precision(sensor_mac, prec){ var packet = [244, 2, 0, 0, 0, prec]; return this.config_send(sensor_mac, packet); } config_set_bp_press_precision(sensor_mac, prec){ var packet = [244, 3, 0, 0, 0, prec]; return this.config_send(sensor_mac, packet); } config_set_amgt_accel(sensor_mac, range){ var packet = [244, 1, 0, 0, 0, range]; return this.config_send(sensor_mac, packet); } config_set_amgt_magnet(sensor_mac, gain){ var packet = [244, 2, 0, 0, 0, gain]; return this.config_send(sensor_mac, packet); } config_set_amgt_gyro(sensor_mac, scale){ var packet = [244, 3, 0, 0, 0, scale]; return this.config_send(sensor_mac, packet); } config_set_filtering(sensor_mac, enable){ var packet = [244, 2, 0, 0, 0, enable]; return this.config_send(sensor_mac, packet); } config_set_data_rate(sensor_mac, data_rate){ var packet = [244, 3, 0, 0, 0, data_rate]; return this.config_send(sensor_mac, packet); } config_set_time_series(sensor_mac, time_series){ var packet = [244, 8, 0, 0, 0, time_series]; return this.config_send(sensor_mac, packet); } config_set_reading_type(sensor_mac, reading_type){ var packet = [244, 4, 0, 0, 0, reading_type]; return this.config_send(sensor_mac, packet); } config_set_motion_threshold_46(sensor_mac, value){ console.log('config_set_motion_threshold_46'); let packet = [244, 1, 0, 0, 0]; let threshold = int2Bytes((value), 4); packet.push(...threshold); console.log(packet); return this.config_send(sensor_mac, packet); } config_set_acceleration_range_24(sensor_mac, value){ console.log('config_set_acceleration_range_24'); var packet = [244, 1, 0, 0, 0, value]; console.log(packet); return this.config_send(sensor_mac, packet); } config_set_periodic_check_rate_76(sensor_mac, value){ console.log('config_set_periodic_check_rate'); let rate = int2Bytes((value), 2); var packet = [244, 32, 0, 0, 0]; packet.push(...rate); console.log(packet); return this.config_send(sensor_mac, packet); } config_set_ppm_threshold_76(sensor_mac, value){ console.log('config_set_ppm_threshold_76'); let rate = int2Bytes((value), 2); var packet = [244, 36, 0, 0, 0]; // packet.push(...rate); console.log(packet); return this.config_send(sensor_mac, packet); } config_set_alert_duration_76(sensor_mac, value){ console.log('config_set_alert_duration_76'); var packet = [244, 38, 0, 0, value]; // packet.push(...rate); console.log(packet); return this.config_send(sensor_mac, packet); } config_set_sensor_boot_time_76(sensor_mac, value){ console.log('config_set_sensor_boot_time_76'); var packet = [244, 36, 0, 0, 0, value]; console.log(packet); return this.config_send(sensor_mac, packet); } config_set_data_rate_24(sensor_mac, value){ console.log('config_set_data_rate_24'); var packet = [244, 2, 0, 0, 0, value]; console.log(packet); return this.config_send(sensor_mac, packet); } config_set_threshold_24(sensor_mac, value){ console.log('config_set_threshold_24'); var packet = [244, 3, 0, 0, 0, value]; console.log(packet); return this.config_send(sensor_mac, packet); } config_set_duration_24(sensor_mac, value){ console.log('config_set_duration_24'); var packet = [244, 4, 0, 0, 0, value]; console.log(packet); return this.config_send(sensor_mac, packet); } config_set_interrupt_24(sensor_mac, value){ console.log('config_set_interrupt_24'); var packet = [244, 9, 0, 0, 0, value]; console.log(packet); return this.config_send(sensor_mac, packet); } // config_set_impact_accel(sensor_mac, range){ // var packet = [244, 1, 0, 0, 0, range]; // return this.config_send(sensor_mac, packet); // } // config_set_impact_data_rate(sensor_mac, rate){ // var packet = [244, 2, 0, 0, 0, rate]; // return this.config_send(sensor_mac, packet); // } // config_set_impact_threshold(sensor_mac, threshold){ // var packet = [244, 3, 0, 0, 0, threshold]; // return this.config_send(sensor_mac, packet); // } // config_set_impact_duration(sensor_mac, duration){ // var packet = [244, 4, 0, 0, 0, duration]; // return this.config_send(sensor_mac, packet); // } config_set_sensor_forced_calibration(sensor_mac, value){ var packet = [244, 31, 0, 0, 0]; var cal_val = int2Bytes(value, 2); packet.push(...cal_val); return this.config_send(sensor_mac, packet); } config_set_sensor_forced_calibration_535(sensor_mac){ console.log('config_set_sensor_forced_calibration_535'); // convert before processing var packet = [244, 32, 0, 0, 0]; return this.config_send(sensor_mac, packet); } config_set_sensor_temperature_offset_44(sensor_mac, value){ console.log('config_set_sensor_temperature_offset_44'); // convert before processing value = value * 100; var packet = [244, 30, 0, 0, 0]; var cal_val = int2Bytes(value, 2); packet.push(...cal_val); console.log(packet); return this.config_send(sensor_mac, packet); } config_set_output_data_rate_p2_81(sensor_mac, output_rate){ console.log('config_set_output_data_rate_p2_81'); var packet = [244, 79, 0, 0, 101, 36, output_rate]; console.log(packet); return this.config_send(sensor_mac, packet); } config_set_sampling_duration_p2_81(sensor_mac, sampling_duration){ console.log('config_set_sampling_duration_p2_81'); var packet = [244, 79, 0, 0, 101, 38, sampling_duration]; console.log(packet); return this.config_send(sensor_mac, packet); } config_set_output_data_rate_101(sensor_mac, output_rate){ console.log('config_set_output_data_rate_101'); var packet = [244, 79, 0, 0, 101, 0, output_rate]; console.log(packet); return this.config_send(sensor_mac, packet); } config_get_output_data_rate_101(sensor_mac, output_rate){ console.log('config_get_output_data_rate_101'); var packet = [244, 79, 0, 0, 101, 1]; console.log(packet); return this.config_send(sensor_mac, packet); } config_set_sampling_duration_101(sensor_mac, sampling_duration){ console.log('config_set_sampling_duration_101'); var packet = [244, 79, 0, 0, 101, 2, sampling_duration]; console.log(packet); return this.config_send(sensor_mac, packet); } config_get_sampling_duration_101(sensor_mac, sampling_duration){ console.log('config_get_sampling_duration_101'); var packet = [244, 79, 0, 0, 101, 3]; console.log(packet); return this.config_send(sensor_mac, packet); } config_set_axis_enabled_101(sensor_mac, x_axis, y_axis, z_axis){ var axis_value = 0; console.log('config_set_axis_enabled_101'); if(x_axis){ axis_value+=1; } if(y_axis){ axis_value+=2; } if(z_axis){ axis_value+=4; } var packet = [244, 79, 0, 0, 101, 4, axis_value]; console.log(packet); return this.config_send(sensor_mac, packet); } config_get_axis_enabled_101(sensor_mac, x_axis, y_axis, z_axis){ var axis_value = x_axis+y_axis+z_axis; console.log('config_get_axis_enabled_101'); var packet = [244, 79, 0, 0, 101, 5]; console.log(packet); return this.config_send(sensor_mac, packet); } config_set_sampling_interval_101(sensor_mac, sampling_interval){ console.log('config_set_sampling_interval_101'); var packet = [244, 79, 0, 0, 101, 6, sampling_interval]; console.log(packet); return this.config_send(sensor_mac, packet); } config_set_sampling_interval_202(sensor_mac, sampling_interval){ console.log('config_set_sampling_interval_202'); var packet = [244, 0, 0, 0, 0, sampling_interval]; console.log(packet); return this.config_send(sensor_mac, packet); } config_set_probe_boot_time_202(sensor_mac, value){ console.log('config_set_probe_boot_time_202'); var packet = [244, 83, 0, 0, 0, value]; console.log(packet); return this.config_send(sensor_mac, packet); } config_get_sampling_interval_101(sensor_mac, sampling_interval){ console.log('config_get_sampling_interval_101'); var packet = [244, 79, 0, 0, 101, 7]; console.log(packet); return this.config_send(sensor_mac, packet); } config_set_full_scale_range_101(sensor_mac, range){ console.log('config_set_full_scale_range_101'); var packet = [244, 79, 0, 0, 101, 11, range]; console.log(packet); return this.config_send(sensor_mac, packet); } config_get_full_scale_range_101(sensor_mac, range){ console.log('config_get_full_scale_range_101'); var packet = [244, 79, 0, 0, 101, 12]; console.log(packet); return this.config_send(sensor_mac, packet); } config_set_operation_mode_80(sensor_mac, mode){ console.log('config_set_operation_mode'); console.log(mode); var packet = [244, 79, 0, 0, 0, 9, mode]; console.log(packet); return this.config_send(sensor_mac, packet); } config_set_filters_80(sensor_mac, filter){ console.log('config_set_filters_80'); var packet = [244, 79, 0, 0, 0, 13, filter]; console.log(packet); return this.config_send(sensor_mac, packet); } config_set_low_pass_filter_80(sensor_mac, lp_filter){ console.log('config_set_low_pass_filters_80'); var packet = [244, 79, 0, 0, 80, 52, lp_filter]; console.log(packet); return this.config_send(sensor_mac, packet); } config_set_high_pass_filter_80(sensor_mac, hp_filter){ console.log('config_set_high_pass_filters_80'); var packet = [244, 79, 0, 0, 80, 54, hp_filter]; console.log(packet); return this.config_send(sensor_mac, packet); } config_set_low_pass_filter_81_p2(sensor_mac, lp_filter){ console.log('config_set_low_pass_filter_81_p2'); var packet = [244, 79, 0, 0, 80, 56, lp_filter]; console.log(packet); return this.config_send(sensor_mac, packet); } config_set_high_pass_filter_81_p2(sensor_mac, hp_filter){ console.log('config_set_high_pass_filter_81_p2'); var packet = [244, 79, 0, 0, 80, 58, hp_filter]; console.log(packet); return this.config_send(sensor_mac, packet); } config_set_measurement_mode_80(sensor_mac, mode){ console.log('config_set_measurement_mode_80'); var packet = [244, 79, 0, 0, 0, 15, mode]; console.log(packet); return this.config_send(sensor_mac, packet); } config_set_on_request_timeout_80(sensor_mac, timeout){ console.log('config_set_on_request_timeout_80'); var packet = [244, 79, 0, 0, 0, 17, timeout]; console.log(packet); return this.config_send(sensor_mac, packet); } config_set_deadband_80(sensor_mac, timeout){ console.log('config_set_deadband_80'); var packet = [244, 79, 0, 0, 0, 40, timeout]; console.log(packet); return this.config_send(sensor_mac, packet); } config_set_current_calibration_individual_80(sensor_mac, value, channel_target){ console.log('config_set_current_calibration_individual_82'); var packet = [244, channel_target, 0, 0, 13]; var cal_val = int2Bytes((value*100), 2); packet.push(...cal_val); console.log(packet); return this.config_send(sensor_mac, packet); } config_set_current_calibration_82(sensor_mac, value){ console.log('current_calibration_82'); var packet = [244, 79, 0, 0, 0, 34]; var cal_val = int2Bytes(value, 4); packet.push(...cal_val); console.log(packet); return this.config_send(sensor_mac, packet); } config_set_led_alert_mode_84(sensor_mac, value){ console.log('config_set_led_alert_mode_84'); var packet = [244, 79, 0, 0, 0, 66, value]; console.log(packet); return this.config_send(sensor_mac, packet); } config_set_led_accelerometer_threshold_84(sensor_mac, value){ console.log('config_set_led_accelerometer_threshold_84'); var packet = [244, 79, 0, 0, 0, 62, value]; console.log(packet); return this.config_send(sensor_mac, packet); } config_set_led_velocity_threshold_84(sensor_mac, value){ console.log('config_set_led_velocity_threshold_84'); var packet = [244, 79, 0, 0, 0, 64, value]; console.log(packet); return this.config_send(sensor_mac, packet); } config_get_sampling_interval_101(sensor_mac, sampling_interval){ console.log('config_get_sampling_interval_101'); var packet = [244, 79, 0, 0, 101, 7]; console.log(packet); return this.config_send(sensor_mac, packet); } config_set_full_scale_range_101(sensor_mac, range){ console.log('config_set_full_scale_range_101'); var packet = [244, 79, 0, 0, 101, 11, range]; console.log(packet); return this.config_send(sensor_mac, packet); } config_get_full_scale_range_101(sensor_mac, range){ console.log('config_get_full_scale_range_101'); var packet = [244, 79, 0, 0, 101, 12]; console.log(packet); return this.config_send(sensor_mac, packet); } config_set_rtc_101(sensor_mac){ console.log('config_set_rtc_101'); console.log(sensor_mac); var date = new Date(); var packet = [244, 79, 0, 0, 101, 8, date.getHours(), date.getMinutes(), date.getSeconds()]; console.log(packet); delete this.fly_101_in_progress; return this.config_send(sensor_mac, packet); } config_set_rtc_202(sensor_mac){ console.log('config_set_rtc_202'); console.log(sensor_mac); var date = new Date(); var packet = [244, 8, 0, 0, 0, date.getHours(), date.getMinutes(), date.getSeconds()]; console.log(packet); delete this.fly_101_in_progress; return this.config_send(sensor_mac, packet); } config_set_roll_threshold_47(sensor_mac, threshold){ console.log('config_set_roll_threshold_47'); var packet = [244, 1, 0, 0, 47, 0, threshold]; console.log(packet); return this.config_send(sensor_mac, packet); } config_set_pitch_threshold_47(sensor_mac, threshold){ console.log('config_set_pitch_threshold_47'); var packet = [244, 3, 0, 0, 47, 0, threshold]; console.log(packet); return this.config_send(sensor_mac, packet); } config_set_accelerometer_threshold_108(sensor_mac, value){ console.log('config_set_accelerometer_threshold_108'); var packet = [244, 32, 0, 0, 0, value]; console.log(packet); return this.config_send(sensor_mac, packet); } config_set_debounce_time_108(sensor_mac, value){ console.log('config_set_debounce_time_108'); var packet = [244, 39, 0, 0, 0, value]; console.log(packet); return this.config_send(sensor_mac, packet); } config_set_debounce_time_v10_108(sensor_mac, value){ console.log('config_set_debounce_time_v10_108'); var packet = [244, 39, 0, 0, 0]; let threshold = int2Bytes((value), 2); packet.push(...threshold); console.log(packet); return this.config_send(sensor_mac, packet); } config_set_clear_timers_108(sensor_mac, value){ console.log('config_clear_timers_108'); var packet = [244, 36, 0, 0, 0, value]; console.log(packet); return this.config_send(sensor_mac, packet); } config_set_accelerometer_state_108(sensor_mac, value){ console.log('config_set_accelerometer_state_108'); var packet = [244, 37, 0, 0, 0, 7, value]; console.log(packet); return this.config_send(sensor_mac, packet); } config_set_input_one_108(sensor_mac, value){ console.log('config_set_input_one_108'); var packet = [244, 41, 0, 0, 0, 1, value]; console.log(packet); return this.config_send(sensor_mac, packet); } config_set_input_two_108(sensor_mac, value){ console.log('config_set_input_two_108'); var packet = [244, 41, 0, 0, 0, 2, value]; console.log(packet); return this.config_send(sensor_mac, packet); } config_set_input_three_108(sensor_mac, value){ console.log('config_set_input_three_108'); var packet = [244, 41, 0, 0, 0, 3, value]; console.log(packet); return this.config_send(sensor_mac, packet); } config_set_counter_threshold_108(sensor_mac, value){ console.log('config_set_counter_threshold_108'); var packet = [244, 43, 0, 0, 0, 0, 0]; let threshold = int2Bytes((value), 2); packet.push(...threshold); console.log(packet); return this.config_send(sensor_mac, packet); } config_set_push_notification_108(sensor_mac, value){ console.log('config_set_push_notification_108'); var packet = [244, 45, 0, 0, 0, value]; console.log(packet); return this.config_send(sensor_mac, packet); } config_set_deactivate_activate_accelero_108(sensor_mac, value){ console.log('config_set_deactivate_activate_accelero_108'); var packet = [244, 37, 0, 0, 0, value]; console.log(packet); return this.config_send(sensor_mac, packet); } config_set_reset_timeout_108(sensor_mac, value){ console.log('config_set_reset_timeout_108'); var packet = [244, 49, 0, 0, 0]; let timeout = int2Bytes((value), 2); packet.push(...timeout); console.log(packet); return this.config_send(sensor_mac, packet); } config_set_reset_mode_to_disabled_108(sensor_mac, value){ console.log('config_set_reset_mode_to_disabled_108'); var packet = [244, 51, 0, 0, 0, value]; console.log(packet); return this.config_send(sensor_mac, packet); } config_set_quality_of_service_108(sensor_mac, value){ console.log('config_set_quality_of_service_108'); var packet = [247, 52, 0, 0, 0, value]; console.log(packet); return this.config_send(sensor_mac, packet); } config_set_rtc_108(sensor_mac){ console.log('config_set_rtc_108'); var date = new Date(); var packet = [244, 53, 0, 0, 0, date.getHours(), date.getMinutes(), date.getSeconds()]; console.log(packet); return this.config_send(sensor_mac, packet); } config_set_transmission_interval_108(sensor_mac, value){ console.log('config_set_transmission_interval_108'); var packet = [244, 55, 0, 0, 0, value]; console.log(packet); return this.config_send(sensor_mac, packet); } config_set_shift_one_108(sensor_mac, hours, minutes){ console.log('config_set_shift_one_108'); var packet = [244, 47, 0, 0, 0, 0, hours, minutes]; console.log(packet); return this.config_send(sensor_mac, packet); } config_set_shift_two_108(sensor_mac,