diff --git a/dht.js b/dht.js index 33989d1..9e4caa6 100644 --- a/dht.js +++ b/dht.js @@ -47,6 +47,7 @@ app.use(morgan('combined')); var auth = require('./src/auth.js'); var ac = require('./ac.js'); var db = require('./src/db'); +var mqtt = require('./src/mqtt.js'); var ir = require('./src/devices/ir'); var u = require('./src/utils'); @@ -160,7 +161,6 @@ app.put('/device/:device_id/:field_name/:field_value', (req, res) => { //!Startup -var wws; if(credentials){ var httpsServer = https.createServer(credentials, app); httpsServer.listen(2443, () => { @@ -202,176 +202,6 @@ wss.on('connection', ws => { }); -var mosca = require('mosca'); -var mqtt_settings = { - port:1883 -} -if(credentials) -{ - mqtt_settings.secure = { - port: 8444, - keyPath: SECURE_KEY, - certPath: SECURE_CERT, - } -} -var mqtt = new mosca.Server(mqtt_settings); -mqtt.on('ready', function(){ - console.log("MQTT ready on port " + mqtt_settings.port); -}) -mqtt.on('clientConnected', function(){ - console.log("MQTT client connected !"); -}); - -var mqtt = require('mqtt'); -var mqtt_client = mqtt.connect('mqtt://'+ config.HomeControllerMQTT); -mqtt_client.on('connect', function () { - console.log("MQTT connected. subscribing to topics"); - mqtt_client.subscribe('tele/tasmota/STATE'); - mqtt_client.subscribe('tele/tasmota/RESULT');//IR - mqtt_client.subscribe('tele/tasmota/INFO2'); - // mqtt_client.subscribe('tele/tasmota/SENSOR');//DHT - mqtt_client.subscribe('tele/+/SENSOR');//DHT - mqtt_client.subscribe('tasmota_3FD92D'); - // mqtt_client.subscribe('tele'); - // mqtt_client.subscribe('dht'); - // mqtt_client.subscribe('ir'); - - // ESP_Easy_0 = garden - mqtt_client.subscribe('Garden/+'); - mqtt_client.subscribe('Garden/+/+'); - mqtt_client.publish('tasmota', 'controller connected'); -}); - -var dht = {}; -// https://github.com/pauloromeira/Sonoff-Tasmota/wiki/Commands -//https://stevessmarthomeguide.com/setting-up-the-sonoff-tasmota-mqtt-switch/ -mqtt_client.on('message', function (topic, message) { - var context = message.toString(); - console.log("MQTT> " + topic + " : " + context); - var handled = false; - if(topic === "tele/tasmota/SENSOR") - { - var j = JSON.parse(message); - //console.log("JSON> " + util.inspect(j)); - if(j.DHT11 && j.DHT11.Humidity !== null) - { - var msg = { - dht:{ - hum: j.DHT11.Humidity, - temp: j.DHT11.Temperature, - dew: j.DHT11.DewPoint - } - }; - - db.devicemessages.insert( 0, "A23_DHT", JSON.stringify(msg), function (err, data) { - if (!err) { console.log("success: "+ data);} - else { console.log("error: " + err); } - }); - }else { - console.log("Got wrong DHT data: " + message ); - } - handled = true; - } - if(topic === "Garden/status/LWT") - { - //!console.log("Garden >'" + message + "'"); - var stat = {}; - var pairs = message.toString().split(';'); - stat.event = pairs[0]; - for (var i = 0; i < pairs.length; i++) - { - var pair = pairs[i].split(':'); - if(pair.length == 2){ - stat[pair[0].trim()] = pair[1].trim() || ''; - //console.log( "'"+pair[0] +"' >'" + pair[1] + "'"); - } - } - dht.ssid=stat["SSID"]; - dht.rssi=stat["RSSI"]; - //if(stat.event ==='ON'){console.log(formatDate(new Date()) + "Device is ONLINE! <" + dht.ssid + "> " + dht.rssi + "dB" );} - //if(stat.event ==='OFF'){console.log(formatDate(new Date()) + "Device went ofline!");} - handled = true; - } - if(topic === "Garden/Soil/RH") - { - //console.log("Garden > soil " + message + "% moisture"); - dht.Soil = message.toString(); - if(dht.Soil > 10){ - SaveDhtIf(); - } else { - console.log("Got suspicious soil RH value:" + dht.Soil); - //dht.Soil = 0; - } - SaveDhtIf(); - handled = true; - } - if(topic === "Garden/bmp/Temperature") - { - dht.Temp = message.toString(); - console.log("Garden > air " + dht.Temp + " C"); - SaveDhtIf(); - handled = true; - } - if(topic === "Garden/bmp/Humidity") - { - dht.Hum = message.toString(); - console.log("Garden > air " + dht.Hum + "% RH"); - SaveDhtIf(); - handled = true; - } - if(topic === "Garden/bmp/Pressure") - { - dht.Pres = message.toString(); - console.log("Garden > air " + dht.Pres + " hPa"); - SaveDhtIf(); - handled = true; - } - if(topic === "Garden/Water/start") - { - var j = JSON.parse(message); - dht.Soil = j.soil; - SaveDhtIf(); - handled = true; - console.log(formatDate(new Date()) + "Garden > Started watering at "+j.time+"(GMT) with " + j.soil + "% soil RH"); - } - if(topic === "Garden/Water/stop") - { - var j = JSON.parse(message); - dht.Soil = j.soil; - SaveDhtIf(); - handled = true; - console.log(formatDate(new Date()) + "Garden > Finished watering at "+j.time+"(GMT) with " + j.soil + "% soil RH"); - } - - if(!handled){ - console.log(topic + " > " + message ); - } -}); -function SaveDhtIf(){ - if(dht.Temp && dht.Hum && dht.Pres)// && dht.Soil - { - // if(dht.Soil && dht.Soil < 5) - // { - // console.log("Soil reported below 5%! Probable loose sensor wire. Record discarded" ); - // dht = {}; - // return; - // } - var msg = JSON.stringify(dht); - db.devicemessages.insert(1, "A23_Garden_dht", msg, function (err, data) { - if (!err) { - console.log("Saved to DB > ["+ data.id +"]:" + msg);//+"; SSID: '"+dht.ssid+"' RSSI:"+ dht.rssi + "dB"); - } - else { console.log("error: " + err); } - }); - dht = {}; - }else{ - console.log("T: %s; H: %s; P: $s", dht.Temp, dht.Hum, dht.Pres); - // if(dht.Temp ){console.log("have Temp");} - // if(dht.Hum ){console.log("have Hum");} - // if(dht.Pres ){console.log("have Pres");} - console.log("Missing all data to write to DB !"); - } -} const env = process.env.NODE_ENV || 'development'; const cfg = require(__dirname + '/config/config.json')[env]; diff --git a/src/db/devices.js b/src/db/devices.js new file mode 100644 index 0000000..4c457b9 --- /dev/null +++ b/src/db/devices.js @@ -0,0 +1,72 @@ + +var mysql = require('mysql'); +const env = process.env.NODE_ENV || 'development'; +const config = require(__dirname + '/../../config/config.json')[env]; + +var pool = mysql.createPool({ + connectionLimit : 20, + host : config.host, + user : config.username, + password : config.password, + database : config.database +}); +pool.on('acquire', function (connection) { + console.log('Connection %d acquired', connection.threadId); + }); + +exports.findByName = function(deviceName, cb) { + process.nextTick(function() { + console.log("findByName(" +deviceName + "," + days +")" ); + pool.getConnection(function(err, con) { + if (err) throw err; // not connected! + con.query("SELECT * FROM devices WHERE (name=? OR ? IS NULL) )", [deviceName, deviceName], (err, data) => { + con.release(); + if (!err) { + cb(null, data); + } else { + cb(new Error('SQL Error: ' + err)); + } + }); + }); + }); +} + +exports.insert = function(deviceName, baseurl, apikey,lastseen, cb){ + var params = [deviceName, baseurl, apikey,lastseen]; + let sql = `INSERT INTO devices (name,baseurl,apikey,lastseen,timestamp) + VALUES (?,?,?,?,NOW());`; + pool.getConnection(function(err, con) { + if (err) throw err; // not connected! + con.query(sql, params,(err, r) => { + con.release(); + //if(!cb) {return;} + if (err) { + console.log("error: ", err); + cb && cb(new Error('SQL Error: ' + err)); + }else{ + console.log("inserted record: ", { id: r.insertId}); + cb && cb(null, { id: r.insertId, ...params }); + } + }); + }); +} + +exports.update = function(deviceName, baseurl, cb){ + var params = [deviceName, baseurl, apikey,lastseen]; + let sql = `INSERT INTO devices (name,baseurl,apikey,lastseen,timestamp) + VALUES (?,?,?,?,NOW());`; + pool.getConnection(function(err, con) { + if (err) throw err; // not connected! + con.query(sql, params,(err, r) => { + con.release(); + //if(!cb) {return;} + if (err) { + console.log("error: ", err); + cb && cb(new Error('SQL Error: ' + err)); + }else{ + console.log("inserted record: ", { id: r.insertId}); + cb && cb(null, { id: r.insertId, ...params }); + } + }); + }); +} \ No newline at end of file diff --git a/src/db/index.js b/src/db/index.js index d6d5582..1176734 100644 --- a/src/db/index.js +++ b/src/db/index.js @@ -20,5 +20,6 @@ data.init(); exports.devicemessages = require('./devicemessages'); +exports.devices = require('./devices'); exports.users = require('./users'); exports.orm = require('./database'); diff --git a/src/mqtt.js b/src/mqtt.js new file mode 100644 index 0000000..1a7b65f --- /dev/null +++ b/src/mqtt.js @@ -0,0 +1,175 @@ +//dependencies +var config = require('./setup_const'); +var db = require('./db'); + +var mosca = require('mosca'); +var mqtt_settings = { + port:1883 +} + +if(typeof credentials!=='undefined') +{ + mqtt_settings.secure = { + port: 8444, + keyPath: SECURE_KEY, + certPath: SECURE_CERT, + } +} +var mqtt = new mosca.Server(mqtt_settings); +mqtt.on('ready', function(){ + console.log("MQTT ready on port " + mqtt_settings.port); +}) +mqtt.on('clientConnected', function(){ + console.log("MQTT client connected !"); +}); + +var mqtt = require('mqtt'); +var mqtt_client = mqtt.connect('mqtt://'+ config.HomeControllerMQTT); +mqtt_client.on('connect', function () { + console.log("MQTT connected. subscribing to topics"); + mqtt_client.subscribe('tele/tasmota/STATE'); + mqtt_client.subscribe('tele/tasmota/RESULT');//IR + mqtt_client.subscribe('tele/tasmota/INFO2'); + // mqtt_client.subscribe('tele/tasmota/SENSOR');//DHT + mqtt_client.subscribe('tele/+/SENSOR');//DHT + mqtt_client.subscribe('tasmota_3FD92D'); + // mqtt_client.subscribe('tele'); + // mqtt_client.subscribe('dht'); + // mqtt_client.subscribe('ir'); + + // ESP_Easy_0 = garden + mqtt_client.subscribe('Garden/+'); + mqtt_client.subscribe('Garden/+/+'); + mqtt_client.publish('tasmota', 'controller connected'); +}); + +var dht = {}; +// https://github.com/pauloromeira/Sonoff-Tasmota/wiki/Commands +//https://stevessmarthomeguide.com/setting-up-the-sonoff-tasmota-mqtt-switch/ +mqtt_client.on('message', function (topic, message) { + var context = message.toString(); + console.log("MQTT> " + topic + " : " + context); + var handled = false; + if(topic === "tele/tasmota/SENSOR") + { + var j = JSON.parse(message); + //console.log("JSON> " + util.inspect(j)); + if(j.DHT11 && j.DHT11.Humidity !== null) + { + var msg = { + dht:{ + hum: j.DHT11.Humidity, + temp: j.DHT11.Temperature, + dew: j.DHT11.DewPoint + } + }; + + db.devicemessages.insert( 0, "A23_DHT", JSON.stringify(msg), function (err, data) { + if (!err) { console.log("success: "+ data);} + else { console.log("error: " + err); } + }); + }else { + console.log("Got wrong DHT data: " + message ); + } + handled = true; + } + if(topic === "Garden/status/LWT") + { + //!console.log("Garden >'" + message + "'"); + var stat = {}; + var pairs = message.toString().split(';'); + stat.event = pairs[0]; + for (var i = 0; i < pairs.length; i++) + { + var pair = pairs[i].split(':'); + if(pair.length == 2){ + stat[pair[0].trim()] = pair[1].trim() || ''; + //console.log( "'"+pair[0] +"' >'" + pair[1] + "'"); + } + } + dht.ssid=stat["SSID"]; + dht.rssi=stat["RSSI"]; + //if(stat.event ==='ON'){console.log(formatDate(new Date()) + "Device is ONLINE! <" + dht.ssid + "> " + dht.rssi + "dB" );} + //if(stat.event ==='OFF'){console.log(formatDate(new Date()) + "Device went ofline!");} + handled = true; + } + if(topic === "Garden/Soil/RH") + { + //console.log("Garden > soil " + message + "% moisture"); + dht.Soil = message.toString(); + if(dht.Soil > 10){ + SaveDhtIf(); + } else { + console.log("Got suspicious soil RH value:" + dht.Soil); + //dht.Soil = 0; + } + SaveDhtIf(); + handled = true; + } + if(topic === "Garden/bmp/Temperature") + { + dht.Temp = message.toString(); + console.log("Garden > air " + dht.Temp + " C"); + SaveDhtIf(); + handled = true; + } + if(topic === "Garden/bmp/Humidity") + { + dht.Hum = message.toString(); + console.log("Garden > air " + dht.Hum + "% RH"); + SaveDhtIf(); + handled = true; + } + if(topic === "Garden/bmp/Pressure") + { + dht.Pres = message.toString(); + console.log("Garden > air " + dht.Pres + " hPa"); + SaveDhtIf(); + handled = true; + } + if(topic === "Garden/Water/start") + { + var j = JSON.parse(message); + dht.Soil = j.soil; + SaveDhtIf(); + handled = true; + console.log(formatDate(new Date()) + "Garden > Started watering at "+j.time+"(GMT) with " + j.soil + "% soil RH"); + } + if(topic === "Garden/Water/stop") + { + var j = JSON.parse(message); + dht.Soil = j.soil; + SaveDhtIf(); + handled = true; + console.log(formatDate(new Date()) + "Garden > Finished watering at "+j.time+"(GMT) with " + j.soil + "% soil RH"); + } + + if(!handled){ + console.log(topic + " > " + message ); + } +}); +function SaveDhtIf(){ + if(dht.Temp && dht.Hum && dht.Pres)// && dht.Soil + { + // if(dht.Soil && dht.Soil < 5) + // { + // console.log("Soil reported below 5%! Probable loose sensor wire. Record discarded" ); + // dht = {}; + // return; + // } + var msg = JSON.stringify(dht); + db.devicemessages.insert(1, "A23_Garden_dht", msg, function (err, data) { + if (!err) { + console.log("Saved to DB > ["+ data.id +"]:" + msg);//+"; SSID: '"+dht.ssid+"' RSSI:"+ dht.rssi + "dB"); + } + else { console.log("error: " + err); } + }); + dht = {}; + }else{ + console.log("T: %s; H: %s; P: $s", dht.Temp, dht.Hum, dht.Pres); + // if(dht.Temp ){console.log("have Temp");} + // if(dht.Hum ){console.log("have Hum");} + // if(dht.Pres ){console.log("have Pres");} + console.log("Missing all data to write to DB !"); + } +} \ No newline at end of file