[Gelöst] Alternierendes Signal

Begonnen von manne44, 27 Januar 2018, 09:23:25

Vorheriges Thema - Nächstes Thema

manne44

Hallo,
ich bekomme von meiner Gartentor-Steuerung folgendes Signal an den Pin des BPi, wenn ich das Tor öffnen oder wieder schließen will:

Tor öffnen:

    +---+   +-----------------------------------------------
    |   |   |
----+   +---+


Tor schließen:

----+   +---+   +---+   +---+   +---+   +---+   
    |   |   |   |   |   |   |   |   |   |   |
    +---+   +---+   +---+   +---+   +---+   +---------------

   
Das ganze wird nun mit folgendem DOIF abgehandelt:

define di_pin13 DOIF ([pin13:Pinlevel] eq "high" and [oWD:Door.Garten] eq "closed") (setreading oWD Door.Garten open, set swGartentorText schließen, \
( IF ([LDRx:ldr_value] < 110) (set pin21 on, defmod myAtoutLightOn at +00:00:02 set pin21 off, \
({Log(3, "TOR-AUTOMATIK: Tor geöffnet und Außenlicht bei Dunkelheit eingeschaltet.")})) \
  ELSE (({Log(3, "TOR-AUTOMATIK: Tor geöffnet.")})))) \
DOELSEIF ([pin13:Pinlevel] eq "low" and [oWD:Door.Garten] eq "open") (setreading oWD Door.Garten closed, set swGartentorText öffnen, \
{Log(3, "TOR-AUTOMATIK: Tor geschlossen.")})


Im Log-File werden dann folgerichtig viele sinnlose Einträge geschrieben:

2018.01.27 07:46:05 2: TOR_AUTOMATIK: Tor geschlossen.
2018.01.27 07:46:06 2: TOR_AUTOMATIK: Tor geöffnet und Außenlicht bei Dunkelheit eingeschaltet.
2018.01.27 07:46:07 2: TOR_AUTOMATIK: Tor geschlossen.
2018.01.27 07:46:08 2: TOR_AUTOMATIK: Tor geöffnet und Außenlicht bei Dunkelheit eingeschaltet.
2018.01.27 07:46:09 2: TOR_AUTOMATIK: Tor geschlossen.
2018.01.27 07:46:10 2: TOR_AUTOMATIK: Tor geöffnet und Außenlicht bei Dunkelheit eingeschaltet.
2018.01.27 07:46:11 2: TOR_AUTOMATIK: Tor geschlossen.
2018.01.27 07:46:12 2: TOR_AUTOMATIK: Tor geöffnet und Außenlicht bei Dunkelheit eingeschaltet.
2018.01.27 07:46:13 2: TOR_AUTOMATIK: Tor geschlossen.
2018.01.27 07:46:14 2: TOR_AUTOMATIK: Tor geöffnet und Außenlicht bei Dunkelheit eingeschaltet.
2018.01.27 07:46:15 2: TOR_AUTOMATIK: Tor geschlossen.
2018.01.27 07:46:16 2: TOR_AUTOMATIK: Tor geöffnet und Außenlicht bei Dunkelheit eingeschaltet.
2018.01.27 07:46:17 2: TOR_AUTOMATIK: Tor geschlossen.
2018.01.27 07:46:18 2: TOR_AUTOMATIK: Tor geöffnet und Außenlicht bei Dunkelheit eingeschaltet.
2018.01.27 07:46:19 2: TOR_AUTOMATIK: Tor geschlossen.
2018.01.27 07:46:20 2: TOR_AUTOMATIK: Tor geöffnet und Außenlicht bei Dunkelheit eingeschaltet.
2018.01.27 07:46:21 2: TOR_AUTOMATIK: Tor geschlossen.
2018.01.27 07:46:22 2: TOR_AUTOMATIK: Tor geöffnet und Außenlicht bei Dunkelheit eingeschaltet.
2018.01.27 07:46:23 2: TOR_AUTOMATIK: Tor geschlossen.


Das ist zwar unschädlich, es gefällt mir aber nicht. Nach dem obigen DOIF müssen diese Einträge auch gemacht werden, aber ich will nur einen davon sehen.
Frage: Wie muß ich das DOIF verändern, damit immer nur ein Eintrag passiert / Befehl ausgeführt wird?
Ich habe schon mit wait(x:y) und mit cmdpause probiert, aber kein vernünftiges Ergebnis bekommen.
Kann mir da jemand helfen?
RPI4-Buster mit SSD, RPI-Zero mit Bookworm

abc2006

Ist das ein digitales Signal, oder ist das ein mechanischer Kontakt (der evtl prellt)?

Wenn mechanisch: analog entprellen (Kondensator).
Wenn digital:
event-aggregator mit hold_time > 5T und function v?

Grüße,
Stephan
FHEM nightly auf Intel Atom (lubuntu) mit VDSL 50000 ;-)
Nutze zur Zeit OneWire und KNX

manne44

Hallo, vielen Dank für die Antwort.
Das Signal kommt als 24-Volt-Wechselstromsignal aus der Torsteuerung, wird von mir gleichgerichtet, mit C geglättet, durch einen Optokoppler gejagt und trifft dann durch Kollektorschaltung des Optokoppler-Transistors auf den GPIO des BPi, wo man das Signal auch abgreifen und sichtbar machen kann. Der Optokoppler dient gleichzeitig als Pegelwandler und der Pegel geht dann von 0..3,6V.

Zum "event-aggregator":
Ich habe von dieser Funktion bisher überhaupt nichts gewußt. Sie ist aber überaus sparsam beschrieben, so dass man bei der richtigen Notation nur raten kann.
Wie soll ich das denn angeben? In der Command-Referenz steht nichts wirklich deutliches und im unvollständigen Wiki steht

attr <device> event-aggregator reading:interval:method:function:holdTime

Das ist wirkungslos:

attr pin13 event-aggregator Pinlevel:none:none:v:12
attr pin13 event-aggregator Pinlevel:12:none:none:v
attr pin13 event-aggregator Pinlevel:12:none:v
attr pin13 event-aggregator Pinlevel:12:v

führt immer zu irgendwelchen arithmetischen Fehlermeldungen wie z.B.

PERL WARNING: Argument "none" isn't numeric in numeric ge (>=) at FHEM/TimeSeries.pm line 265, <GEN58336> line 3.
PERL WARNING: Argument "low" isn't numeric in subtraction (-) at FHEM/TimeSeries.pm line 247, <GEN58336> line 3.
PERL WARNING: Argument "high" isn't numeric in addition (+) at FHEM/TimeSeries.pm line 249, <GEN58336> line 3.

Es scheint so zu sein, dass diese Funktion hauptsächlich zur Mittelwertbildung arithmetischer Werte benutzt werden soll und damit auch die Log-Einträge und Events verringert werden sollen. Also entweder ich mache das mit "event-aggregator" völlig falsch oder es ist für die Lösung meines Problems nicht geeignet.
RPI4-Buster mit SSD, RPI-Zero mit Bookworm

abc2006

Du machst es völlig falsch:) 8)
tl; dr:
Pinlevel:12:none:v


Ne, mal ernsthaft:

reading:interval:method:function:holdTime

reading ist wohl klar: pinlevel_v1
interval: wie ich bereits sagte, würde ich Interval so lang wählen, dass alle wechsel reinpassen. also 5*T. Da ich nicht weiss, wie lang die Periodendauer ist, kann ich dir hier nix vorgeben.
method: hier willst du nix machen. Hier stünden tatsächlich arithmetische funktionen zur Verfügung, die dann zeitgewichtet berechnen. Da du die nicht brauchst: none
function: hier sagst du, dass du den *letzten* Wert haben willst, der in einem Interval aufgetaucht ist.
kurze erklärung:
T=0
Pinlevel = high
T=1
Pinlevel = low
T=11
Pinlevel = high
T=12
Pinlevel = high
Event-aggregator erzeugt ein Event "pin13:pinlevel high"
Dann gehts wieder von vorne los. Wenn keine Events kommen, macht der aggregator auch nix.
holdTime: Da du keinen mittelwert bilden willst, und keine Vergangenheitsdaten haben willst, lässt du diesen Parameter weg. Samt dem Doppelpunkt.
########

Soweit schonmal die reine funktion. Habe gerade auch gesehen, dass die Meldungen im Log auftauchen.
jetzt gibts drei möglichkeiten:
1. ) du lebst damit. Ist ja nur ne Warning.
2. ) du fragst den Maintainer, ob er da irgendwas einbaut, damit die Fehlermeldung nicht mehr kommt (naja, vielleicht gibts da auch schon was was ich nicht kenne)
3.) du kümmerst dich selbst drum:
attr pin13 userReadings pinlevel_bin {ReadingsVal($name,"Pinlevel","error") eq "high" ? 1:0}
damit haste einen Pinlevel 0/1
Wenn du es jetzt umbaust auf
pinlevel_bin:12:none:v


Haste wasde willst :)
Ich hoff, ich hab jetzt nicht allzuviel Mist geschrieben oder dich falsch verstanden .. ist ja schon spät.
Versuchs mal, und wenns nicht klappt, sehen wir weiter.

Grüße,
Stephan

PS: kannste natürlich mit nem zweiten UserReading wieder auf "high" und "low" umwandeln, falls dir das wichtig ist.
FHEM nightly auf Intel Atom (lubuntu) mit VDSL 50000 ;-)
Nutze zur Zeit OneWire und KNX

manne44

Hallo Stephan, vielen Dank für die ausführliche Antwort. Ich habe das eben als letzte Aktion genauso gemacht, aber es gibt keine Änderung, nur dass es jetzt keine Fehlermeldungen mehr gibt:

define pin13 RPI_GPIO 27
...
attr pin13 userReadings pinlevel_bin {ReadingsVal($name,"Pinlevel","error") eq "high" ? 1:0}
attr pin13 event-aggregator pinlevel_bin:12:none:v

und im DOIF auf pinlevel_bin anstatt Pinlevel abfragen:

define di_pin13 DOIF ([pin13:pinlevel_bin] == 1 and [oWD:Door.Garten] eq "closed") (setreading oWD Door.Garten open, set swGartentorText schließen, ...

Die Log-Einträge werden nicht reduziert und das DOIF springt bei jedem Event an.
RPI4-Buster mit SSD, RPI-Zero mit Bookworm

abc2006

okay.. ist dein fhem aktuell?
poste mal die Ausgabe von "version".
und bitte ein "list pin13" sowie ein "list di_pin13", dann schau ich nochmal, ob mir was auffällt...

Grüße,
Stephan
FHEM nightly auf Intel Atom (lubuntu) mit VDSL 50000 ;-)
Nutze zur Zeit OneWire und KNX

manne44

Hier mal die Auflistungen:

Version:

Latest Revision: 15834

File                 Rev   Last Change

fhem.pl              15804 2018-01-06 17:20:00Z rudolfkoenig
96_allowed.pm        15709 2017-12-27 15:03:48Z rudolfkoenig
90_at.pm             15795 2018-01-05 20:46:21Z rudolfkoenig
98_autocreate.pm     15620 2017-12-16 18:10:36Z rudolfkoenig
57_Calendar.pm       15612 2017-12-15 09:26:59Z neubert
98_cmdalias.pm       15161 2017-10-01 10:17:28Z rudolfkoenig
10_CUL_HM.pm         15816 2018-01-07 18:17:57Z martinp876
93_DbLog.pm          15702 2017-12-27 09:19:30Z DS_Starter
98_DOIF.pm           15751 2018-01-02 11:03:10Z Damian
98_dummy.pm          12700 2016-12-02 16:49:42Z rudolfkoenig
91_eventTypes.pm     14888 2017-08-13 12:07:12Z rudolfkoenig
00_FBAHA.pm          15437 2017-11-16 08:48:48Z rudolfkoenig
10_FBDECT.pm         15670 2017-12-22 22:03:42Z rudolfkoenig
72_FB_CALLLIST.pm    15810 2018-01-07 11:09:26Z markusbloch
72_FB_CALLMONITOR.pm 15534 2017-12-01 18:06:31Z markusbloch
93_FHEM2FHEM.pm      15006 2017-09-05 09:37:33Z rudolfkoenig
01_FHEMWEB.pm        15804 2018-01-06 17:20:00Z rudolfkoenig
92_FileLog.pm        15628 2017-12-17 12:01:30Z rudolfkoenig
72_FRITZBOX.pm       15831 2018-01-08 18:51:14Z tupol
# $Id: 99_getstate.pm,v 1.3 2009-12-16 16:46:00 m_fischer Exp $
98_HMinfo.pm         15767 2018-01-03 18:42:20Z martinp876
00_HMUARTLGW.pm      15596 2017-12-12 14:05:48Z mgernoth
02_HTTPSRV.pm        13976 2017-04-12 13:35:44Z neubert
98_IF.pm             12944 2017-01-03 12:56:17Z Damian
49_IPCAM.pm           2626 2013-02-01 19:19:15Z mfr69bs
98_JsonList2.pm      13757 2017-03-20 19:17:02Z rudolfkoenig
93_Log2Syslog.pm     15486 2017-11-23 20:35:07Z DS_Starter
98_logProxy.pm       13399 2017-02-12 13:00:43Z justme1968
00_MQTT.pm           15126 2017-09-24 07:43:17Z eisler
10_MQTT_DEVICE.pm    15202 2017-10-05 20:35:33Z eisler
No Id found for 99_myUtils.pm
91_notify.pm         15795 2018-01-05 20:46:21Z rudolfkoenig
10_OWServer.pm       15589 2017-12-11 11:58:29Z neubert
73_PRESENCE.pm       15793 2018-01-05 17:55:21Z markusbloch
59_PROPLANTA.pm      15358 2017-10-30 20:04:27Z tupol
70_Pushover.pm       15162 2017-10-01 11:25:11Z loredo
33_readingsGroup.pm  15100 2017-09-19 21:21:27Z justme1968
00_RPII2C.pm         15021 2017-09-06 19:48:55Z klausw
51_RPI_GPIO.pm       12129 2016-09-06 21:47:53Z klauswitt
99_SUNRISE_EL.pm     15572 2017-12-08 22:18:13Z rudolfkoenig
98_SVG.pm            15812 2018-01-07 13:22:51Z rudolfkoenig
42_SYSMON.pm         15378 2017-11-01 20:36:57Z hexenmeister
32_SYSSTAT.pm        10567 2016-01-18 21:34:09Z justme1968
50_TelegramBot.pm    15652 2017-12-20 11:29:39Z viegener
98_telnet.pm         15676 2017-12-23 19:33:43Z rudolfkoenig
99_Utils.pm          15713 2017-12-28 11:01:02Z rudolfkoenig
98_version.pm        15140 2017-09-26 09:20:09Z markusbloch
59_Weather.pm        12559 2016-11-13 08:54:54Z borisneubert
98_weblink.pm        14888 2017-08-13 12:07:12Z rudolfkoenig

Blocking.pm          15412 2017-11-09 14:34:29Z rudolfkoenig
Color.pm             11159 2016-03-30 16:08:06Z justme1968
DevIo.pm             14933 2017-08-20 14:21:58Z rudolfkoenig
FritzBoxUtils.pm     14541 2017-06-19 09:13:10Z rudolfkoenig
GPUtils.pm            6653 2014-10-02 11:59:37Z ntruchsess
HMConfig.pm          15817 2018-01-07 18:18:52Z martinp876
HttpUtils.pm         15631 2017-12-17 12:33:03Z rudolfkoenig
# $Id: OWNet.pm,v 1.24 2013/02/02 11:41:28 alfille Exp $
RTypes.pm            10476 2016-01-12 21:03:33Z borisneubert
SetExtensions.pm     12935 2017-01-02 19:51:46Z rudolfkoenig
TcpServerUtils.pm    15707 2017-12-27 14:41:21Z rudolfkoenig
TimeSeries.pm        10907 2016-02-21 17:38:02Z borisneubert
YahooWeatherAPI.pm   15742 2018-01-01 07:55:55Z neubert

doif.js                    15546 2017-12-03 09:57:42Z Ellert
fhemweb.js                 15822 2018-01-07 22:11:05Z rudolfkoenig
fhemweb_readingsGroup.js   15189 2017-10-03 17:53:27Z justme1968


pin13:

Internals:
   DEF        27
   EXCEPT_FD  13
   GPIO_Basedir /sys/class/gpio
   NAME       pin13
   NR         1074
   RPI_pin    27
   STATE      off
   TYPE       RPI_GPIO
   WiringPi_gpio /usr/local/bin/gpio
   lasttrg    1517101082.18907
   READINGS:
     2018-01-28 01:58:02   Dblclick        off
     2018-01-28 01:58:02   Longpress       off
     2018-01-28 07:00:41   Pinlevel        low
     2018-01-28 01:58:02   pinlevel_bin    0
     2018-01-28 01:58:02   state           off
   fhem:
     interfaces switch
Attributes:
   alias      pinTorStatus
   direction  input
   event-aggregator pinlevel_bin:12:none:v
   event-on-change-reading .*
   interrupt  both
   room       BPI_pins
   userReadings pinlevel_bin {ReadingsVal($name,"Pinlevel","error") eq "high" ? 1:0}


di_pin13:

Internals:
   DEF        ([pin13:pinlevel_bin] == 1 and [oWD:Door.Garten] eq "closed") (setreading oWD Door.Garten open, set swGartentorText schließen,
( IF ([LDRx:ldr_value] < 110) (set pin21 on, defmod myAtoutLightOn at +00:00:02 set pin21 off,
({Log(2, "TOR_AUTOMATIK: Tor geöffnet und Außenlicht bei Dunkelheit eingeschaltet.")}))
  ELSE (({Log(2, "TOR_AUTOMATIK: Tor geöffnet.")}))))
DOELSEIF ([pin13:pinlevel_bin] == 0 and [oWD:Door.Garten] eq "open") (setreading oWD Door.Garten closed, set swGartentorText öffnen,
{Log(2, "TOR_AUTOMATIK: Tor geschlossen.")})
   NAME       di_pin13
   NR         1088
   NTFY_ORDER 50-di_pin13
   STATE      cmd_2
   TYPE       DOIF
   READINGS:
     2018-01-28 02:11:52   Device          oWD
     2018-01-28 01:58:02   cmd             2
     2018-01-28 01:58:02   cmd_event       pin13
     2018-01-28 01:58:02   cmd_nr          2
     2018-01-28 02:11:52   e_oWD_Door.Garten closed
     2018-01-28 00:29:38   e_pin13_Pinlevel low
     2018-01-28 01:58:02   e_pin13_pinlevel_bin 0
     2018-01-28 01:58:02   state           cmd_2
     2018-01-27 07:44:40   wait_timer      no timer
   Regex:
   condition:
     0          ReadingValDoIf($hash,'pin13','pinlevel_bin') == 1 and ReadingValDoIf($hash,'oWD','Door.Garten') eq "closed"
     1          ReadingValDoIf($hash,'pin13','pinlevel_bin') == 0 and ReadingValDoIf($hash,'oWD','Door.Garten') eq "open"
   devices:
     0           pin13 oWD
     1           pin13 oWD
     all         pin13 oWD
   do:
     0:
       0          setreading oWD Door.Garten open, set swGartentorText schließen,  ( IF ([LDRx:ldr_value] < 110) (set pin21 on, defmod myAtoutLightOn at +00:00:02 set pin21 off,  ({Log(2, "TOR_AUTOMATIK: Tor geöffnet und Außenlicht bei Dunkelheit eingeschaltet.")}))    ELSE (({Log(2, "TOR_AUTOMATIK: Tor geöffnet.")})))
     1:
       0          setreading oWD Door.Garten closed, set swGartentorText öffnen,  {Log(2, "TOR_AUTOMATIK: Tor geschlossen.")}
     2:
   helper:
     DOIF_Readings_events
     DOIF_eventas
     event      Win.Schlaf: closed
     globalinit 1
     last_timer 0
     sleeptimer -1
     timerdev   pin13
     timerevent Pinlevel: low,off,Longpress: off
     triggerDev oWD
     timerevents:
       Pinlevel: low
       off
       Longpress: off
     timereventsState:
       Pinlevel: low
       state: off
       Longpress: off
     triggerEvents:
       Win.Schlaf: closed
     triggerEventsState:
       Win.Schlaf: closed
   internals:
   itimer:
   readings:
     0           pin13:pinlevel_bin oWD:Door.Garten
     1           pin13:pinlevel_bin oWD:Door.Garten
     all         pin13:pinlevel_bin oWD:Door.Garten
   trigger:
   uiState:
   uiTable:
Attributes:
RPI4-Buster mit SSD, RPI-Zero mit Bookworm

Ellert

Du musst die maximale Sequenzlänge warten und die Zweige gegeneinander verriegeln, ungetestet etwa so

([Signal] eq "high" and [$SELF] ne "cmd_1") (Befehle)
DOELSEIF ([Signal] eq "low"and [$SELF] ne "cmd_2" ) (Befehle)

wait <maximale Sequenzlänge>:<maximale Sequenzlänge>


und das DOIF mit set Name cmd_x initialisieren.

manne44

@Ellert
Vielen Dank, das könnte evtl. die passende Lösung sein, wenn man damit richtig umgehen könnte, aber ich habe das mit "[$SELF] noch nie gemacht und so habe ich das verändert. Ein Zeitabschnitt von fallender zu steigender Flanke beträgt genau 1 sec. Das Ergebnis ist, dass es sich jetzt super verriegelt und nichts mehr ausgeführt wird. Aber die Verriegelung an sich, wenn sie richtig gemacht wird, scheint mir wirkungsvoll zu sein.


define di_pin13 DOIF ([pin13:Pinlevel] eq "high" and [oWD:Door.Garten] eq "closed" and [$SELF] ne "cmd_1") (setreading oWD Door.Garten open, set swGartentorText schließen, \
                          ( IF ([LDRx:ldr_value] < 110) (set pin21 on, defmod myAtoutLightOn at +00:00:02 set pin21 off, \
                                ({Log(2, "TOR_AUTOMATIK: Tor geöffnet und Außenlicht bei Dunkelheit eingeschaltet.")})) \
                            ELSE (({Log(2, "TOR_AUTOMATIK: Tor geöffnet.")})))) \
                DOELSEIF ([pin13:Pinlevel] eq "low" and [oWD:Door.Garten] eq "open" and [$SELF] ne "cmd_2") (setreading oWD Door.Garten closed, set swGartentorText öffnen, \
          {Log(2, "TOR_AUTOMATIK: Tor geschlossen.")})
attr di_pin13 wait (5:12)
attr di_pin13 room BPI_pins

define n_di_pin13_init notify di_pin13:INITIALIZED|REREADCFG (set di_pin13 cmd_2)

RPI4-Buster mit SSD, RPI-Zero mit Bookworm

Ellert

#9
Du könntest 2 DOIF nutzen, das erste filtert das Signal und liefert cmd_1 und cmd_2 oder etwas anderes, wenn Du cmdState nutzt. Damit könntest Du das zweite DOIF mit der weiteren Logik triggern.

Dann könntest Du den Signalfilter separat testen.

Eventuell hilft es wenn Du in beiden Fällen die maximale Sequenzlänge oder etwas länger angibst, dann gibt es keine unerwünschte Wechselwirkung (wait 12:12)

manne44

Hallo,
Dank an alle, die mir geholfen haben. Nach Vorschlag von Ellert habe ich die DOIFs zweigeteilt, etwas mehr gelesen und nachgedacht, und nun funktioniert es so, wie ich es mir immer gewünscht habe.

Für alle, die es interessiert, hier die endgültige Lösung, die bestimmt noch "verhübscht" werden könnte, mit der ich aber sehr zufrieden bin:

Nach Betätigung des Buttons wird ein Relais geschlossen/geöffnet und damit die Torsteuerung getriggert:

define pin15 RPI_GPIO 22
attr pin15 alias pinTorRelais
attr pin15 direction output
attr pin15 event-on-change-reading .*
attr pin15 room BPI_pins

## Test-DOIF für Zeitablauf im Log, sonst keine Funktion
define pin15state DOIF ([pin15] eq "on") ({Log(2, "Pin15 high")}) DOELSE ({Log(2, "Pin15 low")})
attr pin15state room BPI_pins


Hier die Verzögerung des alternierenden Signals von der Torsteuerung bezüglich Torstatus. Die 5 s bei der Öffnung reichen zur Überbrückung des einen Low-High-Pegels, bei der Schließung viele, deshalb 15 s:

## Die Log-Einträge sind nur für die Zeitabläufe
define pin13state DOIF ([pin13:Pinlevel] eq "high") ({Log(2, "Pin13 high")}) DOELSE ({Log(2, "Pin13 low")})
attr pin13state cmdState on|off
attr pin13state wait 5:15
attr pin13state room BPI_pins


Und nun der eigentliche Teil wie bisher:

define di_pin13 DOIF ([pin13state] eq "on") (setreading oWD Door.Garten open, set swGartentorText schließen, set OpenWinCounter {([OpenWinCounter] >= 0 ? [OpenWinCounter]+1 : 1)}, \
        ( IF ([LDRx:ldr_value] < 110) (set pin21 on, defmod myAtoutLightOn at +00:00:02 set pin21 off, ({Log(2, "TOR_AUTOMATIK: Tor geöffnet und Außenlicht bei Dunkelheit eingeschaltet.")})) \
          ELSE (({Log(2, "TOR_AUTOMATIK: Tor geöffnet.")})))) \
        DOELSE (setreading oWD Door.Garten closed, set swGartentorText öffnen, set OpenWinCounter {([OpenWinCounter] > 0 ? [OpenWinCounter]-1 : 0)}, {Log(2, "TOR_AUTOMATIK: Tor geschlossen.")})
attr di_pin13 room BPI_pins


Hier die entsprechenden Log-Einträge:

2018.01.30 14:57:48 2: Pin15 high
2018.01.30 14:57:49 2: Pin15 low
2018.01.30 14:57:55 2: Pin13 high
2018.01.30 14:57:55 2: TOR_AUTOMATIK: Tor geöffnet.
2018.01.30 14:59:23 2: Pin15 high
2018.01.30 14:59:24 2: Pin15 low
2018.01.30 14:59:59 2: Pin13 low
2018.01.30 14:59:59 2: TOR_AUTOMATIK: Tor geschlossen.


Es gibt nur noch einen Eintrag und damit nur noch eine Befehlsfolge, egal wie oft das Signal innerhalb des Attributes "wait" wechselt.
Was mir noch etwas unklar ist, das sind die Zeiten, denn bei der Öffnung vergehen vom Start pin15 bis Pin13 rd. 6 s, aber bei der Schließung über 30 s, wobei das Attribut wait 5:15 lautete. Hier hätte ich ein Delay um 15 s erwartet, aber vielleicht steckt die zusätzliche Verzögerungszeit in der Torsteuerung selbst, die mit ihrem Status (Pin13) verzögert antwortet bzw. mit der Schließung beginnt.
RPI4-Buster mit SSD, RPI-Zero mit Bookworm