diff --git a/.gitattributes b/.gitattributes
new file mode 100644
index 0000000..a1cedf8
--- /dev/null
+++ b/.gitattributes
@@ -0,0 +1,17 @@
+# Zeilenenden gehoeren zum Repository, nicht zur Maschine.
+#
+# Ohne diese Datei entscheidet jede Arbeitsstation fuer sich: Git fuer
+# Windows setzt core.autocrlf=input in seiner System-Konfiguration, die NAS
+# setzt nichts. Dasselbe Repository, zwei Verhalten - und weil der Bestand
+# selbst gemischt war (34 PHP-Dateien mit LF, 30 mit CRLF), gab es kein
+# richtiges Zeilenende, an das ein Werkzeug sich haette halten koennen.
+# Jede Ergaenzung mit LF in einer CRLF-Datei ergab eine gemischte Datei.
+#
+# LF und nicht CRLF, weil dieses Verzeichnis der Web-Ordner der NAS ist und
+# von Linux ausgeliefert wird.
+* text=auto eol=lf
+
+# Eingekaufter Fremdcode bleibt byteweise so, wie er geliefert wurde - dann
+# bleibt ein Update dagegen vergleichbar. Darunter liegen auch 292
+# Zertifikate, die niemand anfassen sollte.
+restricted/WebAuthn/** -text
diff --git a/addUser.php b/addUser.php
index 2411841..30be75d 100644
--- a/addUser.php
+++ b/addUser.php
@@ -1,16 +1,16 @@
-
\ No newline at end of file
diff --git a/ajax/getConsData.php b/ajax/getConsData.php
index 423c134..c8688c8 100644
--- a/ajax/getConsData.php
+++ b/ajax/getConsData.php
@@ -1,162 +1,162 @@
-".mysqli_error($mysql)."
";
- }
- $obj = (object)[]; // Cast empty array to object
- $obj->labels = [];
- $obj->datasets = [];
- $i = 0;
- $filled = 0;
- if ($simRes->num_rows > 1) {
- $dataset = (object)[];
- $row1 = $simRes->fetch_assoc();
- $dataset->borderColor = $linecolors["Vorhersage"];
- $dataset->backgroundColor = $linecolors["Vorhersage"]."55";
- $dataset->borderWidth=1.5;
- $dataset->pointRadius= 0;
- $dataset->pointHoverRadius= 5;
- $dataset->tension=0.2;
- $dataset->stack = "sim";
- $dataset->fill = "none";
- $dataset->yAxisID = 'y';
- $dataset->label = "Vorhersage";
- /*$pt = (object)[];
- $pt->x = $row1["time"]*1000;
- $pt->y = $row1["Vorhersage"];
- $dataset->data[] = clone $pt;
- while ($row1 = $simRes->fetch_assoc()) {
- $pt = (object)[];
- $pt->x = $row1["time"]*1000 + 30*60*1000;
- $pt->y = $row1["Vorhersage"];
- $dataset->data[] = clone $pt;
- }*/
- $obj->datasets[] = clone $dataset;
- $rownext = $simRes->fetch_assoc();
- $nextSimTimestamp = $rownext["time"]*1000 + 30*60*1000;
- }
- if ($result->num_rows > 1) {
- $ii = 1;
- $row = $result->fetch_assoc();
- foreach ($row as $name => $value) {
- $dataset = (object)[];
- if ($name != "time") {
- $dataset->borderColor = $linecolors[$name];
- $dataset->backgroundColor = $linecolors[$name]."55";
- $dataset->borderWidth=1;
- $dataset->pointRadius= 0;
- $dataset->pointHoverRadius= 5;
- $dataset->tension=0.2;
- if ($name == "Solarleistung") {
- $dataset->stack = "SolarPwr";
- $dataset->fill = "none";
- $dataset->yAxisID = 'y';
- } else if ($name == "Ladestand") {
- $dataset->stack = "Charge";
- $dataset->fill = "none";
- $dataset->yAxisID = 'y1';
- } else {
- $dataset->stack = "Consumers";
- if ($filled == 0) {
- $filled = 1;
- $dataset->fill = "origin";
- } else {
- $dataset->fill = "-1";
- }
- $dataset->yAxisID = 'y';
- }
- $dataset->label = $name;
-
- $dataset->data[] = $value;
- $obj->datasets[] = clone $dataset;
- $ii++;
- } else {
- $obj->labels[] = $value * 1000;
- }
- }
- while ($row = $result->fetch_assoc()) {
- $ii = 1;
- foreach ($row as $name => $value) {
- if ($name != "time") {
- $obj->datasets[$ii]->data[] = $value;
- $ii++;
- } else {
- if(($value * 1000) < $nextSimTimestamp){
- $obj->datasets[0]->data[] = $row1["Vorhersage"];
- }else{
- $row1 = $rownext;
- $rownext = $simRes->fetch_assoc();
- $nextSimTimestamp = $rownext["time"]*1000 + 30*60*1000;
- $obj->datasets[0]->data[] = $row1["Vorhersage"];
- }
- $obj->labels[] = $value * 1000;
- }
- }
- }
- }
- $obj->labels[] = $nextSimTimestamp; //Draw future forecast
- $obj->datasets[0]->data[] = $rownext["Vorhersage"];
- while($rownext = $simRes->fetch_assoc()){
- $obj->labels[] = $rownext["time"]*1000 + 30*60*1000;
- $obj->datasets[0]->data[] = $rownext["Vorhersage"];
- }
-
-
-}
-
-
-//header('Content-Type: application/json');
-echo json_encode($obj);
-//echo '{"labels":[1761322682000,1761322782000,1761322882000,1761322982000,1761323082000,1761323182000,1761323282000],"datasets":[{"stack": "Stack 0","cubicInterpolationMode":"monotone","fill":"origin","label":"Acquisitions by year","data":[10,20,50,20,10,5,70]},{"fill": "false","stack": "Stack 1","cubicInterpolationMode": "monotone","label": "Acquisitions by year","data": [10,20,50,20,10,5,70]}]}';
+".mysqli_error($mysql)."
";
+ }
+ $obj = (object)[]; // Cast empty array to object
+ $obj->labels = [];
+ $obj->datasets = [];
+ $i = 0;
+ $filled = 0;
+ if ($simRes->num_rows > 1) {
+ $dataset = (object)[];
+ $row1 = $simRes->fetch_assoc();
+ $dataset->borderColor = $linecolors["Vorhersage"];
+ $dataset->backgroundColor = $linecolors["Vorhersage"]."55";
+ $dataset->borderWidth=1.5;
+ $dataset->pointRadius= 0;
+ $dataset->pointHoverRadius= 5;
+ $dataset->tension=0.2;
+ $dataset->stack = "sim";
+ $dataset->fill = "none";
+ $dataset->yAxisID = 'y';
+ $dataset->label = "Vorhersage";
+ /*$pt = (object)[];
+ $pt->x = $row1["time"]*1000;
+ $pt->y = $row1["Vorhersage"];
+ $dataset->data[] = clone $pt;
+ while ($row1 = $simRes->fetch_assoc()) {
+ $pt = (object)[];
+ $pt->x = $row1["time"]*1000 + 30*60*1000;
+ $pt->y = $row1["Vorhersage"];
+ $dataset->data[] = clone $pt;
+ }*/
+ $obj->datasets[] = clone $dataset;
+ $rownext = $simRes->fetch_assoc();
+ $nextSimTimestamp = $rownext["time"]*1000 + 30*60*1000;
+ }
+ if ($result->num_rows > 1) {
+ $ii = 1;
+ $row = $result->fetch_assoc();
+ foreach ($row as $name => $value) {
+ $dataset = (object)[];
+ if ($name != "time") {
+ $dataset->borderColor = $linecolors[$name];
+ $dataset->backgroundColor = $linecolors[$name]."55";
+ $dataset->borderWidth=1;
+ $dataset->pointRadius= 0;
+ $dataset->pointHoverRadius= 5;
+ $dataset->tension=0.2;
+ if ($name == "Solarleistung") {
+ $dataset->stack = "SolarPwr";
+ $dataset->fill = "none";
+ $dataset->yAxisID = 'y';
+ } else if ($name == "Ladestand") {
+ $dataset->stack = "Charge";
+ $dataset->fill = "none";
+ $dataset->yAxisID = 'y1';
+ } else {
+ $dataset->stack = "Consumers";
+ if ($filled == 0) {
+ $filled = 1;
+ $dataset->fill = "origin";
+ } else {
+ $dataset->fill = "-1";
+ }
+ $dataset->yAxisID = 'y';
+ }
+ $dataset->label = $name;
+
+ $dataset->data[] = $value;
+ $obj->datasets[] = clone $dataset;
+ $ii++;
+ } else {
+ $obj->labels[] = $value * 1000;
+ }
+ }
+ while ($row = $result->fetch_assoc()) {
+ $ii = 1;
+ foreach ($row as $name => $value) {
+ if ($name != "time") {
+ $obj->datasets[$ii]->data[] = $value;
+ $ii++;
+ } else {
+ if(($value * 1000) < $nextSimTimestamp){
+ $obj->datasets[0]->data[] = $row1["Vorhersage"];
+ }else{
+ $row1 = $rownext;
+ $rownext = $simRes->fetch_assoc();
+ $nextSimTimestamp = $rownext["time"]*1000 + 30*60*1000;
+ $obj->datasets[0]->data[] = $row1["Vorhersage"];
+ }
+ $obj->labels[] = $value * 1000;
+ }
+ }
+ }
+ }
+ $obj->labels[] = $nextSimTimestamp; //Draw future forecast
+ $obj->datasets[0]->data[] = $rownext["Vorhersage"];
+ while($rownext = $simRes->fetch_assoc()){
+ $obj->labels[] = $rownext["time"]*1000 + 30*60*1000;
+ $obj->datasets[0]->data[] = $rownext["Vorhersage"];
+ }
+
+
+}
+
+
+//header('Content-Type: application/json');
+echo json_encode($obj);
+//echo '{"labels":[1761322682000,1761322782000,1761322882000,1761322982000,1761323082000,1761323182000,1761323282000],"datasets":[{"stack": "Stack 0","cubicInterpolationMode":"monotone","fill":"origin","label":"Acquisitions by year","data":[10,20,50,20,10,5,70]},{"fill": "false","stack": "Stack 1","cubicInterpolationMode": "monotone","label": "Acquisitions by year","data": [10,20,50,20,10,5,70]}]}';
?>
\ No newline at end of file
diff --git a/ajax/getForecastData.php b/ajax/getForecastData.php
index 1729184..5093ba3 100644
--- a/ajax/getForecastData.php
+++ b/ajax/getForecastData.php
@@ -1,171 +1,171 @@
-= DATE(DATE_SUB(NOW(),INTERVAL 28 DAY)) And DATE(datetime) != DATE(NOW())
- GROUP BY WEEKDAY(datetime)
-ORDER BY datetime";
-
-$prodEstQuery = "SELECT UNIX_TIMESTAMP(CONVERT_TZ(period_End,'GMT','Europe/Berlin')) AS 'time',
- SUM(power*500) AS 'Vorhersage'
- FROM simPower
- WHERE DATE(CONVERT_TZ(period_End,'GMT','Europe/Berlin')) >= DATE(DATE_SUB(NOW(),INTERVAL 7 DAY))
- GROUP BY DAY(CONVERT_TZ(period_End,'GMT','Europe/Berlin'))
- ORDER BY period_End;";
-
-$prodRealQuery = "SELECT
- UNIX_TIMESTAMP(datetime) AS 'time',
- SUM(pvP/12) AS 'Tatsächliche Erzeugung',
- SUM(-totalConsumption/12) AS 'Tatsächlicher Verbrauch'
-FROM EnergyFlow
-WHERE
- DATE(datetime) >= DATE(DATE_SUB(NOW(),INTERVAL 7 DAY))
- GROUP BY DAY(datetime)
-ORDER BY datetime";
-
-
-$linecolors["Tatsächliche Erzeugung"] = "#cccc00";
-$linecolors["Tatsächlicher Verbrauch"] = "#EE9900";
-$linecolors["Vorraussichtl. Verbrauch"] = "#BB4400";
-$linecolors["Auto UG"] = "#00aaFF";
-$linecolors["Auto OG"] = "#0044FF";
-$linecolors["Heizstab"] = "#FF0000";
-$linecolors["Batterieladung"] = "#00aa00";
-$linecolors["Einspeisung"] = "#b0b0b0";
-$linecolors["Ladestand"] = "#00aa00";
-$linecolors["Vorhersage"] = "#4444FF";
-
-
-
-if (checkLogin()) {
- $mysql = new mysqli($mysql_server, $mysql_solarUser, $mysql_solarPass, $mysql_solarDB);
- $consEst = mysqli_query($mysql, $consEstQuery);
- $prodEst = mysqli_query($mysql,$prodEstQuery);
- $prodReal = mysqli_query($mysql,$prodRealQuery);
- if(!$consEst){
- echo "Error:
".mysqli_error($mysql)."
";
- }
- if(!$prodEst){
- echo "Error:
".mysqli_error($mysql)."
";
- }
- if(!$prodRealQuery){
- echo "Error:
".mysqli_error($mysql)."
";
- }
-
- $obj = (object)[]; // Cast empty array to object
- $obj->labels = [];
- $obj->datasets = [];
- $i = 0;
- $filled = 0;
-
- if($consEst->num_rows > 1){
- $row = $consEst->fetch_assoc();
- foreach ($row as $name => $value) {
- $dataset = (object)[];
- if ($name != "time") {
- $dataset->borderColor = $linecolors[$name];
- $dataset->backgroundColor = $linecolors[$name]."66";
- $dataset->borderWidth=1;
- $dataset->pointRadius= 0;
- $dataset->pointHoverRadius= 5;
- $dataset->tension=0.2;
- $dataset->stack = $name;
- //$dataset->fill = "none";
- $dataset->yAxisID = 'y';
- $dataset->label = $name;
- for($i=0;$i<7;$i++){
- $dataset->data[] = NULL;
- }
- $dataset->data[] = $value;
- $obj->datasets[] = clone $dataset;
- }
- }
- while ($row = $consEst->fetch_assoc()) {
- $ii = 0;
- foreach ($row as $name => $value) {
- if ($name != "time") {
- $obj->datasets[$ii]->data[] = $value;
- $ii++;
- }
- }
- }
- }
-
- if ($prodEst->num_rows > 1) {
- $row = $prodEst->fetch_assoc();
- foreach ($row as $name => $value) {
- $dataset = (object)[];
- if ($name != "time") {
- $dataset->borderColor = $linecolors[$name];
- $dataset->backgroundColor = $linecolors[$name]."55";
- $dataset->borderWidth=1;
- $dataset->pointRadius= 0;
- $dataset->pointHoverRadius= 5;
- $dataset->tension=0.2;
- $dataset->stack = $name;
- //$dataset->fill = "none";
- $dataset->yAxisID = 'y';
- $dataset->label = $name;
- $dataset->data[] = $value;
- $obj->datasets[] = clone $dataset;
- } else {
- $obj->labels[] = $value * 1000;
- }
- }
- while ($row = $prodEst->fetch_assoc()) {
- $ii = 1;
- foreach ($row as $name => $value) {
- if ($name != "time") {
- $obj->datasets[$ii]->data[] = $value;
- $ii++;
- } else {
- $obj->labels[] = $value * 1000;
- }
- }
- }
- }
-
- if($prodReal->num_rows > 1){
- $row = $prodReal->fetch_assoc();
- foreach ($row as $name => $value) {
- $dataset = (object)[];
- if ($name != "time") {
- $dataset->borderColor = $linecolors[$name];
- $dataset->backgroundColor = $linecolors[$name]."55";
- $dataset->borderWidth=1;
- $dataset->pointRadius= 0;
- $dataset->pointHoverRadius= 5;
- $dataset->tension=0.2;
- $dataset->stack = $name;
- //$dataset->fill = "none";
- $dataset->yAxisID = 'y';
- $dataset->label = $name;
- $dataset->data[] = $value;
- $obj->datasets[] = clone $dataset;
- }
- }
- while ($row = $prodReal->fetch_assoc()) {
- $ii = 2;
- foreach ($row as $name => $value) {
- if ($name != "time") {
- $obj->datasets[$ii]->data[] = $value;
- $ii++;
- }
- }
- }
- }
-
-
-
-
-}
-
-
-//header('Content-Type: application/json');
-echo json_encode($obj);
-//echo '{"labels":[1761322682000,1761322782000,1761322882000,1761322982000,1761323082000,1761323182000,1761323282000],"datasets":[{"stack": "Stack 0","cubicInterpolationMode":"monotone","fill":"origin","label":"Acquisitions by year","data":[10,20,50,20,10,5,70]},{"fill": "false","stack": "Stack 1","cubicInterpolationMode": "monotone","label": "Acquisitions by year","data": [10,20,50,20,10,5,70]}]}';
+= DATE(DATE_SUB(NOW(),INTERVAL 28 DAY)) And DATE(datetime) != DATE(NOW())
+ GROUP BY WEEKDAY(datetime)
+ORDER BY datetime";
+
+$prodEstQuery = "SELECT UNIX_TIMESTAMP(CONVERT_TZ(period_End,'GMT','Europe/Berlin')) AS 'time',
+ SUM(power*500) AS 'Vorhersage'
+ FROM simPower
+ WHERE DATE(CONVERT_TZ(period_End,'GMT','Europe/Berlin')) >= DATE(DATE_SUB(NOW(),INTERVAL 7 DAY))
+ GROUP BY DAY(CONVERT_TZ(period_End,'GMT','Europe/Berlin'))
+ ORDER BY period_End;";
+
+$prodRealQuery = "SELECT
+ UNIX_TIMESTAMP(datetime) AS 'time',
+ SUM(pvP/12) AS 'Tatsächliche Erzeugung',
+ SUM(-totalConsumption/12) AS 'Tatsächlicher Verbrauch'
+FROM EnergyFlow
+WHERE
+ DATE(datetime) >= DATE(DATE_SUB(NOW(),INTERVAL 7 DAY))
+ GROUP BY DAY(datetime)
+ORDER BY datetime";
+
+
+$linecolors["Tatsächliche Erzeugung"] = "#cccc00";
+$linecolors["Tatsächlicher Verbrauch"] = "#EE9900";
+$linecolors["Vorraussichtl. Verbrauch"] = "#BB4400";
+$linecolors["Auto UG"] = "#00aaFF";
+$linecolors["Auto OG"] = "#0044FF";
+$linecolors["Heizstab"] = "#FF0000";
+$linecolors["Batterieladung"] = "#00aa00";
+$linecolors["Einspeisung"] = "#b0b0b0";
+$linecolors["Ladestand"] = "#00aa00";
+$linecolors["Vorhersage"] = "#4444FF";
+
+
+
+if (checkLogin()) {
+ $mysql = new mysqli($mysql_server, $mysql_solarUser, $mysql_solarPass, $mysql_solarDB);
+ $consEst = mysqli_query($mysql, $consEstQuery);
+ $prodEst = mysqli_query($mysql,$prodEstQuery);
+ $prodReal = mysqli_query($mysql,$prodRealQuery);
+ if(!$consEst){
+ echo "Error:
".mysqli_error($mysql)."
";
+ }
+ if(!$prodEst){
+ echo "Error:
".mysqli_error($mysql)."
";
+ }
+ if(!$prodRealQuery){
+ echo "Error:
".mysqli_error($mysql)."
";
+ }
+
+ $obj = (object)[]; // Cast empty array to object
+ $obj->labels = [];
+ $obj->datasets = [];
+ $i = 0;
+ $filled = 0;
+
+ if($consEst->num_rows > 1){
+ $row = $consEst->fetch_assoc();
+ foreach ($row as $name => $value) {
+ $dataset = (object)[];
+ if ($name != "time") {
+ $dataset->borderColor = $linecolors[$name];
+ $dataset->backgroundColor = $linecolors[$name]."66";
+ $dataset->borderWidth=1;
+ $dataset->pointRadius= 0;
+ $dataset->pointHoverRadius= 5;
+ $dataset->tension=0.2;
+ $dataset->stack = $name;
+ //$dataset->fill = "none";
+ $dataset->yAxisID = 'y';
+ $dataset->label = $name;
+ for($i=0;$i<7;$i++){
+ $dataset->data[] = NULL;
+ }
+ $dataset->data[] = $value;
+ $obj->datasets[] = clone $dataset;
+ }
+ }
+ while ($row = $consEst->fetch_assoc()) {
+ $ii = 0;
+ foreach ($row as $name => $value) {
+ if ($name != "time") {
+ $obj->datasets[$ii]->data[] = $value;
+ $ii++;
+ }
+ }
+ }
+ }
+
+ if ($prodEst->num_rows > 1) {
+ $row = $prodEst->fetch_assoc();
+ foreach ($row as $name => $value) {
+ $dataset = (object)[];
+ if ($name != "time") {
+ $dataset->borderColor = $linecolors[$name];
+ $dataset->backgroundColor = $linecolors[$name]."55";
+ $dataset->borderWidth=1;
+ $dataset->pointRadius= 0;
+ $dataset->pointHoverRadius= 5;
+ $dataset->tension=0.2;
+ $dataset->stack = $name;
+ //$dataset->fill = "none";
+ $dataset->yAxisID = 'y';
+ $dataset->label = $name;
+ $dataset->data[] = $value;
+ $obj->datasets[] = clone $dataset;
+ } else {
+ $obj->labels[] = $value * 1000;
+ }
+ }
+ while ($row = $prodEst->fetch_assoc()) {
+ $ii = 1;
+ foreach ($row as $name => $value) {
+ if ($name != "time") {
+ $obj->datasets[$ii]->data[] = $value;
+ $ii++;
+ } else {
+ $obj->labels[] = $value * 1000;
+ }
+ }
+ }
+ }
+
+ if($prodReal->num_rows > 1){
+ $row = $prodReal->fetch_assoc();
+ foreach ($row as $name => $value) {
+ $dataset = (object)[];
+ if ($name != "time") {
+ $dataset->borderColor = $linecolors[$name];
+ $dataset->backgroundColor = $linecolors[$name]."55";
+ $dataset->borderWidth=1;
+ $dataset->pointRadius= 0;
+ $dataset->pointHoverRadius= 5;
+ $dataset->tension=0.2;
+ $dataset->stack = $name;
+ //$dataset->fill = "none";
+ $dataset->yAxisID = 'y';
+ $dataset->label = $name;
+ $dataset->data[] = $value;
+ $obj->datasets[] = clone $dataset;
+ }
+ }
+ while ($row = $prodReal->fetch_assoc()) {
+ $ii = 2;
+ foreach ($row as $name => $value) {
+ if ($name != "time") {
+ $obj->datasets[$ii]->data[] = $value;
+ $ii++;
+ }
+ }
+ }
+ }
+
+
+
+
+}
+
+
+//header('Content-Type: application/json');
+echo json_encode($obj);
+//echo '{"labels":[1761322682000,1761322782000,1761322882000,1761322982000,1761323082000,1761323182000,1761323282000],"datasets":[{"stack": "Stack 0","cubicInterpolationMode":"monotone","fill":"origin","label":"Acquisitions by year","data":[10,20,50,20,10,5,70]},{"fill": "false","stack": "Stack 1","cubicInterpolationMode": "monotone","label": "Acquisitions by year","data": [10,20,50,20,10,5,70]}]}';
diff --git a/ajax/getHeaterData.php b/ajax/getHeaterData.php
index 763d235..a41a712 100644
--- a/ajax/getHeaterData.php
+++ b/ajax/getHeaterData.php
@@ -1,105 +1,105 @@
-".mysqli_error($mysql)."
";
- }
- $obj = (object)[]; // Cast empty array to object
- $obj->labels = [];
- $obj->datasets = [];
- $i = 0;
- $filled = 0;
-
- if ($result->num_rows > 1) {
- $ii = 0;
- $row = $result->fetch_assoc();
- foreach ($row as $name => $value) {
- $dataset = (object)[];
- if ($name != "time") {
- $dataset->borderColor = $linecolors[$name];
- $dataset->backgroundColor = $linecolors[$name]."22";
- $dataset->borderWidth=2;
- $dataset->pointRadius= 0;
- $dataset->pointHoverRadius= 5;
- $dataset->tension=0.2;
- if(strpos($name,"Speicher") === false) {
- $dataset->fill = "none";
- } else {
- // $dataset->stack = "Consumers";
- if ($filled == 0) {
- $filled = 1;
- $dataset->fill = "origin";
- } else {
- $dataset->fill = "-1";
- }
- $dataset->yAxisID = 'y';
- }
- $dataset->label = $name;
-
- $dataset->data[] = $value;
- $obj->datasets[] = clone $dataset;
- $ii++;
- } else {
- $obj->labels[] = $value * 1000;
- }
- }
- while ($row = $result->fetch_assoc()) {
- $ii = 0;
- foreach ($row as $name => $value) {
- if ($name != "time") {
- $obj->datasets[$ii]->data[] = $value;
- $ii++;
- } else {
- $obj->labels[] = $value * 1000;
- }
- }
- }
- }
-
-
-}
-
-
-//header('Content-Type: application/json');
-echo json_encode($obj);
-//echo '{"labels":[1761322682000,1761322782000,1761322882000,1761322982000,1761323082000,1761323182000,1761323282000],"datasets":[{"stack": "Stack 0","cubicInterpolationMode":"monotone","fill":"origin","label":"Acquisitions by year","data":[10,20,50,20,10,5,70]},{"fill": "false","stack": "Stack 1","cubicInterpolationMode": "monotone","label": "Acquisitions by year","data": [10,20,50,20,10,5,70]}]}';
+".mysqli_error($mysql)."
";
+ }
+ $obj = (object)[]; // Cast empty array to object
+ $obj->labels = [];
+ $obj->datasets = [];
+ $i = 0;
+ $filled = 0;
+
+ if ($result->num_rows > 1) {
+ $ii = 0;
+ $row = $result->fetch_assoc();
+ foreach ($row as $name => $value) {
+ $dataset = (object)[];
+ if ($name != "time") {
+ $dataset->borderColor = $linecolors[$name];
+ $dataset->backgroundColor = $linecolors[$name]."22";
+ $dataset->borderWidth=2;
+ $dataset->pointRadius= 0;
+ $dataset->pointHoverRadius= 5;
+ $dataset->tension=0.2;
+ if(strpos($name,"Speicher") === false) {
+ $dataset->fill = "none";
+ } else {
+ // $dataset->stack = "Consumers";
+ if ($filled == 0) {
+ $filled = 1;
+ $dataset->fill = "origin";
+ } else {
+ $dataset->fill = "-1";
+ }
+ $dataset->yAxisID = 'y';
+ }
+ $dataset->label = $name;
+
+ $dataset->data[] = $value;
+ $obj->datasets[] = clone $dataset;
+ $ii++;
+ } else {
+ $obj->labels[] = $value * 1000;
+ }
+ }
+ while ($row = $result->fetch_assoc()) {
+ $ii = 0;
+ foreach ($row as $name => $value) {
+ if ($name != "time") {
+ $obj->datasets[$ii]->data[] = $value;
+ $ii++;
+ } else {
+ $obj->labels[] = $value * 1000;
+ }
+ }
+ }
+ }
+
+
+}
+
+
+//header('Content-Type: application/json');
+echo json_encode($obj);
+//echo '{"labels":[1761322682000,1761322782000,1761322882000,1761322982000,1761323082000,1761323182000,1761323282000],"datasets":[{"stack": "Stack 0","cubicInterpolationMode":"monotone","fill":"origin","label":"Acquisitions by year","data":[10,20,50,20,10,5,70]},{"fill": "false","stack": "Stack 1","cubicInterpolationMode": "monotone","label": "Acquisitions by year","data": [10,20,50,20,10,5,70]}]}';
diff --git a/ajax/getProdData.php b/ajax/getProdData.php
index d3b1f8a..5c85273 100644
--- a/ajax/getProdData.php
+++ b/ajax/getProdData.php
@@ -1,165 +1,165 @@
-0, gridP, 0) - IF(battP>0, battP, 0) > 0, -totalConsumption - IF(gridP>0, gridP, 0) - IF(battP>0, battP, 0), 0) AS Direktverbrauch,
-IF(battP>0, battP, 0) AS Batteriebezug,
-gridPcons AS Netzbezug,
--totalConsumption AS Verbrauch,".
-//IF(battP<0, -battP, 0) AS Batterieladung,
-"soc AS Ladestand
-FROM solarLog.EnergyFlow
-WHERE EnergyFlow.datetime BETWEEN DATE_ADD(NOW(),INTERVAL ".($_GET["FROM"])." HOUR) and DATE_ADD(NOW(),INTERVAL ".$_GET["TO"]." HOUR)
-ORDER BY EnergyFlow.datetime";
-
-$simQuery = "SELECT
-UNIX_TIMESTAMP(simPower.period_end) AS time,
-power*1000 AS 'Vorhersage'
-FROM solarLog.simPower
-WHERE simPower.period_end BETWEEN DATE_ADD(NOW(),INTERVAL ".($_GET["FROM"])." HOUR) and DATE_ADD(NOW(),INTERVAL ".$_GET["TO"]." HOUR)
-ORDER BY simPower.period_end";
-$linecolors["Solarleistung"] = "#FFFF00";
-$linecolors["Direktverbrauch"] = "#FFcc00";
-$linecolors["Verbrauch"] = "#FFaa44";
-$linecolors["Auto UG"] = "#00aaFF";
-$linecolors["Auto OG"] = "#0044FF";
-$linecolors["Netzbezug"] = "#FF0000";
-$linecolors["Batteriebezug"] = "#00aa00";
-$linecolors["Batterieladung"] = "#0033aa";
-$linecolors["Einspeisung"] = "#b0b0b0";
-$linecolors["Ladestand"] = "#00aa00";
-$linecolors["Vorhersage"] = "#2222FF";
-
-
-
-if (checkLogin()) {
-
- $mysql = new mysqli($mysql_server, $mysql_solarUser, $mysql_solarPass, $mysql_solarDB);
- $result = mysqli_query($mysql, $consQuery);
- $simRes = mysqli_query($mysql,$simQuery);
- if(!$result){
- echo "Error:
".mysqli_error($mysql)."
";
- }
- $obj = (object)[]; // Cast empty array to object
- $obj->labels = [];
- $obj->datasets = [];
- $i = 0;
- $filled = 0;
- if ($simRes->num_rows > 1) {
- $dataset = (object)[];
- $row1 = $simRes->fetch_assoc();
- $dataset->borderColor = $linecolors["Vorhersage"];
- $dataset->backgroundColor = $linecolors["Vorhersage"]."55";
- $dataset->borderWidth=1.5;
- $dataset->pointRadius= 0;
- $dataset->pointHoverRadius= 5;
- $dataset->tension=0.2;
- $dataset->stack = "sim";
- $dataset->fill = "none";
- $dataset->yAxisID = 'y';
- $dataset->label = "Vorhersage";
- /*$pt = (object)[];
- $pt->x = $row["time"]*1000;
- $pt->y = $row["Vorhersage"];
- $dataset->data[] = clone $pt;
- while ($row = $simRes->fetch_assoc()) {
- $pt = (object)[];
- $pt->x = $row["time"]*1000 + 30*60*1000;
- $pt->y = $row["Vorhersage"];
- $dataset->data[] = clone $pt;
- }*/
- $obj->datasets[] = clone $dataset;
- $rownext = $simRes->fetch_assoc();
- $nextSimTimestamp = $rownext["time"]*1000 + 30*60*1000;
- }
- if ($result->num_rows > 1) {
- $ii = 1;
- $row = $result->fetch_assoc();
- foreach ($row as $name => $value) {
- $dataset = (object)[];
- if ($name != "time") {
- $dataset->borderColor = $linecolors[$name];
- $dataset->backgroundColor = $linecolors[$name]."22";
- $dataset->borderWidth=1;
- $dataset->pointRadius= 0;
- $dataset->pointHoverRadius= 5;
- $dataset->tension=0.2;
- if ($name == "Solarleistung") {
- $dataset->stack = "SolarPwr";
- $dataset->fill = "none";
- $dataset->yAxisID = 'y';
- }else if ($name == "Verbrauch") {
- $dataset->stack = "ConsPwr";
- $dataset->fill = "1";
- $dataset->yAxisID = 'y';
- }else if ($name == "Batterieladung") {
- $dataset->stack = "ConsPwr";
- $dataset->fill = "-1";
- $dataset->backgroundColor = $linecolors[$name]."77";
- $dataset->yAxisID = 'y';
- } else if ($name == "Ladestand") {
- $dataset->stack = "Charge";
- $dataset->fill = "none";
- $dataset->yAxisID = 'y1';
- } else {
- $dataset->stack = "Consumers";
- if ($filled == 0) {
- $filled = 1;
- $dataset->fill = "origin";
- } else {
- $dataset->fill = "-1";
- }
- $dataset->yAxisID = 'y';
- }
- $dataset->label = $name;
-
- $dataset->data[] = $value;
- $obj->datasets[] = clone $dataset;
- $ii++;
- } else {
- $obj->labels[] = $value * 1000;
- }
- }
- while ($row = $result->fetch_assoc()) {
- $ii = 1;
- foreach ($row as $name => $value) {
- if ($name != "time") {
- $obj->datasets[$ii]->data[] = $value;
- $ii++;
- } else {
- if(($value * 1000) < $nextSimTimestamp){
- $obj->datasets[0]->data[] = $row1["Vorhersage"];
- }else{
- $row1 = $rownext;
- $rownext = $simRes->fetch_assoc();
- $nextSimTimestamp = $rownext["time"]*1000 + 30*60*1000;
- $obj->datasets[0]->data[] = $row1["Vorhersage"];
- }
- $obj->labels[] = $value * 1000;
- }
- }
- }
- }
- $obj->labels[] = $nextSimTimestamp; //Draw future forecast
- $obj->datasets[0]->data[] = $rownext["Vorhersage"];
- while($rownext = $simRes->fetch_assoc()){
- $obj->labels[] = $rownext["time"]*1000 + 30*60*1000;
- $obj->datasets[0]->data[] = $rownext["Vorhersage"];
- }
-}
-
-
-//header('Content-Type: application/json');
-echo json_encode($obj);
-//echo '{"labels":[1761322682000,1761322782000,1761322882000,1761322982000,1761323082000,1761323182000,1761323282000],"datasets":[{"stack": "Stack 0","cubicInterpolationMode":"monotone","fill":"origin","label":"Acquisitions by year","data":[10,20,50,20,10,5,70]},{"fill": "false","stack": "Stack 1","cubicInterpolationMode": "monotone","label": "Acquisitions by year","data": [10,20,50,20,10,5,70]}]}';
+0, gridP, 0) - IF(battP>0, battP, 0) > 0, -totalConsumption - IF(gridP>0, gridP, 0) - IF(battP>0, battP, 0), 0) AS Direktverbrauch,
+IF(battP>0, battP, 0) AS Batteriebezug,
+gridPcons AS Netzbezug,
+-totalConsumption AS Verbrauch,".
+//IF(battP<0, -battP, 0) AS Batterieladung,
+"soc AS Ladestand
+FROM solarLog.EnergyFlow
+WHERE EnergyFlow.datetime BETWEEN DATE_ADD(NOW(),INTERVAL ".($_GET["FROM"])." HOUR) and DATE_ADD(NOW(),INTERVAL ".$_GET["TO"]." HOUR)
+ORDER BY EnergyFlow.datetime";
+
+$simQuery = "SELECT
+UNIX_TIMESTAMP(simPower.period_end) AS time,
+power*1000 AS 'Vorhersage'
+FROM solarLog.simPower
+WHERE simPower.period_end BETWEEN DATE_ADD(NOW(),INTERVAL ".($_GET["FROM"])." HOUR) and DATE_ADD(NOW(),INTERVAL ".$_GET["TO"]." HOUR)
+ORDER BY simPower.period_end";
+$linecolors["Solarleistung"] = "#FFFF00";
+$linecolors["Direktverbrauch"] = "#FFcc00";
+$linecolors["Verbrauch"] = "#FFaa44";
+$linecolors["Auto UG"] = "#00aaFF";
+$linecolors["Auto OG"] = "#0044FF";
+$linecolors["Netzbezug"] = "#FF0000";
+$linecolors["Batteriebezug"] = "#00aa00";
+$linecolors["Batterieladung"] = "#0033aa";
+$linecolors["Einspeisung"] = "#b0b0b0";
+$linecolors["Ladestand"] = "#00aa00";
+$linecolors["Vorhersage"] = "#2222FF";
+
+
+
+if (checkLogin()) {
+
+ $mysql = new mysqli($mysql_server, $mysql_solarUser, $mysql_solarPass, $mysql_solarDB);
+ $result = mysqli_query($mysql, $consQuery);
+ $simRes = mysqli_query($mysql,$simQuery);
+ if(!$result){
+ echo "Error:
".mysqli_error($mysql)."
";
+ }
+ $obj = (object)[]; // Cast empty array to object
+ $obj->labels = [];
+ $obj->datasets = [];
+ $i = 0;
+ $filled = 0;
+ if ($simRes->num_rows > 1) {
+ $dataset = (object)[];
+ $row1 = $simRes->fetch_assoc();
+ $dataset->borderColor = $linecolors["Vorhersage"];
+ $dataset->backgroundColor = $linecolors["Vorhersage"]."55";
+ $dataset->borderWidth=1.5;
+ $dataset->pointRadius= 0;
+ $dataset->pointHoverRadius= 5;
+ $dataset->tension=0.2;
+ $dataset->stack = "sim";
+ $dataset->fill = "none";
+ $dataset->yAxisID = 'y';
+ $dataset->label = "Vorhersage";
+ /*$pt = (object)[];
+ $pt->x = $row["time"]*1000;
+ $pt->y = $row["Vorhersage"];
+ $dataset->data[] = clone $pt;
+ while ($row = $simRes->fetch_assoc()) {
+ $pt = (object)[];
+ $pt->x = $row["time"]*1000 + 30*60*1000;
+ $pt->y = $row["Vorhersage"];
+ $dataset->data[] = clone $pt;
+ }*/
+ $obj->datasets[] = clone $dataset;
+ $rownext = $simRes->fetch_assoc();
+ $nextSimTimestamp = $rownext["time"]*1000 + 30*60*1000;
+ }
+ if ($result->num_rows > 1) {
+ $ii = 1;
+ $row = $result->fetch_assoc();
+ foreach ($row as $name => $value) {
+ $dataset = (object)[];
+ if ($name != "time") {
+ $dataset->borderColor = $linecolors[$name];
+ $dataset->backgroundColor = $linecolors[$name]."22";
+ $dataset->borderWidth=1;
+ $dataset->pointRadius= 0;
+ $dataset->pointHoverRadius= 5;
+ $dataset->tension=0.2;
+ if ($name == "Solarleistung") {
+ $dataset->stack = "SolarPwr";
+ $dataset->fill = "none";
+ $dataset->yAxisID = 'y';
+ }else if ($name == "Verbrauch") {
+ $dataset->stack = "ConsPwr";
+ $dataset->fill = "1";
+ $dataset->yAxisID = 'y';
+ }else if ($name == "Batterieladung") {
+ $dataset->stack = "ConsPwr";
+ $dataset->fill = "-1";
+ $dataset->backgroundColor = $linecolors[$name]."77";
+ $dataset->yAxisID = 'y';
+ } else if ($name == "Ladestand") {
+ $dataset->stack = "Charge";
+ $dataset->fill = "none";
+ $dataset->yAxisID = 'y1';
+ } else {
+ $dataset->stack = "Consumers";
+ if ($filled == 0) {
+ $filled = 1;
+ $dataset->fill = "origin";
+ } else {
+ $dataset->fill = "-1";
+ }
+ $dataset->yAxisID = 'y';
+ }
+ $dataset->label = $name;
+
+ $dataset->data[] = $value;
+ $obj->datasets[] = clone $dataset;
+ $ii++;
+ } else {
+ $obj->labels[] = $value * 1000;
+ }
+ }
+ while ($row = $result->fetch_assoc()) {
+ $ii = 1;
+ foreach ($row as $name => $value) {
+ if ($name != "time") {
+ $obj->datasets[$ii]->data[] = $value;
+ $ii++;
+ } else {
+ if(($value * 1000) < $nextSimTimestamp){
+ $obj->datasets[0]->data[] = $row1["Vorhersage"];
+ }else{
+ $row1 = $rownext;
+ $rownext = $simRes->fetch_assoc();
+ $nextSimTimestamp = $rownext["time"]*1000 + 30*60*1000;
+ $obj->datasets[0]->data[] = $row1["Vorhersage"];
+ }
+ $obj->labels[] = $value * 1000;
+ }
+ }
+ }
+ }
+ $obj->labels[] = $nextSimTimestamp; //Draw future forecast
+ $obj->datasets[0]->data[] = $rownext["Vorhersage"];
+ while($rownext = $simRes->fetch_assoc()){
+ $obj->labels[] = $rownext["time"]*1000 + 30*60*1000;
+ $obj->datasets[0]->data[] = $rownext["Vorhersage"];
+ }
+}
+
+
+//header('Content-Type: application/json');
+echo json_encode($obj);
+//echo '{"labels":[1761322682000,1761322782000,1761322882000,1761322982000,1761323082000,1761323182000,1761323282000],"datasets":[{"stack": "Stack 0","cubicInterpolationMode":"monotone","fill":"origin","label":"Acquisitions by year","data":[10,20,50,20,10,5,70]},{"fill": "false","stack": "Stack 1","cubicInterpolationMode": "monotone","label": "Acquisitions by year","data": [10,20,50,20,10,5,70]}]}';
?>
\ No newline at end of file
diff --git a/ajax/getStats.php b/ajax/getStats.php
index c146b5e..8dc5104 100644
--- a/ajax/getStats.php
+++ b/ajax/getStats.php
@@ -1,211 +1,211 @@
- date("Y")){
- exit;
-}
-if(isset($_GET["type"])){
- if(strtolower($_GET["type"]) =="lastyear"){
- $_GET["year"] = date("Y")-1;
- }elseif(strtolower($_GET["type"]) =="prelastyear"){
- $_GET["year"] = date("Y")-2;
- }
-}
-
-/**
- * Die Jahresstatistik als eine Abfrage - jetzt auf stats_daily.
- *
- * Gerechnet wird nicht mehr ueber die Rohdaten aus EnergyFlow, sondern ueber
- * die Tageswerte. Zwei Gruende:
- *
- * 1. Die Rohdaten werden nach zwoelf Monaten ausgeduennt bzw. ins
- * Stundenarchiv verschoben (solarlog-rollup.sh). Eine Kachel, die auf
- * EnergyFlow rechnet, zeigt fuer alte Jahre danach zu wenig an.
- * 2. Ein Jahr sind 365 Zeilen statt rund 105.000.
- *
- * Die Tarife bleiben unveraendert: je Zeile ein Stichtag, das Ende holt
- * LEAD() beim naechsten. Weil ein Stichtag ein DATUM ist, kann ein Tag nie
- * zwei Tarife haben - die Verdichtung auf Tage verliert hier also nichts.
- *
- * Was in stats_daily vorberechnet sein MUSS, weil es eine Bedingung je
- * Messwert auswertet und sich aus Tagessummen nicht rekonstruieren laesst:
- *
- * eigenverbrauch_kwh pv - Einspeisung - Batterieladung
- * - Heizstab + Batterieentladung. Dazu addiert
- * wird pv_fehlbetrag_kwh: bei Ausfall einzelner
- * Wechselrichter fehlt deren Beitrag in pv, alle
- * Senken sind dagegen gemessen - die Differenz
- * faellt sonst zu klein oder negativ aus.
- * heizstab_solar_kwh Heizstab, anteilig nach autonomy
- * auto_*_solar_kwh Wallbox, anteilig nach autonomy - dem vom
- * Geraet in feiner Aufloesung gerechneten
- * Nicht-Netz-Anteil der Zufuhr
- *
- * Einheiten sind in stats_daily bereits bereinigt: PL*_EV und PL*_EVog
- * liefern Kilowatt, alle uebrigen Leistungsspalten Watt. In der alten
- * Abfrage stand das als /12 gegen /12000 nebeneinander.
- *
- * Die Solaranteile teilen jetzt durch NULLIF(...): ohne Ladung im Jahr kam
- * vorher 0/0 heraus.
- *
- * "Ersparnis Batterie" rechnet den Nutzen netto: was die entladene Energie
- * aus dem Netz gekostet haette, abzueglich der Verguetung, die fuer den zum
- * Laden verwendeten Strom entgangen ist. Brutto waere die Kachel zu
- * freundlich - der Speicher ist nicht umsonst zu fuellen.
- *
- * Achtung beim Lesen: "Verbrauchsersparnis" ist der GESAMTE Eigenverbrauch
- * zum Strompreis. "Ersparnis Batterie" und "Ersparnis Solarladung" sind
- * Teilmengen davon, nach Herkunft bzw. Verwendung herausgegriffen. Sie
- * duerfen nicht addiert werden.
- *
- * Der Grundpreis fehlt weiterhin bewusst - er haengt an den Tagen des
- * Jahres, nicht an einem Messwert, und kommt aus grundpreisImJahr() dazu.
- */
-function statistikAbfrage($jahr)
-{
- return "WITH
- preis AS (SELECT active_date, cost, gain,
- LEAD(active_date) OVER (ORDER BY active_date) AS folgt FROM gridCosts),
- gas AS (SELECT active_date, cost, kwhPerLitre,
- LEAD(active_date) OVER (ORDER BY active_date) AS folgt FROM gasCosts),
- sprit AS (SELECT active_date, cost, lPer100km, kwhPer100km,
- LEAD(active_date) OVER (ORDER BY active_date) AS folgt FROM fuelCosts)
-SELECT
- SUM(d.netz_bezug_kwh) AS 'Stromverbrauch',
- SUM(d.netz_bezug_kwh * preis.cost) AS 'Stromkosten',
- SUM((d.eigenverbrauch_kwh + IFNULL(d.pv_fehlbetrag_kwh,0)) * preis.cost) AS 'Verbrauchsersparnis',
- SUM(d.netz_einsp_kwh * preis.gain) AS 'Einspeisevergütung',
- SUM(d.heizstab_solar_kwh * gas.cost / NULLIF(gas.kwhPerLitre,0)) AS 'Ersparnis Heizung',
- SUM(d.batt_entladen_kwh * preis.cost - d.batt_laden_kwh * preis.gain) AS 'Ersparnis Batterie',
- SUM(d.autarkie_avg * d.stunden_erfasst) / NULLIF(SUM(d.stunden_erfasst),0) AS 'Ø Autarkie',
- SUM(d.auto_eg_kwh) AS 'Autoladung ges. EG',
- SUM(d.auto_eg_solar_kwh) / NULLIF(SUM(d.auto_eg_kwh),0) * 100 AS 'Autoladung Solar EG',
- SUM(d.auto_eg_solar_kwh * preis.cost) AS 'Ersparnis Solarladung EG',
- SUM(d.auto_eg_kwh * sprit.lPer100km / NULLIF(sprit.kwhPer100km,0)) AS 'Benzin gespart EG',
- SUM(d.auto_eg_kwh * sprit.lPer100km / NULLIF(sprit.kwhPer100km,0) * sprit.cost) AS 'Ersparnis Benzin EG',
- SUM(d.auto_og_kwh) AS 'Autoladung ges. OG',
- SUM(d.auto_og_solar_kwh) / NULLIF(SUM(d.auto_og_kwh),0) * 100 AS 'Autoladung Solar OG',
- SUM(d.auto_og_solar_kwh * preis.cost) AS 'Ersparnis Solarladung OG',
- SUM(d.auto_og_kwh * sprit.lPer100km / NULLIF(sprit.kwhPer100km,0)) AS 'Benzin gespart OG',
- SUM(d.auto_og_kwh * sprit.lPer100km / NULLIF(sprit.kwhPer100km,0) * sprit.cost) AS 'Ersparnis Benzin OG'
-FROM stats_daily d
- JOIN preis ON d.tag >= preis.active_date AND (preis.folgt IS NULL OR d.tag < preis.folgt)
- LEFT JOIN gas ON d.tag >= gas.active_date AND (gas.folgt IS NULL OR d.tag < gas.folgt)
- LEFT JOIN sprit ON d.tag >= sprit.active_date AND (sprit.folgt IS NULL OR d.tag < sprit.folgt)
-WHERE YEAR(d.tag) = " . intval($jahr) . ";";
-}
-
-$Query = statistikAbfrage($_GET["year"]);
-$PrevQuery = statistikAbfrage($_GET["year"] - 1);
-
-// Reihenfolge wie in der Abfrage, mit "Verg.+Einsp. Strom" an Stelle 4.
-$units = Array("kWh","€","€","€","€","€","€","%",
- "kWh","%","€","L","€",
- "kWh","%","€","L","€");
-// Nur bei Verbrauch und Kosten ist weniger besser.
-$LessIsBetter = array_merge([true, true], array_fill(0, count($units) - 2, false));
-
-function array_insert($array,$values,$offset) {
- return array_slice($array, 0, $offset, true) + $values + array_slice($array, $offset, NULL, true);
-}
-
-
-if (checkLogin()) {
-
- $html = "