From 16a5521093e2af0e616922f70c8eac8ca37e5ae2 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Andr=C3=A9s=20Uribe=20Stengel?= Date: Wed, 15 Jul 2020 12:16:04 +0200 Subject: [PATCH 1/7] Make timestamp type date again and add attribute timestampToString. --- client/main.jsx | 2 +- imports/ui/AddPlant.jsx | 5 ++--- imports/ui/Home.jsx | 8 ++++---- mongo-mqtt.js | 12 ++++++++++++ 4 files changed, 19 insertions(+), 8 deletions(-) diff --git a/client/main.jsx b/client/main.jsx index d0a31b8..c719b8a 100644 --- a/client/main.jsx +++ b/client/main.jsx @@ -25,5 +25,5 @@ Meteor.startup(() => { Meteor.setTimeout(function() { ReactDOM.render(, document.getElementById('root')); - }, 1000); + }, 1250); }); \ No newline at end of file diff --git a/imports/ui/AddPlant.jsx b/imports/ui/AddPlant.jsx index 0121cc4..af800e3 100644 --- a/imports/ui/AddPlant.jsx +++ b/imports/ui/AddPlant.jsx @@ -1,5 +1,5 @@ import React from 'react' -import { Button, Form, Container, Row, Col, Table } from 'react-bootstrap'; +import { Button, Form } from 'react-bootstrap'; class AddPlant extends React.Component{ @@ -69,5 +69,4 @@ class AddPlant extends React.Component{ } } -export default AddPlant; - +export default AddPlant; \ No newline at end of file diff --git a/imports/ui/Home.jsx b/imports/ui/Home.jsx index e2715cc..1399c17 100644 --- a/imports/ui/Home.jsx +++ b/imports/ui/Home.jsx @@ -20,7 +20,7 @@ export default function Home() { - + @@ -32,7 +32,7 @@ export default function Home() { - + @@ -46,7 +46,7 @@ export default function Home() { - + @@ -58,7 +58,7 @@ export default function Home() { - + diff --git a/mongo-mqtt.js b/mongo-mqtt.js index b1a6d8f..66fee96 100644 --- a/mongo-mqtt.js +++ b/mongo-mqtt.js @@ -28,10 +28,22 @@ function messageCallback(collection) { const id = topicElements.pop(); var date = new Date; + var time; + + if (date.getHours() <= 9) {time = "0" + date.getHours();} else { + time = date.getHours(); + } + if (date.getMinutes() <= 9) {time = time + ":0" + date.getMinutes();} else { + time = time + ":" + date.getMinutes(); + } + if (date.getSeconds() <= 9) {time = time + ":0" + date.getSeconds();} else { + time = time + ":" + date.getSeconds(); + } let doc = { device_id: id, timestamp: date, + timestampToString: time, } try { doc = _.merge(doc, JSON.parse(message)); From efe1001682b3187cab89b8ed8790a0334a6e1841 Mon Sep 17 00:00:00 2001 From: Timo Volkmann Date: Thu, 16 Jul 2020 10:53:38 +0200 Subject: [PATCH 2/7] got rid of render delay --- client/main.jsx | 4 +- imports/ui/Home.jsx | 129 +++++++++++++++++++--------------- imports/ui/SensorCardDeck.jsx | 70 ++++++++++-------- package.json | 3 +- 4 files changed, 116 insertions(+), 90 deletions(-) diff --git a/client/main.jsx b/client/main.jsx index c719b8a..decd92b 100644 --- a/client/main.jsx +++ b/client/main.jsx @@ -23,7 +23,5 @@ Meteor.startup(() => { Meteor.subscribe('sensorDataCollection'); } - Meteor.setTimeout(function() { - ReactDOM.render(, document.getElementById('root')); - }, 1250); + ReactDOM.render(, document.getElementById('root')); }); \ No newline at end of file diff --git a/imports/ui/Home.jsx b/imports/ui/Home.jsx index 1399c17..d413e61 100644 --- a/imports/ui/Home.jsx +++ b/imports/ui/Home.jsx @@ -4,68 +4,83 @@ import SensorCardDeck from './SensorCardDeck' import {SensorDataCollection} from "../../client/main"; import {useTracker} from 'meteor/react-meteor-data'; import {Col, Row} from "react-bootstrap"; +import { Card, CardDeck } from 'react-bootstrap'; + export default function Home() { const sensorData = useTracker(() => { return SensorDataCollection.find({ device_id: 'esp-andy' }, { sort: { timestamp: -1 }, limit: 10 }).fetch().reverse(); }); - return ( - <> - + if (sensorData.length <= 0) { + return ( + + + + Loading! + Please wait... + + + + ) + } else { + return ( + <> + - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - ) + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + ) + } } \ No newline at end of file diff --git a/imports/ui/SensorCardDeck.jsx b/imports/ui/SensorCardDeck.jsx index 46709ef..f0bcbed 100644 --- a/imports/ui/SensorCardDeck.jsx +++ b/imports/ui/SensorCardDeck.jsx @@ -7,33 +7,45 @@ export default function SensorCardDeck() { const sensorData = useTracker(() => { return SensorDataCollection.find({ device_id: 'esp-andy' }, { sort: { timestamp: -1 }, limit: 1 }).fetch(); }); - - return ( - - - - Temperature - {sensorData[0].temperature} °C - - - - - Humidity - {sensorData[0].humidity} % - - - - - Brightness - {sensorData[0].brightness} lux - - - - - Moisture - {sensorData[0].moisture} % - - - - ) + if (sensorData.length <= 0) { + return ( + + + + Loading! + Please wait... + + + + ) + } else { + return ( + + + + Temperature + {sensorData[0].temperature} °C + + + + + Humidity + {sensorData[0].humidity} % + + + + + Brightness + {sensorData[0].brightness} lux + + + + + Moisture + {sensorData[0].moisture} % + + + + ) + } } \ No newline at end of file diff --git a/package.json b/package.json index afc917c..bceda08 100644 --- a/package.json +++ b/package.json @@ -2,7 +2,8 @@ "name": "smart_garden_server", "private": true, "scripts": { - "start": "meteor run", + "start": "MONGO_URL=mongodb://garden:99009911@cloud.timovolkmann.de:27017/Smart_Garden meteor run", + "plainstart": "meteor run", "test": "meteor test --once --driver-package meteortesting:mocha", "test-app": "TEST_WATCH=1 meteor test --full-app --driver-package meteortesting:mocha", "visualize": "meteor --production --extra-packages bundle-visualizer" From 984fcfdfd69bf049367c7a38cfe44df323aefee5 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Andr=C3=A9s=20Uribe=20Stengel?= Date: Thu, 16 Jul 2020 13:33:40 +0200 Subject: [PATCH 3/7] Add dropdown to set active device and update charts accordingly. --- .meteor/packages | 1 + client/main.jsx | 6 +++ imports/ui/Home.jsx | 76 +++++++++++++++++++++++++++-------- imports/ui/SensorCardDeck.jsx | 8 +++- mongo-mqtt.js | 4 +- server/main.js | 6 +++ 6 files changed, 81 insertions(+), 20 deletions(-) diff --git a/.meteor/packages b/.meteor/packages index 34e9bc5..61ff3c5 100644 --- a/.meteor/packages +++ b/.meteor/packages @@ -21,3 +21,4 @@ shell-server@0.5.0 # Server-side component of the `meteor shell` comm insecure@1.0.7 # Allow all DB writes from clients (for prototyping) static-html react-meteor-data +underscore diff --git a/client/main.jsx b/client/main.jsx index c719b8a..a864387 100644 --- a/client/main.jsx +++ b/client/main.jsx @@ -6,6 +6,7 @@ import 'bootstrap/dist/css/bootstrap.min.css'; export const PlantTypesCollection = new Meteor.Collection('plantTypes'); export const SensorDataCollection = new Meteor.Collection('sensorData'); +export const ActiveDeviceCollection = new Meteor.Collection('activeDevice'); Meteor.startup(() => { if(Meteor.isServer) { @@ -16,11 +17,16 @@ Meteor.startup(() => { Meteor.publish('sensorDataCollection', function() { return SensorDataCollection.find(); }) + + Meteor.publish('activeDeviceCollection', function() { + return ActiveDeviceCollection.find(); + }) } if (Meteor.isClient) { Meteor.subscribe('plantTypesCollection'); Meteor.subscribe('sensorDataCollection'); + Meteor.subscribe('activeDeviceCollection'); } Meteor.setTimeout(function() { diff --git a/imports/ui/Home.jsx b/imports/ui/Home.jsx index 1399c17..086551b 100644 --- a/imports/ui/Home.jsx +++ b/imports/ui/Home.jsx @@ -1,26 +1,68 @@ import React from 'react' import {CartesianGrid, Legend, Line, LineChart, ResponsiveContainer, Tooltip, XAxis, YAxis} from 'recharts'; import SensorCardDeck from './SensorCardDeck' -import {SensorDataCollection} from "../../client/main"; +import {SensorDataCollection, ActiveDeviceCollection} from "../../client/main"; import {useTracker} from 'meteor/react-meteor-data'; -import {Col, Row} from "react-bootstrap"; +import {Col, Form, Row} from "react-bootstrap"; -export default function Home() { - const sensorData = useTracker(() => { - return SensorDataCollection.find({ device_id: 'esp-andy' }, { sort: { timestamp: -1 }, limit: 10 }).fetch().reverse(); +export default function Home() { + + const uniqueEspNames = _.uniq(SensorDataCollection.find({}, { + sort: {device_id: 1}, fields: {device_id: true} + }).fetch().map(function(x) { + return x.device_id; + }), true); + + const deviceName = useTracker(() => { + return ActiveDeviceCollection.find().fetch()[0]; }); + const sensorData = useTracker(() => { + return SensorDataCollection.find({ device_id: deviceName.deviceName }, { sort: { timestamp: -1 }, limit: 61 }).fetch().reverse(); + }); + + const handleChange = (e) => { + if (e.target.value === "") {console.log("No device selected!");} else { + var doc = ActiveDeviceCollection.findOne({ deviceName: deviceName.deviceName }); + ActiveDeviceCollection.update({ _id: doc._id }, {$set:{deviceName: e.target.value}}); + } + } + return ( <> + + +

Devices:

+ + +
+ + +
+ + + + {uniqueEspNames.map((espName, index) =>{ + return + })} + + +
+ + +
active device: {deviceName.deviceName}
+ +
+ - - + + - + @@ -28,11 +70,11 @@ export default function Home() { - - + + - + @@ -42,11 +84,11 @@ export default function Home() { - - + + - + @@ -54,11 +96,11 @@ export default function Home() { - - + + - + diff --git a/imports/ui/SensorCardDeck.jsx b/imports/ui/SensorCardDeck.jsx index 46709ef..6c585ec 100644 --- a/imports/ui/SensorCardDeck.jsx +++ b/imports/ui/SensorCardDeck.jsx @@ -1,11 +1,15 @@ import React from 'react' import { Card, CardDeck } from 'react-bootstrap'; -import {SensorDataCollection} from "../../client/main"; +import {ActiveDeviceCollection, SensorDataCollection} from "../../client/main"; import {useTracker} from 'meteor/react-meteor-data'; export default function SensorCardDeck() { + const deviceName = useTracker(() => { + return ActiveDeviceCollection.find().fetch()[0]; + }); + const sensorData = useTracker(() => { - return SensorDataCollection.find({ device_id: 'esp-andy' }, { sort: { timestamp: -1 }, limit: 1 }).fetch(); + return SensorDataCollection.find({ device_id: deviceName.deviceName }, { sort: { timestamp: -1 }, limit: 1 }).fetch(); }); return ( diff --git a/mongo-mqtt.js b/mongo-mqtt.js index 66fee96..ed29047 100644 --- a/mongo-mqtt.js +++ b/mongo-mqtt.js @@ -36,14 +36,16 @@ function messageCallback(collection) { if (date.getMinutes() <= 9) {time = time + ":0" + date.getMinutes();} else { time = time + ":" + date.getMinutes(); } + /* if (date.getSeconds() <= 9) {time = time + ":0" + date.getSeconds();} else { time = time + ":" + date.getSeconds(); } + */ let doc = { device_id: id, timestamp: date, - timestampToString: time, + timeAsString: time, } try { doc = _.merge(doc, JSON.parse(message)); diff --git a/server/main.js b/server/main.js index addb8fa..b836f96 100644 --- a/server/main.js +++ b/server/main.js @@ -2,6 +2,7 @@ import { Meteor } from 'meteor/meteor'; var PlantTypesCollection = new Meteor.Collection('plantTypes'); var SensorDataCollection = new Meteor.Collection('sensorData'); +var ActiveDeviceCollection = new Meteor.Collection('activeDevice'); Meteor.startup(() => { if(Meteor.isServer) { @@ -12,10 +13,15 @@ Meteor.startup(() => { Meteor.publish('sensorDataCollection', function() { return SensorDataCollection.find(); }) + + Meteor.publish('activeDeviceCollection', function() { + return ActiveDeviceCollection.find(); + }) } if (Meteor.isClient) { Meteor.subscribe('plantTypesCollection'); Meteor.subscribe('sensorDataCollection'); + Meteor.subscribe('activeDeviceCollection'); } }); \ No newline at end of file From 3be2062f5f2083e21977b37007cc2dc7fb7bf2a5 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Andr=C3=A9s=20Uribe=20Stengel?= Date: Thu, 16 Jul 2020 13:59:12 +0200 Subject: [PATCH 4/7] Re-add the timer before loading app so db has time to fetch data. --- client/main.jsx | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/client/main.jsx b/client/main.jsx index 897e9a1..a864387 100644 --- a/client/main.jsx +++ b/client/main.jsx @@ -29,5 +29,7 @@ Meteor.startup(() => { Meteor.subscribe('activeDeviceCollection'); } - ReactDOM.render(, document.getElementById('root')); + Meteor.setTimeout(function() { + ReactDOM.render(, document.getElementById('root')); + }, 1250); }); \ No newline at end of file From 40c5dc2cb09410f1dae24b921c352b7738e07029 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Andr=C3=A9s=20Uribe=20Stengel?= Date: Thu, 16 Jul 2020 14:04:21 +0200 Subject: [PATCH 5/7] Refactor code a bit. --- imports/ui/Home.jsx | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/imports/ui/Home.jsx b/imports/ui/Home.jsx index fac6ca3..8595ea6 100644 --- a/imports/ui/Home.jsx +++ b/imports/ui/Home.jsx @@ -30,7 +30,7 @@ export default function Home() { } - if (sensorData.length <= 0) { + /*if (sensorData.length <= 0) { return ( @@ -41,8 +41,8 @@ export default function Home() { ) - } else { - return ( + } else {}*/ + return ( <> @@ -121,5 +121,5 @@ export default function Home() { - )} + ) } \ No newline at end of file From 76eb9012fad8793126fb2e5225790dec438c0767 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Andr=C3=A9s=20Uribe=20Stengel?= Date: Thu, 16 Jul 2020 15:07:54 +0200 Subject: [PATCH 6/7] Try without timer. --- client/main.jsx | 4 +- imports/ui/Home.jsx | 180 +++++++++++++++++++++++--------------------- 2 files changed, 94 insertions(+), 90 deletions(-) diff --git a/client/main.jsx b/client/main.jsx index a864387..897e9a1 100644 --- a/client/main.jsx +++ b/client/main.jsx @@ -29,7 +29,5 @@ Meteor.startup(() => { Meteor.subscribe('activeDeviceCollection'); } - Meteor.setTimeout(function() { - ReactDOM.render(, document.getElementById('root')); - }, 1250); + ReactDOM.render(, document.getElementById('root')); }); \ No newline at end of file diff --git a/imports/ui/Home.jsx b/imports/ui/Home.jsx index 8595ea6..9d63f78 100644 --- a/imports/ui/Home.jsx +++ b/imports/ui/Home.jsx @@ -6,11 +6,11 @@ import {useTracker} from 'meteor/react-meteor-data'; import {Col, Form, Row} from "react-bootstrap"; -export default function Home() { +export default function Home() { const uniqueEspNames = _.uniq(SensorDataCollection.find({}, { sort: {device_id: 1}, fields: {device_id: true} - }).fetch().map(function(x) { + }).fetch().map(function (x) { return x.device_id; }), true); @@ -19,18 +19,23 @@ export default function Home() { }); const sensorData = useTracker(() => { - return SensorDataCollection.find({ device_id: deviceName.deviceName }, { sort: { timestamp: -1 }, limit: 61 }).fetch().reverse(); + return SensorDataCollection.find({device_id: deviceName.deviceName}, { + sort: {timestamp: -1}, + limit: 61 + }).fetch().reverse(); }); const handleChange = (e) => { - if (e.target.value === "") {console.log("No device selected!");} else { - var doc = ActiveDeviceCollection.findOne({ deviceName: deviceName.deviceName }); - ActiveDeviceCollection.update({ _id: doc._id }, {$set:{deviceName: e.target.value}}); + if (e.target.value === "") { + console.log("No device selected!"); + } else { + var doc = ActiveDeviceCollection.findOne({deviceName: deviceName.deviceName}); + ActiveDeviceCollection.update({_id: doc._id}, {$set: {deviceName: e.target.value}}); } } - /*if (sensorData.length <= 0) { + if ((sensorData.length <= 0) || (deviceName.length <= 0) || (uniqueEspNames.length <= 0)) { return ( @@ -41,85 +46,86 @@ export default function Home() { ) - } else {}*/ - return ( - <> - - -

Devices:

- -
- - -
- - - - {uniqueEspNames.map((espName, index) =>{ - return - })} - - -
- - -
active device: {deviceName.deviceName}
- -
+ } else { + return ( + <> + + +

Devices:

+ +
+ + +
+ + + + {uniqueEspNames.map((espName, index) => { + return + })} + + +
+ + +
active device: {deviceName.deviceName}
+ +
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - ) + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + ) + } } \ No newline at end of file From 620018c501f4679a0733454058c043d03d7c45ba Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Andr=C3=A9s=20Uribe=20Stengel?= Date: Thu, 16 Jul 2020 15:19:01 +0200 Subject: [PATCH 7/7] Remove Timeout. --- imports/ui/Home.jsx | 17 ++++++++++------- 1 file changed, 10 insertions(+), 7 deletions(-) diff --git a/imports/ui/Home.jsx b/imports/ui/Home.jsx index 9d63f78..e57d60e 100644 --- a/imports/ui/Home.jsx +++ b/imports/ui/Home.jsx @@ -3,8 +3,7 @@ import {CartesianGrid, Legend, Line, LineChart, ResponsiveContainer, Tooltip, XA import SensorCardDeck from './SensorCardDeck' import {SensorDataCollection, ActiveDeviceCollection} from "../../client/main"; import {useTracker} from 'meteor/react-meteor-data'; - -import {Col, Form, Row} from "react-bootstrap"; +import {Col, Form, Row, Card, CardDeck} from "react-bootstrap"; export default function Home() { @@ -19,10 +18,14 @@ export default function Home() { }); const sensorData = useTracker(() => { - return SensorDataCollection.find({device_id: deviceName.deviceName}, { - sort: {timestamp: -1}, - limit: 61 - }).fetch().reverse(); + if (deviceName === null || deviceName === undefined) { + return []; + } else { + return SensorDataCollection.find({device_id: deviceName.deviceName}, { + sort: {timestamp: -1}, + limit: 61 + }).fetch().reverse(); + } }); const handleChange = (e) => { @@ -35,7 +38,7 @@ export default function Home() { } - if ((sensorData.length <= 0) || (deviceName.length <= 0) || (uniqueEspNames.length <= 0)) { + if ((sensorData.length <= 0) || (deviceName.length <= 0)) { return (