Greenhouse: door, windows, light

This commit is contained in:
Patrick Haßel 2025-03-03 12:02:12 +01:00
parent 1183be3d83
commit fa4e266bc5
5 changed files with 134 additions and 17 deletions

View File

@ -1,4 +1,4 @@
<?xml version="1.0" encoding="iso-8859-1"?>
<?xml version="1.0" encoding="UTF-8"?>
<svg version="1.1" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 512 512">
<polygon style="fill:#C8DB86;" points="503.83,172.381 435.647,172.381 283.648,59.589 351.831,59.589 "/>
<polygon style="fill:#D4ED85;" points="305.435,59.589 457.434,172.381 312.178,172.381 160.169,59.589 "/>

Before

Width:  |  Height:  |  Size: 2.1 KiB

After

Width:  |  Height:  |  Size: 2.1 KiB

View File

@ -8,7 +8,7 @@
<style>
body {
font-family: sans-serif;
font-size: 12vw;
font-size: 8vw;
margin: 0;
-webkit-user-select: none;
-ms-user-select: none;
@ -50,6 +50,11 @@
float: left;
}
img {
height: 1.5em;
vertical-align: middle;
}
.unit {
float: left;
margin-left: 0.25em;
@ -64,11 +69,11 @@
color: blue;
}
.inputGreen {
.inputGreen, #lightOn {
color: #00ff00;
}
.inputRed {
.inputRed, #lightOff {
color: #ba0000;
}
@ -111,26 +116,60 @@
</div>
</div>
<div class="section">
<div class="title">Tür</div>
<div class="valueAndUnit">
<div class="value" id="door"></div>
</div>
</div>
<div class="section">
<div class="title">Fenster</div>
<div class="valueAndUnit">
<div class="value" id="windows"></div>
</div>
</div>
<div class="section">
<div class="title">Licht</div>
<div class="valueAndUnit">
<span id="lightUnknown">?</span>
<div id="lightOn">
Ein
<img alt="Ein" src="on.svg" onclick="get('/light/off')">
</div>
<div id="lightOff">
Aus
<img alt="Aus" src="off.svg" onclick="get('/light/on')">
</div>
</div>
</div>
</div>
<script>
const NO_VALUE = "- - -";
const NO_VALUE = "?";
const TEMPERATURE_BLUE = 10;
const TEMPERATURE_RED = 35;
const RELATIVE_BLUE = 60;
const RELATIVE_RED = 80;
const htmlTemperature = document.getElementById('temperature');
const htmlRelative = document.getElementById('relative');
const htmlAbsolute = document.getElementById('absolute');
const htmlIlluminance = document.getElementById('illuminance');
const htmlDoor = document.getElementById('door');
const htmlWindows = document.getElementById('windows');
const htmlLightOn = document.getElementById('lightOn');
const htmlLightOff = document.getElementById('lightOff');
const htmlLightUnknown = document.getElementById('lightUnknown');
function status() {
get("/status");
}
function get(path) {
const request = new XMLHttpRequest();
request.onreadystatechange = function () {
@ -141,11 +180,11 @@
request.open('GET', (location.hostname === "localhost" ? "http://10.0.0.160" : "") + path);
request.send();
}
function format(value, decimals) {
return value?.toLocaleString(undefined, {minimumFractionDigits: decimals, maximumFractionDigits: decimals});
}
function update(response) {
try {
const data = JSON.parse(response);
@ -153,7 +192,23 @@
htmlRelative.innerText = format(data?.relative, 0) || NO_VALUE;
htmlAbsolute.innerText = format(data?.absolute, 1) || NO_VALUE;
htmlIlluminance.innerText = format(data?.illuminance, 0) || NO_VALUE;
const doorClosed = data?.door === true;
const doorOpened = data?.door === false;
htmlDoor.innerText = doorClosed ? 'Geschlosssen' : doorOpened ? 'Offen' : NO_VALUE;
setClass(htmlDoor.parentElement, "inputRed", doorOpened);
setClass(htmlDoor.parentElement, "inputGreen", doorClosed);
const windowsClosed = data?.windows === true;
const windowsOpened = data?.windows === false;
htmlWindows.innerText = windowsClosed ? 'Geschlosssen' : windowsOpened ? 'Offen' : NO_VALUE;
setClass(htmlWindows.parentElement, "inputRed", windowsOpened);
setClass(htmlWindows.parentElement, "inputGreen", windowsClosed);
htmlLightOn.style.display = data?.light === true ? 'block' : 'none';
htmlLightOff.style.display = data?.light === false ? 'block' : 'none';
htmlLightUnknown.style.display = data?.light !== false && data?.light !== true ? 'block' : 'none';
const relativeNull = !isSet(data?.relative);
const relativeBlue = !relativeNull && data?.relative < RELATIVE_BLUE;
const relativeRed = !relativeNull && data?.relative > RELATIVE_RED;
@ -175,19 +230,24 @@
reset(e);
}
}
function isSet(v) {
return v !== null && v !== undefined;
}
function reset(e) {
console.error("Failed to handle data:", e);
htmlTemperature.innerText = NO_VALUE;
htmlRelative.innerText = NO_VALUE;
htmlAbsolute.innerText = NO_VALUE;
htmlIlluminance.innerText = NO_VALUE;
htmlDoor.innerText = NO_VALUE;
htmlWindows.innerText = NO_VALUE;
htmlLightOn.style.display = 'none';
htmlLightOff.style.display = 'none';
htmlLightUnknown.style.display = 'block';
}
/**
* @param {HTMLElement} element
* @param {string} className
@ -202,7 +262,7 @@
}
}
}
status();
setInterval(() => status(), 2000);

View File

@ -0,0 +1,20 @@
<?xml version="1.0" encoding="UTF-8"?>
<svg width="800px" height="800px" viewBox="0 0 24 24" xmlns="http://www.w3.org/2000/svg">
<g transform="translate(0 -1028.4)">
<path d="m7 1034.4c-3.3137 0-6 2.6-6 6 0 3.3 2.6863 6 6 6h5 5c3.314 0 6-2.7 6-6 0-3.4-2.686-6-6-6h-5-5z" fill="#95a5a6"/>
<path d="m7 1033.4c-3.3137 0-6 2.6-6 6 0 3.3 2.6863 6 6 6h5 5c3.314 0 6-2.7 6-6 0-3.4-2.686-6-6-6h-5-5z" fill="#bdc3c7"/>
<path d="m7 1035.4c-2.2091 0-4 1.8-4 4s1.7909 4 4 4h5 5c2.209 0 4-1.8 4-4s-1.791-4-4-4h-5-5z" fill="#e74c3c"/>
<path d="m7 1035.4c-2.2091 0-4 1.8-4 4 0 0.1 0.0419 0.3 0.0625 0.5 0.2471-2 1.8985-3.5 3.9375-3.5h5 5c2.039 0 3.69 1.5 3.938 3.5 0.02-0.2 0.062-0.4 0.062-0.5 0-2.2-1.791-4-4-4h-5-5z" fill="#c0392b"/>
<g transform="translate(-11.5,-11.4)">
<g transform="translate(10.5,10.4)">
<path d="m13.023 1039.7-0.023 1.2c-0.04 1.9 1.567 3.5 3.5 3.5h1.5c2.209 0 4-1.8 4-4 0-0.4-0.074-0.7-0.156-1z" fill="#7f8c8d"/>
<path d="m16.5 1036.4c-1.933 0-3.5 1.5-3.5 3.5 0 1.9 1.567 3.5 3.5 3.5h2c1.933 0 3.5-1.6 3.5-3.5 0-2-1.567-3.5-3.5-3.5h-2z" fill="#ecf0f1"/>
<g fill="#bdc3c7">
<path d="m15.5 1037.4c-0.276 0-0.5 0.1-0.5 0.4v3.2c0 0.2 0.224 0.4 0.5 0.4s0.5-0.2 0.5-0.4v-3.2c0-0.3-0.224-0.4-0.5-0.4z"/>
<path d="m17.5 1037.4c-0.276 0-0.5 0.1-0.5 0.4v3.2c0 0.2 0.224 0.4 0.5 0.4s0.5-0.2 0.5-0.4v-3.2c0-0.3-0.224-0.4-0.5-0.4z"/>
<path d="m19.5 1037.4c-0.276 0-0.5 0.1-0.5 0.4v3.2c0 0.2 0.224 0.4 0.5 0.4s0.5-0.2 0.5-0.4v-3.2c0-0.3-0.224-0.4-0.5-0.4z"/>
</g>
</g>
</g>
</g>
</svg>

After

Width:  |  Height:  |  Size: 1.5 KiB

View File

@ -0,0 +1,20 @@
<?xml version="1.0" encoding="UTF-8"?>
<svg viewBox="0 0 24 24" xmlns="http://www.w3.org/2000/svg">
<g transform="translate(0 -1028.4)">
<path d="m17 1034.4c3.314 0 6 2.6 6 6 0 3.3-2.686 6-6 6h-5-5c-3.3137 0-6-2.7-6-6 0-3.4 2.6863-6 6-6h5 5z" fill="#95a5a6"/>
<path d="m17 1033.4c3.314 0 6 2.6 6 6 0 3.3-2.686 6-6 6h-5-5c-3.3137 0-6-2.7-6-6 0-3.4 2.6863-6 6-6h5 5z" fill="#bdc3c7"/>
<path d="m17 1035.4c2.209 0 4 1.8 4 4s-1.791 4-4 4h-5-5c-2.2091 0-4-1.8-4-4s1.7909-4 4-4h5 5z" fill="#2ecc71"/>
<path d="m17 1035.4c2.209 0 4 1.8 4 4 0 0.1-0.042 0.3-0.062 0.5-0.248-2-1.899-3.5-3.938-3.5h-5-5c-2.039 0-3.6904 1.5-3.9375 3.5-0.0206-0.2-0.0625-0.4-0.0625-0.5 0-2.2 1.7909-4 4-4h5 5z" fill="#27ae60"/>
<g transform="matrix(-1,0,0,1,35.5,-11.4)">
<g transform="translate(10.5,10.4)">
<path d="m13.023 1039.7-0.023 1.2c-0.04 1.9 1.567 3.5 3.5 3.5h1.5c2.209 0 4-1.8 4-4 0-0.4-0.074-0.7-0.156-1z" fill="#7f8c8d"/>
<path d="m16.5 1036.4c-1.933 0-3.5 1.5-3.5 3.5 0 1.9 1.567 3.5 3.5 3.5h2c1.933 0 3.5-1.6 3.5-3.5 0-2-1.567-3.5-3.5-3.5h-2z" fill="#ecf0f1"/>
<g fill="#bdc3c7">
<path d="m15.5 1037.4c-0.276 0-0.5 0.1-0.5 0.4v3.2c0 0.2 0.224 0.4 0.5 0.4s0.5-0.2 0.5-0.4v-3.2c0-0.3-0.224-0.4-0.5-0.4z"/>
<path d="m17.5 1037.4c-0.276 0-0.5 0.1-0.5 0.4v3.2c0 0.2 0.224 0.4 0.5 0.4s0.5-0.2 0.5-0.4v-3.2c0-0.3-0.224-0.4-0.5-0.4z"/>
<path d="m19.5 1037.4c-0.276 0-0.5 0.1-0.5 0.4v3.2c0 0.2 0.224 0.4 0.5 0.4s0.5-0.2 0.5-0.4v-3.2c0-0.3-0.224-0.4-0.5-0.4z"/>
</g>
</g>
</g>
</g>
</svg>

After

Width:  |  Height:  |  Size: 1.5 KiB

View File

@ -6,20 +6,37 @@
#include "sensors.h"
#include "../../patrix/mqtt.h"
bool light = false;
void httpStatus(AsyncWebServerRequest* request) {
JsonDocument json;
json["illuminance"] = greenhouseTSL.getIlluminance();;
json["temperature"] = greenhouseDHT22.getTemperature();
json["relative"] = greenhouseDHT22.getRelative();
json["absolute"] = greenhouseDHT22.getAbsolute();
json["door"] = false;
json["windows"] = false;
json["light"] = light;
AsyncResponseStream* stream = request->beginResponseStream("application/json");
serializeJson(json, *stream);
request->send(stream);
}
void httpLightOn(AsyncWebServerRequest* request) {
light = true;
httpStatus(request);
}
void httpLightOff(AsyncWebServerRequest* request) {
light = false;
httpStatus(request);
}
void httpSetup2() {
server.on("/status", httpStatus);
server.on("/light/on", httpLightOn);
server.on("/light/off", httpLightOff);
}
#endif