Initial commit: Haussteuerung V2/V3 Web-Interface
This commit is contained in:
@@ -0,0 +1,386 @@
|
||||
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
|
||||
<html dir="ltr" xmlns="http://www.w3.org/1999/xhtml">
|
||||
|
||||
<head>
|
||||
<title>TTh</title>
|
||||
<meta content="text/html; charset=utf-8" http-equiv="Content-Type" />
|
||||
<link href="form.css" rel="stylesheet" type="text/css" />
|
||||
<style type="text/css">
|
||||
.auto-style1 {
|
||||
color: #FF0000;
|
||||
font-family: "Arial";
|
||||
}
|
||||
|
||||
.auto-style4 {
|
||||
font-family: "Arial";
|
||||
font-size: x-large;
|
||||
text-align: left;
|
||||
}
|
||||
|
||||
.auto-style5 {
|
||||
font-family: "Arial";
|
||||
font-size: x-large;
|
||||
text-align: center;
|
||||
}
|
||||
|
||||
.auto-style6 {
|
||||
color: #000000;
|
||||
font-size: xx-small;
|
||||
}
|
||||
|
||||
.auto-style10 {
|
||||
color: #FF0000;
|
||||
font-family: "Arial";
|
||||
font-size: 11px;
|
||||
line-height: 1.15;
|
||||
margin: 2px 0;
|
||||
}
|
||||
|
||||
.sz-layout {
|
||||
display: flex;
|
||||
align-items: flex-start;
|
||||
gap: 16px;
|
||||
padding: 8px 0;
|
||||
}
|
||||
|
||||
.sz-values {
|
||||
min-width: 180px;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
gap: 2px;
|
||||
}
|
||||
|
||||
.sz-chart-wrap {
|
||||
min-width: 360px;
|
||||
}
|
||||
|
||||
#powerChart {
|
||||
width: 360px;
|
||||
height: 180px;
|
||||
display: block;
|
||||
border-radius: 12px;
|
||||
background: rgba(255,255,255,0.06);
|
||||
border: 1px solid rgba(255,255,255,0.14);
|
||||
}
|
||||
</style>
|
||||
|
||||
</head>
|
||||
|
||||
<body style="color: #00FF00; background-color: #000000">
|
||||
|
||||
<div id="masthead">
|
||||
</div>
|
||||
<div id="top_nav">
|
||||
</div>
|
||||
<div id="container">
|
||||
<div id="page_content">
|
||||
<div class="sz-layout">
|
||||
<div>
|
||||
<p id="tacho_div"></p>
|
||||
</div>
|
||||
<div class="sz-values">
|
||||
<p class="auto-style10" id="ergebnisx1"></p>
|
||||
<p class="auto-style10" id="ergebnisx2"></p>
|
||||
<p class="auto-style10" id="ergebnisx3"></p>
|
||||
<p class="auto-style10" id="ergebnisx4"></p>
|
||||
<p class="auto-style10" id="ergebnisx5"></p>
|
||||
<p class="auto-style10" id="ergebnisx6"></p>
|
||||
<p class="auto-style10" id="ergebnisx7"></p>
|
||||
<p class="auto-style10" id="ergebnisx8"></p>
|
||||
<p class="auto-style10" id="ergebnisx9"></p>
|
||||
<p class="auto-style10" id="ergebnisx10"></p>
|
||||
<p class="auto-style10" id="ergebnisx11"></p>
|
||||
<p class="auto-style10" id="ergebnisx12"></p>
|
||||
</div>
|
||||
<div class="sz-chart-wrap">
|
||||
<canvas id="powerChart" width="360" height="180"></canvas>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
|
||||
|
||||
|
||||
<div id="footer">
|
||||
|
||||
</div>
|
||||
|
||||
|
||||
|
||||
<script type="text/javascript" src="https://www.gstatic.com/charts/loader.js"></script>
|
||||
<script type="text/javascript">
|
||||
let ergebnis = [];
|
||||
let ergebnis_min = [];
|
||||
let powerHistory = [];
|
||||
|
||||
// Chart aktuelle Leistung 20s
|
||||
google.charts.load('current', { 'packages': ['corechart'] });
|
||||
google.charts.setOnLoadCallback(drawChart_live);
|
||||
|
||||
function drawChart_live() {
|
||||
var data = google.visualization.arrayToDataTable([
|
||||
['Stunde', 'kWh'],
|
||||
['0', parseInt(liveChart[1])],
|
||||
['1', parseInt(liveChart[2])],
|
||||
['2', parseInt(liveChart[3])],
|
||||
['3', parseInt(liveChart[4])],
|
||||
['4', parseInt(liveChart[5])],
|
||||
['5', parseInt(liveChart[6])],
|
||||
['6', parseInt(liveChart[7])],
|
||||
['8', parseInt(liveChart[8])],
|
||||
['9', parseInt(liveChart[9])],
|
||||
['10', parseInt(liveChart[10])],
|
||||
['11', parseInt(liveChart[11])],
|
||||
['12', parseInt(liveChart[12])],
|
||||
['13', parseInt(liveChart[13])],
|
||||
['14', parseInt(liveChart[14])],
|
||||
['15', parseInt(liveChart[15])],
|
||||
['16', parseInt(liveChart[16])],
|
||||
['17', parseInt(liveChart[17])],
|
||||
['18', parseInt(liveChart[18])],
|
||||
['19', parseInt(liveChart[19])],
|
||||
['20', parseInt(liveChart[20])]
|
||||
]);
|
||||
|
||||
|
||||
|
||||
var options = {
|
||||
title: 'Verlauf [s]',
|
||||
backgroundColor: 'black',
|
||||
chartArea: { left: 40, top: 0, width: '100%', height: '90%' },
|
||||
//SvAxis: {maxValue: 8000, minValue: -8000},
|
||||
curveType: 'function',
|
||||
legend: { position: 'none' }
|
||||
};
|
||||
|
||||
var chart_live = new google.visualization.LineChart(document.getElementById('curve_chart'));
|
||||
|
||||
chart_live.draw(data, options);
|
||||
|
||||
}
|
||||
|
||||
function addPowerSample(value) {
|
||||
var now = Date.now();
|
||||
if (!isFinite(value)) return;
|
||||
// store a point on every value update (each successful poll)
|
||||
powerHistory.push({ t: now, v: value });
|
||||
var cutoff = now - (5 * 60 * 1000); // 5 minutes
|
||||
while (powerHistory.length && powerHistory[0].t < cutoff) {
|
||||
powerHistory.shift();
|
||||
}
|
||||
}
|
||||
|
||||
function drawPowerChart() {
|
||||
var canvas = document.getElementById('powerChart');
|
||||
if (!canvas) return;
|
||||
var ctx = canvas.getContext('2d');
|
||||
var w = canvas.width, h = canvas.height;
|
||||
|
||||
// background
|
||||
ctx.clearRect(0, 0, w, h);
|
||||
ctx.fillStyle = 'rgba(0,0,0,0.35)';
|
||||
ctx.fillRect(0, 0, w, h);
|
||||
|
||||
// no data yet
|
||||
if (!powerHistory.length) {
|
||||
ctx.fillStyle = 'rgba(234,240,255,0.75)';
|
||||
ctx.font = '12px Segoe UI, Arial, sans-serif';
|
||||
ctx.fillText('Leistung (letzte 5 min) – warte auf Daten…', 12, 24);
|
||||
return;
|
||||
}
|
||||
|
||||
var minV = powerHistory[0].v, maxV = powerHistory[0].v;
|
||||
for (var i = 1; i < powerHistory.length; i++) {
|
||||
var v = powerHistory[i].v;
|
||||
if (v < minV) minV = v;
|
||||
if (v > maxV) maxV = v;
|
||||
}
|
||||
if (minV === maxV) { minV -= 1; maxV += 1; }
|
||||
|
||||
var padL = 38, padR = 10, padT = 18, padB = 22;
|
||||
var plotW = w - padL - padR;
|
||||
var plotH = h - padT - padB;
|
||||
var t0 = powerHistory[0].t;
|
||||
var t1 = powerHistory[powerHistory.length - 1].t;
|
||||
if (t0 === t1) { t0 -= 1; t1 += 1; }
|
||||
|
||||
// grid
|
||||
ctx.strokeStyle = 'rgba(255,255,255,0.10)';
|
||||
ctx.lineWidth = 1;
|
||||
for (var gy = 0; gy <= 4; gy++) {
|
||||
var y = padT + (plotH * gy / 4);
|
||||
ctx.beginPath();
|
||||
ctx.moveTo(padL, y);
|
||||
ctx.lineTo(padL + plotW, y);
|
||||
ctx.stroke();
|
||||
}
|
||||
|
||||
// labels
|
||||
ctx.fillStyle = 'rgba(234,240,255,0.75)';
|
||||
ctx.font = '12px Segoe UI, Arial, sans-serif';
|
||||
ctx.fillText('Leistung – letzte 5 min', 12, 14);
|
||||
|
||||
ctx.fillStyle = 'rgba(234,240,255,0.65)';
|
||||
ctx.font = '11px Segoe UI, Arial, sans-serif';
|
||||
ctx.fillText(Math.round(maxV) + ' W', 6, padT + 10);
|
||||
ctx.fillText(Math.round(minV) + ' W', 6, padT + plotH);
|
||||
|
||||
// line
|
||||
ctx.strokeStyle = 'rgba(99,212,255,0.95)';
|
||||
ctx.lineWidth = 2;
|
||||
ctx.beginPath();
|
||||
for (var j = 0; j < powerHistory.length; j++) {
|
||||
var p = powerHistory[j];
|
||||
var x = padL + ((p.t - t0) / (t1 - t0)) * plotW;
|
||||
var yv = padT + (1 - ((p.v - minV) / (maxV - minV))) * plotH;
|
||||
if (j === 0) ctx.moveTo(x, yv); else ctx.lineTo(x, yv);
|
||||
}
|
||||
ctx.stroke();
|
||||
|
||||
// last point
|
||||
var last = powerHistory[powerHistory.length - 1];
|
||||
var lx = padL + ((last.t - t0) / (t1 - t0)) * plotW;
|
||||
var ly = padT + (1 - ((last.v - minV) / (maxV - minV))) * plotH;
|
||||
ctx.fillStyle = 'rgba(124,255,178,0.95)';
|
||||
ctx.beginPath();
|
||||
ctx.arc(lx, ly, 3, 0, Math.PI * 2);
|
||||
ctx.fill();
|
||||
|
||||
ctx.fillStyle = 'rgba(234,240,255,0.85)';
|
||||
ctx.font = '12px Segoe UI, Arial, sans-serif';
|
||||
ctx.fillText(Math.round(last.v) + ' W', w - 86, 14);
|
||||
}
|
||||
|
||||
// Minuten
|
||||
function drawChart_Minuten() {
|
||||
let array_min = [];
|
||||
for (i = 0; i <= 59; i++) {
|
||||
if (parseFloat(ergebnis_min[i]) > 0) {
|
||||
array_min[i, parseFloat(ergebnis_min[i])];
|
||||
} else {
|
||||
break;
|
||||
};
|
||||
}
|
||||
var data = google.visualization.arrayToDataTable([array_min]);
|
||||
|
||||
var options = {
|
||||
title: 'Tag',
|
||||
titleTextStyle: { color: 'red' },
|
||||
backgroundColor: 'black',
|
||||
chartArea: { left: 40, top: 20, width: '100%', height: '90%' },
|
||||
hAxis: { maxValue: 59, minValue: 0, titleTextStyle: { color: 'red' }, textStyle: { color: 'red' } },
|
||||
vAxis: { title: 'kWh', titleTextStyle: { color: 'red' }, textStyle: { color: 'red' } },
|
||||
legend: 'none',
|
||||
trendlines: { 0: { type: 'linear', color: 'red' } },
|
||||
};
|
||||
|
||||
var chart_Minute = new google.visualization.ScatterChart(document.getElementById('chart_div_Minute'));
|
||||
chart_Minute.draw(data, options);
|
||||
}
|
||||
|
||||
// Tacho
|
||||
google.charts.load('current', { 'packages': ['gauge'] });
|
||||
google.charts.setOnLoadCallback(drawTacho);
|
||||
|
||||
function drawTacho() {
|
||||
|
||||
var data = google.visualization.arrayToDataTable([
|
||||
['Label', 'Value'],
|
||||
['Leistung', 50]
|
||||
]);
|
||||
|
||||
var options = {
|
||||
width: 200, height: 200,
|
||||
max: 8000, min: -8000,
|
||||
greenFrom: -9000, greenTo: 0,
|
||||
redFrom: 5000, redTo: 9000,
|
||||
yellowFrom: 0, yellowTo: 1000,
|
||||
minorTicks: 5
|
||||
};
|
||||
|
||||
var tacho = new google.visualization.Gauge(document.getElementById("tacho_div"));
|
||||
|
||||
tacho.draw(data, options);
|
||||
|
||||
setInterval(function () {
|
||||
data.setValue(0, 1, parseInt(ergebnis[3]));
|
||||
tacho.draw(data, options);
|
||||
//dia_leistung();
|
||||
}, 1000);
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
function showDataTable() {
|
||||
var xmlhttp;
|
||||
if (window.XMLHttpRequest) {
|
||||
// code fuer IE7+, Firefox, Chrome, Opera, Safari
|
||||
xmlhttp = new XMLHttpRequest();
|
||||
} else {
|
||||
// code fuer IE6, IE5
|
||||
xmlhttp = new ActiveXObject("Microsoft.XMLHTTP");
|
||||
}
|
||||
|
||||
xmlhttp.open("GET", "stromzaehler_state.html", true);
|
||||
|
||||
xmlhttp.onreadystatechange = function () {
|
||||
if (xmlhttp.readyState == 4 && xmlhttp.status == 200) {
|
||||
var outputArea = document.getElementById("OutputArea");
|
||||
if (outputArea) outputArea.innerHTML = xmlhttp.responseText;
|
||||
// Refresh Timeout zum Neuladen der Daten setzen
|
||||
|
||||
for (i = 1; i <= 12; i++) {
|
||||
var node = document.getElementById('stromx' + i);
|
||||
ergebnis[i] = node ? node.innerText : '';
|
||||
}
|
||||
|
||||
var p = parseFloat(ergebnis[3]);
|
||||
addPowerSample(p);
|
||||
drawPowerChart();
|
||||
|
||||
document.getElementById('ergebnisx1').innerHTML = 'Bezug: ' + ergebnis[1] + ' kWh';
|
||||
document.getElementById('ergebnisx2').innerHTML = 'Einspeisung: ' + ergebnis[2] + ' kWh';
|
||||
document.getElementById('ergebnisx3').innerHTML = 'aktuelle Leistung: ' + ergebnis[3] + ' W';
|
||||
document.getElementById('ergebnisx4').innerHTML = 'täglicher Bezug: ' + ergebnis[4] + ' kWh';
|
||||
var diff1 = parseFloat(ergebnis[1]) - parseFloat(ergebnis[5]);
|
||||
var diff2 = parseFloat(ergebnis[5]) - parseFloat(ergebnis[6]);
|
||||
var diff3 = parseFloat(ergebnis[6]) - parseFloat(ergebnis[7]);
|
||||
var diff4 = parseFloat(ergebnis[7]) - parseFloat(ergebnis[8]);
|
||||
var diff5 = parseFloat(ergebnis[8]) - parseFloat(ergebnis[9]);
|
||||
var diff6 = parseFloat(ergebnis[9]) - parseFloat(ergebnis[10]);
|
||||
var diff7 = parseFloat(ergebnis[10]) - parseFloat(ergebnis[11]);
|
||||
var diff8 = parseFloat(ergebnis[11]) - parseFloat(ergebnis[12]);
|
||||
document.getElementById('ergebnisx5').innerHTML = '-1: ' + (isNaN(diff1) ? '-' : diff1.toFixed(2)) + ' kWh';
|
||||
document.getElementById('ergebnisx6').innerHTML = '-2: ' + (isNaN(diff2) ? '-' : diff2.toFixed(2)) + ' kWh';
|
||||
document.getElementById('ergebnisx7').innerHTML = '-3: ' + (isNaN(diff3) ? '-' : diff3.toFixed(2)) + ' kWh';
|
||||
document.getElementById('ergebnisx8').innerHTML = '-4: ' + (isNaN(diff4) ? '-' : diff4.toFixed(2)) + ' kWh';
|
||||
document.getElementById('ergebnisx9').innerHTML = '-5: ' + (isNaN(diff5) ? '-' : diff5.toFixed(2)) + ' kWh';
|
||||
document.getElementById('ergebnisx10').innerHTML = '-6: ' + (isNaN(diff6) ? '-' : diff6.toFixed(2)) + ' kWh';
|
||||
document.getElementById('ergebnisx11').innerHTML = '-7: ' + (isNaN(diff7) ? '-' : diff7.toFixed(2)) + ' kWh';
|
||||
document.getElementById('ergebnisx12').innerHTML = '-8: ' + (isNaN(diff8) ? '-' : diff8.toFixed(2)) + ' kWh';
|
||||
|
||||
setTimeout(refreshOutputArea, 500);
|
||||
}
|
||||
}
|
||||
xmlhttp.send(null);
|
||||
}
|
||||
|
||||
|
||||
function refreshOutputArea() {
|
||||
showDataTable();
|
||||
}
|
||||
|
||||
window.onload = function () {
|
||||
refreshOutputArea();
|
||||
|
||||
}
|
||||
|
||||
</script>
|
||||
|
||||
</div>
|
||||
<div id="OutputArea" style="position:fixed;clip:rect(0,0,0,0);overflow:hidden;"></div>
|
||||
</body>
|
||||
|
||||
</html>
|
||||
Reference in New Issue
Block a user