212 lines
5.5 KiB
HTML
212 lines
5.5 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: 12vw;
|
|
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;
|
|
}
|
|
|
|
.unit {
|
|
float: left;
|
|
margin-left: 0.25em;
|
|
text-align: left;
|
|
}
|
|
|
|
.inputNull {
|
|
color: gray;
|
|
}
|
|
|
|
.inputBlue {
|
|
color: blue;
|
|
}
|
|
|
|
.inputGreen {
|
|
color: #00ff00;
|
|
}
|
|
|
|
.inputRed {
|
|
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">°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>
|
|
|
|
<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');
|
|
|
|
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 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;
|
|
}
|
|
|
|
/**
|
|
* @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> |