Seite 1 von 1

Gruppe von Kontakten an Lamba-Funktion übergeben

Verfasst: 9. Dez 2019 14:33
von Cyrelian
Hi,

ich würde gerne folgendes realisieren:

Setup: Ein Zimmer mit zwei Heizkörperthermostaten und zwei Fensterkontakten.

Nun soll, sobald eines der Fenster geöffnet wird, die Gruppe(SchlafzimmerHeizung_WindowState (Gruppe in der Raspberrymatic)) der Heizkörperthermostate in "WindowMode" versetzt werden.

Hardware: Homematic HMIP-etrv und Aqara Kontakte.

Items:

Code: Alles auswählen

Group:Contact:OR(OPEN, CLOSED) gSchlafzimmerTuersensoren	(gTuersensoren)
Contact		SchlafzimmerTuersensor_Status		"Terrassentürsensor ist [MAP(contact.map):%s]" 						<window> 	(gSchlafzimmerTuersensor,gSchlafzimmerTuersensoren)	["ContactSensor"]	{channel="deconz:openclosesensor:Rpi-Phoscon-GW:SchlafzimmerTuersensor:open"}
String                 SchlafzimmerHeizung_WindowState         "Heizung (Schlafzimmer) Fensterabsenkung [MAP(HMIP-eTRV.map):%s]" 		<contact>       (gSchlafzimmerHeizung,gHKTWindowMode)		  {channel="homematic:HmIP-HEATING:HMIPCCU3RM:INT0000002:1#WINDOW_STATE"}

Rule:

Code: Alles auswählen

val Functions$Function1<ContactItem, String> //
	heaterInWindowMode = [ContactState |
		var String message
		if (ContactState.state == OPEN) {
			//logInfo("Lambda", "Fensterabsenkung detektieren" + ContactState.state )
			message = "OPEN"
			return message;
		} else if (ContactState.state == CLOSED) {
			//logInfo("Lambda", " Fensterabsenkung detektieren" + ContactState.state)
			message = "CLOSED"
			return message;
		} else {
			//logInfo("Lambda", " NIX Fensterabsenkung detektieren" + ContactState.state)
			message = "CLOSED"
			return message;
		}
	]


///////////////////////////////////////////////////////////////////////////////
// Heizung Fensterabsenkung detektieren
rule "Heizung Fensterabsenkung detektieren"
when
	//Time cron  "0/30 * * * * ?"
	Item BadezimmerFenstersensor_Status received update or
	Item KinderzimmerFenstersensor_Status received update or
	Item gSchlafzimmerTuersensoren received update //or
	//Item SchlafzimmerTuersensor_Status received update or 
	//Item SchlafzimmerFenstersensor_Status received update
then 
		if (log) logInfo (filename, logPrefix + "Fensterabsenkung erkennen")
		BadHKT_WindowState.sendCommand(heaterInWindowMode.apply(BadezimmerFenstersensor_Status))
		KinderzimmerHKT_WindowState.sendCommand(heaterInWindowMode.apply(KinderzimmerFenstersensor_Status))
		SchlafzimmerHeizung_WindowState.sendCommand(heaterInWindowMode.apply(gSchlafzimmerTuersensoren.state))

end
Bei den "einzelnen" HKT´s klappt das auch. Bei der Gruppe aber nicht, da gSchlafzimmerTuersensoren.state nicht richtig an die Lambda Funktion übergeben werden kann. Habe auch schon dass probiert:

Code: Alles auswählen

SchlafzimmerHeizung_WindowState.sendCommand(heaterInWindowMode.apply(gSchlafzimmerTuersensoren.state as ContactItem))
.
Ich bekomme hier immer einen Cast oder type mismatch.

Habt ihr ne Idee?

Re: Gruppe von Kontakten an Lamba-Funktion übergeben

Verfasst: 9. Dez 2019 16:07
von Tokamak
Ein <irgendein Item>.state ist niemals selbst ein Item und damit sicher kein ContactItem.

Warum übergibst du nicht direkt den Status als String, also

Code: Alles auswählen

SchlafzimmerHeizung_WindowState.postUpdate(gSchlafzimmerTuersensoren.state.toString())
?

Des Weiteren frage ich mich, wofür du das StringItem SchlafzimmerHeizung_WindowState überhaupt benötigst, wenn es doch nur den Status der Gruppe enthalten soll.

An Lambdas übergebe ich meist das Item selbst, nicht den State. Dann hast du in der Lambda voll Kontrolle. Das ginge auch mit einem GroupItem.

Re: Gruppe von Kontakten an Lamba-Funktion übergeben

Verfasst: 10. Dez 2019 10:22
von Cyrelian
Hi,

Code: Alles auswählen

SchlafzimmerHeizung_WindowState.postUpdate(gSchlafzimmerTuersensoren.state.toString())
gute Idee.
An Lambdas übergebe ich meist das Item selbst, nicht den State. Dann hast du in der Lambda voll Kontrolle. Das ginge auch mit einem GroupItem.
So mache ich das normalerweise auch. Hier ist nur das Problem, das ich hier

Code: Alles auswählen

Functions$Function1<ContactItem, String>
an das ContactItem gebunden bin. Gut, ich könnte das auf GroupItem umstellen und nur Gruppen übergeben.
Ich probier´s mal so wie du es geschrieben hast mit dem state.toString.

CU
Cyrelian

Re: Gruppe von Kontakten an Lamba-Funktion übergeben

Verfasst: 10. Dez 2019 18:42
von udo1toni
Ich verstehe auch nicht so ganz, was das Lambda überhaupt soll. Vielleicht erläuterst Du mal, was genau Du erreichen willst.

Re: Gruppe von Kontakten an Lamba-Funktion übergeben

Verfasst: 11. Dez 2019 07:01
von Tokamak
Cyrelian hat geschrieben: 10. Dez 2019 10:22 So mache ich das normalerweise auch. Hier ist nur das Problem, das ich hier

Code: Alles auswählen

Functions$Function1<ContactItem, String>
an das ContactItem gebunden bin. Gut, ich könnte das auf GroupItem umstellen und nur Gruppen übergeben.
Abgesehen davon, dass ich wie udi1toni den Sinn der Lambda nicht verstehe, ist die technische Lösung, ein "GenericItem" zu übergeben. Du kannst dann in der Lambda den eigentlichen Typ "ContactItem" oder "GroupItem" mittels "instanceof" abfragen.
Bei kurzen Lambdas lohnt sich das aber nicht, da ist es einfacher, zwei zu haben.

Re: Gruppe von Kontakten an Lamba-Funktion übergeben

Verfasst: 11. Dez 2019 09:54
von Cyrelian
udo1toni hat geschrieben: 10. Dez 2019 18:42 Ich verstehe auch nicht so ganz, was das Lambda überhaupt soll. Vielleicht erläuterst Du mal, was genau Du erreichen willst.
Hi,

wie oben beschrieben, will ich erreichen, dass sobald ein Fenster/Kontakt in einem Raum mir mehreren Fenster/kontakten geöffnet wird, die Gruppe in den "WindowMode" versetzt wird.
Ja, ich gebe euch recht, nach dem Beispiel von Tokamak

Code: Alles auswählen

SchlafzimmerHeizung_WindowState.postUpdate(gSchlafzimmerTuersensoren.state.toString())
benötige ich dafür keine Lambda. manchmal kann es so einfach sein ;)

THX
Cyrelian

Re: Gruppe von Kontakten an Lamba-Funktion übergeben

Verfasst: 11. Dez 2019 12:01
von peter-pan
Hi,
ich weiss nicht, ob es noch interresant ist, aber ich habe auch mehrere Fenster in verschiedenen Räumen (allerdings jeweils nur einen Thermostaten) und habe das auch mit einem Group-Item für die Fenstersensoren gelöst. Das benutze ich als Rule-Trigger, aber nicht als "Member of.." sondern nur als Item, das war's dann auch schon.

Code: Alles auswählen

//===============================================================================
rule "Fenster Arbeitszimmer Offen"
    when
      Item gWindowOffice changed from "CLOSED" to "OPEN" 
    then
     if(radiator_valve_01_Mode.state == "OFF") return;  // Es sind bereits Fenster offen bzw. der Thermostat ist ausgeschaltet
      radiator_valve_01_Set_prev.postUpdate(radiator_valve_01_Set.state)
      radiator_valve_01_Mode_prev.postUpdate(radiator_valve_01_Mode.state)
      radiator_valve_01_Mode.sendCommand("OFF")
      logInfo("Fenster Arbeitszimmer Offen"," radiator_valve_01_Set {}", radiator_valve_01_Set)
end
//===============================================================================
rule "Fenster Arbeitszimmer Geschlossen"
    when
      Item gWindowOffice changed from "OPEN" to "CLOSED"
    then
      if ((radiator_valve_01_Mode_prev.state == "ECO") || (radiator_valve_01_Mode_prev.state == "COMFORT") || (radiator_valve_01_Mode_prev.state == "OFF")) {
        radiator_valve_01_Mode.sendCommand(radiator_valve_01_Mode_prev.state.toString)
        logInfo("Fenster Arbeitszimmer Geschlossen"," radiator_valve_01_Set {}", radiator_valve_01_Set)
      }
      if (radiator_valve_01_Mode_prev.state == "ON") {
        radiator_valve_01_Set.sendCommand(radiator_valve_01_Set_prev.state as Number)
        logInfo("Fenster Arbeitszimmer Geschlossen"," radiator_valve_01_Set {}", radiator_valve_01_Set)
      }
end
//===============================================================================
Ich speichere auch noch den letzten Thermostat-Modus und die zuletzt eingestellte Temperatur ab.

Ich habe Homematic-Sensoren und Fritz-Thermostate im Einsatz.

Die Homematic-Items sehen so aus:

Code: Alles auswählen

Group:Contact:OR(OPEN,CLOSED)      gWindowOffice                      "Fensterkontakte Büro [MAP(de.map):%s]"                                            
Contact                HmIP_SWDO_DB1C_1STATECONTACT                   "Fenster Arbeitszimmer Ost Kontakt[MAP(de.map):%s]"                 <window>            (gHomeMatic,gWindow,EG_Buro,gWindowOffice)      {channel="homematic:HMIP-SWDO:3014F711A0001F98A9AABCAF:0000DA498BDB1C:1#STATE_CONTACT"}
Contact                HmIP_SWDO_D6D5_1STATECONTACT                   "Fenster Arbeitszimmer Nord Kontakt[MAP(de.map):%s]"                <window>            (gHomeMatic,gWindow,EG_Buro,gWindowOffice)      {channel="homematic:HMIP-SWDO:3014F711A0001F98A9AABCAF:0000DA4994D6D5:1#STATE_CONTACT"}
Das geht vielleicht noch eleganter, evtl. auch in einer Rule, aber es klappt ganz gut.

Re: Gruppe von Kontakten an Lamba-Funktion übergeben

Verfasst: 11. Dez 2019 14:28
von Cyrelian
peter-pan hat geschrieben: 11. Dez 2019 12:01 Hi,
ich weiss nicht, ob es noch interresant ist, aber ich habe auch mehrere Fenster in verschiedenen Räumen (allerdings jeweils nur einen Thermostaten) und habe das auch mit einem Group-Item für die Fenstersensoren gelöst. Das benutze ich als Rule-Trigger, aber nicht als "Member of.." sondern nur als Item, das war's dann auch schon.

Code: Alles auswählen

//===============================================================================
rule "Fenster Arbeitszimmer Offen"
    when
      Item gWindowOffice changed from "CLOSED" to "OPEN" 
    then
     if(radiator_valve_01_Mode.state == "OFF") return;  // Es sind bereits Fenster offen bzw. der Thermostat ist ausgeschaltet
      radiator_valve_01_Set_prev.postUpdate(radiator_valve_01_Set.state)
      radiator_valve_01_Mode_prev.postUpdate(radiator_valve_01_Mode.state)
      radiator_valve_01_Mode.sendCommand("OFF")
      logInfo("Fenster Arbeitszimmer Offen"," radiator_valve_01_Set {}", radiator_valve_01_Set)
end
//===============================================================================
rule "Fenster Arbeitszimmer Geschlossen"
    when
      Item gWindowOffice changed from "OPEN" to "CLOSED"
    then
      if ((radiator_valve_01_Mode_prev.state == "ECO") || (radiator_valve_01_Mode_prev.state == "COMFORT") || (radiator_valve_01_Mode_prev.state == "OFF")) {
        radiator_valve_01_Mode.sendCommand(radiator_valve_01_Mode_prev.state.toString)
        logInfo("Fenster Arbeitszimmer Geschlossen"," radiator_valve_01_Set {}", radiator_valve_01_Set)
      }
      if (radiator_valve_01_Mode_prev.state == "ON") {
        radiator_valve_01_Set.sendCommand(radiator_valve_01_Set_prev.state as Number)
        logInfo("Fenster Arbeitszimmer Geschlossen"," radiator_valve_01_Set {}", radiator_valve_01_Set)
      }
end
//===============================================================================
Ich speichere auch noch den letzten Thermostat-Modus und die zuletzt eingestellte Temperatur ab.

Ich habe Homematic-Sensoren und Fritz-Thermostate im Einsatz.

Die Homematic-Items sehen so aus:

Code: Alles auswählen

Group:Contact:OR(OPEN,CLOSED)      gWindowOffice                      "Fensterkontakte Büro [MAP(de.map):%s]"                                            
Contact                HmIP_SWDO_DB1C_1STATECONTACT                   "Fenster Arbeitszimmer Ost Kontakt[MAP(de.map):%s]"                 <window>            (gHomeMatic,gWindow,EG_Buro,gWindowOffice)      {channel="homematic:HMIP-SWDO:3014F711A0001F98A9AABCAF:0000DA498BDB1C:1#STATE_CONTACT"}
Contact                HmIP_SWDO_D6D5_1STATECONTACT                   "Fenster Arbeitszimmer Nord Kontakt[MAP(de.map):%s]"                <window>            (gHomeMatic,gWindow,EG_Buro,gWindowOffice)      {channel="homematic:HMIP-SWDO:3014F711A0001F98A9AABCAF:0000DA4994D6D5:1#STATE_CONTACT"}
Das geht vielleicht noch eleganter, evtl. auch in einer Rule, aber es klappt ganz gut.
..auch nen guter Ansatz. Jetzt hab ich ja ein paar Ideen und Ansätze auf die man aufbauen kann :D .

Dank Euch
Cyrelian