initial commit: dht client

This commit is contained in:
d-popov
2020-04-09 12:12:05 +03:00
commit 794eda52af
9 changed files with 3468 additions and 0 deletions

1
.gitignore vendored Normal file
View File

@@ -0,0 +1 @@
/node_modules

134
charts.html Normal file
View File

@@ -0,0 +1,134 @@
<!DOCTYPE html PUBLIC"-//W3C//DTD XHTML 1.0 Strict//EN"
"http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<meta charset="utf-8"/>
<script src="https://ajax.googleapis.com/ajax/libs/jquery/3.4.1/jquery.min.js"></script>
<script>
var current;
window.onload = function () {
var dataPoints1 = [];
var dataPoints2 = [];
/*{ x: new Date(2017, 0, 3), y: 650 },
{ x: new Date(2017, 0, 4), y: 700 },
*/
var chart = new CanvasJS.Chart("chartContainer", {
animationEnabled: true,
theme: "light2",
zoomEnabled: true,
zoomType: "x",
exportEnabled: true,
title:{
text: "Retrieving current A23 conditions..."
},
/* subtitles:[{
text: "X Axis scale is Logarithmic",
fontSize: 14
}],*/
axisX:{
valueFormatString: "HH:mm DD MMM",
crosshair: {
enabled: true,
snapToDataPoint: true
}
},
axisY: {
title: "Temperature",
lineColor: "#C24642",
titleFontColor: "#C24642",
labelFontColor: "#C24642",
crosshair: {
enabled: true
}
},
axisY2: [
{
title: "Relative hum %",
titleFontColor: "#51CDA0",
labelFontColor: "#51CDA0"
}
],
//{title: "Temperature",
//lineColor: "#C24642",
//titleFontColor: "#C0504E",
//labelFontColor: "#C0504E"
//},
toolTip:{
shared:true
},
legend:{
cursor:"pointer",
verticalAlign: "bottom",
horizontalAlign: "left",
dockInsidePlotArea: true,
itemclick: toogleDataSeries
},
data: [{
name: "Temperature",
type: "spline",//line
showInLegend: true,
markerType: "square",
xValueFormatString: "HH:mm on DD MMM, YYYY",
color: "#F08080",
dataPoints: dataPoints2
},
{
name: "Humidiry",
type: "spline",
axisYType: "secondary",
axisYIndex: 1,
showInLegend: true,
lineDashType: "dash",
dataPoints: dataPoints1
}]
});
function toogleDataSeries(e){
if (typeof(e.dataSeries.visible) === "undefined" || e.dataSeries.visible) {
e.dataSeries.visible = false;
} else {
e.dataSeries.visible = true;
}
chart.render();
}
function addData(data) {
for (var i = 0; i < data.length; i++) {
if(data[i].field_name == "A23_DHT"){
var dht = JSON.parse(data[i].field_value).dht;
var date = new Date(data[i]["timestamp"]);
if(dht && dht.hum <= 100){
dataPoints1.push({
x: date,
y: dht.hum
});
dataPoints2.push({
x: date,
y: dht.temp
});
}
}
}
chart.render();
$.getJSON("/n/dht", function(data){
if(data && data.dht){
chart.title.set("text", "A23 Currently is " + data.dht.temp + "°C, " + data.dht.hum +"% RH" );
}else {
chart.title.set("text", "A23 conditions");
}
});
}
$.getJSON("/n/dht/A23_DHT", addData);
}
</script>
</head>
<body>
<div id="chartContainer" style="height: 370px; width: 100%;"></div>
<script src="https://canvasjs.com/assets/script/canvasjs.min.js"></script>
</body>
</html>

211
dht.js Normal file
View File

@@ -0,0 +1,211 @@
// ./src/index.js
// importing the dependencies
const express = require('express');
const bodyParser = require('body-parser');
const cors = require('cors');
const helmet = require('helmet');
const morgan = require('morgan');
const cron = require('node-cron');
const request = require('request');
const got = require('got');
const Sequelize = require("sequelize")
//!https endpoint
var fs = require("fs");
var http = require('http');
var https = require('https');
var privateKey = fs.readFileSync('/etc/letsencrypt/live/iot.d-popov.com/privkey.pem', 'utf8');
var certificate = fs.readFileSync('/etc/letsencrypt/live/iot.d-popov.com/cert.pem', 'utf8');
var credentials = {key: privateKey, cert: certificate};
//!database
var mysql = require('mysql');
var con = mysql.createConnection({
host : 'localhost',
user : 'iot',
password : '!iot_popovi',
database : 'iot'
});
var sqlz = new Sequelize('iot', 'iot', '!iot_popovi',{dialect: 'mysql'})
const mongoose = require('mongoose');
const Schema = mongoose.Schema;
let DeviceMessageSchema = new Schema({
_id: {type: Number, required: true},
device_id: {type: String, required: true, max: 100}
});
let DevicesSchema = new Schema({
id: {type: Number, required: true},
url: {type: String, required: true, max: 100}
});
var Device = sqlz.define('device', {
id: { type: Sequelize.INTEGER, autoIncrement: true, primaryKey: true },
name: Sequelize.STRING,
baseurl: Sequelize.TEXT,
apikey: Sequelize.TEXT,
//config: Sequelize.JSON,
lastseen: Sequelize.DATE
});
sqlz.sync();
// defining the Express app
const app = express();
var httpServer = http.createServer(app);
var httpsServer = https.createServer(credentials, app);
// defining an array to work as the database (temporary solution)
const ads = [
{title: 'Hello, world (again)!'}
];
// adding Helmet to enhance your API's security
app.use(helmet());
// using bodyParser to parse JSON bodies into JS objects
app.use(bodyParser.json());
// enabling CORS for all requests
app.use(cors());
// adding morgan to log HTTP requests
app.use(morgan('combined'));
// defining an endpoint to return all ads
app.get('/dht', (req, res) => { (async (res) => {
try {
const response = await got('http://192.168.1.126/json')
res.send(response.body);
} catch (error) {
console.log("DHT Error:" + error); //..response.body);
} })(res);
});
app.get("/dht/:field_name", (req, res) => {
dht = con.query("SELECT * FROM devicemessages WHERE field_name=? OR ? IS NULL",
[req.params.field_name, req.params.field_name], (err, data) => {
//dht = con.query("SELECT * FROM devicemessages", (err, data) => {
if (!err) {
res.send(data);
} else {
console.log("error: ", err);
}
});
});
app.put('/dht/:device_id/:field_name/:field_value', (req, res) => {
var params = [req.params.device_id,req.params.field_name,req.params.field_value];
let sql = `INSERT INTO devicemessages(device_id,field_name,field_value,timestamp)
VALUES (?,?,?,NOW());`;
con.query(sql,params, (err, r) => {
if (err) {
console.log("error: ", err);
res.send( err);
return;
}
if (r.affectedRows == 0) {
// not found Customer with the id
res.send({ kind: "not_found" });
return;
}
console.log("inserted record: ", { id: r.insertId, ...params });
res.send( { id: r.insertId, ...params });
});
//con.end();
//fs.appendFileSync('dht.txt', 'data to append');
});
httpsServer.listen(8443, () => {
console.log('HTTPS server listening on port 8443');
});
httpServer.listen(81, () => {
console.log('HTTP server listening on port 81');
});
var device = Device.build({
name: 'A23',
url: "http://192.168.1.126/"
});
// device.save().then().catch(
// err => {console.log(err);}
// )
//.success(function(savedTask) {
// console.log('device saved with id' + savedTask.id);
// });
// # ┌────────────── second (optional)
// # │ ┌──────────── minute
// # │ │ ┌────────── hour
// # │ │ │ ┌──────── day of month
// # │ │ │ │ ┌────── month
// # │ │ │ │ │ ┌──── day of week
// # │ │ │ │ │ │
// # │ │ │ │ │ │
// # * * * * * *
cron.schedule(' */30 * * * *', () => {//cron.schedule('*/5 * * * * *', () => {
console.log(new Date().toISOString() + ' running a task every 30 minutes');
StoreSensorReadingsAsync();
}).start();
StoreSensorReadings();
async function StoreSensorReadingsAsync()
{
try {
await new Promise(function(resolve, reject) {
request('http://192.168.1.126/json', { json: true }, (err, res, body) => {
if(err) {
return reject(err);
}
else {
var params = [0, "A23_DHT", JSON.stringify(body)];
let sql = `INSERT INTO devicemessages(device_id,field_name,field_value,timestamp)
VALUES (?,?,?,NOW());`;
con.query(sql,params,(err, r) => {
if (err) {
console.log("error: ", err);
}else{
console.log("inserted record: ", { id: r.insertId, ...params });
}
});
resolve(body);
console.log(body);
}
});
});
} catch(error) {
console.error(error);
}
}
function StoreSensorReadings()
{
(async () => {
try {
const dht = await got('http://192.168.1.126/json')
var params = [0, "A23_DHT", dht.body];
let sql = `INSERT INTO devicemessages(device_id,field_name,field_value,timestamp)
VALUES (?,?,?,NOW());`;
con.query(sql,params,(err, r) => {
if (err) {
console.log(err);
}else{
console.log("inserted record: ", { id: r.insertId, ...params });
}
});
} catch (error) {
console.log("DHT Error:" + error); //..response.body);
} })();
}

84
dump.sql Normal file

File diff suppressed because one or more lines are too long

58
index.js Normal file
View File

@@ -0,0 +1,58 @@
// ./src/index.js
// importing the dependencies
const express = require('express');
const bodyParser = require('body-parser');
const cors = require('cors');
const helmet = require('helmet');
const morgan = require('morgan');
var fs = require("fs");
var http = require('http');
var https = require('https');
var privateKey = fs.readFileSync('/etc/letsencrypt/live/zbor.eu.org/privkey.pem', 'utf8');
var certificate = fs.readFileSync('/etc/letsencrypt/live/zbor.eu.org/cert.pem', 'utf8');
var credentials = {key: privateKey, cert: certificate};
// defining the Express app
const app = express();
var httpServer = http.createServer(app);
var httpsServer = https.createServer(credentials, app);
// defining an array to work as the database (temporary solution)
const ads = [
{title: 'Hello, world (again)!'}
];
// adding Helmet to enhance your API's security
app.use(helmet());
// using bodyParser to parse JSON bodies into JS objects
app.use(bodyParser.json());
// enabling CORS for all requests
app.use(cors());
// adding morgan to log HTTP requests
app.use(morgan('combined'));
// defining an endpoint to return all ads
app.get('/', (req, res) => {
res.send(ads);
});
app.get('/dht', (req, res) => {
res.send("DHT");
});
// starting the server
//app.listen(3001, () => {
//console.log('listening on port 3001');
//});
// httpServer.listen(8080, () => {
// console.log('httpServer listening on port 8080');
// });
httpsServer.listen(8443, () => {
console.log('httpsServer listening on port 8443');
});

1001
logs/devicemessages.csv Normal file

File diff suppressed because it is too large Load Diff

1910
package-lock.json generated Normal file

File diff suppressed because it is too large Load Diff

39
package.json Normal file
View File

@@ -0,0 +1,39 @@
{
"name": "iot-rest-api",
"version": "1.0.0",
"description": " test api for IOT devices",
"main": "index.js",
"scripts": {
"test": "echo \"Error: no test specified\" && exit 1"
},
"repository": {
"type": "git",
"url": ""
},
"author": "",
"license": "ISC",
"bugs": {
"url": ""
},
"homepage": "",
"dependencies": {
"body-parser": "^1.19.0",
"cors": "2.8.5",
"express": "^4.8.7",
"got": "^10.7.0",
"helmet": "3.21.3",
"jsonwebtoken": "^7.3.0",
"moment": "^2.17.1",
"moment-timezone": "^0.5.13",
"mongoose": "^5.9.5",
"morgan": "^1.9.1",
"mysql": "^2.18.1",
"mysql2": "^2.1.0",
"node-cron": "^2.0.3",
"node-uuid": "^1.4.8",
"request": "^2.88.2",
"sequelize": "^5.21.5",
"swagger-ui-express": "^2.0.13",
"sync-request": "^4.0.2"
}
}

30
schema.sql Normal file
View File

@@ -0,0 +1,30 @@

DROP TABLE IF EXISTS `devicemessages`;
/*!40101 SET @saved_cs_client = @@character_set_client */;
/*!40101 SET character_set_client = utf8 */;
CREATE TABLE `devicemessages` (
`id` bigint(20) NOT NULL AUTO_INCREMENT,
`device_id` int(20) NOT NULL,
`field_name` varchar(120) NOT NULL,
`field_value` text NOT NULL,
`timestamp` datetime NOT NULL,
PRIMARY KEY (`id`)
) ENGINE=InnoDB AUTO_INCREMENT=1350 DEFAULT CHARSET=utf8;
/*!40101 SET character_set_client = @saved_cs_client */;
DROP TABLE IF EXISTS `devices`;
/*!40101 SET @saved_cs_client = @@character_set_client */;
/*!40101 SET character_set_client = utf8 */;
CREATE TABLE `devices` (
`id` int(11) NOT NULL AUTO_INCREMENT,
`name` varchar(255) DEFAULT NULL,
`baseurl` text DEFAULT NULL,
`apikey` text DEFAULT NULL,
`config` longtext CHARACTER SET utf8mb4 COLLATE utf8mb4_bin DEFAULT NULL,
`lastseen` datetime DEFAULT NULL,
`createdAt` datetime NOT NULL,
`updatedAt` datetime NOT NULL,
PRIMARY KEY (`id`)
) ENGINE=InnoDB AUTO_INCREMENT=3 DEFAULT CHARSET=utf8mb4;
/*!40101 SET character_set_client = @saved_cs_client */;