[Tutorial] - Einbindung eines Keypads in TabletUI für das Modul: Alarmanlage

Begonnen von DarkT, 05 Februar 2018, 08:31:31

Vorheriges Thema - Nächstes Thema

DarkT

Hallo zusammen,

während des Aufbaus meiner TabletUI bin ich über den folgenden Beitrag gestolpert.
Vielen Dank Tom_Tom dafür. Bei der Umsetzung des Projektes hatte ich dann die eine oder andere Frage, die sich letztendlich klären lies.

Um euch am Ergebnis Teil haben zu lassen, hier eine Schritt für Schritt Anleitung:

Ziel
Eure TabletUI mit einem Keypad zu schützen während der Alarm aktiv ist und darüber hinaus über Eingabe des korrekten Pins die Alarmanlage zu entschärfen.

Voraussetzung

  • Ihr habt das Modul Alarmanlage aus diesem Thread bzw. diesem Wiki installiert und einsatzbereit
  • Ihr habt das Modul unter dem Namen AAA angelegt (so wie im Wiki-Artikel). Ansonsten müsst ihr halt euren Namen an den entsprechenden Stellen anpassen.
  • Ihr habt eine laufende TabletUI-Instanz, die um das Keypad erweitert werden soll

Hinweis:
Die Einbindung komplexer multiline Definitionen macht man am besten wie hier beschrieben.

1. AlarmKeypadDummy anlegen
Dieses Device benutzen wir um unseren Pin zu speichern und die Eingaben vom Keypad zu validieren.


defmod AlarmKeypadDummy dummy
attr AlarmKeypadDummy alarmDevice Sensor
attr AlarmKeypadDummy alarmSettings alarm0,|AlarmKeypadDummy:.unlocked|unlocked|off   # wird durch das Modul Alarm angelegt
attr AlarmKeypadDummy event-on-change-reading state,inputPin
attr AlarmKeypadDummy event-on-update-reading key
attr AlarmKeypadDummy readingList key,inputPin,fails,unlockPin
attr AlarmKeypadDummy room Alarm
attr AlarmKeypadDummy setList unlockPin
attr AlarmKeypadDummy userReadings inputPin:key:.[0-9] { return ReadingsVal($NAME, "inputPin", "*") . ReadingsVal($NAME, "key", "0");; }, fails:key:.# { if (ReadingsVal($NAME, "inputPin", "0") ne ReadingsVal($NAME, "unlockPin", "0")) { return ReadingsVal($NAME, "fails", 0)+1;; } else { return 0;; } }, state:key:.# { if (ReadingsVal($NAME, "inputPin", "0") ne ReadingsVal($NAME, "unlockPin", "0")) { return "locked";; } else { return "unlocked";; } }, inputPin:key:.[\<] { my $inputVal = ReadingsVal($NAME, "inputPin", "0");; chop($inputVal);; return $inputVal;; },  inputPin:key:.# { return "";; }


Als kleiner Hinweis für diejenigen die noch nicht FHEM-Code als ihre Muttersprache verstehen:


  • Dem Device kann über die Schaltfläche set unlockPin der gültige Pincode gesetzt werden
  • Die Userreadings füllen (je nach Änderung des Readings key) die folgenden Readings:

    • fails (Anzahl ungültiger Versuche)
    • inputPin (Eingabe Pin aufsummiert aus den einzelnen Keys)
    • state (locked/unlocked)

2. Notify anlegen (Locked)
Das Keypad in der TabletUI prüft den Zustand das AlarmKeypadDummy um entweder angezeigt oder versteckt zu werden. Damit der Dummy auch in den State 'locked' wechseln muss das folgende Notify angelegt werden:


defmod notify_AlarmanalageLocked notify AAA:level0:.armed set AlarmKeypadDummy locked
attr notify_AlarmanalageLocked room Alarm


3. Notify anlegen (Unlock)
In der anderen Richtung möchten wir, falls der richtige Code eingegebn wurde auch die Alarmanlage entschärfen.
Das geschieht durch folgendes Notify

defmod notify_AlarmanalageUnlocked notify AlarmKeypadDummy:unlocked set AAA disarmed 0
attr notify_AlarmanalageUnlocked room Alarm


4. Keypad für TabletUI
in eurer TabletUI müsst ihr den folgenden Code integrieren:


<!-- Alarmanlage Keypad -->
<div data-type="popup" data-device="AlarmKeypadDummy" data-get-on="locked" data-get-off="unlocked" data-width="400px" data-height="500px" class="interlock">
<div class="red bold top-space-2x"></div>
<div class="dialog">
<header>Alarm deaktivieren</header>
<div data-type="label" class="cell big top-space-2x wider">PIN-Code</div>
<div class="inline big top-space">
  <div data-type="push" data-icon="" data-device="AlarmKeypadDummy" data-set="key" data-set-on="1" onclick="">1</div>
  <div data-type="push" data-icon="" data-device="AlarmKeypadDummy" data-set="key" data-set-on="4" onclick="">4</div>
  <div data-type="push" data-icon="" data-device="AlarmKeypadDummy" data-set="key" data-set-on="7" onclick="">7</div>
  <div data-type="push" data-icon="fa-long-arrow-left" data-device="AlarmKeypadDummy" data-set="key" data-set-on="<" onclick=""></div>
</div>
<div class="inline big">
  <div data-type="push" data-icon="" data-device="AlarmKeypadDummy" data-set="key" data-set-on="2" onclick="">2</div>
  <div data-type="push" data-icon="" data-device="AlarmKeypadDummy" data-set="key" data-set-on="5" onclick="">5</div>
  <div data-type="push" data-icon="" data-device="AlarmKeypadDummy" data-set="key" data-set-on="8" onclick="">8</div>
  <div data-type="push" data-icon="" data-device="AlarmKeypadDummy" data-set="key" data-set-on="0" onclick="">0</div>
</div>
<div class="inline big">
  <div data-type="push" data-icon="" data-device="AlarmKeypadDummy" data-set="key" data-set-on="3" onclick="">3</div>
  <div data-type="push" data-icon="" data-device="AlarmKeypadDummy" data-set="key" data-set-on="6" onclick="">6</div>
  <div data-type="push" data-icon="" data-device="AlarmKeypadDummy" data-set="key" data-set-on="9" onclick="">9</div>
  <div data-type="push" data-off-color="green" data-icon="fa-unlock" data-device="AlarmKeypadDummy" data-set="key" data-set-on="#" onclick=""></div>
</div>
<div class="bg-lightgray border-white top-space centered" style="width:280px; height:50px;">
<div data-type="label" data-device="AlarmKeypadDummy" data-get="inputPin" class="tall"></div>
</div>
</div>
</div>


Das integriert zeigt ein Keypad auf eurer TabletUI Seite immer dann an, wenn der State von AlarmKeypadDummy auf 'locked' steht. Darüber hinaus wird bei jedem Klick auf einen der Buttons das key-Reading des Devices gesetzt.

5. Alarm scharf schalten über TabletUI
Wer möchte kann mit Hilfe des folgenden Switches seine Alarmanlage dann auch noch über TabletUI aktivieren:


<!-- Alarm -->
      <li data-row="2" data-col="8" data-sizey="1" data-sizex="1">
        <header>Alarmanlage</header>
<div data-type="switch"
data-states='["armed","armwait","disarmed"]'
data-icons='["fa-lock","fa-unlock","fa-unlock"]'
data-background-colors='["red","red","green"]'
data-device="AAA"
data-get="level0"
data-get-on='["armed","armwait"]'
data-get-off="disarmed"
data-set-on="armed 0"
data-on-background-color="red"
data-off-background-color="green"
style="padding-top:20px">
  </div>
</li>


Eventuell müsst ihr in der Definition den Namen eurer Alarmanlage anpassen.

Ergebnis
Ihr solltet jetzt auf eurer TabletUI Seite einen Button mit Schloss haben über den ihr den Alarm aktivieren könnt (vgl. Bild 1).
Sobald der Alarm aktiv ist wird das Keypad eingeblendet, durch das ihr den Alarm deaktivieren könnt (vgl. Bild 2)

pataya

Danke für die Zusammenfassung, konnte das gut für meine eigene Alarmanlage verwenden :)
Was mir auffällt ist, sobald AlarmKeypadDummy auf locked gesetzt ist und ich TabletUI starte, öffnet er über dem eigentlichen Popup ein weiteres ohne Tasten, das ich auch wegschieben kann (Bilder).
Kannst du das reproduzieren?

DarkT

Freut mich, dass es soweit schon mal geklappt hat.

Reproduzieren kann ich das mit meiner index.html nicht.

Poste doch bitte mal deine. denke dass da irgendwo das Problem liegt.

LG Thomas

pataya

Stimmt, eingebunden in der index_empty.html funktioniert's. Dann schau ich mir meinen Code mal an, wollte den ganzen quatsch eh mal neu aufbauen.

speridal

Hallo DarkT!

Vielen Dank für das Keypad! Es klappt wunderbar und ich hab schon lange danach gesucht.

Eine kleine Ergänzung hätte ich noch. Da ich die Alarmanlage auch mittels Keymatic-Schlüssel deaktiviere, habe ich in der "disarm - Aktion" der Alarmanlage noch ein "set AlarmKeypadDummy unlocked" ergänzt. Dadurch wird das Keypad auch ausgeblendet, wenn die Alarmanlage auf anderem Wege deaktiviert wird.

Gruß,
Bernd

DarkT

Zitat von: speridal am 26 Februar 2018, 08:15:58
Hallo DarkT!

Vielen Dank für das Keypad! Es klappt wunderbar und ich hab schon lange danach gesucht.

Eine kleine Ergänzung hätte ich noch. Da ich die Alarmanlage auch mittels Keymatic-Schlüssel deaktiviere, habe ich in der "disarm - Aktion" der Alarmanlage noch ein "set AlarmKeypadDummy unlocked" ergänzt. Dadurch wird das Keypad auch ausgeblendet, wenn die Alarmanlage auf anderem Wege deaktiviert wird.

Gruß,
Bernd

Super! Freut mich, genau aus dem Grund habe ich das hier zusammen gefasst.

Prof. Dr. Peter Henning


DarkT

Zitat von: Prof. Dr. Peter Henning am 26 Februar 2018, 11:42:35
Sollte eigentlich auch ins Wiki.

LG

pah

Ich habe mir extra einen Account geben lassen. Bin aber leider etwas erschlagen von der Wiki-Verwaltung.
Außerdem wollte ich das noch irgendwie mit deinem Eintrag dort verknüpfen.

Meinst Fu wir bekommen das zusammen hin?
Ich kann das gerne vorbereiten, falls das irgendwie hilft.

Könntest du mir dann beim Einplegen ins Wiki helfen?


DarkT

Wahnsinn. Du hast ja schon fast alles gemacht. Dann werde ich das jetzt mal in Form bringen, wird aber erst nächste Woche was werden.

DarkT


kptkip

Aloa,

hoffe, das ist nach 120 Tagen Inaktivität noch der richtige Thread für die Frage - falls es einen besseren Ort gibt, gerne verschieben oder Rückmeldung geben:

Ich krieg den Dummy nicht ans Laufen - der Rest lüppt.

Ich erhalte nicht die notwendigen userReadings, um Daten in unlockPin und den Rest zu schreiben.

Mein Device sieht folgendermaßen aus:
defmod AlarmKeypadDummy dummy
attr AlarmKeypadDummy DbLogExclude .*
attr AlarmKeypadDummy event-on-change-reading state,inputPin
attr AlarmKeypadDummy event-on-update-reading key
attr AlarmKeypadDummy readingList key,inputPin,fails,unlockPin
attr AlarmKeypadDummy room AlarmRoom
attr AlarmKeypadDummy setList unlockPin
attr AlarmKeypadDummy userReadings inputPin:key:.[0-9] { return ReadingsVal($NAME, "inputPin", "*") . ReadingsVal($NAME, "key", "0");; }, fails:key:.# { if (ReadingsVal($NAME, "inputPin", "0") ne ReadingsVal($NAME, "unlockPin", "0")) { return ReadingsVal($NAME, "fails", 0)+1;; } else { return 0;; } }, state:key:.# { if (ReadingsVal($NAME, "inputPin", "0") ne ReadingsVal($NAME, "unlockPin", "0")) { return "locked";;;; } else { return "unlocked";;;; } }, inputPin:key:.[\<] { my $inputVal = ReadingsVal($NAME, "inputPin", "0");; chop($inputVal);;;; return $inputVal;; },  inputPin:key:.# { return "";; }


Wenn ich dann den Pincode eingebe, passiert Folgendes:
setstate AlarmKeypadDummy unlockPin 1234
setstate AlarmKeypadDummy 2019-06-21 17:02:24 state unlockPin 1234


Übersehe ich da was?

Gruß
kptkip
FHEM Revision: 22312 auf RasPI3B+,1xNeumannCUL,HMLAN,1xRasPi3B+,2xRasPI ZERO W
CUL_HM:HM-Sec-SCo, HM-CC-RT-DN
Fritz: Fritz!Box 6590C,DECT301,DECT200
Shelly:Shelly1,Shelly2, ShellyBulb Xiaomi: Schalter, Fensterkontakte HUE: ConbeeII
Tasmota:SonoffBridge, Stecker

kptkip

Aloa,

ich hab das Teil nun zum Laufen gebracht.

Das Problem war das Eingabeformat vom Attribut readingList. Das muss - zumindest in meiner Installation - mit einem Leerzeichen und nicht mit einem Komma separiert werden.

also anstatt:
attr AlarmKeypadDummy readingList key,inputPin,fails,unlockPin

also:
attr AlarmKeypadDummy readingList key inputPin fails unlockPin

Seither läuft das ganze, wie geschmiert.

Was ich noch hinzugefügt habe, ist ein Notify, das mir bei einer externen Deaktivierung des Alarms (z.B. Telegram) auch den Dummy auf "unlocked" setzt:
defmod NOT_AlarmanlageUnlocked notify Alarmanlage:level0:.disarmed sleep 3;; set AlarmKeypadDummy unlocked
attr NOT_AlarmanlageUnlocked DbLogExclude .*
attr NOT_AlarmanlageUnlocked room AlarmRoom



Gruß
Kptkip
FHEM Revision: 22312 auf RasPI3B+,1xNeumannCUL,HMLAN,1xRasPi3B+,2xRasPI ZERO W
CUL_HM:HM-Sec-SCo, HM-CC-RT-DN
Fritz: Fritz!Box 6590C,DECT301,DECT200
Shelly:Shelly1,Shelly2, ShellyBulb Xiaomi: Schalter, Fensterkontakte HUE: ConbeeII
Tasmota:SonoffBridge, Stecker

Prof. Dr. Peter Henning