Statusvariablen-Log fürs WebFront

Hallo,

habe es jetzt mal getestet. Also wenn der entsprechende Wert im Profil als Association existiert, wird der zugeordnete Text im Log angezeigt in der zugeordneten Farbe. Wenn der Wert dort nicht existiert, erscheint stattdessen in weiß der Rohwert im Log.

Welches Verhalten würdest du denn besser finden?

Danke. Das Problem ist, dass bei einer Float-Variablen sehr viele Werte abgebildet werden können/sollen. Beispiel:

Bei einem Temperatur-Log im Bereich zwischen 0 und 30 C sind es bei den üblichen 0,1-Schritten 300 Werte. Im Profil einer Float-Variable lassen sich (unsbhängig von dem damit verbundenen Aufwand einer Einzeldefinition) nur 36 Werte definieren. Daher kann man in den Float-Profilen Wertbereiche zuordnen.

So habe ich z.B. die Werte 10 (grün zugewiesen) und 35 (rot zugewiesen) definiert und bei Text jeweils „%0.1f“ eingegeben, da ich dachte, dass der so definierte Wertbereich 10 bis 34) bei Deinem Skript in grün dargestellt wird.

Tatsächlich werden allerdings alle Werte außer 10 und 35 ohne Farbe mit dem definierten Suffix ausgegeben. Wenn der Wert der Variablen 10 bzw. 35 ist, wird zudem nicht der Wert, sondern der Inhalt von „Text“, also „%0.1f“, allerding korrekt in grün bzw. in rot ausgegeben (vgl. #16 dieses Threads: https://www.symcon.de/forum/threads/37449-Float-Variable-Farbe/page2).

Es wäre super, wenn das Skript die Werte innerhalb des definierten Wertebereiches (ebenfalls) farbig und alle als Wert ausgeben würde.

Ich hoffe, ich konnte das einigermaßen verständlich darstellen, ansonsten muss ich noch einmal nachlegen…

Aaach so… die Funktionalität kannte ich ja noch gar nicht :eek:

Ist ja cool, muss ich allerdings erst in das Skript einbauen. Wenn ich dazu komme… kann ich im Moment nicht versprechen, mit Glück dieses Wochenende.

Prima, vielen Dank…

Habe das Skript aktualisiert, probier mal damit und sag mir ob’s so funktioniert wie du es dir erhoffst.

Funktioniert super - das war es!

Vielen Dank noch einmal für das Skript und die Modifikationen, das ist echt genial…!!!

LG…

Gerne doch :slight_smile:

Habe Dein Script auch mal ausprobiert und es funktioniert im WebFront auch super. Da ich aber das Dashboard benutze möchte ich es hier nutzen. Wenn ich es im Webbrowser einfüge klappt es auch soweit, nur der Hintergrund der Tabelle ist leider immer weiss. wie kann ich das ändern?

Gelöscht, flascher Thread :wink:

Hallo sokkederheld,

daß Script funktioniert einwandfrei.

Einfach genial.

Vielen Dank für deine Mühe!!:slight_smile:

Gruß
Thomas

1 „Gefällt mir“

@gokart Ich beantworte die Frage jetzt hier im Thread, weil das Skript offenbar noch auf Interesse stößt und wenn ich hier antworte, potentiell auch andere etwas davon haben.

Du möchtest ein gemeinsames Log für mehrere Variablen anzeigen, welches aber nur wenige Einträge lang ist.

Um die Einzellogs der Variablen wegzulassen, kannst du bei allen Variablen den Konfigurationseintrag „single_log_size“ auf 0 setzen.

Beim Shared Log kannst du die Zahl der Einträge begrenzen indem du das Array $shared_logs_list anpasst:

$shared_logs_list = array(
	"test" => 25
);

Im Beispiel ist das Shared Log namens „test“ auf 25 Einträge begrenzt.

Was dein anderes Problem betrifft, müsste ich das Feature nachrüsten. Wenn ich richtig verstehe willst du bei deinen Bewegunsmeldern, dass nur jeweils die Auslösung angezeigt wird, aber nicht das Ende der Auslösung? Also nur der Übergang von false nach true, aber nicht der von true nach false?

Bei der Log-Anzeige von BM werden immer 2 Einträge pro Bewegung generiert. Dies ist auch richtig, weil ja auch 2 Einträge im Log vorhanden sind. Es wäre aber schön, wenn nur die Auslösung von false->true angezeigt wird. Damit wird das Log kürzer und auch übersichtlicher.
grafik

Beim Shared Log geht es um folgenden Wunsch/Idee:
Das Shared Log ist z.B. 60 Zeilen lang. Bin ich nur noch im Wohnzimmer, dann füllt sich das Shared Log mit den Einträgen des Bewegungsmelders „Wohnzimmer“ bis 60 mal der gleiche Eintrag steht.
Ich sehe nicht mehr, dass vor 20 Minuten eine Bewegung in der Garage war und vor 25 Minuten im Keller usw.
Im Sinne einer Überwachung wäre es im Shared Log aber interessant, wenn z.B. nur immer die 3 aktuellsten Logeinträge von jeder Aktivität angezeigt werden. Mit der vorhandenen Zeitangabe können auch die restlichen Aktivitäten im Log übersichtlich angeschaut werden.
Habe ich mich da Verständlich ausgedrückt?

Ich denke, ich verstehe. Finde es auch nicht uninteressant, aber es könnte etwas aufwändiger werden. Muss ich mir mal ansehen.

Versuch mal mit diesem Code. Entscheidend sind die neuen Parameter „suppress_value“ für die einzelne Variable, mit dem du einen bestimmten „Nichts passiert“-Wert festlegen kannst, sowie der Parameter „entries_per_variable“ für das $shared_logs_list-Array, mit dem du für das Shared Log festlegen kannst, wie viele Einträge maximal pro Variable im Log erscheinen. Siehe Definitionen im Code, wie du das Shared Log so konfigurierst.

Guck mal ob das für dich funktioniert und gib mir gerne Rückmeldung.

<?
// This is the list of variables you wish to display log fields for. Keys are
// variable ids to log, values are either:
//
// - the maximum number of entries to display in a log field for only this variable
// - the identifier of a shared log field defined in the $shared_logs_list
// - or an associative array containing the following keys:
//   "single_log_size" - number of entries for single variable log (same effect
//     as only supplying a number as the value of the list entry (see above)
//   "shared_log" - identifier of a shared log field. The same identifier must
//     exist as an entry in the $shared_logs_list, where further parameters of
//     the shared log field are supplied.
//   "name" - pretty name to display in shared log field (not used in single log
//     fields, as there is no such column in them!)
//   "display_old_value" - whether to display the old value in shared log field
//     entries for this variable
//
$var_list = array(
        43093 => array(
            "shared_log" => "motion_sensors",
            "name" => "WohnZ@Flurtür",
            "suppress_value" => false,
            "single_log_size" => 0,
        ),
        35928 => array(
            "shared_log" => "motion_sensors",
            "name" => "WohnZ@Mitte",
            "suppress_value" => false,
            "single_log_size" => 0,
        ),
        27896 => array(
            "shared_log" => "motion_sensors",
            "name" => "Bad EG",
            "suppress_value" => false,
            "single_log_size" => 0,
        ),
        42806 => array(
            "shared_log" => "motion_sensors",
            "name" => "Flur UG hinten",
            "suppress_value" => false,
            "single_log_size" => 0,
        ),
);

// This list contains parameters for shared log fields. Every such field must have
// an entry here. Keys are the identifiers of the fields defined, values are:
//
// - a number representing the maximum number of entries, or
// - an associative array containing the following keys:
//   "log_size" - number of entries, same effect as supplying a number only
// (may be enhanced in future versions of this script!)
//
$shared_logs_list = array(
    "motion_sensors" => array(
        "log_size" => 50,
        "entries_per_variable" => 3,
    ),
);

// After editing the lists, please execute the script in order to apply changes!


////////////////////////////////////////////////////////////////////////////////
// nothing needs to be edited below this line!

// determine whether the script is run manually in the console, in which case
// some debug output is generated and variable ids removed from the list will
// also have the corresponding events and fields removed
$debug = $_IPS['SENDER'] == 'Execute';

// retrieve id of archive control
$ac_id = IPS_GetInstanceListByModuleID('{43192F0B-135B-4CE7-A0A7-1475603F3060}')[0];

// remove log field and event for variables that have been removed from the list
if($debug) { // only when executing the script in the console!
	$children = IPS_GetChildrenIDs($_IPS['SELF']);
	foreach($children as $id) {
		$event = @IPS_GetEvent($id);
		if($event !== false && $event['EventType'] == 0) { // remove single variable log and variable event...
			$var_id = $event['TriggerVariableID'];
			if(!array_key_exists($var_id, $var_list)) {
				echo "Removing logging for variable \"" . @IPS_GetName($var_id) . "\" (ID " . $var_id . ")!\r";
				remove_var_event($var_id);
				remove_single_log_field($var_id);
			}
		} else { // remove shared log fields...
			$link = @IPS_GetLink($id);
			if($link !== false) {
				$field_id = $link['TargetID'];
				$obj = IPS_GetObject($id);
				$ident = $obj['ObjectIdent'];
				if(substr($ident, 0, 24) == 'StateVarLog_SharedField_') {
					$log_name = substr($ident, 24);
					if(!array_key_exists($log_name, $shared_logs_list)) {
						echo "Removing shared log field \"" . $log_name . "\"!\r";
						remove_shared_log_field($log_name);
					}
				}
			}
		}
	}
}

// array to hold history lists for shared log fields
$shared_history = array();

// cache for variable profiles
$profiles = array();

// process the variable list
foreach($var_list as $id => $parameters) {
	if($_IPS['SENDER'] == 'Variable') {
		if($id != $_IPS['VARIABLE'] && !have_shared_log($id, $_IPS['VARIABLE'])) continue;
	}
	
	$var = @IPS_GetVariable($id);
	
	if($var === false) { // check if variable found
		if($debug) echo "Variable with ID " . $id . " not found!\r";
		remove_var_event($id);
		remove_single_log_field($id);
		continue;
	}
	
	// allow a numeric value instead of an associative array to easily specify
	// the number of entries for a single variable log. For advanced parameters,
	// such as shared multiple variable logs an associative array has to be used.
	if(!is_array($parameters)) {
		if(is_int($parameters)) { // most simple case - single variable log with n entries
			$parameters = array("single_log_size" => $parameters);
		} else if(is_string($parameters)) {
			$parameters = array("shared_log" => $parameters);
		} else {
			if($debug) echo "Invalid parameter for variable \"" . @IPS_GetName($var_id) . "\"!\r";
			continue;
		}
	}
	
	ensure_var_event($id); // ensure there is an event for this variable
	$var_name = IPS_GetName($id);
	
	// if the type of the variable supports profiles with associations, try to
	// retrieve the association list so that log entries can be created with
	// text and color, rather than just bare values.
	$profile = false;
	$prof_name = $var['VariableCustomProfile'];
	if($prof_name == '') $prof_name = $var['VariableProfile'];
	
	if($prof_name != '') {
		if(!array_key_exists($prof_name, $profiles)) {
			$profile = @IPS_GetVariableProfile($prof_name);
			
			if($profile === false) {
				if($debug) echo "Profile \"" . $prof_name . "\" not found!\r";
			} else {
				$profiles[$prof_name] = $profile;
			}
		} else {
			$profile = $profiles[$prof_name];
		}
	}
	
	// logging must be activated for this variable in the archive control, make sure it is
	if(!AC_GetLoggingStatus($ac_id, $id)) {
		AC_SetLoggingStatus($ac_id, $id, true);
		IPS_ApplyChanges($ac_id);
	}
	// displaying a graph doesn't make much sense for variables that represent a
	// status, so disable graph display in the webfront for this variable
	if(AC_GetGraphStatus($ac_id, $id) && $profile !== false && count($profile["Associations"]) > 0) {
		AC_SetGraphStatus($ac_id, $id, false);
		IPS_ApplyChanges($ac_id);
	}
	
	// create and/or update single variable log, if so desired for this variable id
	if(array_key_exists('single_log_size', $parameters) && $parameters['single_log_size'] > 0) {
		// retrieve variable change history entries from archive control
		$var_history = AC_GetLoggedValues($ac_id, $id, 0, 0, $parameters['single_log_size']);
		
		$log_id = ensure_single_log_field($id); // ensure a log field exists for this variable and get its id
		
		// construct the html content for this log
		$log_content = generate_log($var_history, $prof_name);
		if($debug) echo $var_name . " Single Log:\r" . $log_content . "\r";
		SetValue($log_id, $log_content); // write into log field
	} else { // if no single log is desired, remove the log field
		remove_single_log_field($id);
	}
	
	// if this variable should be in a shared log
	if(array_key_exists('shared_log', $parameters)) {
		$log_name = $parameters['shared_log'];
		
		if(array_key_exists($log_name, $shared_logs_list)) {
			// allow for simplified $shared_logs_list structure - if an entries' value
			// is numeric, assume that it's the log's size.
			if(is_int($shared_logs_list[$log_name])) {
				$shared_logs_list[$log_name] = array("log_size" => $shared_logs_list[$log_name]);
			}
			
			// ensure a shared history array for this shared log exists
			if(!array_key_exists($log_name, $shared_history)) $shared_history[$log_name] = array();
			
			if(is_array($shared_logs_list[$log_name])) { // if log exists
				$log_size = $shared_logs_list[$log_name]["log_size"];

                // possibility to specify the maximum number of occurences per variable in a shared log
                $entries_per_variable = false;
				if(array_key_exists("entries_per_variable", $shared_logs_list[$log_name])) {
					$entries_per_variable = $shared_logs_list[$log_name]["entries_per_variable"];
				}
				
				// name of the entry will be variable name, or custom name if specified
				// within the variable list entries' parameters
				$name = $var_name;
				if(array_key_exists('name', $parameters)) $name = $parameters['name'];
				
				// determine whether to display the old value in the shared log. This
				// is enabled by default for numeric variables.
				$display_old_value = $var['VariableType'] != 3;
				if(array_key_exists("display_old_value", $parameters)) {
					$display_old_value = $parameters["display_old_value"];
				}

                // determine whether to colour the entry's name red for all values except the known "ok" (for error codes)
                $ok_value_used = false;
				if(array_key_exists("ok_value", $parameters)) {
					$ok_value = $parameters["ok_value"];
                    $ok_value_used = true;
				}

                // possibility to suppress a certain "idle" value from appearing as its own entry in the log
                $suppress_value_used = false;
				if(array_key_exists("suppress_value", $parameters)) {
					$suppress_value = $parameters["suppress_value"];
                    $suppress_value_used = true;
                    $display_old_value = false;
				}
				
				$var_history = AC_GetLoggedValues($ac_id, $id, 0, 0, $log_size + 1);
				foreach($var_history as $vhindex => $var_hist_entry_original) {
					if($vhindex == $log_size) break;
                    if($suppress_value_used && $suppress_value == $var_hist_entry_original["Value"]) continue;
                    if($entries_per_variable !== false) {
                        if($entries_per_variable > 0) {
                            $entries_per_variable--;
                        } else {
                            break;
                        }
                    }
					$var_hist_entry = array(
						"VariableId" => $id,
						"ProfileName" => $prof_name,
						"Name" => $name,
						"TimeStamp" => $var_hist_entry_original["TimeStamp"],
						"Value" => $var_hist_entry_original["Value"],
					);
					if($vhindex + 1 < count($var_history) && $display_old_value) {
						$var_hist_entry["OldValue"] = $var_history[$vhindex + 1]["Value"];
					}
                    if($ok_value_used) {
                        $var_hist_entry["FaultState"] = $var_hist_entry["Value"] != $ok_value;
                    }
                    if($suppress_value_used && $vhindex > 0) {
                        $var_hist_entry_next = $var_history[$vhindex - 1];
                        if($var_hist_entry_next["Value"] == $suppress_value) {
                            $var_hist_entry["UntilSuppressed"] = $var_hist_entry_next["TimeStamp"];
                        }
                    }
						
					$inserted = false;
					foreach($shared_history[$log_name] as $shindex => $shared_hist_entry) {
						if($var_hist_entry['TimeStamp'] > $shared_hist_entry['TimeStamp']) {
							array_splice($shared_history[$log_name], $shindex, 0, array($var_hist_entry));
							$inserted = true;
							break;
						}
					}
					if(!$inserted) array_push($shared_history[$log_name], $var_hist_entry);
					if(count($shared_history[$log_name]) > $log_size) array_pop($shared_history[$log_name]);
				}
			}
		} else { // if shared log name not found in $shared_logs_list
			if($debug) echo "Shared log \"" . $log_name . "\" not defined in shared logs list!\r";
		}
	}
}

foreach($shared_logs_list as $log_name => $parameters) {
	if(!is_array($parameters)) continue;
	if(!array_key_exists("log_size", $parameters)) continue;
	if(!array_key_exists($log_name, $shared_history)) continue;
	
	if($parameters['log_size'] <= 0) continue;
	
	$log_id = ensure_shared_log_field($log_name);
	
	// construct the html content for this log
	$log_content = generate_log($shared_history[$log_name]);
	if($debug) echo "Shared Log \"" . $log_name . "\":\r" . $log_content . "\r";
	SetValue($log_id, $log_content); // write into log field
}

// generate log as an html table string
function generate_log($history, $prof_name = "") {
	$result = '<table cellspacing=5 cellpadding=1>';
	foreach($history as $hist_entry) {
		$ts = $hist_entry['TimeStamp'];
		$val = $hist_entry['Value'];
		$time_str = date('j.n.y H:i:s', $ts);
		
		if(array_key_exists("ProfileName", $hist_entry)) {
			$prof_name = $hist_entry["ProfileName"];
		}
		
		$log_entry_str = '<tr><td>' . $time_str . "\t</td>";
        $name_colour_string = "aaaaaa";
		if(array_key_exists("FaultState", $hist_entry)) {
            $name_colour_string = $hist_entry["FaultState"] ? "ff0000" : "00ff00";
        }
		if(array_key_exists("Name", $hist_entry)) {
			$log_entry_str .= "<td><font color=\"#" . $name_colour_string . "\">" . $hist_entry["Name"] . "\t</font></td>";
		}
        $until_suppressed = false;
		if(array_key_exists("OldValue", $hist_entry)) {
			$old_val = $hist_entry["OldValue"];
			$log_entry_str .= format_value($old_val, $prof_name) . "<td>&rarr;</td>";
			$colspan = 1;
		} else if(array_key_exists("UntilSuppressed", $hist_entry)) {
			$until_suppressed = $hist_entry["UntilSuppressed"];
			$colspan = 1;
		} else {
			$colspan = 3;
		}
		$log_entry_str .= format_value($val, $prof_name, $colspan);
        if($until_suppressed !== false) {
            $time_str_until = date('H:i:s', $until_suppressed);;
			$log_entry_str .= "<td>bis " . $time_str_until . "</td>";
        }
		$log_entry_str .= "</tr>\r";
		$result .= $log_entry_str;
	}
	$result .= '</table>';
	return $result;
}

function format_value($val, $prof_name, $colspan = 1) {
	global $profiles;
	
	$color_str = "ffffff";
	$align = is_string($val) ? "left" : "right";
	$val_str = htmlentities($val);
	
	if(array_key_exists($prof_name, $profiles)) {
		$profile = $profiles[$prof_name];
		$val_str = $profile['Prefix'] . $val_str . trim($profile['Suffix']);
		$assocs = $profile['Associations'];
		$lastAssocVal = false;
		foreach($assocs as $assoc) { // if associations array supplied, use it to display colorful text rather than bare values!
			if($val >= $assoc['Value'] && ($lastAssocVal === false || $assoc['Value'] > $lastAssocVal)) {
				$lastAssocVal = $assoc['Value'];
				$val_str = sprintf($assoc['Name'], $val);
				$color_str = str_pad(dechex($assoc['Color']), 6, '0', STR_PAD_LEFT);
				$align = "left";
			}
		}
	}
	
	return "<td colspan=\"" . $colspan . "\"><div align=\"". $align . "\"><font color=\"#" . $color_str . "\">" . $val_str . "</font></div></td>";
}

function ensure_shared_log_field($log_name) {
	$ident = 'StateVarLog_SharedField_' . $log_name;
	
	// try to retrieve link to the log field for this variable
	$log_link_id = @IPS_GetObjectIDByIdent($ident, $_IPS['SELF']);
	
	if($log_link_id === false) {
		$log_id = @IPS_GetObjectIDByIdent($ident, IPS_GetParent($_IPS['SELF']));
	} else {
		// normally we get the log field's id by following the link
		$log_id = IPS_GetLink($log_link_id)['TargetID'];
	}
	
	if($log_id === false) {
		$log_id = IPS_CreateVariable(3);
		IPS_SetName($log_id, 'Shared Log ' . $log_name);
		IPS_SetParent($log_id, IPS_GetParent($_IPS['SELF']));
		IPS_SetIdent($log_id, $ident);
		IPS_SetVariableCustomProfile($log_id, '~HTMLBox');
	}
	
	// if no link to the log field exists, create one
	if($log_link_id === false) {
		$log_link_id = IPS_CreateLink();
		IPS_SetParent($log_link_id, $_IPS['SELF']);
		IPS_SetIdent($log_link_id, $ident);
	}
	@IPS_SetLinkTargetID($log_link_id, $log_id);
	
	return $log_id;
}

// remove shared log with the given log name
function remove_shared_log_field($log_name) {
	$ident = 'StateVarLog_SharedField_' . $log_name;
	$log_link_id = @IPS_GetObjectIDByIdent($ident, $_IPS['SELF']);
	
	if($log_link_id !== false) {
		$log_id = IPS_GetLink($log_link_id)['TargetID'];
		if($log_id !== false) IPS_DeleteVariable($log_id);
		IPS_DeleteLink($log_link_id);
	}
}

// Ensure a log field, as well as a link to it exist for the specified variable
// id. The link serves as a reference in case the log field gets moved around.
function ensure_single_log_field($var_id) {
	$ident = 'StateVarLog_Field_' . $var_id;
	
	// try to retrieve link to the log field for this variable
	$log_link_id = @IPS_GetObjectIDByIdent($ident, $_IPS['SELF']);
	
	if($log_link_id === false) {
		// if no link exists, we still try to retrieve the potential log field from
		// below the same parent as the variable - just to make this script a bit
		// more robust in case the link got manually deleted.
		$log_id = @IPS_GetObjectIDByIdent($ident, IPS_GetParent($var_id));
	} else {
		// normally we get the log field's id by following the link
		$log_id = IPS_GetLink($log_link_id)['TargetID'];
	}
	
	if($log_id === false) {
		// get the sorting position of the variable, so that the log field can be
		// put in the same position by default
		$pos = IPS_GetObject($var_id)['ObjectPosition'];
		
		$log_id = IPS_CreateVariable(3);
		IPS_SetName($log_id, IPS_GetName($var_id) . ' Log');
		IPS_SetParent($log_id, IPS_GetParent($var_id));
		IPS_SetIdent($log_id, $ident);
		IPS_SetPosition($log_id, $pos);
		IPS_SetVariableCustomProfile($log_id, '~HTMLBox');
	}
	
	// if no link to the log field exists, create one
	if($log_link_id === false) {
		$log_link_id = IPS_CreateLink();
		IPS_SetParent($log_link_id, $_IPS['SELF']);
		IPS_SetIdent($log_link_id, $ident);
	}
	@IPS_SetLinkTargetID($log_link_id, $log_id);
	
	return $log_id;
}

// Remove log field (and the link to it) for the specified variable id.
function remove_single_log_field($var_id) {
	$ident = 'StateVarLog_Field_' . $var_id;
	$log_link_id = @IPS_GetObjectIDByIdent($ident, $_IPS['SELF']);
	
	if($log_link_id !== false) {
		$log_id = IPS_GetLink($log_link_id)['TargetID'];
		if($log_id !== false) IPS_DeleteVariable($log_id);
		IPS_DeleteLink($log_link_id);
	}
}

// Ensure that a change event exists for the specified variable id, and return
// the event id.
function ensure_var_event($var_id) {
	$ident = 'StateVarLog_Event_' . $var_id;
	
	$event_id = @IPS_GetObjectIDByIdent($ident, $_IPS['SELF']);
	if($event_id === false) {
		$event_id = IPS_CreateEvent(0);
		IPS_SetParent($event_id, $_IPS['SELF']);
		IPS_SetEventTrigger($event_id, 1, $var_id);
		IPS_SetEventActive($event_id, true);
		IPS_SetIdent($event_id, $ident);
	}
	
	return $event_id;
}

// Remove change event for the specified variable id.
function remove_var_event($var_id) {
	$ident = 'StateVarLog_Event_' . $var_id;
	
	$event_id = @IPS_GetObjectIDByIdent($ident, $_IPS['SELF']);
	if($event_id !== false) {
		IPS_DeleteEvent($event_id);
	}
}


// determine whether there is a shared log containing both specified variable ids
function have_shared_log($id1, $id2) {
	global $var_list;
	
	if(!array_key_exists($id1, $var_list)) return false;
	if(!array_key_exists($id2, $var_list)) return false;
	
	$parameters1 = $var_list[$id1];
	$parameters2 = $var_list[$id2];
	
	$shared_log_name_1 = false;
	if(is_string($parameters1)) {
		$shared_log_name_1 = $parameters1;
	} else if(is_array($parameters1) && array_key_exists("shared_log", $parameters1)) {
		$shared_log_name_1 = $parameters1['shared_log'];
	}
	
	$shared_log_name_2 = false;
	if(is_string($parameters2)) {
		$shared_log_name_2 = $parameters2;
	} else if(is_array($parameters2) && array_key_exists("shared_log", $parameters2)) {
		$shared_log_name_2 = $parameters2['shared_log'];
	}
	
	if($shared_log_name_1 === false || $shared_log_name_2 === false) return false;
	
	return $shared_log_name_1 == $shared_log_name_2;
}


?>

Danke sokkerheld, das ging aber schnell.
Habe das Script eingebaut und die zwei neuen Funktionen scheinen zu funktionieren. Ich werde das Verhalten noch weiter anschauen. Hier mal ein Screen-Shot:


EG Türe und EG Eingang haben noch keine neuen Parameter, deshalb noch die true->false Anzeige. Wohnzimmer und OG haben eine Beschränkung auf 3 Anzeigen.
:+1:

Deine Präsenzmelder sind ja sehr flink. Ich habe das mit meinen getestet, die viel träger eingestellt sind (weil ich sie für Lichtsteuerung nutze). Aber bei deinen würde es ggf. schöner aussehen wenn „für n Sekunden“ da stehen würde statt der Uhrzeit.

Ich persönlich würde diese Zeitangabe wegnehmen. Meine Präsenzmelder haben vermutlich nie länger als 3 Sekunden um den Status zu wechseln. Auch ich verwende die PM für die Lichtsteuerung (LCN). True schaltet das Licht sofort ein, false startet den individuellen Timer für die Abschaltung der Beleuchtung.

Ich kann das ja noch konfigurierbar machen. Du hast jetzt allerdings bei mir einige Gedanken angestoßen :smiley:

Habe bei mir mal die Variante eingebaut, wo die abgelaufene Zeit zur letzten Aktivität angezegt wird: