Bewegungsmelder mit Timer

Einrichtung der openHAB Umgebung und allgemeine Konfigurationsthemen.

Moderatoren: seppy, udo1toni

Antworten
Benutzeravatar
peter-pan
Beiträge: 2758
Registriert: 28. Nov 2018 12:03
Answers: 30
Wohnort: Schwäbisch Gmünd

Bewegungsmelder mit Timer

Beitrag von peter-pan »

Ich habe einen Bewegungsmelder im Arbeitszimmer und habe dafür eine DSL-Regel gemacht.

Code: Alles auswählen

import org.openhab.core.model.script.ScriptServiceUtil
rule "motion_snzb03"
  when
   Item snzb03_01_occupancy changed to ON
  then
   var  GenericItem itemTemp  = ScriptServiceUtil.getItemRegistry.getItem(triggeringItemName) as GenericItem    // Initialize Generic Item 
   var strLocation = getLocation(itemTemp).label                                                                // Location Label ermitteln
   logInfo("snzb03", "Da hat sich was getan im {} von {} : Bewegung gerade: {} ", strLocation, triggeringItemName,  newState)
end
Jetzt triggert die Regel alle paar Minuten. Ich sitze halt man an Bildschirm ein oder zwei Minuten und "bewege mich nicht" ;) . D. h. ich lese oder schreibe evtl. einen Post. Dadurch wird die Regel immer neu getriggert.
Ich habe zwar hier im Forum schon einige Beispiele gesehen, aber die passen nicht so ganz, weil der Timer halt nicht nach einer bestimmten Zeit ablaufen soll, sondern weiterlaufen soll, wenn der Bewegungssensor innerhalb der ersten Timer-Zeit wieder angeschaltet wird . :oops: :roll:

So sollte es also nicht sein

Code: Alles auswählen

2025-01-30 15:16:10.349 [INFO ] [org.openhab.core.model.script.snzb03] - Da hat sich was getan im Arbeitszimmer von snzb03_01_occupancy : Bewegung gerade: ON 
2025-01-30 15:18:29.803 [INFO ] [org.openhab.core.model.script.snzb03] - Da hat sich was getan im Arbeitszimmer von snzb03_01_occupancy : Bewegung gerade: ON 
2025-01-30 15:21:25.985 [INFO ] [org.openhab.core.model.script.snzb03] - Da hat sich was getan im Arbeitszimmer von snzb03_01_occupancy : Bewegung gerade: ON 
... das alle paar Minuten neu geloggt wird.
von udo1toni » 31. Jan 2025 12:56
Ja, nun. Das Problem dabei ist halt, dass es schlicht nicht möglich ist, zu unterscheiden, ob Bewegnung erkannt wurde, weil der Raum initial betreten wurde oder weil jemand sich zwischenzeitlich nicht bewegt hat - außer halt, man nutzt einen Timer (wie oben vorgeschlagen).
Der Timer muss dann halt lange genug laufen.
Vergiss in diesem Zusammenhang .reschedule(), das ist hier nicht so gut geeignet. Stattdessen reicht es, den Timer neu anzulegen, das kostet auch nicht mehr Zeit.
Also die vollständige Rule ohne unnötigen Ballast:

Code: Alles auswählen

var Timer tMotion = null                                                              // globale Timer Variable

rule "Bewegungserkennung snzb03"
when
    Item snzb03_01_occupancy changed to ON                                            // Bewegung erkannt
then
    if(tMotion===null) {                                                              // valls kein Timer erkannt
        logInfo("snzb03", "Da hat sich was getan im Arbeitszimmer von motion_snzb03") // Meldung für Bewegung
    }
    tMotion?.cancel                                                                   // existente Timer wegwerfen
    tMotion = createTimer(now.plusMinutes(5), [|                                      // Timer Anlegen
        tMotion = null                                                                // Bei Ablauf des Timers Timer löschen
    ])
end
Gehe zur vollständigen Antwort
Pi5/8GB(PiOS Lite 64-bit(bookworm)/SSD 120GB - OH4.3.5 openhabian

violine21
Beiträge: 600
Registriert: 20. Sep 2019 05:49
Answers: 7

Re: Bewegungsmelder mit Timer

Beitrag von violine21 »

Hallo Peter,

ich habe meine Bewegungsmelder alle so per Rule eingebunden:

Code: Alles auswählen

var Timer t_Licht_Anbau = null
rule "Beleuchtung Anbau"
when
    Item HMEGAnbauBewegungsmelder1MOTION changed
then
// Licht Anbau Ein
    if(Shelly25BeleuchtungAnbau_Relay1Output.state == OFF) {
        if(HMEGAnbauBewegungsmelder1MOTION.state == ON && Lichtstaerke.state <= 10) {
            Shelly25BeleuchtungAnbau_Relay1Output.sendCommand(ON)
        }
    }
    
// Licht Anbau Aus
    if(Shelly25BeleuchtungAnbau_Relay1Output.state == ON && HMEGAnbauBewegungsmelder1MOTION.state == OFF) {
        t_Licht_Anbau?.cancel 
        t_Licht_Anbau = createTimer(now.plusSeconds(60), [
            Shelly25BeleuchtungAnbau_Relay1Output.sendCommand(OFF)
            t_Licht_Anbau = null
        ])
    }

// Ausschalt-Zeit stoppen und Timer löschen
    if(Shelly25BeleuchtungAnbau_Relay1Output.state == ON && HMEGAnbauBewegungsmelder1MOTION.state == ON) {
        if(t_Licht_Anbau !== null) {
            t_Licht_Anbau?.cancel
            t_Licht_Anbau = null
        }
    }

end
Wenn während das Licht eingeschaltet ist, erneut eine Bewegung stattfindet, wird die Ausschaltzeit erneut gestartet und das Licht geht zwischendurch nicht aus.
Die Bewegungsmelder sind von Homatic IP.

Gruß André

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

Re: Bewegungsmelder mit Timer

Beitrag von udo1toni »

Noch ist da ja gar kein Timer (also außer dem im Bewegungsmelder eingebauten).
aber ich nehme an, es ist auch nicht mit dem einen Timer getan, die Rule soll sich um mehrere Bewegungsmelder kümmern, oder?
Sonst wäre es reichlich umständlich, über die ItemRegistry die Location zu ermitteln...
Die einfachste Variante ist ein Timer, geprüft und gegebenenfalls erneut gestartet wird.

Code: Alles auswählen

import org.openhab.core.model.script.ScriptServiceUtil

var Timer tMotion = null

rule "motion_snzb03"
when
    Item snzb03_01_occupancy changed to ON
then
    var GenericItem itemTemp  = ScriptServiceUtil.getItemRegistry.getItem(triggeringItemName) as GenericItem    // Initialize Generic Item 
    var strLocation = getLocation(itemTemp).label                                                                // Location Label ermitteln
    if(tMotion===null) {
        logInfo("snzb03", "Da hat sich was getan im {} von {} : Bewegung gerade: {} ", strLocation, triggeringItemName,  newState)
    }
    tMotion?.cancel
    tMotion = createTimer(now.plusMinutes(2),[|
        logInfo("snzb03", "nu aber lang genug gewartet, Licht aus!")
        tMotion = null
    ])
end
Nur wenn der Timer noch nicht gestartet wurde, erfolgt die Meldung. Läuft der Timer hingegen, so bleibt die Meldung aus. Bei jeder Erkennung wird außerdem der Timer gelöscht und erneut gestartet.
Sobald es mehrere Melder betrifft (die voneinander unabhängig arbeiten sollen), benötigt man ein Array, in das man jeweils den Timer hineinschreibt und ihn wieder löscht. Dabei bietet es sich dann an, den jeweiligen Itemnamen auch für den Timer zu verwenden.
openHAB4.3.3 stable in einem Debian-Container (bookworm) (Proxmox 8.3.5, LXC), mit openHABian eingerichtet

Benutzeravatar
peter-pan
Beiträge: 2758
Registriert: 28. Nov 2018 12:03
Answers: 30
Wohnort: Schwäbisch Gmünd

Re: Bewegungsmelder mit Timer

Beitrag von peter-pan »

@violine21
Hallo André,
lange nichts mehr von dir gehört. Danke für dein Vorschlag. Aber eigentlich geht es mir weniger darum ein anderes Gerät zu schalten und ggf. über einen bestimmten Zeitraum nicht wieder ausgehen zu lassen. Ich schau's mir aber nochmal genauer an.
Liebe Grüsse in den Harz - Peter

@udo1toni
udo1toni hat geschrieben: 31. Jan 2025 00:55 Noch ist da ja gar kein Timer (also außer dem im Bewegungsmelder eingebauten).
Das mit der Location ist einfach eine Spielerei um aus einer Eigenschaft (semantisches Modell) den Standort des Gerätes (Equipment) zu ermitteln. Das geht mit DSL super und soweit Ich weiss mit JS nicht bzw. nur ganz kompliziert mit mehreren Repeatern(JustinG) . Das hab ich eigentlich aus einer anderen Regel abgeleitet, die mit mehreren Bewegungsmeldern arbeitet. (Ich vermute mal stark, dass du mir da auch geholfen hast :oops: ). Es geht eigentlich nur um die Information, das eine Bewegung erkannt wurde.
So sieht sie aus:

Code: Alles auswählen

import org.openhab.core.model.script.ScriptServiceUtil
rule "motion_all"
  when
   Member of gMoSo changed to ON
  then
   if (snzb03_01_occupancy.state == ON || snzb03_01_occupancy.state == OFF) return;  // Ergänzung
   var  GenericItem itemTemp  = ScriptServiceUtil.getItemRegistry.getItem(triggeringItemName) as GenericItem    // Initialize Generic Item 
   var strLocation = getLocation(itemTemp).label                                                                // Location Label ermitteln
   logInfo("motion", "Da hat sich was getan im {} von {} : Bewegung gerade: {} ", strLocation, triggeringItemName,  newState)
   val mailActions = getActions("mail","mail:smtp:tonline-smtp")
   mailActions.sendMail("name@provider.de", "Bewegung im: " + strLocation, "durch: " + itemTemp.label)
Ich hab da noch eine Bedingung eingebaut, damit ich nicht mit Spam-Mails und Logs überflutet werde, weil ich im Arbeitszimmer sitze und irgend etwas mache und der Bewegungsmelder isch nach einer gewissen Zeit wieder ausschaltet und danach wieder angeht. (Er soll sozusagen nicht merken, dass ich nichts tue :oops: ;) )

Ich hab auch schon mal versucht einen Timer einzubauen, aber das was ich da fabriziert habe, war nur "Schrott" :oops:
Versuch:

Code: Alles auswählen

// https://openhabforum.de/viewtopic.php?p=57780&hilit=bewegungsmelder+timer#p57780

var Timer occupancyTimer = null
val int timeoutMinutes = 5

rule "motion_snzb03"
  when
   Item snzb03_01_occupancy changed to ON
  then
   var  GenericItem itemTemp  = ScriptServiceUtil.getItemRegistry.getItem(triggeringItemName) as GenericItem    // Initialize Generic Item 
   var strLocation = getLocation(itemTemp).label                                                                // Location Label ermitteln
   logInfo("snzb03", "Da hat sich was getan im {} von {} : Bewegung gerade: {} ", strLocation, triggeringItemName,  newState)
  if	(occupancyTimer === null)	{
  	  occupancyTimer = createTimer(now.plusMinutes(timeoutMinutes)) [|
      logInfo("snzb03", "Da hat sich was getan im {} von {} : Bewegung gerade: {} ", strLocation, triggeringItemName,  newState)
  
  		occupancyTimer = null
  		]
  }	else	if (snzb03_01_occupancy.state == ON) 
      {occupancyTimer.reschedule(now.plusMinutes(timeoutMinutes))
  } else occupancyTimer = null
end
... weil ich's wohl nicht richtig verstanden habe.

Wie gesagt, es geht nur darum (und bei diesem Bewegungmelder), dass die Meldungen(Log/Email) sich nicht permanet wiederholen, wenn sich jemand über längere Zeit im Arbeitszimmer aufhält. Der Timer soll halt bestehen bleiben solange ich mich im Raum aufhalte, auch wenn ich mal eine Minute still stehe :lol: und der Bewegungsmelder sich in der Zwischenzeit aus- und wieder angeschaltet hat.

Dank an euch im voraus.
Pi5/8GB(PiOS Lite 64-bit(bookworm)/SSD 120GB - OH4.3.5 openhabian

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

Re: Bewegungsmelder mit Timer

Beitrag von udo1toni »

Ja, nun. Das Problem dabei ist halt, dass es schlicht nicht möglich ist, zu unterscheiden, ob Bewegnung erkannt wurde, weil der Raum initial betreten wurde oder weil jemand sich zwischenzeitlich nicht bewegt hat - außer halt, man nutzt einen Timer (wie oben vorgeschlagen).
Der Timer muss dann halt lange genug laufen.
Vergiss in diesem Zusammenhang .reschedule(), das ist hier nicht so gut geeignet. Stattdessen reicht es, den Timer neu anzulegen, das kostet auch nicht mehr Zeit.
Also die vollständige Rule ohne unnötigen Ballast:

Code: Alles auswählen

var Timer tMotion = null                                                              // globale Timer Variable

rule "Bewegungserkennung snzb03"
when
    Item snzb03_01_occupancy changed to ON                                            // Bewegung erkannt
then
    if(tMotion===null) {                                                              // valls kein Timer erkannt
        logInfo("snzb03", "Da hat sich was getan im Arbeitszimmer von motion_snzb03") // Meldung für Bewegung
    }
    tMotion?.cancel                                                                   // existente Timer wegwerfen
    tMotion = createTimer(now.plusMinutes(5), [|                                      // Timer Anlegen
        tMotion = null                                                                // Bei Ablauf des Timers Timer löschen
    ])
end
openHAB4.3.3 stable in einem Debian-Container (bookworm) (Proxmox 8.3.5, LXC), mit openHABian eingerichtet

Benutzeravatar
peter-pan
Beiträge: 2758
Registriert: 28. Nov 2018 12:03
Answers: 30
Wohnort: Schwäbisch Gmünd

Re: Bewegungsmelder mit Timer

Beitrag von peter-pan »

Danke, probier ich gleich.
Pi5/8GB(PiOS Lite 64-bit(bookworm)/SSD 120GB - OH4.3.5 openhabian

Harka
Beiträge: 487
Registriert: 30. Apr 2021 13:13
Answers: 19

Re: Bewegungsmelder mit Timer

Beitrag von Harka »

peter-pan hat geschrieben: 31. Jan 2025 12:26 Das mit der Location ist einfach eine Spielerei um aus einer Eigenschaft (semantisches Modell) den Standort des Gerätes (Equipment) zu ermitteln. Das geht mit DSL super und soweit Ich weiss mit JS nicht bzw. nur ganz kompliziert mit mehreren Repeatern(JustinG) .
zur Ehrenrettung von JS - soooo kompliziert ist es auch nicht

Code: Alles auswählen

var sTriggerItem = event.itemName;
var sLocation = (items.getItem(sTriggerItem).semantics.location).label;
console.info(sLocation);

Benutzeravatar
peter-pan
Beiträge: 2758
Registriert: 28. Nov 2018 12:03
Answers: 30
Wohnort: Schwäbisch Gmünd

Re: Bewegungsmelder mit Timer

Beitrag von peter-pan »

Harka hat geschrieben: 31. Jan 2025 19:52 var sTriggerItem = event.itemName;
var sLocation = (items.getItem(sTriggerItem).semantics.location).label;
console.info(sLocation);
Sorry, da hab ich mich wohl falsch ausgedrückt. :oops:
Ich denke schon, dass diese Funktionen/Methoden jetzt auch in JS zur Verfügung stehen.
Ich hab das mehr auf das Scripten in den Widgets bezogen. Da hab ich das bisher noch nicht hingekriegt.
temp.jpg
Yaml-Code:

Code: Alles auswählen

uid: my_temperature_list
tags:
  - https://openhabforum.de/viewtopic.php?t=7384&sid=0dae0b8ffc77799cca3980390293b5a3
props:
  parameters:
    - label: Title
      name: title
      required: true
      type: TEXT
    - context: item
      label: Group
      name: itemGroup
      required: true
      type: TEXT
  parameterGroups: []
timestamp: Jan 24, 2025, 2:58:10 PM
component: oh-list-card
config:
  title: =items[props.itemGroup].displayState + " " + props.title + ":"
  visible: =items[props.itemGroup].state !=0
slots:
  default:
    - component: oh-list
      config:
        mediaList: true
      slots:
        default:
          - component: oh-repeater
            config:
              fetchMetadata: semantics,widgetOrder
              filter: items[loop.item.name].state != 0
              for: item
              fragment: true
              groupItem: =props.itemGroup
              sourceType: itemsInGroup
            slots:
              default:
                - component: oh-list-item
                  config:
                    badge: =loop.item.state
                    badgeColor: teal
                    footer: =loop.item.metadata.semantics.getLocation(item)
                    icon: ='oh:' + loop.item.category
                    title: =loop.item.label + " ; " + loop.item.groupNames
Ich selbst habe mich bisher noch nicht so sehr mit JS beschäftigt und das was ich an Regeln brauche hab ich bisher ganz gut mit DSL lösen können (Text-Files).
Du hast keine ausreichende Berechtigung, um die Dateianhänge dieses Beitrags anzusehen.
Pi5/8GB(PiOS Lite 64-bit(bookworm)/SSD 120GB - OH4.3.5 openhabian

Harka
Beiträge: 487
Registriert: 30. Apr 2021 13:13
Answers: 19

Re: Bewegungsmelder mit Timer

Beitrag von Harka »

peter-pan hat geschrieben: 31. Jan 2025 23:55 Ich hab das mehr auf das Scripten in den Widgets bezogen. Da hab ich das bisher noch nicht hingekriegt.
Jup, da steht nicht der komplette Befehlsumfang zur Verfügung. https://www.openhab.org/docs/ui/widget- ... ables.html

Antworten