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 d0a31b8..897e9a1 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,14 +17,17 @@ 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() { - ReactDOM.render(, document.getElementById('root')); - }, 1000); + ReactDOM.render(, document.getElementById('root')); }); \ 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..e57d60e 100644 --- a/imports/ui/Home.jsx +++ b/imports/ui/Home.jsx @@ -1,71 +1,134 @@ 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, 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(); + + 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]; }); - return ( - <> - + const sensorData = useTracker(() => { + if (deviceName === null || deviceName === undefined) { + return []; + } else { + 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 ((sensorData.length <= 0) || (deviceName.length <= 0)) { + return ( + + + + Loading! + Please wait... + + + + ) + } else { + return ( + <> + + +

Devices:

+ +
+ + +
+ + + + {uniqueEspNames.map((espName, index) => { + return + })} + + +
+ + +
active device: {deviceName.deviceName}
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + ) + } } \ No newline at end of file diff --git a/imports/ui/SensorCardDeck.jsx b/imports/ui/SensorCardDeck.jsx index 46709ef..041a22b 100644 --- a/imports/ui/SensorCardDeck.jsx +++ b/imports/ui/SensorCardDeck.jsx @@ -1,39 +1,55 @@ 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 sensorData = useTracker(() => { - return SensorDataCollection.find({ device_id: 'esp-andy' }, { sort: { timestamp: -1 }, limit: 1 }).fetch(); + const deviceName = useTracker(() => { + return ActiveDeviceCollection.find().fetch()[0]; }); - return ( - - - - Temperature - {sensorData[0].temperature} °C - - - - - Humidity - {sensorData[0].humidity} % - - - - - Brightness - {sensorData[0].brightness} lux - - - - - Moisture - {sensorData[0].moisture} % - - - - ) + const sensorData = useTracker(() => { + return SensorDataCollection.find({ device_id: deviceName.deviceName }, { sort: { timestamp: -1 }, limit: 1 }).fetch(); + }); + 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/mongo-mqtt.js b/mongo-mqtt.js index b1a6d8f..ed29047 100644 --- a/mongo-mqtt.js +++ b/mongo-mqtt.js @@ -28,10 +28,24 @@ 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, + timeAsString: time, } try { doc = _.merge(doc, JSON.parse(message)); diff --git a/package.json b/package.json index 6eed125..8b4d904 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" 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