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>→</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;
}
?>