Hintergrundfarbe einer Variable mit Profil aus den Vorlagen dynamisch mit einem Skript ändern

Ich hab mir viel Mühe bei dem Titel gegeben, daher fällt der Text hier eher dürftig aus :-D. Ich möchte dynamisch die Hintergrundfarbe einer Variable, der eine Vorlage zugewiesen ist ändern. Also ich möchte die Vorlage dynamisch ändern. Hintergrund ist die Anzeige des aktuellen stündlichen Strompreises. Ist der Preis für die nächste Stunde höher, dann wird rot hinterlegt, niedriger ist grün und wenn er gleich bleibt, blau. Derzeit habe ich drei Profile definiert, die dann zugewiesen werden.

Ich kann mir die Antwort selbst geben :wink:
Es geht, aber nicht verwendbar.
Wie geht es?
So.

IPS_SetTemplateValues("{98CD0B56-BB76-40F6-4DDF-01E792C59421}",
    [
        "ICON" => "circle-euro", 
        "DECIMAL_SEPARATOR"=> "Client",
        "COLOR" => 255,
        "DIGITS"=>2,
        "INTERVALS_ACTIVE"=>false,
        "GROUP"=> "{883E24FA-9174-4E4A-C12E-0A739F0A2FF4}",
        "MAX"=>100,
        "INTERVALS"=>"[]",
        "MIN"=> 0,
        "PERCENTAGE"=>false,
        "PREFIX"=> "",
        "SUFFIX"=> " €",
        "THOUSANDS_SEPARATOR"=>"",
        "USAGE_TYPE"=>0
    ]
);

Die ID’s bekommt man mit ips_gettemplatelist() und die Daten der Vorlage mit ips_gettemplate(). Diese „Vorarbeiten“ sind notwendig.
Dann kann man mit ips_settemplatevalues() die Werte setzen. Es reicht aber nicht, einfach nur den COLOR Wert zu ändern. Es muss immer alles rübergeschoben werden. Wenn man das nicht macht, verschwinden die anderen Werte und die Vorlage ist im Vorlagenmanger nicht mehr sichtbar und auch nicht wählbar.
Soweit so gut. Ändert man z.b. die Farbei in einem Skript, wird die Änderung im Vorlagenmanager sofort angezeigt. In der Visualisierung allerdings nicht. Da hilft nur ein neu Laden was es sinnlos macht. Außerdem sind bei mir beim Ändern der Farbe auch mal nicht abgefangene Fehler in der Console erschienen. Beim Löschen der Vorlage kam dann auch ein Fehler, die Vorlage wurde aber gelöscht.
Somit derzeit keine Option zu den alten Profilen.

Ich würde dir nicht empfehlen hier auf die Vorlage zu gehen, denn prinzipiell ist richtet sich die Farbe ja nach dem Variablenwert. Ich sehe damit zwei mögliche Ansätze:

  • Nutze einfach drei Vorlagen und tausche diese aus
  • Setze die Farbe direkt bei der Variablen. Tatsächlich sollte eine Variable mit gesetzter Vorlage und Farbe die gesetzte Farbe nutzen und alle nicht gesetzten Werte aus der Vorlage holen. Das ist eher ein Nebeneffekt der Implementation, ich bin also nicht ganz sicher ob das so klappt.

Dann könnte ich die die Legacy Profile lassen.

Mit welcher Funktion? Und wie kann man die Farben auf Integer umrechnen?

Naja, ich sehe hier zwei Fälle:

  1. Du nutzt deine Vorlage nur bei einer Variablen
    Dann ist die Verwendung einer Vorlage hier natürlich schon unpassend und du solltest die Darstellung direkt an der Variable setzen. Das kannst du dann mit IPS_SetVariableCustomPresentation machen
  2. Du nutzt deine Vorlage bei mehreren Variablen
    Dann ist es natürlich unpassend die Farbe basierend auf den Werten einer Variable zu ändern. Die Farbe sollte dann ja jede Variable für sich entscheiden. Darauf basierten auch meine vorherigen Vorschläge.

Ich nutze es für zwei Variablen. Einmal den Bezugspreis und den Einspeispreis. Bei der Einspeisung ist das mit Rot/Grün anders. Ich finde das mit der Farbe direkt bei der Variable ändern gar nicht so schlecht. Welche Funktion verwende ich dafür und, wie schon gefragt, wie rechne ich die Farben in Integer Werte um?

Ich sehe das nicht so, weil ich die Art der Darstellung eigentlich von der Variable weg haben mag. Ich hab einige Variablen, wo ein Profil/Vorlage hinterlegt ist, das nur bei dieser Variable verwendet wird. Aber das ist ja mein persönlicher Geschmack.

Eben nicht. Die Farbe wird nicht vom aktuellen Wert der Variable definiert, sondern vom Wert der nächsten Stunde.


Das sind die aktuellen Werte für Bezug und Einspeisung. Die Farbe sagt mir, dass der Bezugspreis in der nächsten Stunde höher ist (Rot) und auch die Einspeisvergütung höher ist (Grün).

@Dr.Niels Mit welcher Funktion kann ich die Farbei direkt bei der Variable ändern?

Wie oben geschrieben per IPS_SetVariableCustomPresentation. Funktioniert analog zu IPS_SetTemplateValues, aber halt für die Variable, nicht die Vorlage.

Hallo,

ich habe auch das Problem, den Hintergrund eine Stringvariablen bei einem bestimmten Text auf eine Farbe zu ändern.

IPS_SetVariableCustomPresentation($id_var, ['COLOR' => 255]);

führt hier nicht zum Erfolg. Ist die Syntax hier überhaupt richtig.
Mehr Informationen reiche ich gerne nach.

Danke, Peter

Ich glaube mich daran zu erinnern, damit herumgespielt zu haben. Soweit ich das noch weiß, reicht es nicht nur eine Eigenschaft ([‘COLOR’]) anzugeben, sondern alles. Immer alles. Sonst tut es nicht. Ich mache es weiterhin mit dem Legacy Profil.

Kennst du den bestimmten Text schon vorher? Denn ansonsten kannst du den per Option direkt schon als gefärbt in der Wertanzeige angeben. Dann musst du die Darstellung gar nicht zur Laufzeit anpassen.

Falls das nicht reicht, fehlt bei deinem Aufruf noch die Darstellung selbst. Im einfachsten Fall dann also:

IPS_SetVariableCustomPresentation($id_var, [
  'PRESENTATION' => VARIABLE_PRESENTATION_VALUE_PRESENTATION,
  'COLOR' => 255
]);

Danke an euch beiden.
Habe es in bestimmten Fällen mit dem Wertanzeige-Profil hinbekommen.
Den Tipp von @Dr.Niels muss ich noch testen. Werde ich wahrscheinlich brauchen, wenn die Texte zu unterschiedlich sind, bzw. Variable teile enthalten.

Grüße, Peter

Danke,
funktioniert so wie ich es wünsche. Es müssen aber alle anderen Parameter (wenn gebraucht) mit angegeben werden.
Grüße, Peter

Genau. Alternativ kannst du natürlich vorher einmal die Darstellung auslesen und nur gewisse Felder überschreiben.

Hallo,

ich habe hierzu mal eine Frage. Ich habe das mal versucht nachzustellen. Bei mir wird aber zum Beispiel nur die Farbe blau dargestellt. Ändere ich den Wert “color”, dann ändert sich nur die Farbhelligkeit. Ich würde gerne auch andere Farben darstellen wollen.

Mag mir da jemand einen Tipp geben?

Gruß

Marc

Das Feld COLOR beschreibt eigentlich die RGB-Farbe als hexadezimal codiert. Wenn du mit PHP arbeitest, dann lohnt es sich daher vielleicht auch das ganze als Hex zu notieren. Dann wäre beispielsweise 0xFF0000 ein reines rot, 0xFF00 ein reines grün und 0xFF ein reines blau. Um also etwas nicht blaues zu bekommen muss der Wert also schon größer als 0xFF = 255 sein.

1 „Gefällt mir“

Wie kann ich mit der Funktion IPS_SetVariableCustomPresentation die Farbe verändern ohne die “Darstellung” und die “Vorlage” zu verändern?

Mit (nur) der Angabe von ‚PRESENTATION‘ => VARIABLE_PRESENTATION_VALUE_PRESENTATION bleibt die Wert-Darstellung erhalten, allerdings wird die Vorlage überschrieben.

Danke,
Andreas

Du möchtest eine Vorlage nutzen, aber punktuell Parameter anpassen? Das ist prinzipiell kein vorgesehenes Verhalten, du nutzt eine Vorlage oder eigene Werte.

Wobei es als undokumentiertes Verhalten aktuell funktionieren sollte, dass du einzelne Parameter überschreibst, das klappt dann aber auch nur per PHP-Skript und ich garantiere dir nicht, dass es so bleiben wird! Dann wäre das also:

[
  'PRESENTATION' => VARIABLE_PRESENTATION_VALUE_PRESENTATION,
  'TEMPLATE' => $templateID,
  'COLOR' => 0xff0000
]

Jein, der Anwendungsfall ist, dass ich bei einer Variable die Hintergrundfarbe in Abhängigkeit vom Wertebereich dynamisch verändern will. Nutze ich da Vorlagen, so hat dies schnell Nebeneffekte, da dies ja dann alle Variablen betrifft, die die Vorlagen verwenden.

Was ist denn der Parameter $templateid?

Über den Vorlagenmanager habe ich ausprobiert, verschiedene Assoziationen anzulegen (ich glaube das heißt so, was auch eine Lösung wäre. Ich habe nur in der Doku nicht den Hinweis gefunden, wie ich die Assoziaton per PHP-Skript auswählen kann.

Ich habe einen ähnlichen Fall. Ich habe einen Sollwert und einen IstWert. Je stärker der Istwert vom Sollwert abweicht, desto intensiver wird die Farbe.

Die Farbe setze ich dann mit

$currentPresentation = IPS_GetVariablePresentation($soilMoistureId);
$presentation = array_replace($currentPresentation, [
		'COLOR' => $color,
	]);

IPS_SetVariableCustomPresentation($soilMoistureId, $presentation);

Ist es das, was du machen möchtest?

Hier mein komplettes Beispiel:

function IPSWatering_UpdateSoilMoisturePresentation(int $soilMoistureId, int $thresholdId, string $name = ''): void
{
	if (!IPS_VariableExists($soilMoistureId) || !IPS_VariableExists($thresholdId)) {
		IPSLogger_Wrn(
			basename(__FILE__, '.ips.php'),
			sprintf('Darstellung nicht aktualisiert, Variable fehlt: %s (Feuchte=%d, Soll=%d)', $name, $soilMoistureId, $thresholdId)
		);
		return;
	}

	$threshold = GetValueInteger($thresholdId);
	$currentValue = GetValueInteger($soilMoistureId);
	$green = [0x00, 0xFF, 0x00];
	$red = [0xFF, 0x00, 0x00];
	$blue = [0x00, 0x00, 0xFF];
	$delta = $currentValue - $threshold;
	$tolerance = 2;
	$fullColorDeviation = 10;

	if (abs($delta) <= $tolerance) {
		$color = -1;
	} else {
		$distance = abs($delta) - $tolerance;
		$range = max(1, $fullColorDeviation - $tolerance);
		$factor = min(1, $distance / $range);
		$targetColor = $delta < 0 ? $red : $blue;

		$color = 0;
		for ($i = 0; $i < 3; $i++) {
			$channel = (int) round($green[$i] + (($targetColor[$i] - $green[$i]) * $factor));
			$color |= $channel << ((2 - $i) * 8);
		}
	}

	$currentPresentation = IPS_GetVariablePresentation($soilMoistureId);
	$presentation = array_replace($currentPresentation, [
		'COLOR' => $color,
	]);

	IPS_SetVariableCustomPresentation($soilMoistureId, $presentation);

	IPSLogger_Dbg(
		basename(__FILE__, '.ips.php'),
		sprintf('%s: Darstellung aktualisiert (Ist=%d%%, Soll=%d%%, Farbe=#%06X)', $name, $currentValue, $threshold, $color)
	);
}

Vielleicht kannst du damit etwas anfangen.

1 „Gefällt mir“