Soooo,
ich hab mir jetzt ein Workaround gebastelt.
Ist nicht 100%ig sauber (schon gar nicht gut programmiert, aber als Laie…), aber es geht.
Vermutlich war die Denksportaufgabe und das Umsetzten bis zum Ziel aufwendiger als die Werte manuell nach zu bearbeiten, aber es ging ja auch ums Prinzip 
Jetzt wo ich auf 4.0 upgedatet habe liegen die Geloggten Daten ja als CSV-Daten vor und lassen sich ganz einfach nachbearbeiten.
Ich hab ein Script gebastelt, das nach Vorgabe einiger Daten jeweils einen Monat „glättet“, bzw. wenn an einzelnen Tagen (Intervall bzw. Datendichte ist einstellbar) Daten fehlen (weil z.B. der datenlogger ausgefallen ist (kam bei mir des häufigeren vor)), mittelt das Programm Zwischenwerte aus den letzten bekannten realen Werten.
Mir machte beim Programmieren die Timestampegeschichte (UTC+1 etc) etwas Probleme, so ist es im Script an diesen Stellen auch ein wenig unsauber (und hingebastelt) ist, aber es geht wie man sieht:
Hier mein Script, falls es jemand gebrauchen kann. Irgendwo im Objektbau als script anlegen (reinkopieren), die notwenigen Anpassungen der ersten script-Zeilen mit BEDACHT!!! machen und starten.
Das Script legt sichterheitshalber eine Kopie der Ursprungsdatei an.
Die Daten des Folgemonats und des Vormonats muss man sich jeweils händisch aus der jeweiligen Datei holen. Könnte man auch noch automatisieren, dazu war ich bislang aber zu faul…
<?
/*******************************************************************************
Diese Script kann Lücken in Kummulierten Daten (Graphen) - wie
z.B. elektrische Leistungen - durch gemittelte Werte füllen, damit in
den Graphen nicht so "hässlich" Lücken entstehen und der erst wieder
gemessene Werte die y-Achse sprengt....
Klar kann das scipt nicht hellsehen, es tut so, als ob
zwischen letzten gemessenem Wert und dem ersten neunen Wert der Lücke
die Daten linear weiter gestiegen wären.
Achtung: Geht erst ab IPS4.0 (Daten liegen als CSV-Dateien vor)
Keine Garantie das es sauber läuft!!!!
Wichtig: in den ersten Zeilen dieses Script müssen ein paar Daten
zur Verfügung gestellt werden. 1. Die daten des zu korrigierenden Monats
und die ID der geloggten Variable.
Dann aus dem Vor und dem Folgemonat die letzten verfügbaren Timestamps und
entsprechenden Messwerte hier eintragen.
Das script legt sicherheitshalber eine Kopie der zu ändernden CSV-Datei
im ursprungsordner an. Ggf. einfach rückbenennen.
Autor: hardlog Stand 5.3.2106
*******************************************************************************/
// User Vorgaben: Müssen idividuell angepaßt werden !!!!
$Monat="01"; // zweistellige Angabe !! (ggf. mit führender "0" !!!
$Jahr="2016"; // vierstellige Jahreszahl
$VarID="50944";
$ArchivID=41474; // ID des ArchivHandler
$LetzterTimeStampVormonat=1451603315; // letzten Wert aus vorherigem Monat/CSV-Datei hier eintragen
$LetzterWertVormonat=14072.09; // letzten Wert aus vorherigen Monat/CSV-Datei hier eintragen
$ErsterTimeStampFolgemonat=1454286470; // ersten Wert aus folgender CSV-Datei hier eintragen
$ErsterWertFolgemonat=14514.11; //ersten Wert aus folgender CSV-Datei hier eintragen
$TSabstand=12; // Stundenzahl die zwischen den einzelnen Werten im schnitt liegen sollte (soviele werte werden neu generiert. Standard 12h
//******************************************************************************
// ****************** ab hier mauss nichts mehr verändert werden ***************
//******************************************************************************
$filePath=IPS_GetKernelDir()."db\\$Jahr\\$Monat\\$VarID.csv";
If (!file_exists($filePath)) {echo "Die Datei $filePath existiert nicht!"; Return;}
// Sicherheitslopie der ursprungsdatei im selben Verzeichnis erzeugen:
IPS_Execute("copy", $filePath." ".$filePath."_OLD", false, true);
// Rohdaten werden in Array geladen
$file_handle = fopen($filePath, "r");
$i=0;
while (!feof($file_handle) ) {
$line_of_text = fgetcsv($file_handle, 1024);
if ($line_of_text[1]<>"")
{
$CSVarray[$i]['TimeStamp']=$line_of_text[0];
$CSVarray[$i]['Wert']=$line_of_text[1];
$i=$i+1;
}
}
fclose($file_handle);
$rawCount=count($CSVarray); // Zahl der ursprünglichen Datensätze dieser Datei
// Auf Fehler etc. Prüfen ******************************************************
// gibts in den x ($TSabstand) ersten Stunden einen realen Wert? Sonst Fehlerausgabe!
if (((($CSVarray[0]['TimeStamp'])-mktime(2,0,0,date("m",$CSVarray[0]['TimeStamp']),1,date("Y",$CSVarray[0]['TimeStamp']))) > ($TSabstand*60*60)) and ($LetzterTimeStampVormonat==0))
{Echo "Monat beginnt ohne echte Werte. Bitte Prüfen, bzw. Werte in der Variable 'ManatsbeginnTS' und 'LetzterWertVormonat' in der User-Konfiguration (Anfang dieses Skriptes) vorgeben!"; Return;}
// gibts in den x ($TSabstand) letzten Stunden des Monats einen realen Wert? Sonst Fehlerausgabe!
if ( ( (mktime(23,0,0,date("m",$CSVarray[($rawCount-1)]['TimeStamp']),date("t",$CSVarray[($rawCount-1)]['TimeStamp']),date("Y",$CSVarray[($rawCount-1)]['TimeStamp']))-($CSVarray[($rawCount-1)]['TimeStamp'])) > ($TSabstand*60*60)) and ($ErsterTimeStampFolgemonat==0))
{Echo "Monat endet ohne echte Werte. Bitte Prüfen, bzw. Werte in der Variable 'ManatsabschlussTS' und 'ErsterWertFolgemonat' in der User-Konfiguration (Anfang dieses Skriptes) vorgeben!"; Return;}
// Wenn Monatsanfang uder Ende ein Problem sind, dann hier ertmal die Grenzwerte erzeugen und ins Array einfügen:
If (((($CSVarray[0]['TimeStamp'])-mktime(2,0,0,date("m",$CSVarray[0]['TimeStamp']-3600),1,date("Y",$CSVarray[0]['TimeStamp']-3600))) > ($TSabstand*60*60)) and ($LetzterTimeStampVormonat<>0))
{
if ($LetzterTimeStampVormonat>(mktime(2,0,0,date("m",$CSVarray[0]['TimeStamp']-3600),1,date("Y",$CSVarray[0]['TimeStamp']-3600)))) {echo "'LetzterTimeStampVormonat' nicht real!"; Return;}
$DifferenzMonatsende=mktime(23,0,0,date("m",$LetzterTimeStampVormonat),date("t",$LetzterTimeStampVormonat),date("Y",$LetzterTimeStampVormonat))-$LetzterTimeStampVormonat;
$DifferenzMonatsanfang=$CSVarray[0]['TimeStamp']-(mktime(2,0,0,date("m",$CSVarray[0]['TimeStamp']-3600),1,date("Y",$CSVarray[0]['TimeStamp']-3600)));
$BeginnAnteil=$DifferenzMonatsanfang/($DifferenzMonatsende+$DifferenzMonatsanfang);
$ersterWert=$CSVarray[0]['Wert']-(($CSVarray[0]['Wert']-$LetzterWertVormonat)*$BeginnAnteil);
if ($LetzterWertVormonat>$ersterWert) {echo "'ErsterWertFolgemonat' nicht real!"; Return;}
$ersterTS=(mktime(2,0,0,date("m",$CSVarray[0]['TimeStamp']-3600),1,date("Y",$CSVarray[0]['TimeStamp']-3600))); // Timestamp kurz vor Monatsende einfügen
array_unshift($CSVarray,array('TimeStamp'=> $ersterTS, 'Wert' => round($ersterWert,2)));
$rawCount=count($CSVarray);
}
If ( ( (mktime(23,0,0,date("m",$CSVarray[($rawCount-1)]['TimeStamp']-7200),date("t",$CSVarray[($rawCount-1)]['TimeStamp']-7200),date("Y",$CSVarray[($rawCount-1)]['TimeStamp']-7200))-($CSVarray[($rawCount-1)]['TimeStamp']-7200)) > ($TSabstand*60*60)) and ($ErsterTimeStampFolgemonat<>0))
{
if ($ErsterTimeStampFolgemonat<(mktime(23,0,0,date("m",$CSVarray[($rawCount-1)]['TimeStamp']-3600),date("t",$CSVarray[($rawCount-1)]['TimeStamp']-3600),date("Y",$CSVarray[($rawCount-1)]['TimeStamp']-3600)))) {echo "'ErsterTimeStampFolgemonat' nicht real!"; Return;}
$DifferenzMonatsende=(mktime(23,0,0,date("m",$CSVarray[($rawCount-1)]['TimeStamp']-3600),date("t",$CSVarray[($rawCount-1)]['TimeStamp']-3600),date("Y",$CSVarray[($rawCount-1)]['TimeStamp']-3600)))-$CSVarray[($rawCount-1)]['TimeStamp']-3600;
$DifferenzMonatsanfang=$ErsterTimeStampFolgemonat-(mktime(23,0,0,date("m",$CSVarray[($rawCount-1)]['TimeStamp']-3600),date("t",$CSVarray[($rawCount-1)]['TimeStamp']-3600),date("Y",$CSVarray[($rawCount-1)]['TimeStamp']-3600)));
$AbschlussAnteil=$DifferenzMonatsende/($DifferenzMonatsende+$DifferenzMonatsanfang);
$letzterWert=(($ErsterWertFolgemonat-$CSVarray[$rawCount-1]['Wert'])*$AbschlussAnteil)+$CSVarray[$rawCount-1]['Wert'];
if ($ErsterWertFolgemonat<$letzterWert) {echo "'ErsterWertFolgemonat' nicht real!"; Return;}
$CSVarray[$rawCount]['TimeStamp']=(mktime(23,0,0,date("m",$CSVarray[($rawCount-1)]['TimeStamp']-3600),date("t",$CSVarray[($rawCount-1)]['TimeStamp']-3600),date("Y",$CSVarray[($rawCount-1)]['TimeStamp']-3600))); // Timestamp kurz vor Monatsende einfügen
$CSVarray[$rawCount]['Wert']=round($letzterWert,2);
$rawCount=count($CSVarray);
}
// ab hier werden die Lücken innerhalb des Monats gefüllt
do { // diese schleife wiederholen, bis keine Lücke mehr!
$Holes=0;
//ersten möglichen Timestamp des akteullen Monats (der gewählten Datei) errechnen
$oldTS=$CSVarray[0]['TimeStamp'];
$oldWert=$CSVarray[0]['Wert'];
for ($i=0; $i<=count($CSVarray)-1; $i++)
{
if (($CSVarray[$i]['TimeStamp']-$oldTS)>($TSabstand*60*60)) // wenn ZEITlücke zwischen letztem und aktuellem wert > $TSabstand (s.o.) dann muss eine Lücke gefüllt werden
{
$Holes++;
$neuerTS=floor($CSVarray[$i]['TimeStamp']-(($CSVarray[$i]['TimeStamp']-$oldTS)/2)); // neuen TimeStamp bei der Häfte der Lücke (egal wie groß) setzten (wenn lücke dann immer noch > $TSabstand wird diese Funktion wiederholt...
$neuerWert=round($CSVarray[$i]['Wert']-(($CSVarray[$i]['Wert']-$oldWert)/2),2);
// neue Zeile in Array einschieben
$neuerEintrag=array("1"=> array('TimeStamp' => $neuerTS, 'Wert' => $neuerWert));
array_splice($CSVarray, $i, 0, $neuerEintrag); // setzt hinter $letzterRealerTS einen neuen
}
$oldTS=$CSVarray[$i]['TimeStamp'];
$oldWert=$CSVarray[$i]['Wert'];
}
} while ($Holes>0);
// geändert Daten in Ursprungs-Datei überschreiben
$file_handle = fopen($filePath, "w");
foreach ($CSVarray as $fields)
{
fputcsv($file_handle, $fields);
}
fclose($file_handle);
$reAgg=AC_ReAggregateVariable($ArchivID,$VarID);
echo "ursprüngliche Zeilenzahl: ".$rawCount.PHP_EOL; // Zahl der roh-Datensatzzeilen
echo "Zeilenzahl nach Korrektur: ".count($CSVarray)." (d.h.: ".(count($CSVarray)-$rawCount)." Wert(e) neu eingetragen)".PHP_EOL;
if ($reAgg==TRUE) echo "Die Variable $VarID wurde erfolgereich reaggregiert."; else {echo "Reaggregationsfehler!!!";}
?>
Gruß
hardlog