185 lines
8.5 KiB
JavaScript
185 lines
8.5 KiB
JavaScript
import React from 'react'
|
|
import {CartesianGrid, Legend, Line, LineChart, ResponsiveContainer, Tooltip, XAxis, YAxis} from 'recharts';
|
|
import SensorCardDeck from './SensorCardDeck'
|
|
import {SensorDataCollection, ActiveDeviceCollection, ConfiguredDevicesCollection} from "../../client/main";
|
|
import {useTracker} from 'meteor/react-meteor-data';
|
|
import { Col, Form, Row, Card, CardDeck } from "react-bootstrap";
|
|
import moment from 'moment'
|
|
|
|
export default function Overview() {
|
|
// Return the document of the currently active device in the activeDevice collection.
|
|
const activeDevice = useTracker(() => {
|
|
return ActiveDeviceCollection.find().fetch()[0];
|
|
});
|
|
|
|
// Return all documents of the configuredDevices collection.
|
|
const configuredDevices = useTracker(() => {
|
|
return ConfiguredDevicesCollection.find().fetch();
|
|
});
|
|
|
|
// If the activeDevice is not null or undefined, return and filter the documents of the last two days (48 Hrs) of the currently active device in the sensorData collection
|
|
// and reverse the array so that the oldest documents come first.
|
|
const sensorData = useTracker(() => {
|
|
if (activeDevice === null || activeDevice === undefined) {
|
|
return [];
|
|
} else {
|
|
return SensorDataCollection.find(
|
|
{
|
|
device_id: activeDevice.deviceId,
|
|
timestamp: { $gt: moment(Date.now()).subtract(2, 'days').toDate() }
|
|
},
|
|
{
|
|
sort: { timestamp: -1 }
|
|
}
|
|
).fetch().reverse();
|
|
}
|
|
});
|
|
|
|
// Set the selected device from the configured devices dropdown-menu, to the new currently active device.
|
|
const handleChange = (e) => {
|
|
if (e.target.value === "") {
|
|
console.log("No device selected!");
|
|
} else {
|
|
var doc = ActiveDeviceCollection.findOne({deviceId: activeDevice.deviceId});
|
|
ActiveDeviceCollection.update({_id: doc._id}, {$set: {deviceId: e.target.value}});
|
|
}
|
|
}
|
|
|
|
// Get the current date as string.
|
|
const getLabelFromStamp = (x) => {
|
|
return moment(x.timestamp).format("LLLL");
|
|
}
|
|
|
|
// Workaround for log(0).
|
|
const brightnessMapper = (x) => {
|
|
if (x.brightness < 1) {
|
|
x.brightness = 0.1
|
|
}
|
|
return x;
|
|
}
|
|
|
|
//If the data that is loaded from the database has not been fetched yet, show a loading screen. Else load the application.
|
|
if ((sensorData.length <= 0)) {
|
|
return (
|
|
<>
|
|
<br></br>
|
|
<Row>
|
|
<Col xs lg="2">
|
|
<h4>Devices:</h4>
|
|
</Col>
|
|
</Row>
|
|
<Row>
|
|
<Col xs lg="2">
|
|
<Form>
|
|
<Form.Group>
|
|
<Form.Control as="select" type="text" onChange={handleChange}>
|
|
<option></option>
|
|
{configuredDevices.map((devices, index) => {
|
|
return <option key={index} value={devices.deviceId}>{devices.alias}</option>
|
|
})}
|
|
</Form.Control>
|
|
</Form.Group>
|
|
</Form>
|
|
</Col>
|
|
<Col>
|
|
<h6>active device: {!activeDevice === undefined && !ConfiguredDevicesCollection.findOne({ deviceId: activeDevice.deviceId }) === undefined ?
|
|
ConfiguredDevicesCollection.findOne({ deviceId: activeDevice.deviceId }).alias : "No device selected"}</h6>
|
|
</Col>
|
|
</Row>
|
|
|
|
<CardDeck>
|
|
<Card>
|
|
<Card.Body>
|
|
<Card.Title>Loading!</Card.Title>
|
|
<Card.Text>Please wait...</Card.Text>
|
|
</Card.Body>
|
|
</Card>
|
|
</CardDeck>
|
|
</>
|
|
)
|
|
} else {
|
|
return (
|
|
<>
|
|
<br></br>
|
|
<Row>
|
|
<Col xs lg="2">
|
|
<h4>Devices:</h4>
|
|
</Col>
|
|
</Row>
|
|
<Row>
|
|
<Col xs lg="2">
|
|
<Form>
|
|
<Form.Group>
|
|
<Form.Control as="select" type="text" onChange={handleChange}>
|
|
<option></option>
|
|
{configuredDevices.map((devices, index) => {
|
|
return <option key={index} value={devices.deviceId}>{devices.alias}</option>
|
|
})}
|
|
</Form.Control>
|
|
</Form.Group>
|
|
</Form>
|
|
</Col>
|
|
<Col>
|
|
<h6>active device: {ConfiguredDevicesCollection.findOne({deviceId: activeDevice.deviceId}) === undefined ?
|
|
"No device selected" : ConfiguredDevicesCollection.findOne({deviceId: activeDevice.deviceId}).alias}</h6>
|
|
</Col>
|
|
</Row>
|
|
|
|
<SensorCardDeck/>
|
|
|
|
<Row>
|
|
<Col>
|
|
<ResponsiveContainer width='100%' height={325}>
|
|
<LineChart data={sensorData.filter(el => el.temperature !== null)} margin={{top: 50, right: 50, bottom: 20, left: 5}}>
|
|
<Line type="monotone" dataKey="temperature" stroke="#10b5de" dot={false}/>
|
|
<CartesianGrid stroke="#ccc" strokeDasharray="5 5"/>
|
|
<XAxis dataKey={getLabelFromStamp} tick={false} />
|
|
<YAxis/>
|
|
<Tooltip/>
|
|
<Legend/>
|
|
</LineChart>
|
|
</ResponsiveContainer>
|
|
</Col>
|
|
<Col>
|
|
<ResponsiveContainer width='100%' height={325}>
|
|
<LineChart data={sensorData.filter(el => el.humidity !== null)} margin={{top: 50, right: 50, bottom: 20, left: 5}}>
|
|
<Line type="monotone" dataKey="humidity" stroke="#ff6f00" dot={false}/>
|
|
<CartesianGrid stroke="#ccc" strokeDasharray="5 5"/>
|
|
<XAxis dataKey={getLabelFromStamp} tick={false}/>
|
|
<YAxis/>
|
|
<Tooltip/>
|
|
<Legend/>
|
|
</LineChart>
|
|
</ResponsiveContainer>
|
|
</Col>
|
|
</Row>
|
|
<Row>
|
|
<Col>
|
|
<ResponsiveContainer width='100%' height={325}>
|
|
<LineChart data={sensorData.filter(el => el.brightness !== null).map(brightnessMapper)} margin={{top: 50, right: 50, bottom: 20, left: 5}}>
|
|
<Line type="monotone" dataKey="brightness" stroke="#ffd500" dot={false}/>
|
|
<CartesianGrid stroke="#ccc" strokeDasharray="5 5"/>
|
|
<XAxis dataKey={getLabelFromStamp} tick={false}/>
|
|
<YAxis scale="log" domain={[0.1, 'dataMax']} tickFormatter={val => Math.round(val)} />
|
|
<Tooltip formatter={val => Math.round(val)}/>
|
|
<Legend/>
|
|
</LineChart>
|
|
</ResponsiveContainer>
|
|
</Col>
|
|
<Col>
|
|
<ResponsiveContainer width='100%' height={325}>
|
|
<LineChart data={sensorData.filter(el => el.moisture !== null)} margin={{top: 50, right: 50, bottom: 20, left: 5}}>
|
|
<Line type="monotone" dataKey="moisture" stroke="#1c4399" dot={false}/>
|
|
<CartesianGrid stroke="#ccc" strokeDasharray="5 5"/>
|
|
<XAxis dataKey={getLabelFromStamp} tick={false}/>
|
|
<YAxis/>
|
|
<Tooltip/>
|
|
<Legend/>
|
|
</LineChart>
|
|
</ResponsiveContainer>
|
|
</Col>
|
|
</Row>
|
|
</>
|
|
)
|
|
}
|
|
} |