ich mache von meiner Kamera Snapshots und speichere die als Medinobjekt ab, gecached wird das ganze auch noch.
Ich lösche nach einer Variable (maxAnzahl) immer den ältesten Snapshot aus dem Array, das funktioniert auch wunderbar.
Aber wenn ich IPS neustarte, wirft es die Snapshots durcheinander, die Reihenfolge passt nicht mehr.
Ist das ein Problem an meinem Skript? Oder ist das ein Problem von IPS?
Ich hatte früher das Instar Modul von Fonzo, da war es das selbe.
Ich bin auf 6.4 unterwegs.
Vielleicht kann mir jemand weiter helfen.
Das ist mein Skript.
<?php
$Anzahl_Snapshots = GetValueInteger(24200);
$name = "Kamera Einfahrt";
$ident = "InstarEinfahrt";
//Für Instar 9008 FHD
//$Content = file_get_contents("http://Hans:Wurscht@192.168.17.1/tmpfs/snap.jpg");
//Für Instar 9408 FHD WQHD
$Content = file_get_contents("http://192.168.1.1/snap.cgi?chn=11&user=Hans&pwd=Wurscht");
$filename = time(); //Jede Bild mithilfe von Unix Timestamp unterschiedlich bennennen, damit die Bilder krorrekt in IPS WF. bei Neustart zurückgeladen werden
$picturename ="$filename";
//$picturename ="Snapshot Kamera Einfahrt";
$catid = 50614;
$MediaID = IPS_CreateMedia(1); // Image im MedienPool anlegen
IPS_SetParent($MediaID, $catid); // Medienobjekt einsortieren unter Kategorie $catid
IPS_SetIdent ($MediaID, $ident.time()); // Unix Timestamp als Ident setzen
IPS_SetPosition($MediaID, -time()); // Unix Timestamp invertieren, somit wird der letze Snapshot im Webfront als erster angezeigt
IPS_SetMediaCached($MediaID, true);
// Das Cachen für das Mediaobjekt wird aktiviert.
// Beim ersten Zugriff wird dieses von der Festplatte ausgelesen
// und zukünftig nur noch im Arbeitsspeicher verarbeitet.
$ImageFile = IPS_GetKernelDir()."media".DIRECTORY_SEPARATOR."instar".DIRECTORY_SEPARATOR.$picturename.".jpg"; // Image-Datei
IPS_SetMediaFile($MediaID, $ImageFile, False); // Image im MedienPool mit Image-Datei verbinden
$savetime = date('d.m.Y H:i:s');
IPS_SetName($MediaID, $name." ".$savetime); // Medienobjekt benennen
//IPS_SetName($MediaID, $name." ".$i); // Medienobjekt benennen
//IPS_SetInfo ($MediaID, $savetime);
IPS_SetMediaContent($MediaID, base64_encode($Content)); //Bild Base64 codieren und ablegen
IPS_SendMediaEvent($MediaID); //aktualisieren
//Handling Anzahl der Snapshots
$Ausgabe_Array = IPS_GetObject($catid); //Array des Parents einsammeln
print_r ($Ausgabe_Array); //Ausgabe zum testen
$ID = $Ausgabe_Array['ChildrenIDs']['0']; //ID die gelöscht werden soll ermitteln
$Anzahl = count($Ausgabe_Array['ChildrenIDs']); //Ist- Anzahl vom Array Index ermitteln
//Wenn Arrayindex größer als $Anzahl_Snapshots ist, Index [0] raus löschen
if ($Anzahl >= $Anzahl_Snapshots)
{
IPS_DeleteMedia($ID, true); //Index 0 raus löschen
}
print_r ($Anzahl);
//print_r ($ID);
//$ID = 0;
also es scheint so, dass es auf der Festplatte sowie im Objektbaum von IPS mit der Reihenfolge passt.
Das Durcheinander habe ich im Array von $Ausgabe_Array = IPS_GetObject($catid); //Array des Parents einsammeln
Hier stimmt alles bis ein Neustart von IPS durchgeführt wird.
Da ich aktuell ab 200 Snapshots den Index 0 vom Array entferne, würde das Skript das Medianobjekt mit der ID 21746 entfernen, weil das ja beim nächsten ausführen auf Index 0 rutscht.
ID 21746 liegt aber irgendwo mitten drin, es ist nicht der älteste Snapshot, siehe Screenshot.
Der Index hat nichts mit irgendeiner Reihenfolge zu tun. Der ist rein willkürlich.
Das ältestes Objekt zu ermitteln musst du selbst lösen, zum Beispiel über den Ident den du setzt oder die Position.
Michael
Hi nall-chan,
aha, dass bringt jetzt Licht ins dunkle.
Warum funktioniert es dann so lange IPS läuft, es ist erst nach einem Neustart durcheinander.
Wird das Array bei neustart neu sortiert?
Nicht beim Neustart, sondern weil du Objekte entfernt und hinzufügst, wird es während der Laufzeit verändert und somit quasi durch dein Script sortiert.
Michael
Ich verstehs zwar noch nicht ganz, weil wenn ich von null anfange uns führe das Skript per Hand aus, wir immer ein neuer Snapshot erstellt und der älteste also Array Index [0] rausgelöscht.
Das kann ich beliebig oft machen, es funktioniert wie gewünscht, bis ich IPS neustarte.
Ich versuche jetzt mal nach Datum den ältesten Snapshot zu löschen, dann sollte das Problem behoben sein.
Ich weiß zwar noch nicht wie ich das anstelle. Falls ich Hilfe brauche melde ich mich.
Was hältst du davon einfach das Array sauber nach der Position (die du ja schön setzt) zu sortieren?
Die Sortierung von GetChildrenIDs ist laut Dokumentation willkürlich. (Aktuelle Implementation ist bei Neustart nach IDs sortiert, während der Laufzeit führen wir einfach neue Objekte hinten dran. Laut Doku ist das aber kein Verhalten auf das man sich verlassen darf.)
Also dann werde ich versuchen das array von den childrens zu sortieren, so das dass älteste Foto auf index 0 liegt.
Somit sollte das richtige Löschen alter Fotos funktionieren.
Ich setze es auf meine to do Liste und berichte dann mal.
Also ich habe mich jetzt nochmal mit dem ganzen beschäftigt und ich denke das Ergebnis passt.
Folgender Code arbeitet das ganze bei mir ab.
<?php
$Anzahl_Snapshots = GetValueInteger(24200);
$name = "Kamera Einfahrt";
$ident = "InstarEinfahrt";
//Für Instar 9008 FHD
//$Content = file_get_contents("http://Hans:Wurscht@192.168.17.1/tmpfs/snap.jpg");
//Für Instar 9408 FHD WQHD
$Content = file_get_contents("http://192.168.1.1/snap.cgi?chn=11&user=Hans&pwd=Wurscht");
$filename = time(); //Jede Bild mithilfe von Unix Timestamp unterschiedlich bennennen, damit die Bilder krorrekt in IPS WF. bei Neustart zurückgeladen werden
$picturename ="$filename";
//$picturename ="Snapshot Kamera Einfahrt";
$catid = 50614;
$MediaID = IPS_CreateMedia(1); // Image im MedienPool anlegen
IPS_SetParent($MediaID, $catid); // Medienobjekt einsortieren unter Kategorie $catid
IPS_SetIdent ($MediaID, $ident.time()); // Unix Timestamp als Ident setzen
IPS_SetPosition($MediaID, -time()); // Unix Timestamp invertieren, somit wird der letze Snapshot im Webfront als erster angezeigt
IPS_SetMediaCached($MediaID, true);
// Das Cachen für das Mediaobjekt wird aktiviert.
// Beim ersten Zugriff wird dieses von der Festplatte ausgelesen
// und zukünftig nur noch im Arbeitsspeicher verarbeitet.
$ImageFile = IPS_GetKernelDir()."media".DIRECTORY_SEPARATOR."instar".DIRECTORY_SEPARATOR.$picturename.".jpg"; // Image-Datei
IPS_SetMediaFile($MediaID, $ImageFile, False); // Image im MedienPool mit Image-Datei verbinden
$savetime = date('d.m.Y H:i:s');
IPS_SetName($MediaID, $name." ".$savetime); // Medienobjekt benennen
//IPS_SetName($MediaID, $name." ".$i); // Medienobjekt benennen
//IPS_SetInfo ($MediaID, $savetime);
IPS_SetMediaContent($MediaID, base64_encode($Content)); //Bild Base64 codieren und ablegen
IPS_SendMediaEvent($MediaID); //aktualisieren
//Handling Anzahl und Reihenfolge der Snapshots
foreach(IPS_GetChildrenIDs($catid) as $objectID) //Ids ermitteln
{
$object = IPS_GetObject($objectID);
$objectList[$object["ObjectID"]] = $object["ObjectPosition"]; //Id der Snapshots mit den Positionen verbinden, das sollte analog zum Objektbaum sein
}
asort($objectList); // in aufsteigender Reihenfolge sortieren
print_r($objectList); //array ausgeben
$Anzahl = count($objectList);
print_r($Anzahl);
if ($Anzahl >= $Anzahl_Snapshots) {
//Anzahl Bilder welche gelöscht werden müssen
$objectList_del = $objectList; //Array der ID,s und Positionen umkopieren
arsort($objectList_del); //Array absteigend, gegenläufig zu $objectList sortieren
print_r($objectList_del);
$objectList_del2 = array_keys($objectList_del); //Nur keys also die ID, ausgeben weil danach die Medienobjekte identifiziert werden...
print_r($objectList_del2);
$delCount = count($objectList) - ($Anzahl_Snapshots); //Überhang an zu vielen Snapshots errechnen
for ($i = 0; $i <= $delCount; $i++) {
IPS_DeleteMedia($objectList_del2[$i], true); //Überhang an Medienabjekten anhand der ID und des Index rauslöschen.
}
}
Könnte das evtl. ein Experte beurteilen ob das so taugt, meine PHP Fähigkeiten sind nicht die besten.
Was mir noch aufgeallen ist, in den Arrays $ObjectList usw steht immer ein Medienobjekt drin welches im Objektbaum eigentlich schon gelöscht wurde.
Siehe Screenshots, woran liegt liegt das???
Hier wurde jetzt AnzahlSnapshots auf 5 eingestellt
Wenn ich das bei mir durchlaufen lasse ein paar Mal bei MaxSnapshots = 5, dann habe ich im Array auch 5 IDs aber nur 4 erstellte Mediadateien… Die zuletzt gelöschte steht noch im Array und nimmt praktisch den „Platz“ weg.
Mal so aus ganz Nicht-Experten-Sicht Oh ja, hattest Du ja schon geschrieben, sorry!
PS: Wenn hier jemand noch eine Zeile PHP hätte, wie man die (In meinem Beispiel) 5 Bilder in 5 bestehende Mediendateien kopieren könnte wäre das ein ziemlich gutes Wochenende! Stichwort Mediengalerie und feste ID’s…