There is no context to infer the closure's argument types from. Consider typing the arguments or put the closures into a

Einrichtung der openHAB Umgebung und allgemeine Konfigurationsthemen.

Moderatoren: seppy, udo1toni

Antworten
TomW80
Beiträge: 140
Registriert: 7. Mai 2021 19:11
Answers: 2

There is no context to infer the closure's argument types from. Consider typing the arguments or put the closures into a

Beitrag von TomW80 »

Leider hat mich der Beitrag viewtopic.php?t=9529 nicht weitergebracht bei meinen rules.
Kann mir jemand einen Tip geben?

Die eine rule sieht so aus:

Code: Alles auswählen

rule "geöffnete Fenster zählen"
when 
    Member of gKontakte changed or
    Item KG_Kellerfenster changed
then

    if (kontakteoffen.state == NULL) 
    {
        kontakteoffen.postUpdate(0)
    }

    var Integer nAnz = gKontakte.members.filter[i|i instanceof ContactItem ].filter[s|s.state==OPEN].size
    nAnz = nAnz + gKontakte.members.filter[i|i instanceof SwitchItem ].filter[ s|s.state==ON].size
    kontakteoffen.postUpdate( nAnz )
end
Wenn ich das folgende

Code: Alles auswählen

.filter[s|s.state==OPEN].size
so schreibe,

Code: Alles auswählen

.filter[ContactItem s|s.state==OPEN].size
erhalte ich den Fehler
Type mismatch: cannot convert from (ContactItem)=>boolean to Function1<? super Item, Boolean>
Wie übergebe ich den richtigen Typ
von udo1toni » 3. Feb 2026 03:05
Zunächst mal sieht der Code korrekt aus.
Insbesondere funktioniert die Rule bei mir einwandfrei und auch VS Code ist glücklich.
Welche (exakte) Version von openHAB nutzt Du denn?
Sind in der Datei noch andere Rules vorhanden?

Ein anderer Punkt ist allerdings, dass Du Dir an dieser Stelle zu viel Arbeit machst. :)

Code: Alles auswählen

rule "geöffnete Fenster zählen"
when 
    Member of gKontakte changed
then
    var Integer iAnz = gKontakte.members.filter[s|s.state==OPEN || s.state==ON].size
    kontakteoffen.postUpdate(iAnz)
end
reicht.
Punkt 1: KG_Kellerfenster ist ja wohl Member der Group gKontakte (sonst wird es nicht mitgezählt...)
Punkt 2: Ich gehe davon aus, dass sich in der Gruppe gKontakte nur Kontakte und Switches befinden. Ein Switch Item kann die Status ON, OFF und NULL annehmen. Ein Contact Item kann die Zustände OPEN, CLOSED und NULL annehmen. Wenn Du prüfst, ob ein Switch Item OPEN ist, wird das Ergebnis false sein, ebenso wenn Du bei einem Contact Item auf ON prüfst. Es gibt aber keinen Fehler und auch kein Fehlverhalten.
Der Filter ist ein Bool'scher Ausdruck, da Dich die Summe interessiert, passt das mit dem logischen Oder.
Ob Du hier die Variable als nAnz oder iAnz festlegst, ist egal :) ich habe nur die Macke, den ersten Buchstaben abhängig vom Datentyp (hier Integer) zu verwenden.
Punkt 3: JE nach verwendetem Binding könnte es auch sinnvoll sein, das Eingangssignal des Kellerfenstersensors ebenfalls als Contact abzubilden, das sollte eigentlich immer gehen (bei einigen Addons vielleicht mit einem Umweg verbunden, dennoch...)
Punkt 4: Du kannst auch komplett auf die Rule verzichten und stattdessen gKontakte als Group:Number:COUNT(".*N") definieren, dann zählt das Group Item alle Member, deren Status auf "N" endet.

Ach so... Die Überschrift ist unglücklich. Wir sind hier ein deutschsprachiges Forum und es kommen immer wieder Bots durch, die mit englischen Überschriften auffallen, da ist die Chance groß, eine solche Überschrift reflexhaft als Spam wahrzunehmen.
Besser wäre also notfalls eine Überschrift wie: "Brauche Hilfe bei einer Rule" und dann innerhalb des Postings die Fehlermeldung (als Code markiert...)
Gehe zur vollständigen Antwort

TomW80
Beiträge: 140
Registriert: 7. Mai 2021 19:11
Answers: 2

Re: There is no context to infer the closure's argument types from. Consider typing the arguments or put the closures in

Beitrag von TomW80 »

Jetzt kommt auf einmal kein Fehler mehr wenn ich es so schreibe.

Code: Alles auswählen

var Integer nAnz = gKontakte.members.filter[i|i instanceof ContactItem ].filter[ NumberItem s|s.state==OPEN].size
nAnz = nAnz + gKontakte.members.filter[i|i instanceof SwitchItem ].filter[ NumberItem s|s.state==ON].size
Muss nur noch schauen ob der Fehler weg ist.

TomW80
Beiträge: 140
Registriert: 7. Mai 2021 19:11
Answers: 2

Re: There is no context to infer the closure's argument types from. Consider typing the arguments or put the closures in

Beitrag von TomW80 »

TomW80 hat geschrieben: 1. Feb 2026 17:45 Jetzt kommt auf einmal kein Fehler mehr wenn ich es so schreibe.

Code: Alles auswählen

var Integer nAnz = gKontakte.members.filter[i|i instanceof ContactItem ].filter[ NumberItem s|s.state==OPEN].size
nAnz = nAnz + gKontakte.members.filter[i|i instanceof SwitchItem ].filter[ NumberItem s|s.state==ON].size
Muss nur noch schauen ob der Fehler weg ist.
Zu früh gefreut, VSC meckert heute wieder mit dem o.g. Fehler.
Jemand nun eine Idee wie die rule aussehen muss?

Benutzeravatar
udo1toni
Beiträge: 15614
Registriert: 11. Apr 2018 18:05
Answers: 253
Wohnort: Darmstadt

Re: There is no context to infer the closure's argument types from. Consider typing the arguments or put the closures in

Beitrag von udo1toni »

Zunächst mal sieht der Code korrekt aus.
Insbesondere funktioniert die Rule bei mir einwandfrei und auch VS Code ist glücklich.
Welche (exakte) Version von openHAB nutzt Du denn?
Sind in der Datei noch andere Rules vorhanden?

Ein anderer Punkt ist allerdings, dass Du Dir an dieser Stelle zu viel Arbeit machst. :)

Code: Alles auswählen

rule "geöffnete Fenster zählen"
when 
    Member of gKontakte changed
then
    var Integer iAnz = gKontakte.members.filter[s|s.state==OPEN || s.state==ON].size
    kontakteoffen.postUpdate(iAnz)
end
reicht.
Punkt 1: KG_Kellerfenster ist ja wohl Member der Group gKontakte (sonst wird es nicht mitgezählt...)
Punkt 2: Ich gehe davon aus, dass sich in der Gruppe gKontakte nur Kontakte und Switches befinden. Ein Switch Item kann die Status ON, OFF und NULL annehmen. Ein Contact Item kann die Zustände OPEN, CLOSED und NULL annehmen. Wenn Du prüfst, ob ein Switch Item OPEN ist, wird das Ergebnis false sein, ebenso wenn Du bei einem Contact Item auf ON prüfst. Es gibt aber keinen Fehler und auch kein Fehlverhalten.
Der Filter ist ein Bool'scher Ausdruck, da Dich die Summe interessiert, passt das mit dem logischen Oder.
Ob Du hier die Variable als nAnz oder iAnz festlegst, ist egal :) ich habe nur die Macke, den ersten Buchstaben abhängig vom Datentyp (hier Integer) zu verwenden.
Punkt 3: JE nach verwendetem Binding könnte es auch sinnvoll sein, das Eingangssignal des Kellerfenstersensors ebenfalls als Contact abzubilden, das sollte eigentlich immer gehen (bei einigen Addons vielleicht mit einem Umweg verbunden, dennoch...)
Punkt 4: Du kannst auch komplett auf die Rule verzichten und stattdessen gKontakte als Group:Number:COUNT(".*N") definieren, dann zählt das Group Item alle Member, deren Status auf "N" endet.

Ach so... Die Überschrift ist unglücklich. Wir sind hier ein deutschsprachiges Forum und es kommen immer wieder Bots durch, die mit englischen Überschriften auffallen, da ist die Chance groß, eine solche Überschrift reflexhaft als Spam wahrzunehmen.
Besser wäre also notfalls eine Überschrift wie: "Brauche Hilfe bei einer Rule" und dann innerhalb des Postings die Fehlermeldung (als Code markiert...)
openHAB5.1.1 stable in einem Debian-Container (trixie, OpenJDK 21 headless runtime - LXC, 4 Kerne, 3 GByte RAM)
Hostsystem Proxmox 9.1.5 - AMD Ryzen 5 3600 6 Kerne, 12 Threads - 64 GByte RAM - ZFS Pools: Raid Z1, 3 x 20 TB HDD -> 40 TByte und Raid Z0-Mirrored 4 x 1 TByte NVMe -> 2 TByte

TomW80
Beiträge: 140
Registriert: 7. Mai 2021 19:11
Answers: 2

Re: There is no context to infer the closure's argument types from. Consider typing the arguments or put the closures in

Beitrag von TomW80 »

Hallo udo1toni,

Danke für deine ausführliche Erklärung, werde Punkt 4 nutzen um die Rule zu sparen. :)
Ich verwende OH 5.1.1

TomW80
Beiträge: 140
Registriert: 7. Mai 2021 19:11
Answers: 2

Re: There is no context to infer the closure's argument types from. Consider typing the arguments or put the closures in

Beitrag von TomW80 »

Ich habe in einer zweite Rule genau das gleiche Problem.
Wenn ich das NumberItem (rot) einfüge, erhalte ich den Fehler wie oben schon angegeben.
Type mismatch: cannot convert from (NumberItem)=>boolean to Function1<? super Item, Boolean>
Nach dem .forEach funktioniert das mit dem NumberItem.

Jemand eine Idee wie ich es hier schreiben muss?

Code: Alles auswählen

...
 Temperaturen_all.members.filter[ NumberItem i|i.state<=(fensterOffenWarnungTemperatur.state as Number)].forEach[NumberItem j|    
		 	var String tempitem =  j.name 
            val Number tempvalue = (j.state as Number)
			
            if (now.getHour() >= 22 || now.getHour() <= 7) // keine Nachricht zwischen 22 Uhr und 07 Uhr versenden
            {
                logInfo("Raumtemperatur","Nachricht nicht gesendet, da es Nacht ist")
            }
            else if (gKontakte.state > 0)
            {
                // Meldetext erzeugen
                meldeText = 'Die Temperatur im Raum ' + tempitem.replaceAll('KG_','Kellergeschoß_').replaceAll('EG_','Erdgeschoß ').replaceAll('OG_','Obergeschoß ').replaceAll('_Temp',' ').replaceAll('Kind2_XTemp','Theo ').replaceAll('SpeisXTemp','Speis ') + 'ist kleiner als ' + (fensterOffenWarnungTemperatur.state as Number) + '°C! Aktuell: ' + tempvalue + '°C'

                //Pushover
                val actions = getActions("pushover", "pushover:pushover-account:***")
                actions.sendMessage("Information", meldeText)
                
            }   
            else
            {
                logInfo("Raumtemperatur","Nachricht nicht gesendet, da kein Fenster mehr offen ist")
            } 
		]
...

Benutzeravatar
udo1toni
Beiträge: 15614
Registriert: 11. Apr 2018 18:05
Answers: 253
Wohnort: Darmstadt

Re: There is no context to infer the closure's argument types from. Consider typing the arguments or put the closures in

Beitrag von udo1toni »

Warum fügst Du da überhaupt NumberItem ein? Das ist unnötig.

Der Codeschnipsel sieht außerdem nicht gut aus ;) Warum fragst Du die Uhrzeit innerhalb der Iteration über alle Items ab? Warum prüfst Du innerhalb der Iteration, ob alle Fenster geschlossen sind? Besser:

Code: Alles auswählen

...
if(now.getHour() >= 22 || now.getHour() < 7)                               // keine Nachricht zwischen 22 Uhr und 07 Uhr versenden
    logInfo("Raumtemperatur","Nachricht nicht gesendet, da es Nacht ist")
else if((gKontakte.state as Number) == 0)
    logInfo("Raumtemperatur","Nachricht nicht gesendet, da kein Fenster mehr offen ist")
else {
    val Number minTemp = fensterOffenWarnungTemperatur.state as Number
    Temperaturen_all.members.filter[i|(i.state as Number) <= minTemp].forEach[j|
        var String tempitem =  j.name 
        val Number tempvalue = j.state as Number
        meldeText = 'Die Temperatur im Raum ' + tempitem.replaceAll('KG_','Kellergeschoß_').replaceAll('EG_','Erdgeschoß ').replaceAll('OG_','Obergeschoß ').replaceAll('_Temp',' ').replaceAll('Kind2_XTemp','Theo ').replaceAll('SpeisXTemp','Speis ') + 'ist kleiner als ' + minTemp.toString + ' °C! Aktuell: ' + tempvalue.toString + ' °C'
        val actions = getActions("pushover", "pushover:pushover-account:***")         //Pushover
        actions.sendMessage("Information", meldeText)
    ]
}
...
Der Ruleschnipsel erzeugt für jede Unterschreitung eine eigene Pushover Meldung, falls mehrere Temperaturen unterschritten sind. Es wäre eventuell besser, zunächst alle Items abzufragen und eine einzige Meldung zu generieren.
Auch das Konstrukt mit dem replaceAll wirkt eher wie eine Notbehelf :) möglicherweise ist das Label eindeutig? Ansonsten bliebe noch eine HashMap, um das etwas übersichtlicher zu bekommen.

Code: Alles auswählen

// global definieren
val HashMap<String, String> hmNames = newHashMap(
    "KG_Raum1" -> "Kellergeschoss Raum 1",
    "KG_Raum2" -> "Kellergeschoss Raum 2",
    "KG_Raum3" -> "Kellergeschoss Raum 3"
)
...
rule ...
    val String strText    = hmNames.get(j.name)
    val String strTemp    = String.format("%.1f °C",(j.state as Number))
    val String strTempMin = String.format("%.1f °C",minTemp)
    meldeText = 'Die Temperatur im Raum ' + strText + ' ist kleiner als ' + strTempMin + ' Aktuell: ' + strTemp
    val actions = getActions("pushover", "pushover:pushover-account:***")                                       //Pushover
    actions.sendMessage("Information", meldeText)
...
Eine HashMap liefert für jeden Eingangswert einen Ausgangswert. Natürlich sollte der Eingangswert auch in der Liste enthalten sein :)
openHAB5.1.1 stable in einem Debian-Container (trixie, OpenJDK 21 headless runtime - LXC, 4 Kerne, 3 GByte RAM)
Hostsystem Proxmox 9.1.5 - AMD Ryzen 5 3600 6 Kerne, 12 Threads - 64 GByte RAM - ZFS Pools: Raid Z1, 3 x 20 TB HDD -> 40 TByte und Raid Z0-Mirrored 4 x 1 TByte NVMe -> 2 TByte

TomW80
Beiträge: 140
Registriert: 7. Mai 2021 19:11
Answers: 2

Re: There is no context to infer the closure's argument types from. Consider typing the arguments or put the closures in

Beitrag von TomW80 »

udo1toni hat geschrieben: 5. Feb 2026 18:13 Warum fügst Du da überhaupt NumberItem ein? Das ist unnötig.
Na wegen dem Fehler: "There is no context to infer the closure's argument types from. Consider typing the arguments or put the closures into a typed context."

Eigentlich hat die Rule immer funktioniert, nur taucht der Fehler oben beim start von openhab seit neustem immer auf und läd dadurch die Rule nicht.
Ich habe die Rule jetzt mal so geändert, Fehler taucht aber immer noch auf.

Code: Alles auswählen

rule "Benachrichtigung Temperatur"
when
    Member of Temperaturen_all changed
then

    // Check ob Variablen passen, ansonsten defaultwert setzen
    if ((NotificationTemperatur.state != OFF) && (NotificationTemperatur.state != ON)) {
        NotificationTemperatur.sendCommand(ON)
        logInfo('rules', logPrefix + 'Setze Default-Wert für NotificationTemperatur=An')
    }
    if (fensterOffenWarnungTemperatur.state == NULL) {
        fensterOffenWarnungTemperatur.postUpdate(17)
        logInfo('rules', logPrefix + 'Setze Default-Wert für fensterOffenWarnungTemperatur=17')
    }
    val Number minTemp = fensterOffenWarnungTemperatur.state as Number

    if (NotificationTemperatur.state == ON)
    {
      if(((Temperaturen_all.members.filter[i|(i.state as Number) <= minTemp]).size > 0) && (nNotifications == 0))
      {    
        nNotifications = 1

        if(now.getHour() >= 22 || now.getHour() < 7)                               // keine Nachricht zwischen 22 Uhr und 07 Uhr versenden
            logInfo("Raumtemperatur","Nachricht nicht gesendet, da es Nacht ist")
        else if((gKontakte.state as Number) == 0)
            logInfo("Raumtemperatur","Nachricht nicht gesendet, da kein Fenster mehr offen ist")
        else {           
            Temperaturen_all.members.filter[i|(i.state as Number) <= minTemp].forEach[j|
            var String tempitem =  j.name 
            val Number tempvalue = j.state as Number
            meldeText = 'Die Temperatur im Raum ' + tempitem.replaceAll('KG_','Kellergeschoß_').replaceAll('EG_','Erdgeschoß ').replaceAll('OG_','Obergeschoß ').replaceAll('_Temp',' ').replaceAll('Kind2_XTemp','Theo ').replaceAll('SpeisXTemp','Speis ') + 'ist kleiner als ' + minTemp.toString + ' °C! Aktuell: ' + tempvalue.toString + ' °C'
            val actions = getActions("pushover", "pushover:pushover-account:***")         //Pushover
            actions.sendMessage("Information", meldeText)
    ]
        }

        tFenstertemp = createTimer(now.plusMinutes(15))[  // Timer damit die Meldung nur alle 15 Minuten kommt und nicht ständig
        nNotifications = 0
        ]   
      }
    }

end

Benutzeravatar
udo1toni
Beiträge: 15614
Registriert: 11. Apr 2018 18:05
Answers: 253
Wohnort: Darmstadt

Re: There is no context to infer the closure's argument types from. Consider typing the arguments or put the closures in

Beitrag von udo1toni »

Bist Du sicher, dass die Rule tatsächlich nicht geladen wird? Taucht sie in der Main UI nicht auf?
Das Verhalten erscheint mir seltsam, ich kann das bei mir auch nicht nachvollziehen, ich habe massig Rules mit members.filter[], das müsste dann ja bei mir auch auftreten.
openHAB5.1.1 stable in einem Debian-Container (trixie, OpenJDK 21 headless runtime - LXC, 4 Kerne, 3 GByte RAM)
Hostsystem Proxmox 9.1.5 - AMD Ryzen 5 3600 6 Kerne, 12 Threads - 64 GByte RAM - ZFS Pools: Raid Z1, 3 x 20 TB HDD -> 40 TByte und Raid Z0-Mirrored 4 x 1 TByte NVMe -> 2 TByte

TomW80
Beiträge: 140
Registriert: 7. Mai 2021 19:11
Answers: 2

Re: There is no context to infer the closure's argument types from. Consider typing the arguments or put the closures in

Beitrag von TomW80 »

Ja, da bin ich mir sicher.
Screenshot 2026-02-07 190957.jpg
openhab versucht die Rule zu laden, erkennt einen Fehler und entlädt sie dann wieder.

Wenn ich nach erfolgreichem Start von openhab die Datei mit der Rule neu abspeichere, wird die Rule geladen.
In diesem Beitrag habe ich das dazu gelesen.
at compile time (i.e. when the Rules are loaded) the Rules Engine can’t figure out what type is being used in the lambdas (everything between is a lambda). In particular, it can’t figure out what the type of ITEM is in the first filter in your first Rule or i isin the Windows filter in your second rule.
Und das ist wohl auch mein Problem.
Du hast keine ausreichende Berechtigung, um die Dateianhänge dieses Beitrags anzusehen.

Antworten