Helligkeit/data/Greenhouse/http/index.html

272 lines
7.8 KiB
HTML

<!DOCTYPE html>
<html lang="de">
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1">
<link rel="icon" type="image/x-icon" href="favicon.svg">
<title>Gewächshaus</title>
<style>
body {
font-family: sans-serif;
font-size: 8vw;
margin: 0;
-webkit-user-select: none;
-ms-user-select: none;
user-select: none;
background-color: #5c875c;
}
div {
overflow: hidden;
}
.heading {
padding: 0.25em 0;
text-align: center;
background-color: #93da93;
border-bottom: 1px solid gray;
}
.content {
padding: 0.25em;
}
.section {
clear: both;
margin-bottom: 0.5em;
}
.title {
font-size: 50%;
font-style: italic;
}
.valueAndUnit {
clear: both;
float: right;
}
.value {
float: left;
}
img {
height: 1.5em;
vertical-align: middle;
}
.unit {
float: left;
margin-left: 0.25em;
text-align: left;
}
.inputNull {
color: gray;
}
.inputBlue {
color: blue;
}
.inputGreen, #lightOn {
color: #00ff00;
}
.inputRed, #lightOff {
color: #ba0000;
}
</style>
</head>
<body>
<div class="heading">Gewächshaus</div>
<div class="content">
<div class="section">
<div class="title">Temperatur</div>
<div class="valueAndUnit">
<div class="value" id="temperature"></div>
<div class="unit">&deg;C</div>
</div>
</div>
<div class="section">
<div class="title">Relative Luftfeuchte</div>
<div class="valueAndUnit">
<div class="value" id="relative"></div>
<div class="unit">%</div>
</div>
</div>
<div class="section">
<div class="title">Absolute Luftfeuchte</div>
<div class="valueAndUnit">
<div class="value" id="absolute"></div>
<div class="unit">g/m³</div>
</div>
</div>
<div class="section">
<div class="title">Helligkeit</div>
<div class="valueAndUnit">
<div class="value" id="illuminance"></div>
<div class="unit">lux</div>
</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 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 () {
if (request.readyState === 4) {
update(request.responseText);
}
};
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);
htmlTemperature.innerText = format(data?.temperature, 1) || NO_VALUE;
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;
const relativeGreen = !relativeNull && !relativeBlue && !relativeRed;
setClass(htmlRelative.parentElement, "inputNull", relativeNull);
setClass(htmlRelative.parentElement, "inputRed", relativeBlue);
setClass(htmlRelative.parentElement, "inputGreen", relativeGreen);
setClass(htmlRelative.parentElement, "inputBlue", relativeRed);
const temperatureNull = !isSet(data?.temperature);
const temperatureBlue = !temperatureNull && data?.temperature < TEMPERATURE_BLUE;
const temperatureRed = !temperatureNull && data?.temperature > TEMPERATURE_RED;
const temperatureGreen = !temperatureNull && !temperatureBlue && !temperatureRed;
setClass(htmlTemperature.parentElement, "inputNull", temperatureNull);
setClass(htmlTemperature.parentElement, "inputBlue", temperatureBlue);
setClass(htmlTemperature.parentElement, "inputGreen", temperatureGreen);
setClass(htmlTemperature.parentElement, "inputRed", temperatureRed);
} catch (e) {
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
* @param {boolean} enabled
*/
function setClass(element, className, enabled) {
if (element.classList.contains(className) !== enabled) {
if (enabled) {
element.classList.add(className);
} else {
element.classList.remove(className);
}
}
}
status();
setInterval(() => status(), 2000);
</script>
</body>
</html>