209 lines
8.9 KiB
JavaScript
209 lines
8.9 KiB
JavaScript
import React from 'react'
|
|
import {Col, Form, Row, Card, CardDeck, Button, Container} from "react-bootstrap";
|
|
import { Meteor } from 'meteor/meteor';
|
|
import {getAllEspIds} from "../api/espIds";
|
|
import {getAllPlantTypes} from "../api/plantTypes";
|
|
import {ConfiguredDevicesCollection, PlantTypesCollection} from "../../client/main";
|
|
import {useTracker} from 'meteor/react-meteor-data';
|
|
|
|
export default function Settings() {
|
|
// Return all documents of the plantTypes collection.
|
|
const plantTypes = useTracker(() => {
|
|
return PlantTypesCollection.find();
|
|
});
|
|
|
|
const espIds = useTracker(getAllEspIds);
|
|
|
|
// Variables for the configuration of the selected device.
|
|
var selectedEspId;
|
|
var selectedAlias = "";
|
|
var selectedType;
|
|
var selectedMode = null;
|
|
|
|
// Settings from the database for each plant type to be published to the mqtt broker.
|
|
const payloadVegi = plantTypes.fetch()[0];
|
|
const payloadCacti = plantTypes.fetch()[1];
|
|
const payloadFlower = plantTypes.fetch()[2];
|
|
|
|
// If the Name field is empty, log a warning. Else set the entered string as selectedAlias.
|
|
const handleChangeAlias = (e) => {
|
|
if (e.target.value === "") {
|
|
console.log("Nickname cannot be empty!");
|
|
} else {
|
|
selectedAlias = e.target.value;
|
|
}
|
|
}
|
|
|
|
// If no device is selected, log a warning. Else set the selected device as selectedEspId.
|
|
const handleChangeDevice = (e) => {
|
|
if (e.target.value === "") {
|
|
console.log("No device selected!");
|
|
} else {
|
|
selectedEspId = e.target.value;
|
|
}
|
|
}
|
|
|
|
// If no plant type is selected, log a warning. Else set the selected type as selectedType.
|
|
const handleChangeType = (e) => {
|
|
if (e.target.value === "") {
|
|
console.log("No type selected!");
|
|
} else {
|
|
selectedType = e.target.value;
|
|
}
|
|
}
|
|
|
|
// If no mode is selected, log a warning. Else set the selected mode as selectedMode.
|
|
const handleChangeMode = (e) => {
|
|
if (e.target.value === "") {
|
|
console.log("No mode selected!");
|
|
} else {
|
|
selectedMode = e.target.value;
|
|
}
|
|
}
|
|
|
|
// Save the configured device to the database and send the payload data to the mqtt broker.
|
|
const handleSendData = (e) => {
|
|
var payload = "";
|
|
var nmValue = null;
|
|
var minLux = PlantTypesCollection.findOne({plantType: selectedType}).data.light.minLux;
|
|
|
|
// Configure the payload depending on the selected plant type and the selected mode.
|
|
if (selectedType === "Vegetables") {payload = JSON.stringify(payloadVegi.data.soilMoisture);}
|
|
if (selectedType === "Cacti") {payload = JSON.stringify(payloadCacti.data.soilMoisture);}
|
|
if (selectedType === "Flowers") {payload = JSON.stringify(payloadFlower.data.soilMoisture);}
|
|
if (selectedMode === "Growth") {nmValue = 450}
|
|
if (selectedMode === "Bloom") {nmValue = 700}
|
|
|
|
// Log all data
|
|
console.log("Payload: " + payload);
|
|
console.log("Alias: " + selectedAlias);
|
|
console.log("ID: " + selectedEspId);
|
|
console.log("Type: " + selectedType);
|
|
console.log("Mode: " + selectedMode);
|
|
|
|
// If one of the values is empty, null or undefined send an alert. Else insert a document in the configuredDevices collection with the entered data,
|
|
// or update the data if the device has already been configured.
|
|
if ((payload === "") || (nmValue === null) || (minLux === undefined) || (selectedEspId === undefined) ||
|
|
(selectedAlias === "") || (selectedType === undefined) || (selectedMode === null)) {alert("Nickname is empty or no device/type/mode selected!");} else {
|
|
var doc = ConfiguredDevicesCollection.findOne({deviceId: selectedEspId});
|
|
if (doc === undefined) {ConfiguredDevicesCollection.insert({deviceId: selectedEspId, alias: selectedAlias, type: selectedType, mode: selectedMode});} else {
|
|
ConfiguredDevicesCollection.update({_id: doc._id}, {$set: {alias: selectedAlias, type: selectedType, mode: selectedMode}});
|
|
}
|
|
|
|
// Publish the configuration data of the selected plant type for the selected device to the mqtt broker.
|
|
Meteor.call('mqttPublish', {
|
|
topic: 'smartgarden/commands/' + selectedEspId + '/soil',
|
|
payload: payload
|
|
}, (err, res) => {
|
|
if (err) {
|
|
alert(err);
|
|
} else {
|
|
console.log('success')
|
|
}
|
|
})
|
|
|
|
// Publish the irrigation and light values as true to the mqtt broker, to activate the automatic irrigation and lighting for the selected device.
|
|
Meteor.call('mqttPublish', {
|
|
topic: 'smartgarden/commands/' + selectedEspId + '/automatic',
|
|
payload: JSON.stringify({
|
|
'irrigation': 'true',
|
|
'light': 'true'
|
|
})
|
|
}, (err, res) => {
|
|
if (err) {
|
|
alert(err);
|
|
} else {
|
|
console.log('success')
|
|
}
|
|
})
|
|
|
|
// Publish the minimum lux value of the selected plant type and the nanometer value of the selected mode for the selected device to the mqtt broker.
|
|
Meteor.call('mqttPublish', {
|
|
topic: 'smartgarden/commands/' + selectedEspId + '/light',
|
|
payload: JSON.stringify({
|
|
'minLX': minLux,
|
|
'nm': nmValue
|
|
})
|
|
}, (err, res) => {
|
|
if (err) {
|
|
alert(err);
|
|
} else {
|
|
console.log('success')
|
|
}
|
|
})
|
|
}
|
|
}
|
|
|
|
|
|
//If the data that is loaded from the database has not been fetched yet, show a loading screen. Else load the application.
|
|
if ((plantTypes.length <= 0) || (espIds.length <= 0)) {
|
|
return (
|
|
<CardDeck>
|
|
<Card>
|
|
<Card.Body>
|
|
<Card.Title>Loading!</Card.Title>
|
|
<Card.Text>Please wait...</Card.Text>
|
|
</Card.Body>
|
|
</Card>
|
|
</CardDeck>
|
|
)
|
|
} else {
|
|
return (
|
|
<>
|
|
<Container>
|
|
<Row className="justify-content-md-center">
|
|
<Col md="auto">
|
|
<h1>Settings</h1>
|
|
</Col>
|
|
</Row>
|
|
<Row className="justify-content-md-center">
|
|
<a>Configure your plant here. Based on your settings the smart garden will automate your plant environment.</a>
|
|
</Row>
|
|
|
|
<br></br>
|
|
|
|
<Form autoComplete='off'>
|
|
<Form.Group>
|
|
<Form.Label>Name:</Form.Label>
|
|
<Form.Control
|
|
type="text"
|
|
id="alias"
|
|
autoFocus ref={(input) => {this.nameInput=(input)}}
|
|
placeholder="Enter a device nickname..."
|
|
onChange={handleChangeAlias}/>
|
|
</Form.Group>
|
|
<Form.Group>
|
|
<Form.Label>Device:</Form.Label>
|
|
<Form.Control as="select" type="text" onChange={handleChangeDevice}>
|
|
<option></option>
|
|
{espIds.map((espName, index) => {
|
|
return <option key={index} value={espName}>{espName}</option>
|
|
})}
|
|
</Form.Control>
|
|
</Form.Group>
|
|
<Form.Group>
|
|
<Form.Label>Type:</Form.Label>
|
|
<Form.Control as="select" type="text" onChange={handleChangeType}>
|
|
<option></option>
|
|
{getAllPlantTypes().map((type, index) => {
|
|
return <option key={index} value={type}>{type}</option>
|
|
})}
|
|
</Form.Control>
|
|
</Form.Group>
|
|
<Form.Group>
|
|
<Form.Label>Mode:</Form.Label>
|
|
<Form.Control as="select" type="text" onChange={handleChangeMode}>
|
|
<option></option>
|
|
<option key="0" value="Growth">Growth</option>
|
|
<option key="1" value="Bloom">Bloom</option>
|
|
</Form.Control>
|
|
</Form.Group>
|
|
<Button type={"sendData"} onClick={handleSendData} >Send</Button>
|
|
</Form>
|
|
|
|
</Container>
|
|
|
|
</>
|
|
)
|
|
}
|
|
} |