Anwesenheitserkennung umsetzen

Einrichtung der openHAB Umgebung und allgemeine Konfigurationsthemen.

Moderatoren: seppy, udo1toni

MrCrashy
Beiträge: 113
Registriert: 2. Jan 2021 09:53
Answers: 0

Re: Anwesenheitserkennung umsetzen

Beitrag von MrCrashy »

Das Handy ist ein Switch-Item

Code: Alles auswählen

String WLAN_Handy1 "WLAN [%s]"
Switch Handy1 "Elias ist [MAP(anwesenheit.map):%s]" <motion> ["Switchable"]
Es sieht jetzt dann genau so aus:

Code: Alles auswählen

2021-01-14 19:25:37.772 [INFO ] [el.core.internal.ModelRepositoryImpl] - Refreshing model 'anwesenheit.rules'
2021-01-14 19:26:03.380 [INFO ] [e.smarthome.model.script.Anwesenheit] - Rule getriggert. WLAN_Handy1 Status: UNDEF
2021-01-14 19:26:18.393 [INFO ] [e.smarthome.model.script.Anwesenheit] - Elias ist unterwegs!
2021-01-14 19:26:32.886 [INFO ] [e.smarthome.model.script.Anwesenheit] - Rule getriggert. WLAN_Handy1 Status: o2-WLAN52
2021-01-14 19:26:47.902 [INFO ] [e.smarthome.model.script.Anwesenheit] - Elias ist unterwegs!
Es erkennt ja anscheinend die SSID. Aber aus irgendeinem Grund triggert es trotzdem die obere Rule.

Der string kennt ja nur zwei Zustände. Einmal den "UNDEF" (wenn ich aus dem WLAN bin) und einmal den "o2-WLAN52" (Wenn ich im WLAN bin). Deswegen kappiere ich das nicht ganz.

EDIT: Muss man vielleicht Definieren, welcher Zustand (Also UNDEF oder o2-WLAN52) gewünscht ist?

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

Re: Anwesenheitserkennung umsetzen

Beitrag von udo1toni »

Ja, aber der Status heißt ja nun o2-WLAN52, nicht WLAN_Handy1. Du musst als String zum Vergleichen also o2-WLAN52 eintragen.
openHAB4.3.5 stable in einem Debian-Container (bookworm) (Proxmox 8.4.1, LXC), mit openHABian eingerichtet

MrCrashy
Beiträge: 113
Registriert: 2. Jan 2021 09:53
Answers: 0

Re: Anwesenheitserkennung umsetzen

Beitrag von MrCrashy »

udo1toni, vielen Dank für die unermüdliche Hilfe! Ich habe es jetzt soweit, dass die Anwesenheit funktioniert. Leider habe ich mir trotzdem irgendwie einen Bock geschossen. Ich wollte für meine Lampensteuerung überprüfen ob ich Zuhause bin oder nicht (Wenn niemand Zuhause ist, braucht das Licht auch nicht angehen). Genauso, sollte auch sein, dass wenn die Lampen eigentlich angeschaltet sein sollen (Also entweder bei festgelegter Zeit oder nach Sonnenuntergang) und ich nach Hause komme, die Lampen dann angehen.
Also z.B. die Lampen stehen auf "Sonnenuntergang" und ich bin nicht Zuhause, dann sollen die nicht eingeschaltet werden. Wenn ich aber nach Sonnenuntergang nach Hause kommen, sollen die Lampen eingeschaltet werden. Ich habe versucht das so umzusetzen:

Code: Alles auswählen

rule "Zeitschaltuhr"
when 
    Time cron "0 00 17-20 * * ?" or //täglich um 17, 18, 19 und 20 Uhr
    Time cron "0 00 21-23 * * ?" or //täglich um 21, 22 und 23 Uhr
    Item Sunset changed to ON or
    Item Spotlight1_Kitchen_Timer_On changed or
    Item Spotlight1_Kitchen_Timer_Off changed or
    Item Livingwall_Childsroom_Timer_On changed or
    Item Livingwall_Childsroom_Timer_Off changed or
    Item Anwesend changed 
then 
    val Spotlight1_OnSel = if(Spotlight1_Kitchen_Timer_On.state instanceof Number) (Spotlight1_Kitchen_Timer_On.state as Number) else 0
    val Spotlight1_OffSel = if(Spotlight1_Kitchen_Timer_Off.state instanceof Number) (Spotlight1_Kitchen_Timer_Off.state as Number) else 0
    val Livingwall_Childsroom_OnSel = if(Livingwall_Childsroom_Timer_On.state instanceof Number) (Livingwall_Childsroom_Timer_On.state as Number) else 0
    val Livingwall_Childsroom_OffSel = if(Livingwall_Childsroom_Timer_Off.state instanceof Number) (Livingwall_Childsroom_Timer_Off.state as Number) else 0
    if(Anwesend == ON){
        if(Spotlight1_OnSel == 0){
            if(Sunset.state == ON && HUE_Kitchen_Spotlight1.getStateAs(OnOffType) != ON){
                HUE_Kitchen_Spotlight1.sendCommand(ON)
                logInfo("lighting", "Spotlight in der Küche wurde zum Sonnenuntergang eingeschaltet!")
            }
        } else if(now.getHourOfDay > (15 + Spotlight1_OnSel) && HUE_Kitchen_Spotlight1.getStateAs(OnOffType) != ON){
            HUE_Kitchen_Spotlight1.sendCommand(ON)
            logInfo("lighting", "Spotlight in der Küche wurde um {}:00 Uhr eingeschaltet!", (16 + Spotlight1_OnSel))
        } else if(now.getHourOfDay > (19 + Spotlight1_OffSel) && HUE_Kitchen_Spotlight1.getStateAs(OnOffType) != OFF){
            HUE_Kitchen_Spotlight1.sendCommand(OFF)
            logInfo("lighting", "Spotlight in der Küche wurde um {}:00 Uhr ausgeschaltet!", (20 + Spotlight1_OffSel))
        }
        if(Livingwall_Childsroom_OnSel == 0){
            if(Sunset.state == ON && HUE_Childsroom_Livingwall.getStateAs(OnOffType) != ON){
                HUE_Childsroom_Livingwall.sendCommand(ON)
                logInfo("lighting", "Wohnwand im Kinderzimmer wurde zum Sonnenuntergang eingeschaltet!")
            }
        } else if(now.getHourOfDay > (15 + Livingwall_Childsroom_OnSel) && HUE_Childsroom_Livingwall.getStateAs(OnOffType) != ON){
            HUE_Childsroom_Livingwall.sendCommand(ON)
            logInfo("lighting", "Wohnwand im Kinderzimmer wurde um {}:00 Uhr eingeschaltet!", (16 + Livingwall_Childsroom_OnSel))
        } else if(now.getHourOfDay > (19 + Livingwall_Childsroom_OffSel) && HUE_Childsroom_Livingwall.getStateAs(OnOffType) != OFF){
            HUE_Childsroom_Livingwall.sendCommand(OFF)
            logInfo("lighting", "Wohnwand im Kinderzimmer wurde um {}:00 Uhr ausgeschaltet!", (20 + Livingwall_Childsroom_OffSel))
        }
    } else if(Anwesend.state == OFF){
        LampsOff.sendCommand(OFF)
        logInfo("lighting", "Alle Lampen wurden Ausgeschaltet, da die Wohnung verlassen wurde.")
    }
end 


Leider bleibt jetzt das Licht immer aus :?: und es wird immer nur der letzte Abschnitt, also "LampsOff" durchgeführt.

int5749
Beiträge: 1173
Registriert: 4. Nov 2019 22:08
Answers: 9

Re: Anwesenheitserkennung umsetzen

Beitrag von int5749 »

MrCrashy hat geschrieben: 14. Jan 2021 19:25 Das Handy ist ein Switch-Item

Code: Alles auswählen

String WLAN_Handy1 "WLAN [%s]"
Mit welchem Binding kann man denn das WLAN abfragen, in dem sich ein Handy befindet? Klingt interessant.
openHAB 4.1.0 Release mit openHABian in einem Debian Bookworm (LXC) unter Proxmox 8.1.3

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

Re: Anwesenheitserkennung umsetzen

Beitrag von udo1toni »

Anwesend ist ein Item. Entsprechend musst Du if(Anwesend.state == ON) schreiben. Hinten hat Du es zwar richtig genutzt, strenggenommen sollte es aber ausreichen, nur vorne nach dem Status zu schauen und hinten lediglich das else stehen zu lassen.

Ohne logInfo(), dafür wesentlich kompakter:

Code: Alles auswählen

rule "Zeitschaltuhr"
when 
    Time cron "0 00 17-20 * * ?" or //täglich um 17, 18, 19 und 20 Uhr
    Time cron "0 00 21-23 * * ?" or //täglich um 21, 22 und 23 Uhr
    Item Sunset changed to ON or
    Item Spotlight1_Kitchen_Timer_On changed or
    Item Spotlight1_Kitchen_Timer_Off changed or
    Item Livingwall_Childsroom_Timer_On changed or
    Item Livingwall_Childsroom_Timer_Off changed or
    Item Anwesend changed 
then 
    val Sl_OnSel  = if(Spotlight1_Kitchen_Timer_On.state instanceof Number) (Spotlight1_Kitchen_Timer_On.state as Number) else 0
    val Sl_OffSel = if(Spotlight1_Kitchen_Timer_Off.state instanceof Number) (Spotlight1_Kitchen_Timer_Off.state as Number) else 0
    val Lc_OnSel  = if(Livingwall_Childsroom_Timer_On.state instanceof Number) (Livingwall_Childsroom_Timer_On.state as Number) else 0
    val Lc_OffSel = if(Livingwall_Childsroom_Timer_Off.state instanceof Number) (Livingwall_Childsroom_Timer_Off.state as Number) else 0
    var Sl = NULL
    var Lc = NULL
    if(Anwesend.state == ON){
        if(Sl_OnSel == 0)
            if(Sunset.state == ON)                   Sl = ON
        else if(now.getHourOfDay > (15 + Sl_OnSel))  Sl = ON
        if(now.getHourOfDay > (19 + Sl_OffSel))      Sl = OFF
        if(Lc_OnSel == 0)
            if(Sunset.state == ON)                   Lc = ON
        else if(now.getHourOfDay > (15 + Lc_OnSel))  Lc = ON
        if(now.getHourOfDay > (19 + Lc_OffSel))      Lc = OFF
    } else {
        Lc = OFF
        Sl = OFF
    }
    if(Sl != NULL && Sl != HUE_Kitchen_Spotlight1.getStateAs(OnOffType)) HUE_Kitchen_Spotlight1.sendCommand(Sl)
    if(Lc != NULL && Lc != UE_Childsroom_Livingwall.getStateAs(OnOffType)) HUE_Childsroom_Livingwall.sendCommand(Lc)
end 
Im ersten Block wird für beide Items entschieden, wie der Sollzustand lautet.
Im zweiten Block wird, falls der Sollzustand gesetzt werden soll (ON oder OFF, nicht NULL) für den Fall eines abweichenden Status der Sollstatus gesetzt. Durch die kürzeren Variablennamen wird der Code (etwas) besser lesbar.

Achso... Du triggerst von 17 - 20 Uhr und dann von 21 bis 23 Uhr. Da sollte dann ein Trigger 17-23 ausreichen.
openHAB4.3.5 stable in einem Debian-Container (bookworm) (Proxmox 8.4.1, LXC), mit openHABian eingerichtet

MrCrashy
Beiträge: 113
Registriert: 2. Jan 2021 09:53
Answers: 0

Re: Anwesenheitserkennung umsetzen

Beitrag von MrCrashy »

OK, ich werde mir das morgen mal ansehen, denn mein System spielt mit meiner Variante etwas verrückt.
Jetzt schaltet sich das Licht gar nicht mehr aus und wenn man die Ausschaltzeit ändert, gehen ALLE Lampen in dieser Rule an. Also z.b es ist 22 Uhr. Wenn ich die Zeit aus Spaß dann auf 21 Uhr Stelle gehen halt alle Lampen dieser Rule an. Muss Mal schauen was da los ist.

Achso und int5749, das kann man über die OpenHAB App auslesen, indem man die App die Handydaten dem Server senden lässt. Habe da ein gutes Tutorial gefunden.
https://bloggingwelt.de/anwesenheitserk ... enhab-app/

int5749
Beiträge: 1173
Registriert: 4. Nov 2019 22:08
Answers: 9

Re: Anwesenheitserkennung umsetzen

Beitrag von int5749 »

MrCrashy hat geschrieben: 15. Jan 2021 22:19 Achso und int5749, das kann man über die OpenHAB App auslesen, indem man die App die Handydaten dem Server senden lässt. Habe da ein gutes Tutorial gefunden.
https://bloggingwelt.de/anwesenheitserk ... enhab-app/
Ahh, OK. Scheint es nur für Android zu geben, in der iOS App finde ich die EInstellung nicht. Mir reicht derzeit die Erkennung über die Fritzbox, auch wenn diese mitunter ein paar Minuten verzögert ist. Ich nutze dies in erster Linie für die Steuerung der Rollladen, je nachdem wer zu Hause ist (Eltern und/oder Kinder oder eben keiner) und zur automatischen AKtivierung des Anwesendheitssimulation etc. Da kann ich mit der Verzögerung leben
openHAB 4.1.0 Release mit openHABian in einem Debian Bookworm (LXC) unter Proxmox 8.1.3

MrCrashy
Beiträge: 113
Registriert: 2. Jan 2021 09:53
Answers: 0

Re: Anwesenheitserkennung umsetzen

Beitrag von MrCrashy »

Ok, ich habe jetzt glaube ich den Fehler gefunden, weiß aber leider nicht wie ich das Lösen soll.
Wenn der Modus auf "Sonnenuntergang" steht, wird ja über den Schalter "Sunset", sobald dieser sich ändert, alles eingeschaltet. Wenn jetzt alles eingeschaltet wurde, dann ist auch alles in Ordnung. Wenn sich das Licht um z.B. 21 Uhr abgeschaltet hat und der Timecron um 22 Uhr wieder triggert, dann wird das Licht wieder eingeschaltet, da der Schalter "Sunset" immer noch An ist, wird die Rule getriggert.

Normalerweise würde ich den Sunset Schalter einfach nach einer Stunde wieder auf "Off" schalten lassen. Das Problem ist ja, wenn ich z.B. eine Stunde nach Sonnenuntergang nach Hause komme, dann triggert die Rule zwar aber das Licht geht nicht an, da der "Sunset" ja schon wieder aus ist.

Außerdem habe ich jetzt mal deine Variante probiert aber VS Code spuckt mir eine Menge Fehler aus:

Code: Alles auswählen

{
	"resource": "/etc/openhab2/rules/beleuchtung.rules",
	"owner": "_generated_diagnostic_collection_name_#0",
	"code": "org.eclipse.xtext.xbase.validation.IssueCodes.incompatible_types",
	"severity": 8,
	"message": "Type mismatch: cannot convert from OnOffType to UnDefType",
	"startLineNumber": 74,
	"startColumn": 62,
	"endLineNumber": 74,
	"endColumn": 64
}
UND

Code: Alles auswählen

Type mismatch: cannot convert from UnDefType to String
Den oberen Fehler hat er in vielen verschiedenen Zeilen, den unteren Fehler hat er in zwei Zeilen (80, 81)
im OpenHAB Log sind aber keine Fehler, die Rules lädt er angeblich normal.

So sieht meine Rule jetzt aus:

Code: Alles auswählen

rule "Zeitschaltuhr"
when 
    Time cron "0 00 17-23 * * ?" or //täglich um 17, 18, 19 und 20 Uhr
    Item Sunset changed to ON or
    Item Spotlight1_Kitchen_Timer_On changed or
    Item Spotlight1_Kitchen_Timer_Off changed or
    Item Livingwall_Childsroom_Timer_On changed or
    Item Livingwall_Childsroom_Timer_Off changed or
    Item Anwesend changed 
then 
    val Sl1_OnSel = if(Spotlight1_Kitchen_Timer_On.state instanceof Number) (Spotlight1_Kitchen_Timer_On.state as Number) else 0
    val Sl1_OffSel = if(Spotlight1_Kitchen_Timer_Off.state instanceof Number) (Spotlight1_Kitchen_Timer_Off.state as Number) else 0
    val Lc_OnSel = if(Livingwall_Childsroom_Timer_On.state instanceof Number) (Livingwall_Childsroom_Timer_On.state as Number) else 0
    val Lc_OffSel = if(Livingwall_Childsroom_Timer_Off.state instanceof Number) (Livingwall_Childsroom_Timer_Off.state as Number) else 0
    var Sl = NULL
    var Lc = NULL
    if(Anwesend.state == ON){
        if(Sl1_OnSel == 0)
            if(Sunset.state == ON)                       Sl = ON 
        else if(now.getHourOfDay > (15 + Sl1_OnSel))     Sl = ON
        if(now.getHourOfDay > (19 + Sl1_OffSel))         Sl = ON 
        if(Lc_OnSel == 0)
            if(Sunset.state == ON)                      Lc = ON 
        else if(now.getHourOfDay > (15 + Lc_OnSel))     Lc = ON
        if(now.getHourOfDay > (19 + Lc_OffSel))         Lc = OFF 
    } else {
        Lc = OFF 
        Sl = OFF 
    }
    if(Sl != NULL && Sl != HUE_Kitchen_Spotlight1.getStateAs(OnOffType)) HUE_Kitchen_Spotlight1.sendCommand(Sl)
    if(Lc != NULL && Lc != HUE_Childsroom_Livingwall.getStateAs(OnOffType)) HUE_Childsroom_Livingwall.sendCommand(Lc)
end 

MrCrashy
Beiträge: 113
Registriert: 2. Jan 2021 09:53
Answers: 0

Re: Anwesenheitserkennung umsetzen

Beitrag von MrCrashy »

EDIT: Ich habe jetzt trotzdem einfach mal über einen Schalter in der Sitemap den "Sunset" getriggert. In der Openhablog-Datei habe ich nun folgenden Fehler

Code: Alles auswählen

Rule 'Zeitschaltuhr': An error occurred during the script execution: Could not invoke method: org.eclipse.smarthome.model.script.actions.BusEvent.sendCommand(org.eclipse.smarthome.core.items.Item,java.lang.String) on instance: null
Ich komme nicht auf den Fehler.

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

Re: Anwesenheitserkennung umsetzen

Beitrag von udo1toni »

Es ist schade, dass da offensichtlich etwas geändert wurde, früher mal hat das funktioniert. Dann läuft es darauf hinaus, dass die Rule immer einen definierten Zustand erzwingen muss.

Code: Alles auswählen

rule "Zeitschaltuhr"
when 
    Time cron "0 00 17-20 * * ?" or //täglich um 17, 18, 19 und 20 Uhr
    Time cron "0 00 21-23 * * ?" or //täglich um 21, 22 und 23 Uhr
    Item Sunset changed to ON or
    Item Spotlight1_Kitchen_Timer_On changed or
    Item Spotlight1_Kitchen_Timer_Off changed or
    Item Livingwall_Childsroom_Timer_On changed or
    Item Livingwall_Childsroom_Timer_Off changed or
    Item Anwesend changed 
then 
    val Sl_OnSel  = if(Spotlight1_Kitchen_Timer_On.state instanceof Number) (Spotlight1_Kitchen_Timer_On.state as Number) else 0
    val Sl_OffSel = if(Spotlight1_Kitchen_Timer_Off.state instanceof Number) (Spotlight1_Kitchen_Timer_Off.state as Number) else 0
    val Lc_OnSel  = if(Livingwall_Childsroom_Timer_On.state instanceof Number) (Livingwall_Childsroom_Timer_On.state as Number) else 0
    val Lc_OffSel = if(Livingwall_Childsroom_Timer_Off.state instanceof Number) (Livingwall_Childsroom_Timer_Off.state as Number) else 0
    var Sl = OFF
    var Lc = OFF
    if(Anwesend.state == ON){
        if(Sl_OnSel == 0)
            if(Sunset.state == ON)                   Sl = ON
        else if(now.getHourOfDay > (15 + Sl_OnSel))  Sl = ON
        if(now.getHourOfDay > (19 + Sl_OffSel) || now.getHourOfDay < 15)      Sl = OFF
        if(Lc_OnSel == 0)
            if(Sunset.state == ON)                   Lc = ON
        else if(now.getHourOfDay > (15 + Lc_OnSel))  Lc = ON
        if(now.getHourOfDay > (19 + Lc_OffSel) || now.getHourOfDay < 15)      Lc = OFF
    } else {
        Lc = OFF
        Sl = OFF
    }
    if(Sl != HUE_Kitchen_Spotlight1.getStateAs(OnOffType)) HUE_Kitchen_Spotlight1.sendCommand(Sl)
    if(Lc != UE_Childsroom_Livingwall.getStateAs(OnOffType)) HUE_Childsroom_Livingwall.sendCommand(Lc)
end 
Also ohne die Einschränkung mit NULL. Grundstellung ist OFF. Die OR Bedingung sorgt dafür, dass das Licht nicht vor 15 Uhr angeht.
Die Sache mit dem Sonnenuntergang dürfte bei "meiner" Variante kein Problem sein, da der Schalter zwar zuerst nach ON wechselt, anschließend aber wieder nach OFF gewechselt wird, falls die Ausschaltzeit bereits erreicht wurde.
openHAB4.3.5 stable in einem Debian-Container (bookworm) (Proxmox 8.4.1, LXC), mit openHABian eingerichtet

Antworten