diff --git a/package-lock.json b/package-lock.json index 7cfcef0..19a4e19 100644 --- a/package-lock.json +++ b/package-lock.json @@ -15,6 +15,7 @@ "@types/node": "^16.18.11", "@types/react": "^18.0.27", "@types/react-dom": "^18.0.10", + "date-fns": "^2.29.3", "react": "^18.2.0", "react-dom": "^18.2.0", "react-scripts": "5.0.1", @@ -6068,6 +6069,18 @@ "node": ">=10" } }, + "node_modules/date-fns": { + "version": "2.29.3", + "resolved": "https://registry.npmjs.org/date-fns/-/date-fns-2.29.3.tgz", + "integrity": "sha512-dDCnyH2WnnKusqvZZ6+jA1O51Ibt8ZMRNkDZdyAyK4YfbDwa/cEmuztzG5pk6hqlp9aSBPYcjOlktquahGwGeA==", + "engines": { + "node": ">=0.11" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/date-fns" + } + }, "node_modules/debug": { "version": "4.3.4", "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.4.tgz", @@ -21115,6 +21128,11 @@ "whatwg-url": "^8.0.0" } }, + "date-fns": { + "version": "2.29.3", + "resolved": "https://registry.npmjs.org/date-fns/-/date-fns-2.29.3.tgz", + "integrity": "sha512-dDCnyH2WnnKusqvZZ6+jA1O51Ibt8ZMRNkDZdyAyK4YfbDwa/cEmuztzG5pk6hqlp9aSBPYcjOlktquahGwGeA==" + }, "debug": { "version": "4.3.4", "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.4.tgz", diff --git a/package.json b/package.json index 2515558..00a7d0f 100644 --- a/package.json +++ b/package.json @@ -10,6 +10,7 @@ "@types/node": "^16.18.11", "@types/react": "^18.0.27", "@types/react-dom": "^18.0.10", + "date-fns": "^2.29.3", "react": "^18.2.0", "react-dom": "^18.2.0", "react-scripts": "5.0.1", diff --git a/src/App.css b/src/App.css index 722afc6..7617ca8 100644 --- a/src/App.css +++ b/src/App.css @@ -8,14 +8,31 @@ height: 3vh; } -@media (max-width: 400px) { +.soil-gauge { + border: .01em solid black; + padding: .6em; + height: 5vh; +} + +@media (max-width: 501px) { .sensors { display: display !important; } + .sensors>* { + margin: .6em !important; + } + + .merrysky { + height: 50vh !important; + } + + .soil-gauge { + height: 10vh; + } + .rainfall-gauge { - color: blue; - height: 5vh; + height: 6vh; } } @@ -27,6 +44,10 @@ .rainfall-gauge { height: 5vh; } + + .merrysky { + height: 80vh !important; + } } .header { @@ -59,4 +80,5 @@ .sensors >* { flex: 1 1 160px; + margin: .2em; } \ No newline at end of file diff --git a/src/App.tsx b/src/App.tsx index 9cde89a..679486f 100644 --- a/src/App.tsx +++ b/src/App.tsx @@ -1,6 +1,7 @@ import React from 'react'; import './App.css'; import Rainfall from './components/rainfall'; +import Soil from './components/soil'; function App() { return ( @@ -9,6 +10,7 @@ function App() {

Welcome to the MooreForge Weather Station. While a work in progress, there are some functional sensors shown below.

+
diff --git a/src/components/rainfall/index.tsx b/src/components/rainfall/index.tsx index 8ac1a7c..f066b83 100644 --- a/src/components/rainfall/index.tsx +++ b/src/components/rainfall/index.tsx @@ -1,13 +1,13 @@ import React, { useEffect, useState } from 'react'; -import './rainfall.css'; +import './style.css'; const MM_PER_CLICK = .254; const INCHES_PER_CLICK = .01; const Sensor = () => { const [totalRainfall, setTotalRainfall] = useState(0); - console.log(process.env); + async function pullDataFromBackend() { const response = await fetch(process.env.REACT_APP_RAIN_GAUGE_DATA ?? ''); const data = await response.json(); diff --git a/src/components/rainfall/rainfall.css b/src/components/rainfall/style.css similarity index 100% rename from src/components/rainfall/rainfall.css rename to src/components/rainfall/style.css diff --git a/src/components/soil/index.tsx b/src/components/soil/index.tsx new file mode 100644 index 0000000..6383ac4 --- /dev/null +++ b/src/components/soil/index.tsx @@ -0,0 +1,44 @@ +import React, { useEffect, useState } from 'react'; + +import { isBefore } from 'date-fns'; + +import './style.css'; + +const Sensor = () => { + const [temp, setTemp] = useState(0); + const [cap, setCap] = useState(0); + + async function pullTempFromBackend() { + const response = await fetch(process.env.REACT_APP_SOIL_TEMP_DATA ?? ''); + const data = await response.json(); + const result = data + .reduce((accum: any, datum: any) => ( ((accum && isBefore(new Date(accum?.timestamp), new Date(datum?.timestamp))) || !accum ) ? datum : accum )); + + setTemp(result.value); + } + + async function pullCapFromBackend() { + const response = await fetch(process.env.REACT_APP_SOIL_CAP_DATA ?? ''); + const data = await response.json(); + const result = data + .reduce((accum: any, datum: any) => ( ((accum && isBefore(new Date(accum?.timestamp), new Date(datum?.timestamp))) || !accum ) ? datum : accum )); + + setCap(result.value); + } + + useEffect(() => { + setInterval(() => pullTempFromBackend(), 1000); + setInterval(() => pullCapFromBackend(), 1000); + }, []); + + return ( +
+
Temperature (in C)
+
{temp}
+
Capacitance
+
{cap}
+
+ ); +}; + +export default Sensor; \ No newline at end of file diff --git a/src/components/soil/style.css b/src/components/soil/style.css new file mode 100644 index 0000000..f9011df --- /dev/null +++ b/src/components/soil/style.css @@ -0,0 +1,11 @@ +.gauge-body { + display: flex; + flex-direction: column; + justify-content: space-between; + align-content: space-between; + text-align: center; +} + +.gauge-label { + font-weight: bold; +} \ No newline at end of file