WebFront Manager - Reduzierte Kopien eines WebFronts verwalten

Heute möchte ich ein simples Skript teilen, mit dem ich meine WebFronts verwalte.

Es gibt bei mir ein iPad in der Küche, welches neben dem Kühlschrank hängt und auf dem permanent ein WebFront läuft. Das werden viele so oder ähnlich haben :smiley:

Ich möchte allerdings nicht, dass bestimmte Menüs auf diesem WebFront angezeigt werden, bzw. nicht immer. Ich möchte in Zukunft auch noch weitere WebFronts haben können, die nur Teile dessen anzeigen, was ich insgesamt in meinem „Haupt-Webfront“ habe, das ich nur auf meinen persönlichen Geräten anzeige und das mit Kennwort gesichert ist.

Darum organisiere ich meine WebFronts-Konfiguratoren so, dass ich einen „Master“ habe, an dem ich herum editieren kann, allerdings nur mit Kennwort. Und davon abgeleitet werden durch das folgende Skript „Slave“-WebFronts befüllt, bei denen im Vergleich zum Master bestimmte Elemente ausgeblendet sind. Welche ich ausblenden will, kann ich entweder fest definieren, oder ich mache es von bestimmten Flags abhängig - ob jemand zu Hause ist beispielsweise. Oder ob ein wie auch immer zu triggernder „Expertenmodus“ aktiviert ist :wink:

Im Skript müsst ihr logischerweise die IDs durch die eurer eigenen Konfiguration ersetzen:

<?
// This simple script will allow you to organize several WebFronts by defining
// a "master" WebFront, from which a number of "slave" WebFronts will then
// inherit the items structure. (ALl other settings will not be transferred.)
// It is possible to name specific items that will be hidden on specific slave
// WebFronts. Thereby you can have WebFronts with limited functionality - for
// example if you want simplified status displays, a "guest" tablet and so on.

// The ID of your "master" WebFront, i.e. the one you wish all the Slave Web-
// Fronts to inherit from.
$master_wf_id = 42264 /*[Master]*/;

// Definitions of webfront item IDs, to make the following table more readable.
// Need to replace these with your own - check out your master WebFront
// Configurator for the relevant IDs you wish to be able to hide / reveal in
// the slave WebFronts
define('ITEM_NETWORK',       'item5203');
define('ITEM_EXPERT_CONFIG', 'item8603');
define('ITEM_ALARM',         'item4860');
define('ITEM_TABLEAU',       'item9412');
define('ITEM_AV',            'item8488');

// Definitions of the slave WebFronts, which inherit from the master WebFront.
// Simple example:
// $instance_id => array(
//   'hide_items' => array(ITEM_FOO, ITEM_BAR), // hide what's visible in master WF
//   'reveal_items' => array(ITEM_HELLO), // reveal what's invisible in master WF
// )
$kitchen_expert_mode = GetValue(15582 /*[Konfiguration und Software-Instanzen\WebFront\Expertenmodus iPad Küche]*/);
$home = GetValue(48274 /*[Haus-Status\Anwesenheit]*/);
$slave_wf_ids = array(
	26390 /*[Küchen-Tablet]*/ => array(
		'hide_items' => array(
			only_if(!$kitchen_expert_mode || !$home, ITEM_NETWORK),
			only_if(!$kitchen_expert_mode || !$home, ITEM_EXPERT_CONFIG),
			only_if(!$home, ITEM_ALARM),
			only_if(!$home, ITEM_TABLEAU),
			only_if(!$home, ITEM_AV),
		),
		'reveal_items' => array()
	)
);

// No changes required below this line!

// read configuration of master webfront
$cfg_json = IPS_GetConfiguration($master_wf_id);
$cfg = json_decode($cfg_json, true);
$items_master_json = $cfg['Items']; // get items list as json string

// for each slave webfront
foreach($slave_wf_ids as $wf_id => $wf_cfg) {
	// obtain a new copy of the master wf's items list
	$items = json_decode($items_master_json, true);
	
	// also get a list of this slave wf's items list to check for changes
	$cfg_slave_json = IPS_GetConfiguration($wf_id);
	$cfg_slave = json_decode($cfg_slave_json, true);
	$items_slave_json = $cfg_slave['Items'];
	$items_old = json_decode($items_slave_json, true);
	
	// initialize dirty flag -  if the script has not been called by a variable
	// event, always assume it's been called because the master wf has changed and
	// all slave webfronts need updating
	$dirty = ($_IPS['SENDER'] != 'Variable');
	
	// for each element in master items list
	foreach($items as $index => $item) {
		$visible_old = false;
		$visible_new = true;
		
		// get "Visible" entry of old item of the same ID, if it exists
		foreach($items_old as $item_old) {
			if($item_old['ID'] == $item['ID']) {
				$visible_old = $item_old['Visible'];
				break;
			}
		}
		
		// set to hide or unhide if so configured
		if(in_array($item['ID'], $wf_cfg['hide_items'])) {
			if($item['ParentID'] != '') $visible_new = false;
		} else if(in_array($item['ID'], $wf_cfg['reveal_items'])) {
			$visible_new = true;
		}
		
		// flag dirty if visibility has changed
		if($visible_old != $visible_new) $dirty = true;
		
		// write into item list
		$item['Visible'] = $visible_new;
		$items[$index] = $item;
	} // foreach
	
	// if something changed, save new items list for this slave wf
	if($dirty) {
		$items_slave_json = json_encode($items);
		IPS_SetProperty($wf_id, 'Items', $items_slave_json);
		IPS_ApplyChanges($wf_id);
		WFC_Reload($wf_id);
	}
}

function only_if($condition, $true_value) {
	if($condition) return $true_value;
	return '-';
}
?>

Im Skript habe ich eine gewisse Logik eingebaut mit Bedingungen, nach denen die Items im Slave-Webfront versteckt werden sollen. Das kann man aber auch einfacher haben, wenn die Elemente permanent versteckt sein sollen (ist im Code als Kommentar vermerkt). Ich dachte aber, ich lasse mal meine Konfiguration zur Veranschaulichung drin. Die Variablen von denen die Sichtbarkeit einiger Elemente abhängt sind dann nochmal als Variablen-Change-Ereignis mit dem Skript verknüpft.