/** * Created by bin.shen on 6/4/16. */ var moment = require('moment'); var config = require('./config'); var queue = require('./queue'); module.exports.toDec = function(hex) { if(typeof hex === 'number') { return parseInt(hex); } return Number('0x' + hex); }; module.exports.toDecStr = function(hex) { return this.toDec(hex).toString(); }; module.exports.toDateStr = function(hex) { var digit = this.toDec(hex); if(digit < 10) { return '0' + digit.toString(); } return digit.toString(); }; module.exports.checkSum = function(data) { var fields = data.match(/.{2}/g); var length = fields.length; var total = 0; var check_sum = ''; for(var i in fields) { if(i == 0) continue; if(i < length - 2) { total += Number('0x' + fields[i]); } else if(i == length - 2) { check_sum = fields[i]; } } if(total.toString(16).substr(-2) == check_sum) { return true; } else { return false; } }; module.exports.calSum = function(fields) { var length = fields.length; var total = 0; for(var i in fields) { if(i == 0) continue; if(i == length - 2) break; total += fields[i]; } return total.toString(16).substr(-2); }; module.exports.insertDocument = function(db, data, callback) { var collection = db.collection(config.COLLECTION); collection.insertOne({ data: data, date: Date.now() }, function(err, result) { if (err) return; callback(result); }); }; module.exports.checkSum2 = function(fields) { var length = fields.length; var total = 0; var check_sum = ''; for(var i in fields) { if(i == 0) continue; if(i < length - 2) { total += fields[i]; } else if(i == length - 2) { check_sum = fields[i]; } } if(total.toString(16).substr(-2) == check_sum) { return true; } else { return false; } }; module.exports.getMac = function(data) { var fields = data.match(/.{2}/g); var mac = fields[6] + fields[7] + fields[8] + fields[9] + fields[10] + fields[11]; //Mac return mac.toLowerCase(); }; module.exports.getAppStatus = function(db, data, callback) { var mac = this.getMac(data); this.updateDeviceLastUpdated(db, mac, function(data) {}); db.collection("devices").find({ mac: mac }).limit(1).next(function(err, doc){ if (err || doc == null) return; callback(doc); }); }; module.exports.registerDevice = function(db, data, callback) { var fields = data.match(/.{2}/g); var mac = fields[6] + fields[7] + fields[8] + fields[9] + fields[10] + fields[11]; //Mac mac = mac.toLowerCase(); var ver1 = this.toDecStr(fields[16]) + '.' + this.toDecStr(fields[17]) + '.' + this.toDecStr(fields[18]) + '.' + this.toDecStr(fields[19]); var ver2 = '20' + this.toDateStr(fields[20]) + '-' + this.toDateStr(fields[21]) + '-' + this.toDateStr(fields[22]) + ' ' + this.toDateStr(fields[23]) + this.toDateStr(fields[24]) + this.toDateStr(fields[25]); var type = this.toDec(fields[15]) <= 80 ? 1 : 0; var collection = db.collection("devices"); collection.find({ mac: mac }).limit(1).next(function(err, doc){ if (err) return; if(doc == null) { collection.insertOne({ mac: mac, type: type, ver1: ver1, ver2: ver2, status: 1, last_updated: Date.now() }, function(err, result) { if (err) return; callback(result); }); } else { collection.findOneAndUpdate({ mac: mac }, { $set: { type: type, ver1: ver1, ver2: ver2, status: 1, last_updated: Date.now() } }, {}, function(err, result) { if (err) return; callback(result); }); } }); }; module.exports.insertData = function(db, data, callback) { var fields = data.match(/.{2}/g); var mac = fields[6] + fields[7] + fields[8] + fields[9] + fields[10] + fields[11]; //Mac mac = mac.toLowerCase(); this.updateDeviceLastUpdated(db, mac, function(data) {}); //通过版本号来判断传感器数据的协议格式 //var ver = this.toDec(fields[18]) * 256 + this.toDec(fields[19]); //版本号 var x1 = this.toDec(fields[20]) * 256 + this.toDec(fields[21]); //PM2.5数据 var x2 = this.toDec(fields[22]) * 256 + this.toDec(fields[23]); //PM10 var x3 = this.toDec(fields[24]) * 256 + this.toDec(fields[25]); //0.1升0.3um量 var x4 = this.toDec(fields[26]) * 256 + this.toDec(fields[27]); //0.1升2.5um量 var x5 = fields[28]; //(甲醛)(首字) var x6 = fields[29]; //(甲醛)(ID) var x7 = fields[30]; //(甲醛)(数据单位) var x8 = this.toDec(fields[31]); //(甲醛)(当量) var x9 = this.toDec(fields[32]) * 256 + this.toDec(fields[33]); //甲醛 if(x8 == 4) { x9 = x9 / 1000; } else if(x8 == 3) { x9 = x9 / 100; } else if(x8 == 2) { x9 = x9 / 10; } var x10 = this.toDec(fields[34]) * 256 + this.toDec(fields[35]); //湿度 //var x11 = this.toDec(fields[36]) * 256 + this.toDec(fields[37]); //温度 var x11 = this.toDec(fields[36]) == 0 ? this.toDec(fields[37]) : -1 * this.toDec(fields[37]); var x12 = this.toDec(fields[38]) * 256 + this.toDec(fields[39]); //风速 var x13 = this.toDec(fields[40]) * 256 + this.toDec(fields[41]); //电池电量 var x14 = this.toDec(fields[42]) * 256 + this.toDec(fields[43]); //光线强度 var s = this.toDec(fields[44]); var p1 = this.toDec(fields[45]); var p2 = this.toDec(fields[46]); var p3 = this.toDec(fields[47]); var p4 = this.toDec(fields[48]); var fei = this.toDec(fields[58]); //var ferval = this.toDec(fields[59]); var feival = this.toDec(fields[71]) == 0 ? (this.toDec(fields[72]) * 256 + this.toDec(fields[73])) : -1 * (this.toDec(fields[72]) * 256 + this.toDec(fields[73])); var t = this.toDec(fields[56]); var aqi = this.toDec(fields[60]) * 256 + this.toDec(fields[61]); //AQI var ddv = this.toDec(fields[62]) * 256 + this.toDec(fields[63]); var mcu = this.toDec(fields[64]) + this.toDec(fields[65]) / 100; var _config = global.configs[mac]; if(_config == null) { _config = config.ALARM_DEFAULTS; _config.mac = mac; global.configs[mac] = _config; } var current = moment(); var sensor_data = { mac: mac, location: _config.location, data: { x0: feival, x1: x1, //PM2.5 - (单位:ppm) x2: x3, //PM2.5 - 0.1升0.3um量 x3: x9, //甲醛 x4: x11, //温度 x5: x10, //湿度 x6: x14, //光线强度 mcu: mcu }, options: _config.options, time: current.valueOf() }; queue.pushToMQ('ex_data_screen', sensor_data); var rank = 0; if(s > 0) { rank = this.random(100200, 102000);//this.random(1000, 99999999); db.collection("device_ranks").insertOne({ mac: mac, rank: rank, created: current.valueOf() }, function(err, result) { }); } if(t > 0) { db.collection("device_tests").insertOne({ mac: mac, test: t, created: current.valueOf() }, function(err, result) { }); } var _this = this; db.collection("data").insertOne({ mac: mac, x1: x1, x2: x2, x3: x3, x4: x4, x5: x5, x6: x6, x7: x7, x8: x8, x9: x9, x10: x10, x11: x11, x12: x12, x13: x13, x14: x14, p1: p1, p2: p2, p3: p3, p4: p4, fei: fei, ferval: feival, aqi: aqi, s: s, rank: rank, ddv: ddv, mcu: mcu, day: current.format('YYYYMMDD'), created: current.valueOf() }, function(err, doc) { if (err) return; var level1 = _this.getLevel(x1, _config['options'][1]); var level2 = _this.getLevel(x9, _config['options'][2]); var level3 = _this.getLevel(x11, _config['options'][3]); var level4 = _this.getLevel(x10, _config['options'][4]); var level5 = _this.getLevel(x14, _config['options'][5]); var level = Math.max(level1, level2, level3, level4, level5); if(level > 0) { sensor_data._id = doc.insertedId; sensor_data.level = level; sensor_data.notice = _config.notice; sensor_data.address = _config.address; sensor_data.data.levels = [level1, level2, level3, level4, level5]; queue.pushToMQ('ex_data_alarm', sensor_data); } callback(doc, rank); }); }; module.exports.getLevel = function(val, option) { var level = 0; if(option == null || option.length < 3) return level; if(val > option[0]) { var level = 1; if(val > option[2]) { level = 3; } else if(val > option[1]) { level = 2; } } return level; }; module.exports.updateDeviceSleep = function(db, data, callback) { var mac = this.getMac(data); var collection = db.collection("devices"); collection.findOneAndUpdate({ mac: mac }, { $set: { status: 0 } }, {}, function(err, doc) { if (err) return; callback(doc); }); }; module.exports.updateDeviceWakeup = function(db, data, callback) { var mac = this.getMac(data); var collection = db.collection("devices"); collection.findOneAndUpdate({ mac: mac }, { $set: { status: 1 } }, {}, function(err, doc) { if (err) return; callback(doc); }); }; module.exports.updateDeviceLastUpdated = function(db, mac, callback) { var collection = db.collection("devices"); collection.findOneAndUpdate({ mac: mac }, { $set: { status: 1, last_updated: Date.now() } }, {}, function(err, doc) { if (err) return; callback(doc); }); }; module.exports.getSort = function(db, data, callback) { var collection = db.collection("data"); collection.aggregate([ { $match: { created: { $gt: Date.now() - 60*1000 }, x3: { $lt: data } } }, { $group: { _id: "$mac" } }, { $group: { _id: null, total:{ $sum: 1 } } } ], function(err ,doc) { if (err) return; callback(doc[0]); }); }; module.exports.createSort = function(db, callback) { var _this = this; db.collection("devices").find({ last_updated: { $gt: Date.now() - 60*1000 } }).toArray(function(err, docs){ if (err) return; docs.forEach(function(doc) { var mac = doc.mac; db.collection("data").find({ mac: mac }).sort({created: -1}).limit(1).next(function(err, doc){ if (err) return; var data = doc["x3"]; _this.getSort(db, data, function(doc) { console.log(mac + ": " + data + " - " + doc['total']) }); }); }); }); }; ///////////////////////////////////////////////// module.exports.random = function random(n,m){ return Math.floor(Math.random() * (m - n + 1) + n); }; module.exports.padLeft = function (str,lenght) { if(str.length >= lenght) { return str; } else { return this.padLeft("0" + str, lenght); } }; module.exports.initConfigs = function(db) { var _address = config.ALARM_DEFAULTS.address; var _location = config.ALARM_DEFAULTS.location; var _options = config.ALARM_DEFAULTS.options; db.collection("devices").find().toArray(function(err, docs) { docs.forEach(function(doc) { var mac = doc.mac; var address = doc.address || _address; var location = doc.location || _location; var options = doc.options || _options; var notice = doc.notice; var config = { mac: mac, address: address, location: location, notice: notice, options: options }; if(notice == null || notice == {}) { var userID = doc.userID; db.collection("users").find({"_id": userID}).limit(1).next(function(err, user){ if(user) { config["notice"] = { tel: user.username, email: user.email, open_id: user.open_id }; global.configs[mac] = config; } }); } else { global.configs[mac] = config; } }); }); };