Neues Modul für Alarmanlage

Begonnen von Prof. Dr. Peter Henning, 08 September 2014, 20:43:06

Vorheriges Thema - Nächstes Thema

jmike

#660
Zitat von: dadoc am 14 Oktober 2016, 23:08:26
...
Bei anderen bekomme ich es jedoch nicht hin, das Abschneiden des Eintrags nach dem ersten Anführungszeichen zu verhindern, etwa bei
set einbruch_d Einbruch;{my $timestamp = Value("einbruch_d")." um ".ReadingsTimestamp("einbruch_d","state","")

Kannst du mal zeigen wie die komplette "Action" aussieht? Ich nehme an es handelt sich um eine set/unset Action.
Dir fehlt nämlich eine "}" im Beispiel oben und wohl auch der Rest des Befehls.

Dann können wir vielleicht auch einen Workaround bauen.


dadoc

Sorry, Klammer fehlte, weil ich es aus dem level6onact-attr rauskopiert hatte. Der ursprüngliche Eintrag lautet:
set einbruch_d Einbruch;{my $timestamp = Value("einbruch_d")." um ".ReadingsTimestamp("einbruch_d","state",""); fhem "set einbruch_datetime_d $timestamp"}
Nach dem Speichern (Set Alarms + Save config) bleibt:
set einbruch_d Einbruch;{my $timestamp = Value(
Standort 1: FS20 mit CUL und FHEM auf Raspi. HM-Komponenten (Heizung, Rollladen, Schalter). HM IP über Raspimatic (testweise)
Standort 2: Homematic (Wired) über CCU2 und PocketHome HD
3 x Raspi3 mit piCorePlayer/Kodi für Multiroom Audio (+ Tablets/iPeng/iPods

jmike

#662
Ok.

Also schreibst du den Wert+Timestamp vom Dummy einbruch_d in den state von einbruch_datetime_d.

Das kannst du z.b. auch per userReading machen.
attr einbruch_datetime_d userReadings state { ReadingsVal("einbruch_d","state")." um ".ReadingsTimestamp("einbruch_d","state","")}
ungetestet

Damit sollte einbruch_datetime_d aktualisiert werden wenn einbruch_d aktualisiert wird.
Das ist zwar (noch) nicht die Lösung aber vielleicht ein Workaround.

noch mal edit nachdem die Syntax doch falsch war...
userReadings werden erst abgearbeitet wenn das Device aktualisiert wird, ein deinem Fall einbruch_datetime_d - und damit nie.
Du müsstest also in der Alarm Action "set einbruch_d Einbruch;set einbruch_datetime_d update;" oder sowas machen damit das userReading aktiv wird.
Auch nicht gerade hübsch...

jmike

#663
oder einfach so..

set einbruch_d Einbruch;; {fhem('set einbruch_datetime_d '. ReadingsVal('einbruch_d','state','').' um '.ReadingsTimestamp('einbruch_d','state',''))}

dadoc

Erstaml vielen Dank für Deine Unterstützung!
Zitat von: jmike am 15 Oktober 2016, 10:30:15
Also schreibst du den Wert+Timestamp vom Dummy einbruch_d in den state von einbruch_datetime_d.
Genau.
Zitat
Das kannst du z.b. auch per userReading machen.
attr einbruch_datetime_d userReadings state { ReadingsVal("einbruch_d","state")." um ".ReadingsTimestamp("einbruch_d","state","")}
ungetestet
Mein Problem ist ja nicht, dass mein Code nicht das täte, was er soll (er tut es), sondern dass er das nur so lange tut, wie man die Alarm Settings kein zweites Mal speichert, da er durch das zweite Speichern "kastriert" wird.
Der Code, den Du in Deinem letzten Post vorschlägst, wird zwar nicht kastriert (d.h. bleibt im Eingabfeld des Alarmmoduls auch nach mehrmaligem Speichern erhalten), funktioniert aber dafür nicht :/

Klar könnte ich das auch außerhalb des Alarmmoduls mit einem notify oder DOIF lösen (so hatte ich es bislang auch), aber ich hatte den Ehrgeiz entwickelt, die Alarm-relevanten Komponenten auch im Alarm-Modul zu verwalten.
Standort 1: FS20 mit CUL und FHEM auf Raspi. HM-Komponenten (Heizung, Rollladen, Schalter). HM IP über Raspimatic (testweise)
Standort 2: Homematic (Wired) über CCU2 und PocketHome HD
3 x Raspi3 mit piCorePlayer/Kodi für Multiroom Audio (+ Tablets/iPeng/iPods

jmike

Ich hatte es noch mal angepasst, siehe zwei ;; nach dem ersten Befehl.

Bei mir klappt es so.
dummy ist mein Sensor für clear
dummy2 ist mein Sensor für raise

Wenn ich dummy2 auf on setze wird einbruch_d gesetzt und zeitgleich einbruch_datetime_d

dadoc

Hmm...
{fhem('set einbruch_datetime_d '. ReadingsVal('einbruch_d','state','').' um '.ReadingsTimestamp('einbruch_d','state',''))}
geht bei mir definitiv nicht, auch nicht im Eingabefeld des WebUI ein - einbruch_datetime_d bleibt unverändert. Und da müsste es in meinem Verständnis ja auch funktionieren.

Bei mir geht (im Eingabefeld und im Alarm-Modul)
{my $timestamp = Value("einbruch_d")." um ".ReadingsTimestamp("einbruch_d","state","");; fhem "set einbruch_datetime_d $timestamp"}
Standort 1: FS20 mit CUL und FHEM auf Raspi. HM-Komponenten (Heizung, Rollladen, Schalter). HM IP über Raspimatic (testweise)
Standort 2: Homematic (Wired) über CCU2 und PocketHome HD
3 x Raspi3 mit piCorePlayer/Kodi für Multiroom Audio (+ Tablets/iPeng/iPods

MaxAut

#667
Guten Morgen!

Zitat von: dadoc am 15 Oktober 2016, 11:07:52Klar könnte ich das auch außerhalb des Alarmmoduls mit einem notify oder DOIF lösen (so hatte ich es bislang auch), aber ich hatte den Ehrgeiz entwickelt, die Alarm-relevanten Komponenten auch im Alarm-Modul zu verwalten.

--> diesen Ehrgeiz hatte ich ebenfalls, musste ich aber aufgrund diverser Unzulänglichkeiten/Einschränkungen des Moduls rasch aufgeben. Ich wollte aber dennoch eine übersichtliche und an so wenig Stellen wie möglich verwaltete Alarmanlage implementieren (daher ja auch der ursprüngliche Ansatz alles innerhalb des Moduls zu lösen), und habe es letztlich mit einer eigenen Funktion in den myUtils gemacht. Das ist, wenn man sich einmal an die im Vergleich zu modernen Programmiersprachen etwas "eingerostete" und teilweise umständliche Syntax von Perl gewöhnt hat, recht simpel. Bei mir gibt es eine "sub", die ich mit unterschiedlichen Parametern aufrufe, welche dann in einem großen "switch" jeweils ausführt was zu tun ist. Wichtig war mir dabei, dass es eine Subroutine ist, und nicht Mehrere, weil ich es eben auf so wenig Stellen wie möglich verteilen wollte. Etwaige Variablen/Status-Informationen "speichere" ich in genau einem zentralen Dummy mittels UserReadings ab. Vielleicht ist das ja auch ein Ansatz für Dich dadoc.

Liebe Grüße,
Max

jmike

Zitat von: dadoc am 15 Oktober 2016, 15:24:35
Bei mir geht (im Eingabefeld und im Alarm-Modul)
{my $timestamp = Value("einbruch_d")." um ".ReadingsTimestamp("einbruch_d","state","");; fhem "set einbruch_datetime_d $timestamp"}

Ich werd jetzt nicht ganz schlau draus, ob dein Problem gelöst ist oder nicht.
Warum die erste Variante nicht geht bleibt vorerst auch ein Geheimnis ?!

Hier noch mal 3 Varianten, alle funktionieren für sich, syntax getestet per Telnet, siehe v1/v2/v3.

v1 funktioniert bei mir und lässt sich auch im Alarm Modul speichern und über "set dummy on" auslösen:
fhem> {fhem('set einbruch_datetime_d '. ReadingsVal('einbruch_d','state','').' v1 um '.ReadingsTimestamp('einbruch_d','state',''))}
fhem> list einbruch_datetime_d
Internals:
   NAME       einbruch_datetime_d
   STATE      Einbruch v1 um 2016-10-15 11:19:03


v2 (deine Version) lässt sich bei mir im Modul nicht abspeichern bzw. ab dem ersten " abgeschnitten, ginge aber Grundsätzlich.
fhem> {my $timestamp = Value("einbruch_d")." v2 um ".ReadingsTimestamp("einbruch_d","state","");; fhem "set einbruch_datetime_d $timestamp"}
fhem> list einbruch_datetime_d
Internals:
   NAME       einbruch_datetime_d
   STATE      Einbruch v2 um 2016-10-15 11:19:03


Und v3 (deine Version mit ' ) läuft zwar im Telnet und lässt sich abspeichern aber ausgelöst durch das Alarm Modul bekomme ich nur  "Unknown command {my, try help."
fhem> {my $timestamp = ReadingsVal('einbruch_d','state','').' v3 um '.ReadingsTimestamp('einbruch_d','state','');; fhem 'set einbruch_datetime_d '.$timestamp}
fhem> list einbruch_datetime_d
Internals:
   NAME       einbruch_datetime_d
   STATE      Einbruch v3 um 2016-10-15 11:19:03

Prof. Dr. Peter Henning

#669
Wenn irgend jemand
ZitatUnzulänglichkeiten/Einschränkungen des Moduls
empfindet, soll er sich doch bitte tummeln und seine eigene Software schreiben. So er kann. Die Mäkelei ist vollkommen unangemessen.
LG

pah

PSI69

@All
Nachdem ich im Juni diesen Jahres über dieses Modul 'gestolpert' bin, den Verlauf hier im Forum dazu mit wachsender Begeisterung komplett duchgeackert und mir Notizen gemacht hatte, ist es nun an der Zeit, das Alarm Modul auch einzusetzen...

Vorgegangen bin ich nach Wiki; der Einstieg sollte das Ersetzen des Notify bei schwachen Batterien und der damit verschickten Telegram Message durch einen Alalrm Level im Modul sein; und ich dachte, ich bin gut vorbereitet und es kann gar nichts passieren; doch ...

Als Sensor habe ich den Vorschlag im Wiki übernommen:
# Notify für Batterie Warnungen
#
define N_LowBatterie notify .*:[Bb]attery.*[Ll]ow.* set LowBatt.Warn $NAME
attr N_LowBatterie group deviceDetector
attr N_LowBatterie room IS Alarmanlage

define LowBatt.Warn dummy
attr LowBatt.Warn alarmDevice Sensor
attr LowBatt.Warn alarmSettings alarm2,|LowBatt.Warm|Batterie $EVENT|on
attr LowBatt.Warn group deviceDetector
attr LowBatt.Warn room IS Alarmanlage


Auch der Global Cancel aus dem Wiki steht in der Konfig:
# Globaler Abbruch Alarmanlage
#
define Global.Cancel dummy
attr Global.Cancel alarmDevice Sensor
attr Global.Cancel alarmSettings alarm0,alarm1,alarm2,alarm3,alarm4,alarm5,alarm6,alarm7,|Global.Cancel||off
attr Global.Cancel alias Globaler Alarm Abbruch
attr Global.Cancel room IS Alarmanlage
attr Global.Cancel setList state:Abbruch
attr Global.Cancel webCmd Abbruch


Als Actor hatte ich das Telegram Device als solches erfolglos versucht, aktuell benutze ich einen Dummy:
# Dymmy für Telegram Nachricht
#
define Telegram.Alarm dummy
attr Telegram.Alarm alarmDevice Actor
attr Telegram.Alarm alarmSettings alarm2,|set TeleBot message '$NAME'||0
attr Telegram.Alarm group alarmActor
attr Telegram.Alarm room IS Alarmanlage


Hier noch die Konfig der 'AAA':
define AAA Alarm
attr AAA alias Alarmanlage
attr AAA armact set TeleBot message 'Alarmanlage scharf geschaltet.'
attr AAA armdelay 0:30
attr AAA armwait set TeleBot message 'Alarmanlage wird in Kürze scharf geschaltet.'
attr AAA cancelact set TeleBot message 'Alarm widerrufen.'
attr AAA disarmact set TeleBot message 'Alarmanlage unscharf geschaltet.'
attr AAA level0end 0
attr AAA level0msg 0
attr AAA level0start 0
attr AAA level0xec disarmed
attr AAA level1end 0
attr AAA level1msg 0
attr AAA level1start 0
attr AAA level1xec disarmed
attr AAA level2end 23:59
attr AAA level2msg schwach
attr AAA level2offact
attr AAA level2onact set TeleBot message '$NAME';;
attr AAA level2start 0:00
attr AAA level2xec armed
attr AAA level3end 0
attr AAA level3msg 0
attr AAA level3start 0
attr AAA level3xec disarmed
attr AAA level4end 0
attr AAA level4msg 0
attr AAA level4start 0
attr AAA level4xec disarmed
attr AAA level5end 0
attr AAA level5msg 0
attr AAA level5start 0
attr AAA level5xec disarmed
attr AAA level6end 0
attr AAA level6msg 0
attr AAA level6start 0
attr AAA level6xec disarmed
attr AAA level7end 0
attr AAA level7msg 0
attr AAA level7start 0
attr AAA level7xec disarmed
attr AAA lockstate unlock
attr AAA room IS Alarmanlage
define AAA_weblink weblink htmlCode {Alarm_Html("AAA")}
attr AAA_weblink room AlarmRoom


Die Notifys beim Druck auf Set Alarms werden geschrieben:
define alarm2.off.N notify (Global.Cancel) {main::Alarm_Exec("AAA",2,"$NAME","$EVENT","off")}
attr alarm2.off.N group alarmNotifier
attr alarm2.off.N room Alarm
define alarm2.on.N notify (LowBatt.Warm) {main::Alarm_Exec("AAA",2,"$NAME","$EVENT","on")}
attr alarm2.on.N group alarmNotifier
attr alarm2.on.N room Alarm


Mein Problem: Ich bekomme keine Nachricht von der Alarmanlage, wenn ich LowBatt per Trigger absetze, nur mein altes noch parallel vorhandenes Notify, was ich ja ersetzen will, reagiert und sendet:
# Batteriestatus
define N_BatterieStatus notify .*:[Bb]attery.* { if ($EVENT !~ m/ok/) {fhem ("set TeleBot message '$NAME' Batterie wechseln!")}  }


Hier der Auszug aus dem Eventmonitor beim Triggern:
2016-10-31 10:47:08 TelegramBot TeleBot message 'Fensterkontakt.EG.Bad' Batterie wechseln!
2016-10-31 10:47:08 dummy LowBatt.Warn Fensterkontakt.EG.Bad
2016-10-31 10:47:08 CUL_HM Fensterkontakt.EG.Bad Battery:low
2016-10-31 10:47:08 TelegramBot TeleBot sentMsgResult: SUCCESS
2016-10-31 10:47:08 TelegramBot TeleBot sentMsgId: 2793

2016-10-31 10:48:21 TelegramBot TeleBot message 'Fensterkontakt.EG.Windfang' Batterie wechseln!
2016-10-31 10:48:21 dummy LowBatt.Warn Fensterkontakt.EG.Windfang
2016-10-31 10:48:21 CUL_HM Fensterkontakt.EG.Windfang Battery:low
2016-10-31 10:48:22 TelegramBot TeleBot sentMsgResult: SUCCESS
2016-10-31 10:48:22 TelegramBot TeleBot sentMsgId: 2794


Also, für mich reagiert der neue Trigger aus dem Wiki korrekt und setzt den Sensor 'dummy LowBatt.Warn' auf getriggerten Wert; nur, warum die Alarmanlage nicht anspringt, da habe ich im Moment keinen Plan!

Die im Modul hintelegten Telegram Messages beim Armen/Disarmen eines Alarmlevels werden korrekt verschickt (siehe AAA Konfiguration).

Hat jemand von Euch einen Tip für mich?
Danke Peter
FHEM auf RPi 5 unter Bookworm mit inzwischen einem ganzen Zoo von Geräten...

Prof. Dr. Peter Henning

Zitatda habe ich im Moment keinen Plan!

Plan habe ich auch keinen. Ich lese aber in der Konfiguration des neuen Dummies:

attr LowBatt.Warn alarmSettings alarm2,|LowBatt.Warm|Batterie $EVENT|on

d.h. Warm statt Warn.

Damit wird dieser reguläre Ausdruck nie zutreffen und logischerweise die Alarmanlage nicht ausgelöst.

LG

pah

PSI69

@pah

Uuups...
Ich habe das gestern gefühlt 100* übersehen; zum Versenden nehme ich jetzt '{fhem('set TeleBot message '.ReadingsVal('AAA','short',0))}'; damit läuft dann der erste Alarm.

Was ist eigentlich sinnvoller: den TeleBot selbst als Actor zum Versenden definieren, oder weiter mit einem Dummy zu arbeiten?

Danke!
Peter
FHEM auf RPi 5 unter Bookworm mit inzwischen einem ganzen Zoo von Geräten...

PSI69

Ich habe noch zwei Fragen...

Nachdem ich nun in Level 7 meine SD's (HM-SEC-SD) eingebunden habe, stellte ich fest, dass ein Alarm von Level 7, den Alarm Level 2 (Batterie schwach) überschreibt, d.h. hier erfolgt dann eine Benachrichtigung ohne Abbruch / Cancel des vorherigen Alarms mit Level 2.
In jedem anderem Fall (weiterer Alarm gleichen Levels, bzw. Alarm geringeren Levels, jeweils ohne Cancel des vorherigen Alarm State) erfolgt keine weitere Aktion / Benachrichtigung der Alarmanlege; ist diese Annahme korrekt?

Ist es sinnvoll für die SD's in Level 7 einen Sensor mit Cancel Action hinzuzufügen, oder nach Beseitigung der Ursache des Auslösens der SD's (der hoffentlich nie eintritt) den Alarm Status der AAA manuell zu canceln?

Was sagt ihr dazu?
Danke Peter
FHEM auf RPi 5 unter Bookworm mit inzwischen einem ganzen Zoo von Geräten...

Prof. Dr. Peter Henning

Die Annahme ist korrekt.

Level 7 ist bei mir für die lebensbedrohlichen Situationen vorbehalten - dazu gehört Feueralarm. Das sollte man nie automatisch canceln - aber ich habe einen manuellen Sensor (=Taste), der dies auch mit erledigt.

LG

pah