IP-Symcon - Wie kann ich... 2.0

Quelle: Wochenschaltuhr (by agotthold)

<? 

function Schaltzeit ($Tag, $Beginn, $Ende) 
    { 
   $Beginn = mktime(substr ($Beginn,0,2), substr ($Beginn,3,5), 0, 0, 0, 0, -1); 
   $jetzt = mktime(date("H"), date("i"), 0, 0, 0, 0, -1); 
   $Ende = mktime(substr ($Ende,0,2), substr ($Ende,3,5), 0, 0, 0, 0, -1); 
   $heute = date ("N"); 
   $Tag = explode("-" ,$Tag); 
   $cntTag = count($Tag); 
    
   for ($a = 0; $a < $cntTag; $a++) 
       { 
            if ($Tag[$a] == $heute) 
              { 
          if ($Beginn < $Ende) 
               { 
               if ($Beginn <= $jetzt && $jetzt <= $Ende) 
                       { 
                          return true; 
                       } 
                  else 
                       { 
                       return false; 
                       } 
            } 
            else 
                    { 
                    if ($Beginn <= $jetzt || $jetzt <= $Ende) 
                     { 
                      return true; 
                      } 
                  else 
                       { 
                       return false; 
                      } 
               } 
           } 
       } 
   } 

//======================================================================================== 

if (Schaltzeit ("1-2-3-4-5", "20:00", "23:50")) 
    { 
    echo "Jetzt schalten wir Montag-Freitag von 20:00 - 23:50"; 
    } 
elseif (Schaltzeit ("6-7", "19:00", "20:00")) 
    { 
    echo "Jetzt schalten wir Samstag und Sonntag von 19:00 - 20:00"; 
    } 
elseif (Schaltzeit ("1-3-5", "19:00", "20:00")) 
    { 
    echo "Jetzt schalten wir Montag, Mittwoch und Freitag von 19:00 - 20:00"; 
    } 
?>

Über IPS_GetScriptThreads() erhält man Informationen über gerade laufende Scripte.

Hier ein Beispiel wie man die Laufzeit überwachen kann

Define ('MAX_RUNTIME', 300); // maximale Laufzeit in s 

//sleep (MAX_RUNTIME + 1); //zu Testzwecken 

//print_r (IPS_GetScriptThreads(IPS_GetScriptThreadList())); 
foreach (IPS_GetScriptThreads(IPS_GetScriptThreadList()) as $Thread){ 
    $ScriptID = $Thread['ScriptID']; 
    if ($ScriptID > 0){ 
        if ((time()-$Thread['StartTime']) > MAX_RUNTIME) { 
            // ..... hier kann man reagieren (Info, Reboot, ...) 
        } 
    } 
}  

<?
// Anzahl der Threads ausgeben
$Threads = IPS_GetScriptThreadList();
//print_r($Threads);


// Threads ausgeben
for($i=1;$i<=count($Threads);$i++) {
	//print_r(IPS_GetScriptThread($i));
	$ThreadArray[$i] = IPS_GetScriptThread($i);
	if ($ThreadArray[$i]['ScriptID'] != 0) {
		echo $ThreadArray[$i]['ScriptID'].PHP_EOL;
	}
}
?>

Alles mögliche zum Thema Datum, Uhrzeit, Wochentage, Monate, …

<?
// http://php.net/manual/de/function.date.php

$Uhrzeit = date("H:i:s");  // Stunde:Minute:Sekunde
echo "Aktuelle Uhrzeit = ".$Uhrzeit."
";

$Datum_Heute = date("d.m.Y");  // Tag.Monat.Jahr
echo "Das heutige Datum = ".$Datum_Heute."

";




// Befehle nur zu bestimmten Zeiten ausführen

if ((date("H") >= 12) AND (date("H") < 23)) {
	echo "Es ist zwischen 12.00 Uhr und 22.59 Uhr
";
}
else {
   echo "Es ist zwischen 23.00 Uhr und 11.59 Uhr
";
}

if ((date("d") >= 1) AND (date("d") <= 15)) {
	echo "Der heutige Tag liegt zwischen dem 1. und 15. des Monats
";
}
else {
	echo "Der heutige Tag liegt zwischen dem 16. und letzten Tag des Monats

";
}




// Mit Uhrzeiten/Tagen "rechnen"

$time = time();  // http://www.unixtimestamp.de/
echo "Der aktuelle Timestamp ist: ".$time."
";

$Datum1 = strtotime("01.01.2015");
$SekundenSeitDatum1 = $time - $Datum1;
echo "Seit dem 01.01.2015 sind $SekundenSeitDatum1 Sekunden vergangen
";
$MinutenSeitDatum1 = ($time - $Datum1) / 60;
echo "Seit dem 01.01.2015 sind ".(int)$MinutenSeitDatum1." Minuten vergangen
";
$StundenSeitDatum1 = ($time - $Datum1) / 60 / 60;
echo "Seit dem 01.01.2015 sind ".(int)$StundenSeitDatum1." Stunden vergangen
";
$TageSeitDatum1 = ($time - $Datum1) / 60 / 60 / 24;
echo "Seit dem 01.01.2015 sind ".(int)$TageSeitDatum1." Tage vergangen

";

if ($SekundenSeitDatum1 > 60) {
	echo "Seit dem 01.01.2015 sind mehr als 60 Sekunden vergangen

";
}





// Wochentage/Monate ausgeben

$Wochentage_Array = array(1=>"Montag",2=>"Dienstag",3=>"Mittwoch",4=>"Donnerstag",5=>"Freitag",6=>"Samstag",7=>"Sonntag");
$Wochentag_Heute = date("w");
$Wochentag = $Wochentage_Array[$Wochentag_Heute];
echo "Heute ist $Wochentag
";

$MonateArray = array(1=>"Januar",2=>"Februar",3=>"März",4=>"April",5=>"Mai",6=>"Juni",7=>"Juli",8=>"August",9=>"September",10=>"Oktober",11=>"November",12=>"Dezember");
$Monat_Heute = date("n");
$Monat = $MonateArray[$Monat_Heute];
echo "Wir haben den Monat $Monat
";
echo "Heute ist ".$Wochentag." der ".date("d").". ".$Monat;
?>

Basierend auf einem Skript von Raketenschnecke.

<?
// Skript einmal von Hand ausführen
$Check_Intervall = 60;  // Prüf-Intervall in Sekunden

if ($_IPS['SENDER'] == "Execute") {
    IPS_SetScriptTimer($_IPS['SELF'], $Check_Intervall);
}


$Threads = IPS_GetScriptThreadList();
$count = 0;

for($i=0;$i<count($Threads);$i++) {
    if (@IPS_GetScriptThread($i)['StartTime'] != 0) {
        $count++;
    }
}

$Auslastung = round(($count/count($Threads)), 1)*100;
echo "Die PHP-Threads haben eine Auslastung von $Auslastung%";

if ($Auslastung >= 80) {
   echo "!!!ACHTUNG!!! PHP-Threads haben eine Auslastung von $Auslastung%";
}
?>

Beispiel für LCN SKH :


<?
// SKH von Modul 7 auswerten.
// LCNPRO-Taste in M7 = 57 ff 01 (Byte 2 = $hb , Byte3 = $lb)
// $lb -  01 =kurz, 02=lang,03=los
// Skript wir bei Var Änderung von 58383  /*[LCN-Module\007\Befehl (0, 7)\Befehl]*/ aufgerufen.

$s_steuer = GetValue(58383 /*[LCN-Module\007\Befehl (0, 7)\Befehl]*/ );
       $hb = substr($s_steuer, 0, 3);
       $lb = substr($s_steuer, 3, 3);
	if ($hb  == 255)
	{
		if ($lb  == 1)
		{
			ZW_SwitchMode(14360  /*[zwave-Module\Z-Wave Switch (NodeID 006)Merten- Play3]*/,1);
		}
		if ($lb  == 2)
			{
			ZW_SwitchMode(14360  /*[zwave-Module\Z-Wave Switch (NodeID 006)Merten- Play3]*/,0);
			}

		if ($lb  == 4)
		{
			ZW_SwitchMode(22914  /*[zwave-Module\Z-Wave Switch (NodeID 005) Dbox]*/,1);
		}
		if ($lb  == 5)
			{
			ZW_SwitchMode(22914  /*[zwave-Module\Z-Wave Switch (NodeID 005) Dbox]*/,0);
			}
	 }
?>


<?
// Beispiel Messwerte ins LCN Display Zeile2 ("DT2")
$temp_aussen= GetValueFloat (34928  /*[LCN-Module\155-ix Gartenhütte\Values (90, 155)\01 HYT Temp.]*/   );
$feuchte_aussen = GetValueFloat (19873  /*[LCN-Module\155-ix Gartenhütte\Values (90, 155)\02 HYT Feuchte]*/);
$tau = GetValueFloat (30794  /*[LCN-Module\155-ix Gartenhütte\Values (90, 155)\03 HYT Taupunkt]*/);

$zeile='A'.$temp_aussen.'° '.' F'.$feuchte_aussen.'%  T'.$tau.'°';

$text=substr($zeile,0,12);
LCN_SendCommand(27686  /*[OG 140C|UPP GT4D (000,007)]*/ ,'GT','DT21'.$text);
$text=substr($zeile,12,12);
LCN_SendCommand(27686  /*[OG 140C|UPP GT4D (000,007)]*/ ,'GT','DT22'.$text);
$text=substr($zeile,24,12);
LCN_SendCommand(27686  /*[OG 140C|UPP GT4D (000,007)]*/ ,'GT','DT23'.$text);
$text=substr($zeile,36,12);
LCN_SendCommand(27686  /*[OG 140C|UPP GT4D (000,007)]*/ ,'GT','DT24'.$text);

//Anzeige ist : A11.7° F99.9% T11.7°
?>


<?
$StringVarID = 12345;  // ID deiner String Variable mit Variablenprofil "~TextBox" eintragen
$Zeilen = 50; // Anzahl der letzten X Zeilen die ausgelesen werden sollen


$filename="logfile.log";
$path=IPS_GetKernelDir()."logs\\"; // Windows
//$path = "/var/log/symcon/";   // Raspberry,UNIX,...
$LogFile = $path.$filename;


// Letzten X Zeilen vom Log auslesen und in Variable speichern
$LetztenXZeilen = readLastLinesOfFile($LogFile, $Zeilen);
$LetztenXZeilenString = implode("
",$LetztenXZeilen);  // für Ausgabe in HTMLBox muss "
" in "<br>" geändert werden
SetValueString($StringVarID, $LetztenXZeilenString);
echo $LetztenXZeilenString; // auskommentieren für Live-Betrieb


// Anzahl der Zeilen vom Log ausgeben lassen
$ZeilenAnzahl = countLines($LogFile);
echo "

Das Log hat aktuell $ZeilenAnzahl Zeilen.".PHP_EOL; // auskommentieren für Live-Betrieb



function readLastLinesOfFile($filePath, $lines) {
    $handle = fopen($filePath, "r");
    if (!$handle) {
        return array();
    }
    $linecounter = $lines;
    $pos = -2;
    $beginning = false;
    $text = array();
    while ($linecounter > 0) {
        $t = " ";
        while ($t != "
") {
            if(fseek($handle, $pos, SEEK_END) == -1) {
                $beginning = true;
                break;
            }
            $t = fgetc($handle);
            $pos--;
        }
        $linecounter--;
        if ($beginning) {
            rewind($handle);
        }
        $text[$lines-$linecounter-1] = str_replace(array("\r", "
", "	"), '', fgets($handle));
        if ($beginning) break;
    }
    fclose($handle);
    return array_reverse($text);
}


function countLines($file) {
	$lines = 0;
   $fh = fopen($file, 'r');
   while(fgets($fh)) {
   	$lines++;
   }
   return $lines;
}
?>

<?
$id1 = CreateVariableByName($_IPS['SELF'], "Temperatur", 2);
$id2 = CreateVariableByName($_IPS['SELF'], "Volts", 2);
$id3 = CreateVariableByName($_IPS['SELF'], "Clock", 2);

SetValue($id1 ,(exec("cat /sys/class/thermal/thermal_zone0/temp "))/1000);
SetValue($id2 ,(float)(substr(exec("vcgencmd measure_volts"),5)));
SetValue($id3 ,(int)((exec("cat  /sys/devices/system/cpu/cpu0//cpufreq/scaling_cur_freq")) / 1000));


function CreateVariableByName($id, $name, $type)
{
   $vid = @IPS_GetVariableIDByName($name, $id);
   if($vid===false) {
      $vid = IPS_CreateVariable($type);
      IPS_SetParent($vid, $id);
      IPS_SetName($vid, $name);
   }
   return $vid;
}

function CreateEventIDByName($id, $name, $type)
{
   $eid = @IPS_GetEventIDByName($name, $id);
   if($eid===false) {
      $eid = IPS_CreateEvent($type);
      IPS_SetParent($eid, $id);
      IPS_SetName($eid, $name);
   }
   return $eid;
}

?>

Beispiel mit einem Bewegungsmelder:

<?
// Geloggte Daten eines Bewegungsmelder aus dem Archiv auswerten
//
// Beispiel:
// Bewegungen vom 11.09.2015 (00:00:00 bis 23:59:59) auswerten
//
// !!ACHTUNG!! Da "Rohdaten" verwendet werden, kann die Auswahl eines größeren Zeitraumes eine erhöhte CPU-Auslastung verursachen!


$ArchiveID = IPS_GetInstanceListByModuleID('{43192F0B-135B-4CE7-A0A7-1475603F3060}')[0]; // Archiv Handler ID wird automatisch ausgelesen
$State_VarID_Bewegungsmelder = 12345 /*[Hardware\HomeMatic\Bewegungsmelder\B04 (Wohnzimmer vorne)\Sensor\MOTION]*/;  // Hier die Variablen ID (z.B. bei HomeMatic die "STATE" Variable eintragen
// Zeitraum bei AC_GetLoggedValues wird wie folgt angegeben (Stunde, Minute, Sekunde, Monat, Tag, Jahr)
$ZeitraumVON = mktime(0, 0, 0, 9, 11, 2015);     // Es kann auch date oder strtotime oder sonstiges verwendet werden
$ZeitraumBIS = mktime(23, 59, 59, 9, 11, 2015);  // Es kann auch date oder strtotime oder sonstiges verwendet werden
$LogDatenAR = AC_GetLoggedValues($ArchiveID, $State_VarID_Bewegungsmelder, $ZeitraumVON, $ZeitraumBIS, 0);
//print_r($LogDatenAR);

$Count = 0;
$Duration = 0;
foreach ($LogDatenAR as $LogWert) {
	if ($LogWert['Value'] == 1) {
	   $Count++;
	   $Duration = $Duration + $LogWert['Duration'];
	}
}

$DurationSek = $Duration;
$DurationMin = intval($Duration / 60);
$DurationStd = round($DurationMin / 60, 2);

echo "Es wurden $Count Bewegungs-Phasen erkannt.
Die Bewegungs-Phasen hatten eine Gesamtdauer von $DurationMin Minuten (= $DurationSek Sekunden = $DurationStd Stunden).";
?>

Beispiel mit einer Haustür:

<?
// Geloggte Daten einer Tür/eines Fenster aus dem Archiv auswerten
//
// Beispiel:
// Bewegungen vom 11.09.2015 (00:00:00 bis 23:59:59) auswerten
//
// !!ACHTUNG!! Da "Rohdaten" verwendet werden, kann die Auswahl eines größeren Zeitraumes eine erhöhte CPU-Auslastung verursachen!

$ArchiveID = IPS_GetInstanceListByModuleID('{43192F0B-135B-4CE7-A0A7-1475603F3060}')[0]; // Archiv Handler ID wird automatisch ausgelesen
$State_VarID_TuerFenster = 12345 /*[Hardware\HomeMatic\Tür-Fenster-Kontakt\KONTAKT03 (Haustür)\Kontakt\STATE]*/;  // Hier die Variablen ID (z.B. bei HomeMatic die "STATE" Variable eintragen
// Zeitraum bei AC_GetLoggedValues wird wie folgt angegeben (Stunde, Minute, Sekunde, Monat, Tag, Jahr)
$ZeitraumVON = mktime(0, 0, 0, 9, 11, 2015);     // Es kann auch date oder strtotime oder sonstiges verwendet werden
$ZeitraumBIS = mktime(23, 59, 59, 9, 11, 2015);  // Es kann auch date oder strtotime oder sonstiges verwendet werden
$LogDatenAR = AC_GetLoggedValues($ArchiveID, $State_VarID_TuerFenster, $ZeitraumVON, $ZeitraumBIS, 0);
//print_r($LogDatenAR);

$Count = 0;
$Duration = 0;
foreach ($LogDatenAR as $LogWert) {
	if ($LogWert['Value'] == 1) {
	   $Count++;
	   $Duration = $Duration + $LogWert['Duration'];
	}
}

$DurationSek = $Duration;
$DurationMin = intval($Duration / 60);
$DurationStd = round($DurationMin / 60, 2);

echo "Es wurden $Count Tür/Fenster-Öffnungen erkannt.
Die gesamte Öffnungsdauer beträgt $DurationSek Sekunden (= $DurationMin Minuten = $DurationStd Stunden).";
?>
	$location = IPS_GetLocation (IPS_GetParent ($_IPS['SELF']));
	$ALL_EVENTS = IPS_GetEventList ( );
   foreach ($ALL_EVENTS  as $key => $value)
   {
       $Pfad = " ".IPS_GetLocation ($value);
        if(strpos ($Pfad,$location) !=  0)
       {
			if(IPS_GetObject ($value)['ObjectType'] == 4)//Event
			{
				if(IPS_GetEvent ($value)['EventActive'])
				{
 					IPS_SetEventActive ($value,false);
				}
				else
				{
 					IPS_SetEventActive ($value,true);
				}
			}
			else
			{
			}
       }
       else
       {
       }
   }

<?
$TestTimestamp = strtotime("23.09.2015");

$Ausgabe = EN_DE_Date_Umwandler("D j. M Y", $TestTimestamp);
echo $Ausgabe;


function EN_DE_Date_Umwandler($DateSyntax, $Timestamp) {
	$trans = array(
		'Monday'    => 'Montag',
		'Tuesday'   => 'Dienstag',
		'Wednesday' => 'Mittwoch',
		'Thursday'  => 'Donnerstag',
		'Friday'    => 'Freitag',
		'Saturday'  => 'Samstag',
		'Sunday'    => 'Sonntag',
		'Mon'       => 'Mo',
		'Tue'       => 'Di',
		'Wed'       => 'Mi',
		'Thu'       => 'Do',
		'Fri'       => 'Fr',
		'Sat'       => 'Sa',
		'Sun'       => 'So',
		'January'   => 'Januar',
		'February'  => 'Februar',
		'March'     => 'März',
		'May'       => 'Mai',
		'June'      => 'Juni',
		'July'      => 'Juli',
		'October'   => 'Oktober',
		'December'  => 'Dezember'
	);
	$DEdate = strtr(date($DateSyntax, $Timestamp), $trans);
	return $DEdate;
}
?>
<?
// Beispiel um das Datum von jedem 2. Montag ausgeben lassen
$TagX = "Montag";  // Montag wird gesucht
$IntervallX = 2;   // Jeder 2.
$Jahr = 2015;      // Im Jahr 2015


$Counter = 1;
for ($MonatC = 1; $MonatC <= 12; $MonatC++) {
	$MonatTage = date("t", strtotime("01.$MonatC.$Jahr"));
	for ($TageC = 1; $TageC <= $MonatTage; $TageC++) {
	   $Wochentag = EN_DE_Date_Umwandler("l", strtotime("$TageC.$MonatC.$Jahr"));
	   if ($Wochentag == $TagX) {
			if ($Counter == $IntervallX) {
				$DatumAR[] = EN_DE_Date_Umwandler("d.m.Y", strtotime("$TageC.$MonatC.$Jahr"));
		      $Counter = 1;
	      }
	      else {
		      $Counter++;
		   }
	   }
	}
}

// AUSGABE DES ARRAY
print_r($DatumAR);

// AUSGABE EINZELN
foreach ($DatumAR as $DatumA) {
	echo $DatumA.PHP_EOL;
}



function EN_DE_Date_Umwandler($DateSyntax, $Timestamp) {
	$trans = array(
		'Monday'    => 'Montag',
		'Tuesday'   => 'Dienstag',
		'Wednesday' => 'Mittwoch',
		'Thursday'  => 'Donnerstag',
		'Friday'    => 'Freitag',
		'Saturday'  => 'Samstag',
		'Sunday'    => 'Sonntag',
		'Mon'       => 'Mo',
		'Tue'       => 'Di',
		'Wed'       => 'Mi',
		'Thu'       => 'Do',
		'Fri'       => 'Fr',
		'Sat'       => 'Sa',
		'Sun'       => 'So',
		'January'   => 'Januar',
		'February'  => 'Februar',
		'March'     => 'März',
		'May'       => 'Mai',
		'June'      => 'Juni',
		'July'      => 'Juli',
		'October'   => 'Oktober',
		'December'  => 'Dezember'
	);
	$DEdate = strtr(date($DateSyntax, $Timestamp), $trans);
	return $DEdate;
}
?>
<?
// Beispiel um das Datum von jedem 2. Montag PRO MONAT ausgeben lassen
$TagX = "Montag";  // Montag wird gesucht
$IntervallX = 2;   // Jeder 2.
$Jahr = 2015;      // Im Jahr 2015


$Counter = 1;
for ($MonatC = 1; $MonatC <= 12; $MonatC++) {
	$MonatTage = date("t", strtotime("01.$MonatC.$Jahr"));
	for ($TageC = 1; $TageC <= $MonatTage; $TageC++) {
	   $Wochentag = EN_DE_Date_Umwandler("l", strtotime("$TageC.$MonatC.$Jahr"));
	   if ($Wochentag == $TagX) {
			if ($Counter == $IntervallX) {
				$DatumAR[] = EN_DE_Date_Umwandler("d.m.Y", strtotime("$TageC.$MonatC.$Jahr"));
		      $Counter = 1;
	      }
	      else {
		      $Counter++;
		   }
	   }
	}
	$Counter = 1;
}

// AUSGABE DES ARRAY
print_r($DatumAR);

// AUSGABE EINZELN
foreach ($DatumAR as $DatumA) {
	echo $DatumA.PHP_EOL;
}



function EN_DE_Date_Umwandler($DateSyntax, $Timestamp) {
	$trans = array(
		'Monday'    => 'Montag',
		'Tuesday'   => 'Dienstag',
		'Wednesday' => 'Mittwoch',
		'Thursday'  => 'Donnerstag',
		'Friday'    => 'Freitag',
		'Saturday'  => 'Samstag',
		'Sunday'    => 'Sonntag',
		'Mon'       => 'Mo',
		'Tue'       => 'Di',
		'Wed'       => 'Mi',
		'Thu'       => 'Do',
		'Fri'       => 'Fr',
		'Sat'       => 'Sa',
		'Sun'       => 'So',
		'January'   => 'Januar',
		'February'  => 'Februar',
		'March'     => 'März',
		'May'       => 'Mai',
		'June'      => 'Juni',
		'July'      => 'Juli',
		'October'   => 'Oktober',
		'December'  => 'Dezember'
	);
	$DEdate = strtr(date($DateSyntax, $Timestamp), $trans);
	return $DEdate;
}
?>
<?
// Zeigt an, wann der Computer zuletzt gestartet wurde. Getestet unter Win7 und Win10
$uptime = IPS_Execute('cmd /c net statistics server | find /i "Statistik seit"', "", false, true);
preg_match('|seit(.*)|', $uptime, $matchuptime);
$uptime = substr($matchuptime[1], 1, -1);

echo "Server online seit: $uptime";
?>

Quelle: Archivkontrolle (by Nall chan)

Skript zum Löschen aller verwaisten Archiv-Einträge. Es werden alle Einträge aus dem Archiv gelöscht, wovon keine zugehörigen Variablen mehr existieren. Diese sind im Archiv meisten daran zu erkennen >> „Objekt #12345 existiert nicht“

Sollte die VariablenID in der Zwischenzeit neu vergeben worden sein, dann wird nichts gelöscht und man hat sich das Logging versaut :smiley: Wurde die ID an ein Skript oder ein anderes Objekt vergeben, dann wird dieser Name auch im Archiv angezeigt und fällt weniger auf, wird aber dann durch dieses entfernt.

Einfach das Skript unten einmal ausführen, dann wird einem angezeigt was gelöscht werden würden. Braucht man die alten Archiveinträge nicht mehr, dann kann man die Variable $Testlauf auf FALSE setzen und nach ein paar Sekunden/Minuten (je nach Anzahl) sind alle verwaisten Einträge weg :slight_smile:

<?
ini_set("max_execution_time", 600);

$Testlauf = true;  // Variable auf FALSE setzen, dann werden die Variablen wirklich aus dem Archiv gelöscht. Bei TRUE werden die Variablen-IDs nur angezeigt/ausgegeben, aber es wird nichts gelöscht!


$VarCount = 0;
$VarCountX = 0;
$AC_ID =  IPS_GetInstanceListByModuleID('{43192F0B-135B-4CE7-A0A7-1475603F3060}')[0];
$LoggedVarIDs = AC_GetAggregationVariables($AC_ID, true);
foreach ($LoggedVarIDs as $VarID)
{
    if (!IPS_VariableExists($VarID['VariableID'])) {
       $VarCount++;
       if ($Testlauf == true) {
            echo "INFO - Variable mit ID ".$VarID['VariableID']." existiert nicht!".PHP_EOL;
        }
        else {
            $deleted = AC_DeleteVariableData($AC_ID,$VarID['VariableID'],$VarID['FirstTime'],$VarID['LastTime']);
            if ($deleted !== true) {
                echo "FEHLER - Konnte Variable mit ID ".$VarID['VariableID']." nicht löschen!".PHP_EOL;
                $VarCountX++;
            }
        }
    }
}

if ($Testlauf == true) {
    echo "Es wurden $VarCount Archiv-Einträge mit nicht existierenden Variablen gefunden!".PHP_EOL;
}
else {
   echo "Es wurden $VarCount Archiv-Einträge mit nicht existierenden Variablen gelöscht!".PHP_EOL;
   echo "Es konnten $VarCountX Archiv-Einträge nicht gelöscht werden!".PHP_EOL;
}
?>
<?
$Duration = "2:01:03";  // 2 Stunden & 1 Minute & 3 Sekunden

$DurationAR = explode(":", $Duration);
$DurationSTD = (int)$DurationAR[0];
$DurationMIN = (int)$DurationAR[1];
$DurationSEK = (int)$DurationAR[2];
$DurationGesamt = $DurationSEK + ($DurationMIN * 60) + ($DurationSTD * 3600);

echo "$Duration entspricht $DurationGesamt Sekunden";
?>

Umgebung:
Wirksystem unter Windows mit IPS 3.4, auf dem Skripte erstellt werden.
Ein oder mehrere Raspis mit IPS 4.0, auf denen die verwendeten Skripte auf dem neuesten Stand gehalten werden sollen.

Skript:
Das nachfolgende Skript verwendet JSON, deshalb müssen Lizenz-Benutzernamen und das Fernzugriff Kennwort für jedes System zur Verfügung gestellt werden.
Es bietet sich an, diese Informationen in ein eigenes Skript zu schreiben, damit es beliebig in andere Skripte inkludiert werden kann, der Name (hier „ObjIDsLAN.inc.php“ ist bindend, da damit aufgerufen wird).
Für jedes IPS-System existiert ein Index-Eintrag in dem folgendes individuell eingetragen werden muß

  1. Name des Systems als Index
  2. ‚IP‘ => IP-Adresse
  3. ‚PW‘ => Fernzugriff Kennwort

Der Lizenz-Benutzername muß im Index-Eintrag ‚Svr1‘ unter ‚Li‘ eingetragen werden

<?
/*
 * File mit Kennwerten des LAN's für Devices.
 *
 * @file          ObjIDsLAN.inc.php
 * @author        Harald Hertlein
 * @version       21.09.15 00:09
 * Remark:        OS-unabhängig
 */

$LAN = array (//
    'Svr1'    => array (
        'IP'   => '192.168.0.6',
        'Port' => '80', // Port unter dem der PC per JSON erreichbar ist
        'Li'   => 'H?????@??????.de', // Lizenz-Nehmer
        'PW'   => '?????', // auf dem PC eingestelltes IPS-Paßwort
        'IPS'  => '3.40;12.08.15;#3775',
    ),
    'RaspiA1' => array (
        'IP'   => '192.168.0.81',
        'Port' => '3777',
        'PW'   => '?????',
        'IPS'  => '4.00;07.10.2015;b3ed15e7',
    ),
    'RaspiA2' => array (
        'IP'   => '192.168.0.82',
        'Port' => '3777',
        'PW'   => '????',
        'IPS'  => '4.00;06.10.2015;43cd1657489d',
    ),
);


?>

In das folgende Arbeitsskript muß dann nur noch der File-Name des zu übertragenden Skriptes und der/die PCs eingetragen werden, zu denen das Skript transferiert werden soll.

<?

/*
 * @file          IPS2Beitrag_SkriptTransfer.ips.php
 * @author        Harald Hertlein
 * @version       21.10.15 17:03
 *
 * Läuft auf dem zentralen Arbeitssystem und transferiert Skripte auf die Raspis
 *
 */


// Definiere erst mal die Parameter (PCs, Skript)
//$PC = 'RaspiA1';      // einer, wenn auskommentiert alle
$Skript = 'IPS2Beitrag_SkriptAgent.ips.php';
$StarteSkript = 1;  // wenn gesetzt, wird das Skript auf dem Remote-PC gestartet, sofern es dort benannt wurde


include_once "ObjIDsLAN.inc.php";
if (isset ($PC)) {
    $PCs = array ($PC);
} else {
    $PCs = array (
        'RaspiA1',
        'RaspiA2',
    );
}


foreach ($PCs as $PC) {
    $EAObj1 = @IPS_GetScriptIDByFile ($Skript);
    if ($EAObj1 === false) {
        echo "
Lokales Skript '$Skript' nicht gefunden!";
      return;
    } else {
        echo "

Lokales Skript '$Skript' hat die Objekt-ID " . $EAObj1;
    }

    // $rpc = new JSONRPC("http://user:password@'IP':'Port'/api/");
    $rpc = new JSONRPC ("http://" . $LAN['Svr1']['Li'] . ':' . $LAN[$PC]['PW'] . '@' . $LAN[$PC]['IP'] . ':' . $LAN[$PC]['Port'] . '/api/');

    // $EAObj2 = $rpc -> IPS_GetScriptIDByFile ($Skript); führt bei Nichtexistenz zu einem JSON-Fehler, deshalb
    $Liste = $rpc -> IPS_GetScriptList ();            // von hinten durch die Brust ins Auge
    $EAObj2 = false;
    foreach ($Liste as $SkriptID) {
        $GetScript = $rpc -> IPS_GetScript ($SkriptID);
        if ($GetScript['ScriptFile'] == $Skript) {
            $EAObj2 = $GetScript['ScriptID'];
            break;
        }
    }
    if ($EAObj2 === false) {
        echo "
Remotes Skript '$Skript' nicht gefunden!";
        $NameOK = false;
        $EAObj2 = $rpc -> IPS_CreateScript (0);                                         // Als ObjektName
        //$rpc -> IPS_SetName ($EAObj2, substr ($Skript, 0, stripos ($Skript, '.'))); // entweder gekürzten Datei-Namen
        $rpc -> IPS_SetName ($EAObj2, $Skript);                                     // oder vollen Datei-Namen (entsprechend auskommentieren)
        echo "
Remotes Skript '$Skript' angelegt mit der Objekt-ID " . $EAObj2 . " auf PC '$PC'";

        //$rpc -> rename (IPS_GetKernelDir () . 'scripts/' . $EAObj2 . '.ips.php', IPS_GetKernelDir () . 'scripts/' . $Skript); // diese Funktion crashed weil sie rename nicht findet
        //$rpc -> IPS_SetScriptFile ($EAObj2, $Skript);     // diese Funktion crashed, wenn $Skript nicht vorhanden, deshalb leider
        echo "
ACHTUNG!!: Remotes Skript '" . $EAObj2 . ".ips.php' auf PC '$PC' muß umbenannt werden in '$Skript'";
        $NameOK = false;
    } else {
        echo "
Remotes Skript '$Skript' hat die Objekt-ID " . $EAObj2 . " auf PC $PC";
        $NameOK = true;
    }

    $rpc -> IPS_SetScriptContent ($EAObj2, IPS_GetScriptContent ($EAObj1));
    if ($StarteSkript && $NameOK) {
        echo " und wird ausgeführt!!";
        $Msg = $rpc -> IPS_RunScriptWait ($EAObj2);
        print ("
---------- Meldung von PC $PC --------- 
$Msg--------------------------------------- 
");
    }
}

?>


Die für IPS zur Verfügung gestellte JSON-RPC API hat den Mangel, dass keine PHP-Befehle per Remote ausgeführt werden können. Wenn das zu transferierende Skript auf dem Ziel-PC noch nicht existiert, kann der File-Name nicht korrekt wiedergegeben werden.
Beim Ersttransfer eines Skriptes muß daher per Konsole auf dem Ziel-PC der File-Name korriegiert werden
Erfolgt dies nicht, wird beim nächsten Update ein neues Skript angelegt.
Existiert der File-Name, wird das entsprechende Skript upgedated.

Man kann sich aber durch das nachfolgende Agenten-Skript „IPS2Beitrag_SkriptAgent.ips.php“ behelfen:
Es wird

  1. das Agenten-Skript mit dem obigen Skript „IPS2Beitrag_SkriptTransfer.ips.php“ übertragen
  2. dann entsprechend der Aufforderung des Skriptes (ACHTUNG!!: Remotes Skript … auf PC … muß umbenannt werden ) auf den remoten PCs einmalig umbenennen.
  3. das Skript „IPS2Beitrag_SkriptTransfer.ips.php“ mit ‚$StarteSkript = 1‘ nochmal ausführen; damit wird/werden die Agenten-Skripte auf den remoten PCs ausgeführt und die darin konfigurierten Kategorien, Variablen, Skripte, Timer, Batchfiles für Linux angelegt.
  4. die dann noch auf den remoten PCs noch leeren Skripte mit dem obigen Skript „IPS2Beitrag_SkriptTransfer.ips.php“ befüllen (mehrfach mit ‚$StarteSkript = 0‘ und jeweils veränderter Variable $Skript für den Skript-Namen befüllen
<?

/*
 * @file          IPS2Beitrag_SkriptAgent.ips.php
 * @author        Harald Hertlein
 * @version       21.10.15 17:03
 *
 * Legt verschiedene Komponenten auf einem (remoten) IPS-System an:
 * Kategorien
 * Variablen
 * Skripte
 * Timer
 * Batchfiles für Linux
 *
 */


$Msg = '';

// ----------------- Konfigurationsanweisungen Start -----
// 1
$KAT = CreateCategory ('Name', 0, 100, 'Ident');
// 1.1
$VIS = CreateVariable ('Variable zur Visualisierung', 3, $KAT, 0, "~HTMLBox", null, '', '', "VIS");
// 1.2
$DTA = CreateVariable ('Variable zur Datenspeicherung', 3, $KAT, 1, "~String", null, '', '', "DTA");
IPS_SetHidden ($DTA, true);
// 1.3
$MON = CreateEmptyScript ('Anzeige-Skript', $KAT, 2, true, 'MON');    // Skript zur Anzeige, Position 2, Hidden
// 1.4
$ACT = CreateEmptyScript ('Ausführungs-Skript', $KAT, 3, true, 'ACT');    // Skript zur Ausführung
// 1.4.1
CreateTimer_CyclicByMinutes('Trigger', $ACT, 8, false);        // Timer, noch nicht aktiviert
// 1.4.2 ff
CreateEmptyScript ('Linux', $ACT, 2, false, '', 'sh');       // ein Batchfiles für Linux (Linux.sh)
// ----------------- Konfigurationsanweisungen Ende -----

echo $Msg;

function CreateCategory ($Name, $ParentId = 0, $Position = 0, $ident = "") {
    global $Msg;
    if ($ident == "")
        $ident = Trim_Ident ($Name);
    $ObjectId = @IPS_GetObjectIDByIdent ($ident, $ParentId);
    if ($ObjectId === false)
        $ObjectId = @IPS_GetVariableIDByName ($Name, $ParentId);
    if ($ObjectId === false) {
        $ObjectId = IPS_CreateCategory ();
        IPS_SetName ($ObjectId, $Name);
        IPS_SetParent ($ObjectId, $ParentId);
        IPS_SetPosition ($ObjectId, $Position);
        if ($ident)
            IPS_SetIdent ($ObjectId, $ident);
        $Msg .=  "$ObjectId ist neue Kategory '" . $Name . "' (Ident: " . $ident . ")
";
    }
    return $ObjectId;
}

/** Quelle IPSInstaller: Anlegen einer Variable (mod.) */
function CreateVariable ($Name, $Type, $ParentId, $Position = 0, $Profile = "", $Action = null, $ValueDefault = '', $Icon = '', $ident = "") {
    global $Msg;
    if ($ident == "")
        $ident = Trim_Ident ($Name);
    $ObjectId = @IPS_GetObjectIDByIdent ($ident, $ParentId);
    if ($ObjectId === false)
        $ObjectId = @IPS_GetVariableIDByName ($Name, $ParentId);
    if ($ObjectId === false) {
        $ObjectId = IPS_CreateVariable ($Type);
        IPS_SetName ($ObjectId, $Name);
        IPS_SetIdent ($ObjectId, $ident);
        IPS_SetParent ($ObjectId, $ParentId);
        IPS_SetPosition ($ObjectId, $Position);
        IPS_SetVariableCustomProfile ($ObjectId, $Profile);
        IPS_SetVariableCustomAction ($ObjectId, $Action);
        IPS_SetIcon ($ObjectId, $Icon);
        SetValue ($ObjectId, $ValueDefault);
        $Msg .=  "$ObjectId ist neue Variable '" . $Name . "' (Ident: " . $ident . ")
";
    }
    $VariableData = IPS_GetVariable ($ObjectId);
    if ($VariableData['VariableCustomProfile'] <> $Profile) {
        $Msg .=  "      VariableProfile '$Profile' für Variable '$Name'
";
        IPS_SetVariableCustomProfile ($ObjectId, $Profile);
    }
    if ($VariableData['VariableCustomAction'] <> $Action) {
        $Msg .=  "      VariableCustomAction '$Action' für Variable '$Name'
";
        IPS_SetVariableCustomAction ($ObjectId, $Action);
    }
    UpdateObjectData ($ObjectId, $Position, $Icon);
    return $ObjectId;
}

/** Quelle IPSInstaller: Anlegen eines Scriptes. (mod.) */
function CreateScript ($Name, $File, $ParentId, $Position = 0) {
    global $Msg;
    $ObjectId = @IPS_GetObjectIDByIdent (Trim_Ident ($Name), $ParentId);
    if ($ObjectId === false)
        $ObjectId = @IPS_GetScriptIDByName ($Name, $ParentId);
    if ($ObjectId === false) {
        $ObjectId = IPS_CreateScript (0);
        IPS_SetName ($ObjectId, $Name);
        IPS_SetIdent ($ObjectId, Trim_Ident ($Name));
        if ($File)
            IPS_SetScriptFile ($ObjectId, $File);
        IPS_SetParent ($ObjectId, $ParentId);
        IPS_SetPosition ($ObjectId, $Position);
        $Msg .=  "$ObjectId ist neues Script '" . $Name . "'
";
    }
    UpdateObjectData ($ObjectId, $Position);
    return $ObjectId;
}

function CreateEmptyScript ($Name, $ParentId, $Position = 0, $Hidden = true, $Ident = '', $Ext = 'ips.php') {
    global $Msg;
    if (file_exists (IPS_GetKernelDir () . '/scripts/' . $Name . '.' . $Ext)) {
        $ObjectId = @IPS_GetObjectIDByIdent ($ident, $ParentId);
        if ($ObjectId === false)
            $ObjectId = @IPS_GetVariableIDByName ($Name, $ParentId);
        return $ObjectId;
    }
    $ObjectId = CreateScript ($Name, '', $ParentId, $Position);
    if ($Ident)
        IPS_SetIdent ($ObjectId, $Ident);
    rename (IPS_GetKernelDir () . '/scripts/' . IPS_GetScript ($ObjectId)['ScriptFile'], IPS_GetKernelDir () . '/scripts/' . $Name . '.' . $Ext);
    IPS_SetScriptFile ($ObjectId, $Name . '.' . $Ext);
    IPS_SetHidden ($ObjectId, $Hidden);
    $Msg .= "      $Name.$Ext (Ident: $Ident)
";
    return $ObjectId;
}

/** Quelle IPSInstaller: Definieren "Minuten" Timer */
function CreateTimer_CyclicByMinutes($Name, $ParentId, $Minutes, $Active = true) {
    global $Msg;
    $ObjectId = @IPS_GetObjectIDByIdent(Trim_Ident($Name), $ParentId);
    if ($ObjectId === false)
        $ObjectId = @IPS_GetEventIDByName($Name, $ParentId);
    if ($ObjectId === false) {
        $ObjectId = IPS_CreateEvent(1 /* Cyclic Event */);
        IPS_SetName($ObjectId, $Name);
        IPS_SetIdent($ObjectId, Trim_Ident($Name));
        IPS_SetParent($ObjectId, $ParentId);
        if (!IPS_SetEventCyclic($ObjectId, 2 /* Daily */, 1 /* Unused */, 0 /* Unused */, 0/* Unused */, 2/* TimeType Minutes */, $Minutes/* Minutes */)) {
            $Msg .=  "IPS_SetEventCyclic failed !!!
";
            exit;
        }
        IPS_SetEventActive($ObjectId, $Active);
        $Msg .=  "$ObjectId ist neuer Timer '" . $Name . "'
";
    }
    return $ObjectId;
}

/** Quelle IPSInstaller (unzutreffenderweise Get_IdentByName: Ident aus Namen generieren) */
function Trim_Ident ($name) {
    $ident = str_replace (' ', '', $name);
    $ident = str_replace (array ('ö', 'ä', 'ü', 'Ö', 'Ä', 'Ü'), array ('oe', 'ae', 'ue', 'Oe', 'Ae', 'Ue'), $ident);
    $ident = str_replace (array ('"', '\'', '%', '&', '(', ')', '=', '#', '<', '>', '|', '\\'), '', $ident);
    $ident = str_replace (array (',', '.', ':', ';', '!', '?'), '', $ident);
    $ident = str_replace (array ('+', '-', '/', '*'), '', $ident);
    return $ident;
}


// ------------------------------------------------------------------------------------------------
function UpdateObjectData ($ObjectId, $Position, $Icon = "") {
    global $Msg;
    $ObjectData = IPS_GetObject ($ObjectId);
    $ObjectPath = IPS_GetLocation ($ObjectId);
    if ($ObjectData['ObjectPosition'] <> $Position and $Position !== false) {
        $Msg .=  "Set ObjectPosition='$Position' for Object='$ObjectPath' 
";
        IPS_SetPosition ($ObjectId, $Position);
    }
    if ($ObjectData['ObjectIcon'] <> $Icon and $Icon !== false) {
        $Msg .=  "Set ObjectIcon='$Icon' for Object='$ObjectPath' 
";
        IPS_SetIcon ($ObjectId, $Icon);
    }
}
?>


Achtung Falle !!
Wenn man ein auf einem Windows-PC ein für einen Linux-PC vorgesehenes Skript-File (*.sh) erstellt und dorthin überträgt, ist die Wahscheinlichkeit, dass es auf dem Linux-PC nicht korrekt abläuft, ziemlich hoch.
Grund: Die Text-Formate von Microsoft und dem Rest der Welt sind unterschiedlich und die Bash-Shell von Linux repariert das leider nicht!
Deshalb muß ein mit der obigen Methode übertragene Nicht-PHP-File auf dem Linux-PC „nachbearbeitet“ werden. Am besten geht das m.E. mit dem Tool Dos2Unix, das man sich folgendermaßen unter Linux installiert:

$ sudo apt-get install dos2unix

Auf neueren Windows-Systemen ist das Tool leider nicht installierbar.
Auch Text-Dateien (z.B. CRON-JOB Listen), die für Linux auf einem Windows-PC erstellt worden sind, müssen so nachbearbeitet werden!

Viel Spaß
Harald

Das folgende Skript z.B. mit dem Namen „WebhookBY.php“ im IP-Symcon Ordner unter /webfront/user abspeichern:

<?
if (isset($_GET["RUNScriptID"])) {
	$IPS_RunScriptID = (int)$_GET["RUNScriptID"];
	IPS_RunScript($IPS_RunScriptID);
	echo "Skript mit der ID ".$IPS_RunScriptID." wurde ausgeführt!";
}
elseif ((isset($_GET["SETVarID"])) AND (isset($_GET["SETVarVALUE"]))) {
	$IPS_SETVarID = (int)$_GET["SETVarID"];
	$IPS_SETVarVALUE = (int)$_GET["SETVarVALUE"];
	SetValue($IPS_SETVarID, $IPS_SETVarVALUE);
	echo "Die Variable mit der ID ".$IPS_SETVarID." wurde auf den Wert ".$IPS_SETVarVALUE." gesetzt!";
}
elseif (isset($_GET["GETVALVarID"])) {
	$IPS_GETVarID = (int)$_GET["GETVALVarID"];
	$GETWert = GetValue($IPS_GETVarID);
	echo "Die Variable mit der ID ".$IPS_GETVarID." hat den Wert '".$GETWert."'!";
}
?>

Dann kann man über die folgenden URLs ein Skript ausführen, den Wert einer existierenden Variable ändern oder den Wert einer Variable auslesen:
[b]

http://192.168.1.20:82/user/WebhookBY.php?SETVarID=22222&SETVarVALUE=25

[/b]

Variable mit ID 22222 auf Wert 25 setzen

[b]

http://192.168.1.20:82/user/WebhookBY.php?RUNScriptID=11111

[/b]

Skript mit der ID 11111 ausführen

[b]

http://192.168.1.20:82/user/WebhookBY.php?GETVALVarID=33333

[/b]
>> Wert der Variable 33333 auslesen

IP und PORT natürlich gegen die IP vom eigenen IPS-Server und dem zugehörigen WebFront Port austauschen.

<?
$HEXwert = "FABF";  // HEX-Wert
$BINwert = CS_hex2bin($HEXwert);

echo "HEX = $HEXwert // Binär = $BINwert";


function CS_hex2bin($str) {
    $build = '';
    $build = decbin(hexdec($str));
    $build = str_pad($build, 8,0, STR_PAD_LEFT);
    return $build;
}
?>