neues modul 98_combine.pm: kombinieren von readings

Begonnen von justme1968, 13 April 2020, 21:42:51

Vorheriges Thema - Nächstes Thema

justme1968

anbei eine erste version eines moduls um readings aus unterschiedlichen devices zu kombinieren.

achtung: frühes stadium, keine ahnung ob es nützlich ist, es ist nicht alles getestet, ... bitte hierzu auch die offenen fragen am ende beachten.


die grundidee ist ähnlich wie die virtuellen kanäle in manchen hm dim aktoren: durch die kombination und priorisierung lassen sich vorrangschaltungen bauen oder mit readings rechnen:

  • treppenhausschaltung
    zeitgesteuert wird bei dunkelheit ein nachtlicht aktiviert, dieses wird bei erkannter bewegung heller und lässt sich über den lichtschalter überschreiben
  • heizungsteuerung
    die gewünschte tempereratur lässt sich per fenster offen meldung absenken und über einen party-taster zeitweise erhöhen
  • zirkulationspumpe mit nacht- und abweseheits schaltung
  • verbräuche aufsummieren
    die verbrauchsreadings in unterschiedlichen devices werden aufsummiert
  • zählen der häufigkeit von zuständen
  • ...
 
wie schaut das ganze aus:

define <name> combine <device>:<reading> [<OP> <device1>:<reading1> [<OP> <device2>:<reading2> [...]]]  [= <result>]

statt <device>:<reading> ist es auch möglich einen festen <wert> anzugeben, <device> kann eine regex sein. achtung:
das geht nur wenn <device> nicht an erster stelle vorkommt weil es sonst der operator nicht bekannt ist. als workaround
kann man an erster stelle einen festen (für den jeweiligen opeartor passenden) wert angeben. aktuell darf nur <device> eine regex sein, <reading> nicht.

<OP> kann sein: OR (= MAX), AND (= MIN), XOR, PLUS (+), MINUS (-), MULT (*), DIV (/)

nicht möglich weil werteberich nicht bekannt und unnötig weil statt dessen <wert> MINUS ... möglich ist. :
     OR_INVERS, AND_INVERS, PLUS_INVERS, MINUS_INVERS, INVERS_PLUS, INVERS_MINUS, INVERS_MULT

<result> kann sein:

  • nicht angeben -> das ergebnis landet in state des <combine> devices
  • <reading> -> das ergebnis landet im entsprechenden reading des <combine> device
  • <device>:<reading> -> das ergebnis landet in <reading> von <device> device
  • ein beliebiges fhem kommando, z.b.: set <name> $RESULT
    $RESULT ist das aktuelle ergebnis
  • das fhem kommando kann auch {perl} code sein

über das values attribut lassen sich nicht-numerische reading werte in numerische verwandeln:
                   
attr <combine> values present:30 absent:20 on:100 off:0 open:1 closed:0


in der device detail ansicht gibt es eine tabellarisch übersicht der beteiligten devices und der aktuellen werte. die jeweiligen devStateIcons lassen sich per klick normal bedienen.


anbei noch jeweils konkrete demo versionen der beispiele oben:

treppe:
  - ein timer der alle 10 sekunden zwischen aktiv und inaktiv wechselt. das wäre die zeisteuerung per at oder weekdaytimer
  - ein bewegungsmelder der sich durch klick aktivieren lässt, geht nach 5 sekunden wieder auf nomotion
  - ein schalter der sich durch klick ein- und ausschalten lässt

  - das ganze wird in einem combine device wie folgt kombiniert:
    - wenn der timer aktiv ist geht das licht auf 20%
    - wenn bei aktivem timer Bewegung erkannt wird geht das licht auf 50%
    - wenn der schalter eingeschaltet ist geht das licht immer auf 100%

  - das ergebnis steuert eine lampe (screenshots 1-3)

defmod combine combine timer:active AND motion:motion OR schalter:state = set lampe $RESULT
attr combine devStateIcon {Color::devStateIcon($name,"dimmer",undef,"state")}
attr combine group 2 - combine
attr combine room demo 1 - treppe
attr combine values off:0 on:100 nomotion:20 motion:50

defmod lampe dummy
attr lampe devStateIcon {Color::devStateIcon($name,"dimmer",undef,"state")}
attr lampe group 3 - output
attr lampe readingList pct
attr lampe room demo 1 - treppe
attr lampe setList on off pct
attr lampe webCmd :

defmod motion dummy
attr motion devStateIcon nomotion:motion_detector:on-5 motion:motion_detector@red:off
attr motion eventMap /on-for-timer 5:on-5/\

attr motion group 1 - inputs
attr motion room demo 1 - treppe
attr motion setList on off motion
attr motion stateFormat motion
attr motion useSetExtensions 1
attr motion userReadings motion:(on|off) {ReadingsVal($name,'state','off') eq 'off' ? 'nomotion' : 'motion'}
attr motion webCmd :

defmod schalter dummy
attr schalter devStateIcon on:taster@green:off off:taster:on
attr schalter group 1 - inputs
attr schalter room demo 1 - treppe
attr schalter setList on off
attr schalter webCmd :

defmod timer at +*00:00:10 {\
  my $current = ReadingsVal( 'timer', 'active', 'off' );;\
  \
  if( $current eq 'off' ) {\
    fhem( 'setreading timer active on' );;\
  } else {\
    fhem( 'setreading timer active off' );;\
  }\
}
attr timer devStateIcon on:control_on_off@green off:control_home
attr timer group 1 - inputs
attr timer room demo 1 - treppe
attr timer stateFormat active\
<br>\
state

setstate combine 100
setstate combine 2020-04-13 20:51:09 state 100

setstate lampe 100
setstate lampe 2020-04-13 20:51:09 state 100

setstate motion nomotion
setstate motion 2020-04-13 20:38:05 motion nomotion
setstate motion 2020-04-13 20:38:05 state off

setstate schalter on
setstate schalter 2020-04-13 20:38:18 state on

setstate timer off\
<br>\
Next: 20:51:19
setstate timer 2020-04-13 20:51:09 active off
setstate timer 2020-04-13 20:51:09 state Next: 20:51:19


heizung:
  - ein slider stellt die gewünschte temperatur ein
  - ein fenster lässt sich durch klick öffnen und schließen
  - über einen taster lässt sich ein 'party-mode' für 5 sekunden aktivieren oder deaktivieren

  - das ganze wird in einem combine device wie folgt kombiniert:
    - die gewünschte temperatur geht auf 16 grad runter sobald das fenster offen ist
    - wenn der taster aktiv ist geht die gewünschte temperatur auf 26

  - das ergebnis steuert eine heizung (screenshot 4-6)

defmod desired combine temp:state OR party:state AND fenster:state = set heizung $RESULT
attr desired group 2 - combine
attr desired room demo 2 -  heizung
attr desired values open:16 closed:30 off:0 on:26

defmod fenster dummy
attr fenster devStateIcon open:fts_window_1w_open:closed closed:fts_window_1w:open
attr fenster group 1 - input
attr fenster room demo 2 -  heizung
attr fenster setList open closed

defmod heizung dummy
attr heizung group 3 - target
attr heizung room demo 2 -  heizung

defmod party dummy
attr party devStateIcon on:taster@green:off off:taster:on-5
attr party eventMap /on-for-timer 5:on-5/
attr party group 1 - input
attr party room demo 2 -  heizung
attr party setList on off
attr party useSetExtensions 1
attr party webCmd :

defmod temp dummy
attr temp group 1 - input
attr temp room demo 2 -  heizung
attr temp setList state:slider,15,0.5,30,1
attr temp webCmd state

setstate desired 16
setstate desired 2020-04-13 20:38:43 state 16

setstate fenster open
setstate fenster 2020-04-13 20:38:36 state open

setstate heizung 16
setstate heizung 2020-04-13 20:38:43 state 16

setstate party off
setstate party 2020-04-13 20:38:43 state off

setstate temp 22.5
setstate temp 2020-04-13 20:15:28 state 22.5


summe:
  - drei slider simulieren numerische readings

  - die summe wird ins summen device geschrieben

defmod summe combine slider1:state + slider2:state + slider3:state = summe
attr summe group 2 - combine
attr summe room demo 3 - summe
attr summe stateFormat summe

defmod slider1 dummy
attr slider1 group 1 - input
attr slider1 room demo 3 - summe
attr slider1 setList state:slider,0,1,100
attr slider1 webCmd state

defmod slider2 dummy
attr slider2 group 1 - input
attr slider2 room demo 3 - summe
attr slider2 setList state:slider,0,1,100
attr slider2 webCmd state

defmod slider3 dummy
attr slider3 group 1 - input
attr slider3 room demo 3 - summe
attr slider3 setList state:slider,0,1,100
attr slider3 webCmd state

setstate slider1 51
setstate slider1 2020-04-13 19:38:05 state 51

setstate slider2 23
setstate slider2 2020-04-13 20:25:50 state 23

setstate slider3 68
setstate slider3 2020-04-13 20:25:48 state 68

setstate summe 142
setstate summe 2020-04-13 20:30:29 summe 142


zählen
- drei fenster lassen sich per klick öffnen und schließen

- über zwei unterschiedliche combine devices wird die anzahl der geöffneten fenster gezählt.
- ein mal sind alle fenster einzeln im define angegeben
- ein mal sind die fenster als regex hinterlegt. wenn zur laufzeit fenster hinzukommen werden diese mit gezählt.

defmod anzahl combine fenster1:state + fenster2:state + fenster3:state
attr anzahl alias anzahl (einzeln)
attr anzahl group 2 - combine
attr anzahl room demo 4 - zählen
attr anzahl values open:1 closed:0

defmod anzahl2 combine 0 + fenster.:state
attr anzahl2 alias anzahl (regex)
attr anzahl2 group 2 - combine
attr anzahl2 room demo 4 - zählen
attr anzahl2 values open:1 closed:0

defmod fenster1 dummy
attr fenster1 devStateIcon open:fts_window_1w_open:closed closed:fts_window_1w:open
attr fenster1 group 1 - input
attr fenster1 room demo 4 - zählen
attr fenster1 setList open closed

defmod fenster2 dummy
attr fenster2 devStateIcon open:fts_window_1w_open:closed closed:fts_window_1w:open
attr fenster2 group 1 - input
attr fenster2 room demo 4 - zählen
attr fenster2 setList open closed

defmod fenster3 dummy
attr fenster3 devStateIcon open:fts_window_1w_open:closed closed:fts_window_1w:open
attr fenster3 group 1 - input
attr fenster3 room demo 4 - zählen
attr fenster3 setList open closed

setstate anzahl 2
setstate anzahl 2020-04-13 20:38:52 state 2

setstate anzahl2 2
setstate anzahl2 2020-04-13 20:38:52 state 2
 
setstate fenster1 open
setstate fenster1 2020-04-13 20:38:51 state open
 
setstate fenster2 closed
setstate fenster2 2020-04-13 20:38:51 state closed

setstate fenster3 open
setstate fenster3 2020-04-13 20:38:52 state open


offene fragen:
- sind fehlende klammern ein problem ? wenn ja: die könnte man ergänzen.             
- braucht es ein device spezifisches values attribut ?                   
- sind bei den readings die setmagic suffixe sinnvoll (num/runden/...)?                         
- ist ein threshold für die quell werte sinnvoll um diese auf eine binären wert abzubilden ?         
- weitere sinnvolle operatoren: NOR, NAND, ... ?
- ist eine regex für die <reading> angabe sinnvoll?                         
- ist eine erweiterte <device> angabe per devspec/filter sinnvoll?
- $COUNT um durchschnitt einfacher zu machen?

edit 2020-04-24:
- neuer operator , DIV (/)
- angabe von result kann auch durch <device>:<reading> erfolgen
hue, tradfri, alexa-fhem, homebridge-fhem, LightScene, readingsGroup, ...

https://github.com/sponsors/justme-1968

FunkOdyssey

Ich bin überwältigt. Das könnte viele meiner Probleme, die ich seit Jahren nicht vollständig lösen könnte, endlich beheben. Sobald ich Zeit finde werde ich das Modul testen.
Die Priorisierung von unterschiedlichen Einschaltungen (Treppenlicht) will ich damit umsetzten.

Tomk

Perfekt, genau das habe ich gerade gesucht um aus 4 Readings einen Mittelwert zu berechnen...
kleiner Hinweis: in der Beschreibung solltest du das Symbol für MULT korrigieren...

FunkOdyssey

Mir ist aufgefallen, dass ich täglich das rote Fragezeichen mit einer ungespeicherten Änderung sehe.
Ist das bekannt und evtl. normal?
Ich habe mir leider nicht gemerkt, was geändert wurde. Ich werde beim nächsten mal darauf achten.

justme1968

das ist noch ,normal'

das modul erkennt unter anderem rename und hinzufügen von anderen devices und prüft ob es auswirkungen auf sich selber hat.

dabei bin ich noch faul und mache ein modify auf sich selber.

das muss noch geändert werden so das es keine falsch positiven gibt.
hue, tradfri, alexa-fhem, homebridge-fhem, LightScene, readingsGroup, ...

https://github.com/sponsors/justme-1968

dancatt

Moin,

folgendes combine:

Internals:
   .FhemMetaInternals 1
   DEF        1_02_WZ_Tuerkontakt:closed AND 1_02_WZ_Rollladen_l:on = result
   FUUID      5ea0330c-f33f-cf0a-60a3-fe6f0b6647f7eed2
   FVERSION   98_combine.pm:0.213660/2020-03-06 ALPHA
   NAME       combine_Terasse_Licht
   NOTIFYDEV  1_02_WZ_Rollladen_l,global,1_02_WZ_Tuerkontakt
   NR         479
   NTFY_ORDER 50-combine_Terasse_Licht
   STATE      0
   TYPE       combine
   mayBeVisible 1
   .attraggr:
   .attrminint:
   READINGS:
     2020-04-23 08:38:45   result          0
   helper:
     result_reading result
     rules:
       1_02_WZ_Tuerkontakt:closed
       AND
       1_02_WZ_Rollladen_l:on
     values:
     watch:
       1_02_WZ_Rollladen_l:on
       1_02_WZ_Tuerkontakt:closed 0
Attributes:
   DbLogExclude .*
   room       0_03_Licht


Egal welcher Zustand der Rollladen und der Türkontakt haben. result hat immer den Wert 0.
Mache ich was falsch? Hätte vermutet wenn beide Bedingungen erfüllt sind dass dann in result 1 drin steht.
Was mir auch aufgefallen ist, dass result nicht aktualisiert wird wenn sich der Zustand vom Rollladen oder des Türkontakts ändern.

Vielen Dank.
Gruß Daniel
Cubietruck: FHEM-Server 6.0

Homematic: HM-USB-CFG2, HM-CFG-LAN, HM-LC-SW1-FM, HM-LC-Sw1-Pl-DN-R1, HM-CC-RT-DN, HM-TC-IT-WM-W-EU, HM-SEC-SC-2, HM-SEC-SD, HM-PB-6-WM55

justme1968

deine reading werte sind nicht numerisch. d.h. du brauchst ein passendes values attribut.

mit verbose 4 oder 5 solltest du die genaue verknüpfung und aktualisierung im log sehen
hue, tradfri, alexa-fhem, homebridge-fhem, LightScene, readingsGroup, ...

https://github.com/sponsors/justme-1968

dancatt

Danke. Log half. Es muss in der Def natürlich
1_02_WZ_Tuerkontakt:state AND 1_02_WZ_Rollladen_l:state = result
heißen.

Vielen Dank.
Cubietruck: FHEM-Server 6.0

Homematic: HM-USB-CFG2, HM-CFG-LAN, HM-LC-SW1-FM, HM-LC-Sw1-Pl-DN-R1, HM-CC-RT-DN, HM-TC-IT-WM-W-EU, HM-SEC-SC-2, HM-SEC-SD, HM-PB-6-WM55

Thomas41587

Cooles Modul! Allerdings habe ich (glaube ich) einen Bug entdeckt:
defmod combine_dummy_esszimmer_sensorbox combine dummy_esszimmer_sensorbox:maxhelligkeit OR dummy_esszimmer_sensorbox:helligkeit1 OR dummy_esszimmer_sensorbox:helligkeit2 OR dummy_esszimmer_sensorbox:helligkeit2 = setreading dummy_esszimmer_sensorbox maxhelligkeit $RESULT

Das liefert mir z.B. einen state "combine_dummy_esszimmer_sensorbox 2020-04-24 09:37:44 state 92.6\". Und auch der dummy_esszimmer_sensorbox hat entsprechend "92.6\" im Reading stehen. Ich weiß nicht wo der Zeilenumbruch her kommt, den scheint das Modul zu "erfinden"

justme1968

#9
zeig mal bitte ein list von device und vom original device.

und was sagt das log bei verbose 5?
hue, tradfri, alexa-fhem, homebridge-fhem, LightScene, readingsGroup, ...

https://github.com/sponsors/justme-1968

justme1968

ich glaube du hast in diesem define auch noch einen fehler. du verknüpfst maxhelligkeit mit helligkeit1 und helligkeit2 und schreibst das ergebniss wieder in maxhelligkeit.

du möchtest doch aber helligkeit1, helligkeit2 und helligkeit3 verknüpfen und in maxhelligkeit schreiben.
hue, tradfri, alexa-fhem, homebridge-fhem, LightScene, readingsGroup, ...

https://github.com/sponsors/justme-1968

justme1968

ganz oben gibt es ein update:

- neuer operator DIV

- angabe von result als <device>:<reading>
hue, tradfri, alexa-fhem, homebridge-fhem, LightScene, readingsGroup, ...

https://github.com/sponsors/justme-1968

Thomas41587

Da hatte sich tatsächlich der Fehlerteufel eingeshclichen. Das mahelligkeit am Anfang war ein verständnisfehler von mir, dass 2x Helligkeit2 drin war, war ein copy&paste fehler.
Inetressanter weise funktioniert es damit jetzt einwandfrei:
defmod cmobine_dummy_esszimmer_sensorbox combine dummy_esszimmer_sensorbox:helligkeit1 OR dummy_esszimmer_sensorbox:helligkeit2 OR dummy_esszimmer_sensorbox:helligkeit3 = setreading dummy_esszimmer_sensorbox maxhelligkeit $RESULT
Danke für dieses praktische Modul!

justme1968

#13
sehr schön.

mit dem update von oben kannst du jetzt auch 
Zitat... = dummy_esszimmer_sensorbox: maxhelligkeit

schreiben statt setreading ...
hue, tradfri, alexa-fhem, homebridge-fhem, LightScene, readingsGroup, ...

https://github.com/sponsors/justme-1968

Thomas41587

Gibt es bei der Thematik logging in Kombination mit dem Modul etwas zu beachten?
Hintgerund:
Mein dummy hat 3 Helligkeitswerte. Combine wird genutzt um die maxhelligkeit zu bestimmen. Für Helligkeit 1-3 bekomme ich über die Tablet-UI meinen Plot angezeigt. Der Graph für maxhelligkeit wird nicht angezeigt. event-on-change-reading ist dabei auf ".*" gesetzt (sollte also alle readings loggen)