NEWS
Umfassendes Alarmanlagen-Skript
-
Hallo an @kosy oder allen Anderen die hier so tolle Arbeit leisten.
Bin neu hier und versuche mich gerade an dem tollen Alarmanlagen Skript.
Dazu hätte ich zu der letzten Aktualisierung (IgnoreOpen) eine Frage.
Wie kann man die Sensoren die jetzt in IgnoreOpen drinn stehen aber mit false auf truhe ändern um sie von der Alarmanlage auszuschließen wenn sie das Fenster offen ist.
Wenn ich zb. auf false klick tut sich gar nichts, kann man das nicht da ändern?
Sorry wenn meine Frage komisch kling, aber ich bin noch gaaaanz am Anfang.
Sonst läuft eh alles.
Bitte um Hilfe Gruß aus Tirol. -
Funktioniert
-
Funktioniert
@holger_b76 Danke!
Ich habe jetzt die Änderungen oben im ersten Post eingearbeitet.
Außerdem habe ich das Script auf den aktuellen Javascript-Adapter angepasst und ACK-Flags gesetzt bei createState und setState.
Könntet ihr das auch mal ausprobieren? Es ist noch ungetestet... Bitte um euer Feedback!
Danke! -
Hallo an @kosy oder allen Anderen die hier so tolle Arbeit leisten.
Bin neu hier und versuche mich gerade an dem tollen Alarmanlagen Skript.
Dazu hätte ich zu der letzten Aktualisierung (IgnoreOpen) eine Frage.
Wie kann man die Sensoren die jetzt in IgnoreOpen drinn stehen aber mit false auf truhe ändern um sie von der Alarmanlage auszuschließen wenn sie das Fenster offen ist.
Wenn ich zb. auf false klick tut sich gar nichts, kann man das nicht da ändern?
Sorry wenn meine Frage komisch kling, aber ich bin noch gaaaanz am Anfang.
Sonst läuft eh alles.
Bitte um Hilfe Gruß aus Tirol.Sorry für diese reichlich späte Rückmeldung auf deine Frage! Das Verhalten wurde ein paar Posts vorher diskutiert, da lag ein Fehler drin.
Versuch es nochmal mit dem aktualisierten Skript ganz oben.Liebe Grüße
Andreas -
Hallo Andreas, hallo Community,
ich habe mich nun nach vielm Lesen und Testen des Scripts dazu durchgerungen, mal hier zu posten.
Dein Script habe ich eingebaut und es funktioniert auch fehlerfrei.
In den Aufzählungen sind folgende Melder drin:

Die Datenpunkte (deines Scripts) z.b. "Open Detectors" und auch andere unter "Output" funktionieren scheinbar korrekt, jedenfalls sehe ich bei Statusänderungen der Fenster auch die Datenpunkte sich ändern.
Auch die "IgnoreOpen" funktionieren einwandfrei.Was mir komisch vorkommt, sind JAVASCRIPT "Warnungen", die ich nicht zuordnen kann und was diese zu bedeuten haben:

Jedesmal, wenn ein Bewegungsmelder (KNX) bewegung dedektiert, kommt dieser "Warnungsblock", oder auch wenn ich ein Fenster öffne, oder schliesse
Muss ich mir Sorgen machen ?? Oder darf ich das ignorieren... bzw. wie lassen sich diese Warnungn, wenn sie nicht tragisch sein sollten, deaktivieren??
Bzw. was muss ich/kann ich tun um diese Warnungen zu beheben ?Sorry für so blöde Fragen, aber ich weis keinen Rat mehr, da ich kein Javascript behersche und bevor ich das Praktisch verwende, wollte ich sichergehen, das das Script auch korrekt läuft.
Danke jedenfalls im voraus für eure/deine Hilfe :-)
Gruß Michael
-
Hallo Andreas, hallo Community,
ich habe mich nun nach vielm Lesen und Testen des Scripts dazu durchgerungen, mal hier zu posten.
Dein Script habe ich eingebaut und es funktioniert auch fehlerfrei.
In den Aufzählungen sind folgende Melder drin:

Die Datenpunkte (deines Scripts) z.b. "Open Detectors" und auch andere unter "Output" funktionieren scheinbar korrekt, jedenfalls sehe ich bei Statusänderungen der Fenster auch die Datenpunkte sich ändern.
Auch die "IgnoreOpen" funktionieren einwandfrei.Was mir komisch vorkommt, sind JAVASCRIPT "Warnungen", die ich nicht zuordnen kann und was diese zu bedeuten haben:

Jedesmal, wenn ein Bewegungsmelder (KNX) bewegung dedektiert, kommt dieser "Warnungsblock", oder auch wenn ich ein Fenster öffne, oder schliesse
Muss ich mir Sorgen machen ?? Oder darf ich das ignorieren... bzw. wie lassen sich diese Warnungn, wenn sie nicht tragisch sein sollten, deaktivieren??
Bzw. was muss ich/kann ich tun um diese Warnungen zu beheben ?Sorry für so blöde Fragen, aber ich weis keinen Rat mehr, da ich kein Javascript behersche und bevor ich das Praktisch verwende, wollte ich sichergehen, das das Script auch korrekt läuft.
Danke jedenfalls im voraus für eure/deine Hilfe :-)
Gruß Michael
Hi Michael!
Sorry für die späte Antwort! Freut mich, dass du auch KNX einsetzt! Nur interessehalber: verwendest du den openknx-Adapter oder den knx?
Ich seh mir das an! Melde hier zurück sobald möglich. Bitte gib mir eine Woche dafür. ;-)
LG Andreas
-
Hi Michael!
Sorry für die späte Antwort! Freut mich, dass du auch KNX einsetzt! Nur interessehalber: verwendest du den openknx-Adapter oder den knx?
Ich seh mir das an! Melde hier zurück sobald möglich. Bitte gib mir eine Woche dafür. ;-)
LG Andreas
Hi Andreas, derzeit verwende ich "noch" den knx Adapter. Eigentlich habe ich nicht geplant zu wechseln, aber man weiss ja nie.
Spielt das denn eine Rolle ??
Gibt es eigentlich eine Möglichkeit dein Script Zonenbasiert zu erweitern ?
Ich würde nämlich gerne den Keller getrennt, vom Wohnraum absichern ...
Spricht Zone Keller, getrennt scharf/unscharf/Meldelinien und Wohnraum (EG,OG,DG) scharf/unscharf/Meldelinien ....
Wenn das ginge, wäre das TOP :-)Freu mich von dir zu lesen....
-
Hi Andreas, derzeit verwende ich "noch" den knx Adapter. Eigentlich habe ich nicht geplant zu wechseln, aber man weiss ja nie.
Spielt das denn eine Rolle ??
Gibt es eigentlich eine Möglichkeit dein Script Zonenbasiert zu erweitern ?
Ich würde nämlich gerne den Keller getrennt, vom Wohnraum absichern ...
Spricht Zone Keller, getrennt scharf/unscharf/Meldelinien und Wohnraum (EG,OG,DG) scharf/unscharf/Meldelinien ....
Wenn das ginge, wäre das TOP :-)Freu mich von dir zu lesen....
Hallo Michael,
also - um es kurz zu machen: Es war ein Fehler im Script! Die Ignore-Open Flags wurden nicht korrekt eingetragen und diese werden aber bei jedem Melder-Event abgefragt.
Die Fehlermeldung ist jetzt weg. Ich habe das Script im ersten Posting ganz oben bereits korrigiert neu reingestellt.Sorry, dass es so lange gedauert hat!
Liebe Grüße
Andreas -
Hi Andreas, derzeit verwende ich "noch" den knx Adapter. Eigentlich habe ich nicht geplant zu wechseln, aber man weiss ja nie.
Spielt das denn eine Rolle ??
Gibt es eigentlich eine Möglichkeit dein Script Zonenbasiert zu erweitern ?
Ich würde nämlich gerne den Keller getrennt, vom Wohnraum absichern ...
Spricht Zone Keller, getrennt scharf/unscharf/Meldelinien und Wohnraum (EG,OG,DG) scharf/unscharf/Meldelinien ....
Wenn das ginge, wäre das TOP :-)Freu mich von dir zu lesen....
Achja, noch zu der Frage
Gibt es eigentlich eine Möglichkeit dein Script Zonenbasiert zu erweitern ?
Ja, die gibt's! ;-) Einfach das Script ein zweites mal kopieren und laufen lassen für die jeweilige Zone. In den Aufzählungen, die du dort angibst, kannst du dann beispielsweise alle Melder vom Keller reinschmeißen.
-
Achja, noch zu der Frage
Gibt es eigentlich eine Möglichkeit dein Script Zonenbasiert zu erweitern ?
Ja, die gibt's! ;-) Einfach das Script ein zweites mal kopieren und laufen lassen für die jeweilige Zone. In den Aufzählungen, die du dort angibst, kannst du dann beispielsweise alle Melder vom Keller reinschmeißen.
@andreaskos
Hallo Andreas -> TOP!
Funktioniert nun einwandfrei .... :-) Endlich kann ich den Keller fertig machen...Ich habe ebenfalls auch andere "Input" Funktionsgruppennamen gewählt, aber das funktioniert ebenfalls ;-)
Meinst du, das könnte mal ein Adapter werden ??
Das wäre natürlich der Hammer ;-)
lg Micha
-
ACHTUNG - wichtige Korrektur!
Wenn das Script neu gestartet wurde, dann konnte dies dazu führen, dass die Alarmanlage in "unscharf" geht. Was zB übel ist, wenn dem Rechner aus irgendeinem Grund der Strom ausgeht, wenn zuvor "scharf" geschaltet wurde. Denn wenn der Strom wieder da ist, dann soll die Anlage wieder auf "scharf" gehen, so wie es vorher war.
Bitte auf die neueste Version updaten.
LG Andreas
-
Hi @Tirador hab jetzt meine Vis auf das Script angepasst nochmal Vielen Dank an Andreas für die Umsetzung.
Funktioniert hervorragend. :+1:
Hab noch meine Pineingabe mit integriert.
Hier mal 2 Screenshots wie meine Vis jetzt Aussieht.
Sag Bescheid ob du es haben willst dann stelle ich alles hier ein.Grüße

Hier meine Alarmanlage als Vorlage.
Bitte die einzelnen View genau so anlegen wie die Textdatei heißen dann sollte es sofort funktionieren ansonsten alles an die eigene Struktur anpassen.
Voraussetzung ist das [Projekt] MDCSS v2: Material Design CSS Version 2 von Uhula.
Für die Pineingabe das Blocklyscript ist auch dabei und angepasst, es muss nur der vierstellige Pin im Datenpunkt PW_Auswertung eingegeben werden.Viel Spaß.
-
Hallo
also das Script kann nur true oder false verarbeiten.
Allerdings können meine Melder nur Open oder closed melden, wie bekomme dann das umgeändert? -
@longbow Habe ich vor einem Tag in diesem Thread erklärt ...
https://forum.iobroker.net/topic/72237/jarvis-visualisierung-von-sensoren-im-status-an-aus/2?_=1706256243752Danke klappt aber nicht, denn der Homematic Fensterkontakt gibt den Wert CLOSED(0) oder OPEN(1) aus, wenn ich das so machen, wie du es beschrieben hast, reagiert der DP Aliase nicht.
hab nur mal die Zahl genommen... hat geklappt.
Jetzt ist true für zu, false für offen oder ?
-
Danke klappt aber nicht, denn der Homematic Fensterkontakt gibt den Wert CLOSED(0) oder OPEN(1) aus, wenn ich das so machen, wie du es beschrieben hast, reagiert der DP Aliase nicht.
hab nur mal die Zahl genommen... hat geklappt.
Jetzt ist true für zu, false für offen oder ?
-
Guten Morgen,
ich wollte ja dieses Script bei mir umsetzen.
Ich habe es am Laufen, vom Script her läuft es, wenn ich das Starte bekomme ich keine Fehlermeldung.Unter Funktionen habe ich den Meldern (Fenster und Tür, wie Bewegungsmelder) je die Funktion hinzugefügt, muss ich diese dann noch im Script unter ,,Arrays für die Melder'' dort die DP noch mal eingeben?
Kann die Alarmanlage scharf und unscharf stellen unter Objekte, aber wenn ich das Fenster, die Tür und den Bewegungsmelder offen oder Bewegung meldet, gibt es bei Scharf keine Veränderung.
Mit dem Tipp die Fensterkontakte von 1 zahl auf ture/false bekommen, das läuft auch prima. Nur es passiert an der Meldung nichts, wenn was sich bewegt oder geöffnet wird.Was mache ich falsch?
-
Liebe Community!
Kurzfassung
Hier stelle ich ein Skript für eine Alarmanlage vor. Einfach die Einstellungen im Skript anpassen und über die erzeugten Datenpunkte (default unter javascript.0.Alarmanlage) steuern.LG Andreas
Langfassung
Aufbau
Die Alarmanlage besteht aus folgenden Komponenten:- Schaltstellen für scharf/unscharf Schaltung
- Alarmgeber
- Einbruchsmelder
Außer den Einbruchsmeldern werden alle Punkte NUR als Datenpunkte angelegt, über die eine weitere Interaktion erfolgen kann. Hierfür bietet ioBroker ja zahlreiche Möglichkeiten wie die Einbindung in eine Visualisierung, die Verwendung in Scripts, Szenen, Blocklys und so weiter.
Für die Einbruchsmelder werden States aus ioBroker verwendet, die true beim Auslösen sind und false in Ruhe (wenn sie geschlossen sind). Die Namen der Melder sollten sinnvoll vergeben sein, gegebenenfalls daher die name-Attribute der Objekte in ioBroker noch anpassen. Die Melder müssen in Aufzählungen (ENUMs) in ioBroker eingefügt werden. Per default (kann in den Experteneinstellungen im Skript geändert werden) sind das die folgenden Aufzählungen:- alarmanlage_aussenhaut
In dieser Aufzählung befinden sich alle Melder der äußeren Hülle, die überwacht werden soll. Hier gehören Öffnungskontakte, Glasbruchsensoren, Riegelschaltkontakt, etc. hinein. - alarmanlage_innenraum
Hier werden die Melder für die Innenraum-Überwachung zusammengefasst. Das sind im wesentlichen Bewegungsmelder, Näherungssensoren, eventuell auch ganz normale Taster (z.B. für Licht etc.). - alarmanlage_verzoegert
Melder, welche für einen Eingang benötigt werden, der bei Auslösung zu einem verzögerten Alarm führt. Damit kann durch der überwachte Bereich durch die Eingangstür betreten werden und danach (innerhalb der Eingangsverzögerung) unscharf gestellt werden.
Funktion: scharf/unscharf Schalten
Grundsätzlich kann die Alarmanlage extern oder intern scharf geschaltet werden. Extern bedeutet, dass sich der Bediener selbst extern aufhält und somit alle verfügbaren Melder verwendet werden.
Intern bedeutet, dass sich der Bediener intern aufhält und somit nur die Melder zur Überwachung der Außenhaut verwendet werden.
Die Scharfschaltung für Extern kann auch verzögert erfolgen. Dabei läuft eine Ausgangsverzögerungszeit ab nach dem Schaltbefehl. Nach dem Ende der Verzögerungszeit erfolgt erst die tatsächliche Scharfschaltung.Das bedeutet also, dass Melder in Außenhaut oder Innenraum eingeteilt werden. Zusätzlich können Melder aus diesen Gruppen auch als verzögert gelten. Diese drei Gruppen von Meldern müssen in den entsprechenden Aufzählungen enthalten sein.
ACHTUNG: Scharf (egal, ob extern oder intern) kann nur geschaltet werden, wenn sich alle Melder in Ruhe befinden, also geschlossen sind! Sollte das nicht der Fall sein, so ist die Anlage nicht bereit zur Scharfschaltung. Dies wird in einem eigenen Ready-Datenpunkt angezeigt, sowie im AlarmText.
Sollte eine Scharfschaltung eingehen, obwohl die Anlage nicht bereit ist, so wird ein Fehler bei der Scharfschaltung durch den Error-Datenpunkt und wieder einem entsprechenden AlarmText angezegt.
Das kann auch dazu führen, dass bei verzögertem scharf Schalten ein Fehler bei der Scharfschaltung auftritt, den man unter Umständen nicht mehr bemerkt, weil man schon das Haus verlassen hat. Das muss man wissen oder sich einen Hinweis darauf erzeugen, zB durch ein Skript, etwa das Versenden einer Telegram-Meldung im Fehlerfall.Funktion: Alarm geben
Bei scharf gestellter Anlage wird bei Auslösung eines Melders geprüft, welcher Schaltzustand vorherrscht (intern/extern) und welchen Meldergruppen der auslösende Melder zuzuordnen ist. Davon abhängig wird Alarm ausgelöst oder die Eingangsverzögerung gestartet. Nach dieser erfolgt die Alarmierung, sofern nicht zwischenzeitlich unscharf geschaltet wird.Bei den Alarmgebern werden drei Datenpunkte angeboten:
Der AlarmAccoustical ist der akustische Alarm, dieser darf in Ö übrigens 3 Minuten nicht übersteigen. Die Werte bei den Einstellungen werden in Sekunden eingegeben, also maximal 180 Sekunden (keine eingebaute Beschränkung im Skript).
Der AlarmOptical ist der optische Alarm. Dieser darf so lange dauern, wie gewünscht. Soll er ewig antehen bis zum nächsten unscharf, dann kann die Zahl -1 für die Dauer verwendet werden.
Der ganz normale Alarm Datenpunkt steht immer auf true, wenn ein Alarm ausgelöst wurde bis zum nächsten unscharf.Bedienung oder Verwendung der Input-Datenpunkte
Über die States im Unterpunkt Input kann die Anlage scharf/unscharf geschaltet werden.
Mit dem Wert true auf den Datenpunkten erfolgt der Schaltbefehl unmittelbar oder verzögert im Falle von SwitchExternalDelayed.
Mit dem Wert false wird immer sofort auf unscharf geschaltet.Mit unscharf erfolgt auch immer ein Reset der Anlage, d.h. alle Alarme werden beendet und der Status- und Alarmtext entsprechend angepasst.
Es kann nicht von einem Scharf-Zustand auf einen anderen Scharf-Zustand gewechselt werden, es muss immer dazwischen unscharf geschaltet werden, ansonsten wird ein "Fehler bei der Scharfschaltung" geworfen.
Unter "Input" ist ein eigener Knoten namens "IgnoreOpen" zu finden. Unterhalb diesem können per Flag die einzelnen Melder inaktiv geschaltet werden.
true = von der Überwachung ausgenommen
false = wird mitüberwachtACHTUNG
Die Einstellung der IgnoreOpen-Flags wird (derzeit) nicht automatisch zurück gesetzt, etwa beim Scharf-Schalten. Das bedeutet, man muss selbst drauf achten, dass ein Melder nicht ewig auf Inaktiv bleibt, weil man vergessen hat das Flag wieder auf true zu stellen.Verwendung der Output-Datenpunkte
Über die Output-Datenpunkte können die Alarmgeber angesteuert werden (z.B. über ein zusätliches Script oder Blockly). Es gibt auch eine Menge an weiteren Datenpunkten, die für zusätzliche Funktionen oder Anzeigen in Visualisierungen nützlich sein können. Hier eine Auflistung mit kurzer Erklärung:- Active: Schaltzustand der Anlage insgesamt, true=scharf, false=unscharf. [boolean]
- ActiveInternal: Anlage intern scharf [boolean]
- ActiveExternal: Anlage extern scharf [boolean]
- ActiveNumber: gibt Auskunft über den tatsächlichen Zustand mit den Ziffern:
0 ... unscharf
1 ... intern scharf
2 ... extern scharf
3 ... Eingangsverzögerung aktiv
4 ... Ausgangsverzögerung aktiv - Alarm: true=Alarm ausgelöst, false=kein Alarm [boolean]
- AlarmAccoustical: Akustischer Alarm aktiv [boolean]
- AlarmOptical: Optischer Alarm aktiv [boolean]
- Ready: Anlage bereit zur Scharfschaltung [boolean]
- EntryDelayActive: Eintrittsverzögerung aktiv [boolean]
- ExitDelayActive: Ausgangsverzögerung aktiv [boolean]
- AlarmingDetector: Name des auslösenden Melders [string]
- AlarmingDetectorJSON: Name und alle weiteren verfügbaren Eigenschaften des auslösenden Melderobjektes und dessen Parent- und ParentsParent-Objekt im JSON-Format. [string]
- OpenDetectors: Namen aller offenen Melder [string]
- OpenDetectorsJSON: JSON-String wie beim AlarmingDetector mit Liste aller offenen Melder [string]
- OpenDetectorsOuterSkingJSON: JSON-String wie beim AlarmingDetector mit Liste aller offenen Melder der Außenhaut [string]
- OpenDetectorsIndoorJSON: JSON-String wie beim AlarmingDetector mit Liste aller offenen Melder des Innenraums [string]
- StatusText: Gibt Auskunft über Schaltzustand und aktive Verzögerungen [string]
- AlarmText: Gibt Auskunft über Alarmzustand und Bereitschaft oder Fehler bei der Scharfschaltung [string]
- OpenDetectorsIgnoreOpen Liste der offenen Melder mit gesetztem IgnoreOpen-Flag. Diese Melder kommen nicht in die Liste der ganz regulär offenen Melder. Diesen Datenpunkt könnte man verwenden, um sich zu warnen, wenn zum Zeitpunkt des Scharf-Schaltens (oder ein paar Millisekunden später) hier Text enthalten ist.
Die Texte, die in den Text-Datenpunkten verwendet werden, können in den Einstellungen im Skript angepasst werden.
Das Skript
/* ######################################################################################################################## # ALARMSYSTEM # # Das Skript bildet eine einfache Alarmanlage nach mit der Schaltmöglichkeit # für intern und extern. # Datenpunkte für Inputs und Outputs werden angelegt. # Nähere Beschreibung siehe im ioBroker-Forum unter # https://forum.iobroker.net/topic/32885/umfassendes-alarmanlagen-skript # Änderungshistorie: # 2020-05-01 Andreas Kos Erstellt # 2020-05-02 Andreas Kos Schaltwunsch mit Number-Datenpunkt Input.SwitchNumber (Idee von @Homer.J.) # Schaltstatus mit Number-Datenpunkt Output.ActiveNumber (Idee von @Homer.J.) # 2020-05-03 Andreas Kos Korrekturen, u.a. für Melderauswertung (chage: "ne") & AlarmText # 2020-05-04 Andreas Kos - Melder werden aus den Functions (Aufzählungen, enums) dafür geholt. Auch beim Unscharf- # schalten, dadurch ist kein Neustarten des Skripts notwendig bei # Änderungen an diesen Aufzählungen. # - Eine Schaltung von einem scharf-Zustand auf einen anderen # wird verhindert. ZB von scharf intern auf scharf extern. # Es muss immer unscharf dazwischen geschaltet werden. # 2020-05-09 Andreas Kos Zusätzliche Objekte mit JSON-Strings für: # - den auslösenden Melder # - alle offenen Melder # - alle offenen Melder der Außenhaut # - alle offenen Melder des Innenraums # Die JSON-String beinhalten das auslösende Objekt, sowie (falls vorhanden) # das Parent und das ParentsParent-Objekt mit allen in ioBroker verfügbaren Eigenschaften. # Kleinere Verbesserungen, z.B. bezüglich setzen der AlarmTexte. # 2020-05-12 Andreas Kos Setzen des Datenpunkts idReady zur Bereitschaftsanzeige neu gemacht. # 2021-06-13 Andreas Kos Einbau der Funktion zum Ausnehmen einzelner Melder der Aussenhülle # von der Melder-Überwachung. Soll zum Kippen von Fenstern dienen u.ä. # 2022-03-20 Andreas Kos Verbesserung beim Laden der Parents- und Parentsparents-Objekte und # Umbau auf aktuellen Javascript-Adapter mit Ack-Flags bei createState und setState # 2022-12-02 Andreas Kos Korrektur beim Prüfen der IgnoreOpen-Flags. # 2022-12-18 Andreas kos Korrektur beim Anlegen der States, sodass ein Neustart des Scripts eine weitere # Funktion der Anlage garantiert, auch, wenn diese zuvor im Zustand "scharf" war. ######################################################################################################################## */ // EINBRUCHSMELDER // Jeder Melder muss ein State sein, der bei Auslösung true liefert und in Ruhe (geschlossen) false. // Die Melder sind in Arrays zusammengefasst, d.h. sie müssen jeweils mit Beistrich voneinander getrennt werden. // Die Namen der Melder sollten gut gepflegt sein für eine sinnvolle Verwendung (Attribut name bei den Objekten) // Melder der Außenhaut // Dies können Öffnungskontakte sein von Fenster und Türen in den Außenmauern des Objekts. // EINGABE: In der Aufzählung "alarmanlage_aussenhaut" die States einfügen. // Melder des Innenraums // Dies können Bewegungsmelder sein aus dem Inneren. // EINGABE: In der Aufzählung "alarmanlage_innenraum" die States einfügen. // Verzögerte Melder // Diese kommen in den Gruppen oben auch vor. Sie bewirken eine Aktivierung der Eingangsverzögerung // bei scharf geschalteter Anlage und erlauben während der Ausgangsverzögerung nach dem // Scharfschalten das Haus zu verlassen. // EINGABE: In der Aufzählung "alarmanlage_verzoegert" die States einfügen. // EINSTELLUNGEN const entryDelay = 30; // Eingangsverzögerung in Sekunden (sollte maximal 60s sein) const exitDelay = 30; // Ausgangsverzögerung in Sekunden (sollte maximal 60s sein) const alarmDurationAccoustical = 180; // Dauer des akkustischen Alarms in Sekunden (ACHTUNG: in Ö sind maximal 180s erlaubt!) const alarmDurationOptical = -1; // Dauer des optischen Alarm in Sekunden, -1 für unendlich // TEXTE FÜR SCHALTZUSTAND // Diese Text geben Auskunft über den Zustand der Anlage. // Sie werden in den Datenpunkt "javascript.X.Output.StatusText" geschrieben. const textStatusInactive = "unscharf"; const textStatusActiveInternal = "scharf intern"; const textStatusActiveExternal = "scharf extern"; const textActiveExternalDelayed = "scharf extern verzögert"; const textEntryDelayActive = "Eingangsverzögerung aktiv"; const textExitDelayActive = "Ausgangsverzögerung aktiv"; // TEXTE FÜR ALARMIERUNG UND FEHLER // Diese Text geben im unscharfen Zustand der Anlage Auskunft über die Bereitschaft // zum Scharfschalten (nur möglich, wenn alle Melder geschlossen - in Ruhe - sind) und // Fehler bei der Scharfschaltung bzw. bei scharfer Anlage über den Zustand Frieden oder Alarm. // Sie werden in den Datenpunkt "javascript.X.Output.AlarmText" geschrieben. const textAlarmInactive = "Alles OK"; const textAlarmActive = "Alarm!!"; const textReady = "Bereit"; const textNotReady = "Nicht bereit"; const textError = "Fehler bei der Scharfschaltung"; // EXPERTEN-EINSTELLUNGEN const pathToCreatedStates = "Alarmanlage"; // Beispiel: States werden erzeugt unter javascript.X.Alarmanlage const seperator = ", "; // Trenn-String, der zwischen den Meldernamen verwendet wird, im Datenpunkt "OpenDetectors" const loglevel = 3; // 0 bis 3. 0 ist AUS, 3 ist maximales Logging // Empfehlung für Nachvollziehbarkeit aller Handlungen ist 2 (Ereignisliste) const functionOuterSkin = "alarmanlage_aussenhaut"; const functionIndoor = "alarmanlage_innenraum"; const functionDelayedDetectors = "alarmanlage_verzoegert"; /* ############################################################################### DO NOT CHANGE ANYTHING BELOW THIS LINE AB HIER NICHTS MEHR ÄNDERN ############################################################################### */ // =============================================================================== // Variablen // =============================================================================== // Arrays für die Melder var detectorsOuterSkin = []; var detectorsIndoor = []; var detectorsDelayed = []; // Array für die IgnoreOpen-Melder (beinhaltet nur Flags). // Das Array ist inital deckungsgleich mit detectorsOuterSkin, da diese // nur aus dieser Function kommen können. // Dieses Array ist 2-Dimensional: [Melder-ID, IgnoreOpen-Zustands-ID] var detectorsIgnoreOpen = []; // Javascript-Instanz mit der das Alarmanlagen-Skript ausgeführt wird var javascriptInstance = instance; // States, die erzeugt werden für Status-Ausgaben var idActive = "javascript." + javascriptInstance + "." + pathToCreatedStates + ".Output.Active"; var idActiveExternal = "javascript." + javascriptInstance + "." + pathToCreatedStates + ".Output.ActiveExternal"; var idActiveInternal = "javascript." + javascriptInstance + "." + pathToCreatedStates + ".Output.ActiveInternal"; var idActiveNumber = "javascript." + javascriptInstance + "." + pathToCreatedStates + ".Output.ActiveNumber"; var idAlarm = "javascript." + javascriptInstance + "." + pathToCreatedStates + ".Output.Alarm"; var idAlarmAccoustical = "javascript." + javascriptInstance + "." + pathToCreatedStates + ".Output.AlarmAccoustical"; var idAlarmOptical = "javascript." + javascriptInstance + "." + pathToCreatedStates + ".Output.AlarmOptical"; var idReady = "javascript." + javascriptInstance + "." + pathToCreatedStates + ".Output.Ready"; var idEntryDelayActive = "javascript." + javascriptInstance + "." + pathToCreatedStates + ".Output.EntryDelayActive"; var idExitDelayActive = "javascript." + javascriptInstance + "." + pathToCreatedStates + ".Output.ExitDelayActive"; var idAlarmingDetector = "javascript." + javascriptInstance + "." + pathToCreatedStates + ".Output.AlarmingDetector"; var idAlarmingDetectorJSON = "javascript." + javascriptInstance + "." + pathToCreatedStates + ".Output.AlarmingDetectorJSON"; var idOpenDetectors = "javascript." + javascriptInstance + "." + pathToCreatedStates + ".Output.OpenDetectors"; var idOpenDetectorsJSON = "javascript." + javascriptInstance + "." + pathToCreatedStates + ".Output.OpenDetectorsJSON"; var idOpenDetectorsOuterSkinJSON = "javascript." + javascriptInstance + "." + pathToCreatedStates + ".Output.OpenDetectorsOuterSkinJSON"; var idOpenDetectorsIndoorJSON = "javascript." + javascriptInstance + "." + pathToCreatedStates + ".Output.OpenDetectorsIndoorJSON"; var idOpenDetectorsWithIgnoreOpenFlagSet = "javascript." + javascriptInstance + "." + pathToCreatedStates + ".Output.OpenDetectorsIgnoreOpen"; var idStatusText = "javascript." + javascriptInstance + "." + pathToCreatedStates + ".Output.StatusText"; var idAlarmText = "javascript." + javascriptInstance + "." + pathToCreatedStates + ".Output.AlarmText"; var idError = "javascript." + javascriptInstance + "." + pathToCreatedStates + ".Output.Error"; // States, die erzeugt werden für Eingaben var idSwitchExternal = "javascript." + javascriptInstance + "." + pathToCreatedStates + ".Input.SwitchExternal"; var idSwitchInternal = "javascript." + javascriptInstance + "." + pathToCreatedStates + ".Input.SwitchInternal"; var idSwitchExternalDelayed = "javascript." + javascriptInstance + "." + pathToCreatedStates + ".Input.SwitchExternalDelayed"; var idSwitchNumber = "javascript." + javascriptInstance + "." + pathToCreatedStates + ".Input.SwitchNumber"; // Sonstige globale Variablen, die gebraucht werden var timerExitDelay = null; var timerTexts = null; // =============================================================================== // Precode // =============================================================================== // Logging if (loglevel >= 1) log ("Alarmsystem started."); getAllDetectors(); // States erzeugen myCreateState(idActive, "boolean", false, "Switch Status Total", false, "info.status"); myCreateState(idActiveExternal, "boolean", false, "Switch Status External", false, "info.status"); myCreateState(idActiveInternal, "boolean", false, "Switch Status Internal", false, "info.status"); myCreateState(idAlarm, "boolean", false, "Alarm Status", false, "sensor.alarm"); myCreateState(idAlarmAccoustical, "boolean", false, "Accoustical Alarm Status", false, "sensor.alarm"); myCreateState(idAlarmOptical, "boolean", false, "Optical Alarm Status", false, "sensor.alarm"); myCreateState(idReady, "boolean", false, "Alarmsystem Ready", false, "info.status"); myCreateState(idError, "boolean", false, "Error Switching Active", false, "info.status"); myCreateState(idEntryDelayActive, "boolean", false, "Entry Delay Active Status", false, "info.status"); myCreateState(idExitDelayActive, "boolean", false, "Exit Delay Active Status", false, "info.status"); myCreateState(idAlarmingDetector, "string", "", "Alarming Detector", false, "text"); myCreateState(idAlarmingDetectorJSON, "string", "", "Alarming Detector JSON", false, "json"); myCreateState(idOpenDetectors, "string", "", "Open Detectors", false, "info.name"); myCreateState(idOpenDetectorsJSON, "string", "", "Open Detectors JSON", false, "json"); myCreateState(idOpenDetectorsOuterSkinJSON, "string", "", "Open Detectors Outer Skin JSON", false, "json"); myCreateState(idOpenDetectorsIndoorJSON, "string", "", "Open Detectors Indoor JSON", false, "json"); myCreateState(idOpenDetectorsWithIgnoreOpenFlagSet, "string", "", "Open Detectors with IgnoreOpen-Flag set", false, "text"); myCreateState(idStatusText, "string", "", "Status Text", false, "text"); myCreateState(idAlarmText, "string", "", "Alarm Text", false, "text"); myCreateState(idSwitchExternal, "boolean", false, "Enable Surveillance External", true, "switch"); myCreateState(idSwitchInternal, "boolean", false, "Enable Surveillance Internal", true, "switch"); myCreateState(idSwitchExternalDelayed, "boolean", false, "Enable Surveillance External Delayed", true, "switch"); myCreateMultiState (idActiveNumber, "number", 0, "Switch Status Number", false, 0, 4,"0:"+textStatusInactive+"; 1:"+textStatusActiveInternal+"; 2:"+textStatusActiveExternal+"; 3:"+textExitDelayActive+"; 4:"+textEntryDelayActive); myCreateMultiState (idSwitchNumber, "number", 0, "Switch by Number", true, 0, 3, "0:"+textStatusInactive+"; 1:"+textStatusActiveInternal+" ; 2:"+textStatusActiveExternal+" ; 3:"+textActiveExternalDelayed); // Erzeugen der Datenpunkte für die IgnoreOpen-Einstellung myCreateIgnoreOpenDPs(); // Melder nach dem Starten checken checkDetectors(detectorsOuterSkin.concat(detectorsIndoor)); // =============================================================================== // ON-Subscribtions // =============================================================================== // Auf Schaltstellen EXTERN verzögert reagieren (schalten EIN/AUS) on ({id: idSwitchExternalDelayed, change: "any"}, function(obj){ if (loglevel >= 3) log ("Switching External Delayed, Value: " + getState(obj.id).val); if (getState(obj.id).val) { // Einschalten, scharf extern VERZÖGERT if (loglevel >= 2) log ("Switching required: Delayed External Active"); if (getState(idActive).val) { if (loglevel >= 3) log ("Alarmsystem already active, switch to inactive first!"); setState(idError, true, true); } else { setState(idExitDelayActive, true, true); if (timerExitDelay) clearTimeout(timerExitDelay); timerExitDelay = setTimeout(switchActiveExternal, exitDelay * 1000); } } else { // Ausschalten, unscharf SOFORT if (loglevel >= 2) log ("Switching required: Inactive"); switchInactive(); } }); // Auf Schaltstellen EXTERN sofort reagieren (schalten EIN/AUS) on ({id: idSwitchExternal, change: "any"}, function(obj){ if (loglevel >= 3) log ("Switching External Immediately, Value: " + getState(obj.id).val); if (getState(obj.id).val) { // Einschalten, scharf extern if (loglevel >= 2) log ("Switching required: External Active"); if (getState(idActive).val) { if (loglevel >= 3) log ("Alarmsystem already active, switch to inactive first!"); setState(idError, true, true); } else { switchActiveExternal(); } } else { // Ausschalten, unscharf if (loglevel >= 2) log ("Switching required: Inactive"); switchInactive(); } }); // Auf Schaltstellen INTERN sofort reagieren (schalten EIN/AUS) on ({id: idSwitchInternal, change: "any"}, function(obj){ if (loglevel >= 3) log ("Switching Internal, Value: " + getState(obj.id).val); if (getState(obj.id).val) { // Einschalten, scharf intern if (loglevel >= 2) log ("Switching required: Internal Active"); if (getState(idActive).val) { if (loglevel >= 3) log ("Alarmsystem already active, switch to inactive first!"); setState(idError, true, true); } else { switchActiveInternal(); } } else { // Ausschalten, unscharf switchInactive(); if (loglevel >= 2) log ("Switching required: Inactive"); } }); // Auf Schaltstelle mit Datenpunkt SwitchNumber reagieren // Folgende Reaktionen: // 0 ... unscharf schalten // 1 ... scharf intern schalten // 2 ... scharf extern schalten // 3 ... verzögert scharf extern schalten on ({id: idSwitchNumber, change: "any"}, function(obj){ if (loglevel >= 3) log ("Switching Number, Value: " + obj.state.val); switch (obj.state.val) { case 0: if (loglevel >= 2) log ("Switching required: Inactive"); switchInactive(); break; case 1: if (loglevel >= 2) log ("Switching required: Internal Active"); if (getState(idActive).val) { if (loglevel >= 3) log ("Alarmsystem already active, switch to inactive first!"); setState(idError, true, true); } else { switchActiveInternal(); } break; case 2: if (loglevel >= 2) log ("Switching required: External Active"); if (getState(idActive).val) { if (loglevel >= 3) log ("Alarmsystem already active, switch to inactive first!"); setState(idError, true, true); } else { switchActiveExternal(); } break; case 3: if (loglevel >= 2) log ("Switching required: Delayed External Active"); if (getState(idActive).val) { if (loglevel >= 3) log ("Alarmsystem already active, switch to inactive first!"); setState(idError, true, true); } else { setState(idExitDelayActive, true, true); if (timerExitDelay) clearTimeout(timerExitDelay); timerExitDelay = setTimeout(switchActiveExternal, exitDelay * 1000); } break; default: if (loglevel >= 3) log ("idSwitchNumber has unknown number!"); } }); // Auf Fehler bei der Scharfschaltung reagieren on ({id: idError, val: true, change: "any"}, function(obj){ if (loglevel >= 1) log ("Error when switching to active."); setState(idAlarmText, textError, true); }); // Auf Eingangsverzögerung reagieren on({id: idEntryDelayActive, val: true, change: "ne"}, function (obj) { if (loglevel >= 2) log ("Entry Delay is active (" + entryDelay + " seconds)"); setState(idStatusText, textEntryDelayActive, true); setStateDelayed(idAlarmAccoustical, true, true, entryDelay * 1000, true); setStateDelayed(idAlarmOptical, true, true, entryDelay * 1000, true); }); // Auf Ausgangsverzögerung reagieren on({id: idExitDelayActive, val: true, change: "ne"}, function (obj) { if (loglevel >= 2) log ("Exit Delay is active (" + exitDelay + " seconds)"); setState(idStatusText, textExitDelayActive, true); }); // Auf Akustischen Alarm reagieren on ({id: idAlarmAccoustical, val: true, change: "ne"}, function(obj){ if (loglevel >= 1) log ("ALARM is active!"); setState(idEntryDelayActive, false, true); setState(idAlarmText, textAlarmActive, true); setState(idAlarm, true, true); setStateDelayed(idAlarmAccoustical, false, true, alarmDurationAccoustical * 1000, true); if (getState(idActiveExternal).val) setState(idStatusText, textStatusActiveExternal, true); if (getState(idActiveInternal).val) setState(idStatusText, textStatusActiveInternal, true); }); // Auf Optischen Alarm reagieren on ({id: idAlarmOptical, val: true, change: "ne"}, function(obj){ if (alarmDurationOptical >= 0) setStateDelayed(idAlarmOptical, false, true, alarmDurationOptical * 1000, true); }); // Melderauswertung on( {id: detectorsOuterSkin.concat(detectorsIndoor), change: "ne"}, function(obj){ detectorSurveillance(obj); }); // Status in Active.Number schreiben on ({id: [idActiveInternal, idActiveExternal, idEntryDelayActive, idExitDelayActive], change: "ne"}, function(obj){ if (loglevel >= 3) log ("on for writing ActiveNumber, Trigger: " + obj.id); setActiveNumber(); }); // Texte korrekt setzen on ({id: [idAlarm, idActive, idOpenDetectors], change: "any"}, function (obj) { // Das Timeout ggf. abbrechen if (timerTexts) clearTimeout(timerTexts); // Nach einem Timeout den Check anfangen timerTexts = setTimeout(setTexts, 200); }); // =============================================================================== // Funktionen // =============================================================================== // Funktion checkIfIgnoreOpenFlagSet // ===================================== // Parameter: Prüft, ob das IgnoreOpen-Flag für einen Melder gesetzt ist. // Übergabewert: Melder-ID // Rückgabewert: Flag-Zustand function checkIfIgnoreOpenFlagSet(id){ var i=0; while (i<detectorsIgnoreOpen.length){ if ( detectorsIgnoreOpen[i][0] == id ) if (getState(detectorsIgnoreOpen[i][1]).val) return true; i++; } return false; } // Function setTexts // ================= // Parameter: keiner // Funktion: Abhängig von den Zuständen scharf/unscharf und // Alarm / Kein Alarm werden Texte für // den AlarmText richtig gesetzt. Auch der Datenpunkt idReady wird hier gesetzt. // Rückgabewert: keiner function setTexts(){ var textListOfDetectors = getState(idOpenDetectors).val; if (textListOfDetectors.length > 0) { if (!getState(idActive).val) // Offene Melder gefunden und unscharf setState(idAlarmText, textNotReady, true); setState(idReady, false, true); return false; } else { if (getState(idActive).val && !getState(idAlarm).val) // kein offener Melder gefunden und scharf und kein Alarm setState(idAlarmText, textAlarmInactive, true); else if (!getState(idActive).val) // kein offener Melder gefunden und unscharf setState(idAlarmText, textReady, true); setState(idReady, true, true); return true; } } // Function getAllDetectors // ======================== // Parameter: keiner // Funktion: Über die Funktion getDetectorsFromFunction werden // alle Melder von den Functions geholt und in die // globalen Variablen dafür geschrieben. // Rückgabewert: keiner function getAllDetectors(){ var i=0; detectorsOuterSkin = getDetectorsFromFunction(functionOuterSkin); detectorsIgnoreOpen = []; while (i<detectorsOuterSkin.length) { detectorsIgnoreOpen.push([detectorsOuterSkin[i++]]); } addIgnoreOpenFlags(); detectorsIndoor = getDetectorsFromFunction(functionIndoor); detectorsDelayed = getDetectorsFromFunction(functionDelayedDetectors); } // Function getDetectorsFromFunction // ================================= // Parameter: functionString // Name der Function, in der die Melder enthalen sind. // Funktion: Alle Teilnehmer der übergebenen Function werden // in ein Array geschrieben. // Rückgabewert: Array der Melder-IDs function getDetectorsFromFunction( functionString ) { if (loglevel >= 3) log ("Function getDetectorsFromFunction"); var detectors = []; $('state(functions='+functionString+')').each(function(id, i) { detectors.push(id); if (loglevel >= 3) log ("This detector was added to surveillance from function "+functionString+": " + id); }); return detectors; } // Function detectorSurveillance // ============================= // Parameter: obj // Objekt des auslösenden Melders // Funktion: Abhängig vom Schaltzustand werden die Melder überprüft. // Bei unscharf wird nur die Liste der offenen Melder und die // Bereitschaft der Anlage zum Scharfschalten gepfelgt. // Bei scharf geschalteter Anlage ist es anders: // Es wird geprüft, ob der auslösende Melder in den Außenhaut- oder // Innenraum-Meldern enthalten ist und ob dieser ein verzögerter Melder ist. // Abhängig davon wird entweder sofort oder verzögert Alarm ausgelöst. // Rückgabewert: keiner function detectorSurveillance (obj) { var active = getState(idActive).val; var activeExternal = getState(idActiveExternal).val; var activeInternal = getState(idActiveInternal).val; var ready; var ignoreOpenSet; if (loglevel >= 2) log ("Surveillance of detectors started, triggering detector: " + obj.common.name); // Alle offenen Melder feststellen ready = checkDetectors(detectorsOuterSkin.concat(detectorsIndoor)); // Auslösenden Melder schreiben setState(idAlarmingDetector, obj.common.name, true); setState(idAlarmingDetectorJSON, JSON.stringify( getDetectorObject(obj.id) ), true); // Prüfen, wie der der Schaltzustand ist // bei unscharf if (!active) { if (loglevel >= 2) log ("Alarmsystem is Inactive"); } // bei scharf intern if (activeInternal) { if (loglevel >= 2) log ("Alarmsystem is Internal Active"); if (detectorsOuterSkin.indexOf(obj.id) != -1) { if (loglevel >= 3) log ("Detector is part of Outer Skin"); if (detectorsDelayed.indexOf(obj.id) != -1) { if (loglevel >= 3) log ("Detector is part of Delayed Detectors"); if(!getState(idAlarm).val) setState(idEntryDelayActive, true, true); else { if (loglevel >= 3) log ("EntryDelay was already active, alarming now"); setState(idAlarmAccoustical, true, true); setState(idAlarmOptical, true, true); } } else { if (loglevel >= 3) log ("Detector is not delayed"); setState(idAlarmAccoustical, true, true); setState(idAlarmOptical, true, true); } } } // bei scharf extern if (activeExternal) { if (loglevel >= 2) log ("Alarmsystem is External Active"); // Prüfen, ob er der Melder das IgnoreOpen-Flag gesetzt hat. ignoreOpenSet = checkIfIgnoreOpenFlagSet(obj.id); if (loglevel >= 2) log ("Detector has IgnoreOpen-Flag set true!"); if (ignoreOpenSet) return; if (detectorsOuterSkin.concat(detectorsIndoor).indexOf(obj.id) != -1) { if (loglevel >= 3) log ("Detector is part of Outer Skin or Indoor"); if (detectorsDelayed.indexOf(obj.id) != -1) { if (loglevel >= 3) log ("Detector is part of Delayed Detectors"); if(!getState(idAlarm).val) setState(idEntryDelayActive, true, true); else { if (loglevel >= 3) log ("EntryDelay was already active, alarming now"); setState(idAlarmAccoustical, true, true); setState(idAlarmOptical, true, true); } } else { if (loglevel >= 3) log ("Detector is not delayed"); if (loglevel >= 2) log ("System is ALARMING now!"); setState(idAlarmAccoustical, true, true); setState(idAlarmOptical, true, true); } } } } // Function myCreateState // ======================= // Parameter: id ... id des neu anzulegenden Datenpunkts // typ ... typ des anzulegenden Datenpunkts ("boolean", "string", "number", etc.) // val ... Wert, den der Datenpunkt nach dem Anlegen haben soll // descr ... Name als String // writeaccess Schreibrechte true oder false // Funktion: Mit der Funktion createState wird der neue Datenpunkt mit den übergebenen // Parametern angelegt. // Rückgabewert: keiner function myCreateState(id, typ, val, descr, writeaccess, role) { if (loglevel >= 3) log ("Function myCreateState for " + id); if (!existsState(id)){ createState( id, val, { read: !writeaccess, write: writeaccess, name: descr, type: typ, def: val, role: role ? role : "state" }, function() { setState(id, val, true); if (loglevel >= 3) log ("ID " + id + " sucessfully created."); } ); } else { if (loglevel >= 3) log ("ID " + id + " already existed."); } } // Function myCreateMultiState // =========================== // Parameter: id ... id des neu anzulegenden Datenpunkts // typ ... typ des anzulegenden Datenpunkts ("boolean", "string", "number", etc.) // val ... Wert, den der Datenpunkt nach dem Anlegen haben soll // descr ... Name als String // min ... Minimalwert // max ... Maximalwert // list ... Liste mit Werten und Bezeichnern im Format "0:Text0; 1:Text1; 2:Text2" // writeaccess Schreibrechte true oder false // Funktion: Mit der Funktion createState wird der neue Datenpunkt mit den übergebenen // Parametern angelegt. // Rückgabewert: keiner function myCreateMultiState(id, typ, val, descr, writeaccess, minimum, maximum, list, role) { if (loglevel >= 3) log ("Function myCreateMultiState for " + id); if (!existsState(id)){ createState(id, val, { read: true, write: writeaccess, name: descr, type: typ, def: val, min: minimum, max: maximum, states: list, role: role ? role : "state" }); } else { if (loglevel >= 3) log ("ID " + id + " already existed."); } } // Funktion myCreateIgnoreOpenDPs // ============================== // Parameter: Keine // Funktion: Erzeugt die Datenpunkte für die Ignoge-Open-Melder. // Dafür werden die Namen aus dem detectorsOuterSkin-Array geholt. // Die IDs der Ignore-Open Datenpunkte für jeden Melder werden auch in // das Array detectorsIgnoreOpen geschrieben. Dieses wird damit 3-Dimensional. // Rückgabewert: Keiner. function myCreateIgnoreOpenDPs(){ var detectorName; var idBase = "javascript." + javascriptInstance + "." + pathToCreatedStates + ".Input.IgnoreOpen."; var i=0; while (i<detectorsOuterSkin.length) { detectorName = getObject(detectorsOuterSkin[i]).common.name.replace(/\./g,"_"); myCreateState(idBase + detectorName, "boolean", false, "Ignore Open for " + detectorName, true, "switch"); detectorsIgnoreOpen[i].push(idBase + detectorName); i++; } } // Funktion addIgnoreOpenFlags // ============================== // Parameter: Keine // Funktion: Fügt dem Array für die Ignore-Open Datenpunkte die Flags hinzu. // Rückgabewert: Keiner. function addIgnoreOpenFlags(){ var detectorName; var idBase = "javascript." + javascriptInstance + "." + pathToCreatedStates + ".Input.IgnoreOpen."; var i=0; while (i<detectorsOuterSkin.length) { detectorName = getObject(detectorsOuterSkin[i]).common.name.replace(/\./g,"_"); detectorsIgnoreOpen[i].push(idBase + detectorName); i++; } } // Function switchActiveExternal // ============================= // Parameter: keiner // Funktion: Nach Prüfung auf Bereitschaft zum externen Scharfschalten, wird // scharf geschaltet oder ein Fehler angezeigt. // Rückgabewert: keiner function switchActiveExternal () { if (loglevel >= 3) log ("Function switchActiveExternal"); setState(idExitDelayActive, false, true); var ok = checkDetectors(detectorsOuterSkin.concat(detectorsIndoor)); if (ok) { setState(idActiveExternal, true, true); setState(idActive, true, true); setState(idStatusText, textStatusActiveExternal, true); setState(idAlarmText, textAlarmInactive, true); setState(idAlarmingDetector,"", true); setState(idError, false, true); if (loglevel >= 2) log ("Switched to External Active"); } else { if (loglevel >= 2) log ("NOT ready to switch to External Active!"); setState(idError, true, true); } } // Function switchActiveInternal // ============================= // Parameter: keiner // Funktion: Nach Prüfung auf Bereitschaft zum internen Scharfschalten, wird // scharf geschaltet oder ein Fehler angezeigt. // Rückgabewert: keiner function switchActiveInternal () { if (loglevel >= 3) log ("Function switchActiveInternal"); var ok = checkDetectors(detectorsOuterSkin); if (ok) { setState(idActiveInternal, true, true); setState(idActive, true, true); setState(idStatusText, textStatusActiveInternal, true); setState(idAlarmText, textAlarmInactive, true); setState(idAlarmingDetector,"", true); setState(idError, false, true); if (loglevel >= 2) log ("Switched to Internal Active"); } else { if (loglevel >= 2) log ("NOT ready to switch to Internal Active!"); setState(idError, true, true); } ;} // Function switchInactive // ============================= // Parameter: keiner // Funktion: Es wird unscharf geschaltet und die ganze Anlage resetiert. // Rückgabewert: keiner function switchInactive () { if (loglevel >= 3) log ("Function switchInactive"); if (timerExitDelay) clearTimeout(timerExitDelay); setState(idEntryDelayActive, false, true); setState(idExitDelayActive, false, true); setState(idActiveExternal, false, true); setState(idActiveInternal, false, true); setState(idActive, false, true); setState(idError, false, true); clearStateDelayed(idAlarmAccoustical); clearStateDelayed(idAlarmOptical); setState(idAlarmAccoustical, false, true); setState(idAlarmOptical, false, true); setState(idAlarm, false, true); setState(idAlarmText, textAlarmInactive, true); setState(idStatusText, textStatusInactive, true); checkDetectors(detectorsOuterSkin.concat(detectorsIndoor)); if (loglevel >= 2) log ("Switched to Inactive"); getAllDetectors(); } // Function setActiveNumber // ======================= // Parameter: keine // Funktion: Prüft ob intern scharf, extern scharf oder unscharf ist und // ob jeweils Eingangs- oder Ausgangsverzögerung aktiv ist. // Abhängig davon wird der Datenpunt "Output.ActiveNumber" // wie folgt gesetzt: // 0 ... unscharf // 1 ... intern scharf // 2 ... extern scharf // 3 ... Eingangsverzögerung aktiv // 4 ... Ausgangsverzögerung aktiv // Rückgabewert: keiner function setActiveNumber () { if (loglevel >= 3) log ("Function setActiveNumber"); var internal = getState(idActiveInternal).val; var external = getState(idActiveExternal).val; var entry = getState(idEntryDelayActive).val; var exit = getState(idExitDelayActive).val; if (!external && !internal) { if (exit) setState(idActiveNumber, 4, true); else setState(idActiveNumber, 0, true); } if (internal) setState(idActiveNumber, 1, true); if (external){ if (entry) setState(idActiveNumber, 3, true); else setState(idActiveNumber, 2, true); } } // Function checkDetectors // ======================= // Parameter: detectors // Array mit Melder-IDs // Funktion: Alle Melder aus dem Array werden geprüft und alle offenen // Melder werden in einen Datenpunkt geschrieben als String. // Das Trennzeichen zwischen den Meldernamen ist die globale // Variable "seperator". // Rückgabewert: true, wenn alle Melder in Ruhe sind // false, wenn ein oder mehr Melder ausgelöst sind function checkDetectors ( detectors ) { if (loglevel >= 3) log ("Function checkDetectors"); var i=0; var textListOfDetectors=""; var textListOfDetectorsIgnoreOpen=""; var objOpenDetectors = { title: "All open detectors", zone: null, listOfDetectors: [] }; var objOpenDetectorsOuterSkin = { title: "Open detectors outer skin", zone: functionOuterSkin, listOfDetectors: [] }; var objOpenDetectorsIndoor = { title: "Open detectors indoor", zone: functionIndoor, listOfDetectors: [] }; while(i < detectors.length) { if (getState(detectors[i]).val) { if (checkIfIgnoreOpenFlagSet(detectors[i])) { if (textListOfDetectorsIgnoreOpen.length > 0) textListOfDetectorsIgnoreOpen += seperator; textListOfDetectorsIgnoreOpen += getObject(detectors[i]).common.name; } else { if (textListOfDetectors.length > 0) textListOfDetectors += seperator; textListOfDetectors += getObject(detectors[i]).common.name; } var detObj = getDetectorObject(detectors[i]); objOpenDetectors.listOfDetectors.push(detObj); if (detectorsOuterSkin.indexOf(detectors[i]) != -1) objOpenDetectorsOuterSkin.listOfDetectors.push(detObj); if (detectorsIndoor.indexOf(detectors[i]) != -1) objOpenDetectorsIndoor.listOfDetectors.push(detObj); } i++; } if (loglevel >= 3) log ("Open Detectors found: " + (textListOfDetectors.length ? textListOfDetectors : "none")); // Datenpunkte schreiben setState(idOpenDetectors, textListOfDetectors, true); setState(idOpenDetectorsWithIgnoreOpenFlagSet, textListOfDetectorsIgnoreOpen, true); setState(idOpenDetectorsJSON, JSON.stringify(objOpenDetectors), true); setState(idOpenDetectorsOuterSkinJSON, JSON.stringify(objOpenDetectorsOuterSkin), true); setState(idOpenDetectorsIndoorJSON, JSON.stringify(objOpenDetectorsIndoor), true); if (textListOfDetectors.length > 0) { return false; } else { return true; } } // Function getDetectorObject // ========================== // Parameter: id // id eines Melder-States // Funktion: Vom Melder mit der id wird das Objekt über getObjekt(id) geholt, // sowie von seinem Parent und ParentsParent. // Alle Objekte kommen in ein großes Objekt und werden zurück gegeben. // Rückgabewert: Das Objekt des Melders samt Parent und ParentsParent (sofern es welche gibt) function getDetectorObject (id) { if (loglevel >= 3) log ("Function getDetectorObject for id: " + id); // ioBroker Parent-Datenpunkt (z.B. Kanal), kann auch null sein (zB bei KNX) var idParent = id.substr(0, id.lastIndexOf(".")); // ioBroker ParentsParent-Datenpunkt (z.B. Gerät), kann auch null sein (zB bei KNX) var idParentsParent = idParent.substr(0, idParent.lastIndexOf(".")); // Objekte dazu holen (falls es welche gibt) var obj = getObject(id); var objParent = null; if ($('state[id=' + idParent + '$]').length > 0) { objParent = getObject(idParent); } var objParentsParent = null; if ($('state[id=' + idParentsParent + '$]').length > 0) { objParentsParent = getObject(idParentsParent); } // Alle Objekte in ein großes Objekt sammeln var detectorsObj = { id: id, self: obj, parent: objParent, parentsparent: objParentsParent }; // Rückgeben return detectorsObj; }Änderungshistorie
- 2020-05-01, Erstellung
- 2020-05-02, Number-Datenpunkte für Ein- und Ausgabe des Schaltzustands (Idee von @Homer.J.)
- 2020-05-03, Korrekturen, u.a. für Melderauswertung (chage: "ne") & Status-Text
- 2020-05-04, Melder werden aus den Functions (Aufzählungen, enums) dafür geholt. Auch beim Unscharf-schalten, dadurch ist kein Neustarten des Skripts notwendig bei Änderungen an diesen Aufzählungen.
Eine Schaltung von einem scharf-Zustand auf einen anderen wird verhindert. ZB von scharf intern auf scharf extern. Es muss immer unscharf dazwischen geschaltet werden. - 2020-05-09, Zusätzliche Objekte mit JSON-Strings für:
_ den auslösenden Melder
_ alle offenen Melder
_ alle offenen Melder der Außenhaut
_ alle offenen Melder des Innenraums
Die JSON-String beinhalten das auslösende Objekt, sowie (falls vorhanden) das Parent und das ParentsParent-Objekt mit allen in ioBroker verfügbaren Eigenschaften.
Außerdem kleinere Verbesserungen, z.B. bezüglich setzen der AlarmTexte. - 2020-05-12 Andreas Kos Setzen des Datenpunkts idReady zur Bereitschaftsanzeige neu gemacht.
- 2021-06-13 Andreas Kos Einbau der Funktion zum Ausnehmen einzelner Melder der Aussenhülle von der Melder-Überwachung. Soll zum Kippen von Fenstern dienen u.ä.
- 2022-03-20 Andreas Kos Verbesserung beim Laden der Parents- und Parentsparents-Objekte und Umbau auf aktuellen Javascript-Adapter mit Ack-Flags bei createState und setState
- 2022-12-02 Andreas Kos Korrektur beim Prüfen der IgnoreOpen-Flags.
- 2022-12-18 Andreas kos Korrektur beim Anlegen der States, sodass ein Neustart des Scripts eine weitere Funktion der Anlage garantiert, auch, wenn diese zuvor im Zustand "scharf" war.
Servus Andreas
wie bekomme ich denn das Skript in mein Blokly ?mit importieren über " Blöcke Importieren " klapps irgendwie nicht .
Grüße
Balu