NEWS
[Vorlage] Servicemeldungen Volume2
-
@looxer01 sagte in [Vorlage] Servicemeldungen Volume2:
@knallochse
Hi,
bei Homematic classic werden die Sabotage Meldungen unter MessageType "Error" geführt und da ist auch der Zähler bei dir auf 1. Das ist anders bei HMIP. Da werden die Sabotage Meldungen unter Sabotage geführt.
Ich könnte das zwar code technisch abfangen. Das wäre aber irgendwie schon sehr Spaghetti.Dann hab ich es verstanden. Ich bräuchte keine Änderung.
zu den instanzen.
CUxD. Das sind ja vermutlich keine HM-Geräte, die darunter laufen. Da also die Datenstrukturen vermutlich anders sind, sind dann auch die Meldungen nicht identisch. Ich habe keine Ahnung wie das funktioniert.Eine Überwachung der CUxD Geräte vom Skript ist nicht nötig. Aber die rpc.0 Instanz wird ja überwacht, und die Geräte zur Überwachung befinden sich ja in anderen Instanzen. Wird dann noch alles richtig zugeordnet bzw. überwacht?
Die anderen schaue ich mir an.
Die virtuellen Gruppen habe ich z.Zt draußengelassen. Der Mehrwert bei Meldungen zur Gruppe ist ohnehin fragwürdig. Allerdings sind die nur auskommentiert im Coding und lassen sich einfach aktivieren.In den Gruppen befinden sich ja die einzelnen Geräte und diese werden ja schon überwacht.
vG Looxer
-
Von meiner Seite vielen Dank für dein Skript. Schön, dass du dich der Sache annimmst.
-
@knallochse sagte in [Vorlage] Servicemeldungen Volume2:
Eine Überwachung vom Skript ist nicht nötig. Aber die rpc.0 Instanz wird ja überwacht, und die Geräte zur Überwachung befinden sich ja in anderen Instanzen. Wird dann noch alles richtig zugeordnet bzw. überwacht?
ich denke ja. Dann muß also CuxD einfach nur auschgeschlossen werden.
@knallochse sagte in [Vorlage] Servicemeldungen Volume2:
In den Gruppen befinden sich ja die einzelnen Geräte und diese werden ja schon überwacht.
genau, also ist die Hinzunahme der Gruppen nicht notwendig.
Ich habe für dich die Configuration im folgenden Code gemacht. Diesen müßtest du durch den Vorhandenen ersetzen.
const idsUNREACH = []; // @ts-ignore $('state[id=hm-rpc.1.*.UNREACH_ALARM]').each(id => idsUNREACH.push(id)); // @ts-ignore $('state[id=hm-rpc.2.*.UNREACH_ALARM]').each(id => idsUNREACH.push(id)); // @ts-ignore // $('state[id=hm-rpc.3.*.UNREACH_ALARM]').each(id => idsUNREACH.push(id)); // auskommentiert keine Gruppenmeldungen const idsSTICKY_UNREACH = []; // @ts-ignore $('state[id=hm-rpc.1.*.STICKY_UNREACH_ALARM]').each(id => idsSTICKY_UNREACH.push(id)); // @ts-ignore $('state[id=hm-rpc.2.*.STICKY_UNREACH_ALARM]').each(id => idsSTICKY_UNREACH.push(id)); // @ts-ignore //$('state[id=hm-rpc.3.*.STICKY_UNREACH_ALARM]').each(id => idsSTICKY_UNREACH.push(id)); // auskommentiert keine Gruppenmeldungen const idsConfig_Pending = []; // @ts-ignore $('state[id=hm-rpc.1.*.CONFIG_PENDING_ALARM]').each(id => idsConfig_Pending.push(id)); // @ts-ignore $('state[id=hm-rpc.2.*.CONFIG_PENDING_ALARM]').each(id => idsConfig_Pending.push(id)); // @ts-ignore // $('state[id=hm-rpc.3.*.CONFIG_PENDING_ALARM]').each(id => idsConfig_Pending.push(id)); // auskommentiert keine Gruppenmeldungen const idsUPDATE_PENDING_ALARM = []; // @ts-ignore $('state[id=hm-rpc.1.*.UPDATE_PENDING_ALARM]').each(id => idsUPDATE_PENDING_ALARM.push(id)); // @ts-ignore $('state[id=hm-rpc.2.*.UPDATE_PENDING_ALARM]').each(id => idsUPDATE_PENDING_ALARM.push(id)); // @ts-ignore //$('state[id=hm-rpc.3.*.UPDATE_PENDING_ALARM]').each(id => idsUPDATE_PENDING_ALARM.push(id)); // auskommentiert keine Gruppenmeldungen const idsLOWBAT_ALARM = []; // @ts-ignore $('state[id=hm-rpc.1.*.LOWBAT_ALARM]').each(id => idsLOWBAT_ALARM.push(id)); // @ts-ignore $('state[id=hm-rpc.2.*.LOW_BAT_ALARM]').each(id => idsLOWBAT_ALARM.push(id)); // @ts-ignore //$('state[id=hm-rpc.3.*.LOW_BAT_ALARM]').each(id => idsLOWBAT_ALARM.push(id)); // auskommentiert keine Gruppenmeldungen const idsDEVICE_IN_BOOTLOADER_ALARM = []; // @ts-ignore $('state[id=hm-rpc.1.*.DEVICE_IN_BOOTLOADER_ALARM]').each(id => idsDEVICE_IN_BOOTLOADER_ALARM.push(id)); // nur HM-Classic const idsERROR = []; // @ts-ignore $('state[id=hm-rpc.1.*.ERROR]').each(id => idsERROR.push(id)); // @ts-ignore $('state[id=hm-rpc.2.*.ERROR]').each(id => idsERROR.push(id)); // @ts-ignore // $('state[id=hm-rpc.3.*.ERROR]').each(id => idsERROR.push(id)); // auskommentiert keine Gruppenmeldungen const idsFAULT_REPORTING = []; // @ts-ignore $('state[id=hm-rpc.1.*.FAULT_REPORTING]').each(id => idsFAULT_REPORTING.push(id)); // nur HM-Classic const idsSABOTAGE_ALARM = []; // @ts-ignore $('state[id=hm-rpc.1.*.SABOTAGE_ALARM]').each(id => idsSABOTAGE_ALARM.push(id)); // @ts-ignore $('state[id=hm-rpc.2.*.SABOTAGE_ALARM]').each(id => idsSABOTAGE_ALARM.push(id)); // @ts-ignore //$('state[id=hm-rpc.3.*.SABOTAGE_ALARM]').each(id => idsSABOTAGE_ALARM.push(id)); // auskommentiert keine Gruppenmeldungen const idsERROR_NON_FLAT_POSITIONING_ALARM = []; // @ts-ignore $('state[id=hm-rpc.1.*.ERROR_NON_FLAT_POSITIONING_ALARM]').each(id => idsERROR_NON_FLAT_POSITIONING_ALARM.push(id)); // @ts-ignore $('state[id=hm-rpc.2.*.ERROR_NON_FLAT_POSITIONING_ALARM]').each(id => idsERROR_NON_FLAT_POSITIONING_ALARM.push(id));
-
@looxer01 Vielen Dank.
Ich habe den Code durch deinen ersetzt. Ich beobachte das ganze mal eine Weile.
Schade, dass sich Batteriemeldungen schlecht simulieren lassen. -
@knallochse
sehr gerne.
Ich mache die Instanz wahrscheinlich noch variabel. Dann ist es einfacher anzupassen für alle die, die CuxD verwenden -
Hi,
Version 1.06 ist online:- GruppenSelektoren auskommentiert fuer unreach#
- Korrektur fuer REGA subcription:Timer variable zuruecksetzen
- HM-Classic Sabotage counts werden umgeleitet von error auf Sabotage
- Instanzen zur Selektion sind jetzt als Variable definiert - z.B. um CuxD auszuschliessen
Looxer01
-
@looxer01 mit der 1.6 scheint der Zähler bei Auslösen eines Sabotage Aktors nicht mehr zu funktionieren
in der Nachricht (Telegram) steht SABOTAGE
-
@knallochse
vielen Dank
Fehler ist gefunden. Fix kommt mit der nächsten Version.vG Looxer
-
Version 1.07 ist online.
- Zähler für Sabotage funktioniert jetzt für HMClassic und HMIP
- Text StandardMessages angepasst
- Fuer alle Messenger Services kann die gewuenschte Instanz angegeben werden
Looxer
-
ist das im 1.07 richtig so
// telegram Einstellungen const TelegramUser = "";
beim 1.06 sieht das so aus
// telegram Einstellungen const TelegramIstanz = 0; const TelegramUser = "";
-
@emil70
Hi,
ja, das ist ok, weil jetzt alle Messenger mit der Instanz einstellbar sindconst services = ['email', 'whatsApp', 'Signal', 'Telegram', 'Pushover', 'Pushsafer']; const MessengerScope = { 'UNREACH_ALARM': [false, true, false, false, false, false], 'LOWBAT_ALARM': [false, true, false, false, false, false], 'SABOTAGE_ALARM': [false, true, false, false, false, false], 'CONFIG_PENDING': [false, true, false, false, false, false], 'Sonstige': [false, false, false, false, false, false], 'keineSM': [false, true, false, false, false, false], } const MessengerInstanz = [0, 0, 0, 0, 0, 0 ]; // Instanz des Messengers
-
@looxer01 Mit der 1,07 funktioniert der Zähler für Sabotage Super
-
Hi,
Version 1.08 ist online- Ein wenig Kosmetik
- LowBat Meldungen waren nicht vollstaendig für HMIP Geräte. Batterietypen-Hinweis sollte jetzt funktionieren
vG Looxer
-
@looxer01 @looxer01 Hallo, bin zufällig über das Script gestolpert, aufgrund der Vielzahl meiner HM-Geräte war mein Interesse geweckt. Leider bin ich absoluter DAU was JS betrifft, bekomme beim Start des Scripts die folgende Fehlermeldungen. Was kann/muss ich hier tun? Oder habe ich ein grundsätzliches Problem in den Einstellungen der Adapter usw.? Ich freue mich auf deine Rückmeldung, vielen Dank!
15.11.2024, 13:43:09.525 [info ]: javascript.0 (800865) Start JavaScript script.js.Telegram_Meldungen.Fehlermeldungen (Javascript/js) 15.11.2024, 13:43:09.630 [warn ]: javascript.0 (800865) script.js.Telegram_Meldungen.Fehlermeldungen: More than 100 subscriptions registered. Check your script! 15.11.2024, 13:43:09.631 [warn ]: javascript.0 (800865) script.js.Telegram_Meldungen.Fehlermeldungen: More than 200 subscriptions registered. Check your script! 15.11.2024, 13:43:09.631 [warn ]: javascript.0 (800865) script.js.Telegram_Meldungen.Fehlermeldungen: More than 300 subscriptions registered. Check your script! 15.11.2024, 13:43:09.632 [warn ]: javascript.0 (800865) script.js.Telegram_Meldungen.Fehlermeldungen: More than 400 subscriptions registered. Check your script! 15.11.2024, 13:43:09.634 [info ]: javascript.0 (800865) script.js.Telegram_Meldungen.Fehlermeldungen: registered 468 subscriptions, 1 schedule, 0 messages, 0 logs and 0 file subscriptions 15.11.2024, 13:43:09.690 [error]: javascript.0 (800865) script.js.Telegram_Meldungen.Fehlermeldungen: Routine Create States - Fehler beim Erstellen der Zustaende: TypeError: Cannot read properties of undefined (reading 'TYPE')
-
@flkontakt
Hi,nicht so schwierig. Das kriegst du hin.
Die ersten Meldungen sind Warnmeldungen. Es gibt unterschiedliche Möglichkeiten damit umzugehen.
- Du akzeptierst, dass du Warnmeldungen beim Aufrufen des Scripts hast
- Du machst eine Einstellung im Javascript Adapter
- allgemeine Einstellungen unter "Maximale Auslöser/Trigger pro Skript (bis zur Warnung)
stells du z.B. 500 ein. Damit sind die Warnmeldungen Geschichte
- allgemeine Einstellungen unter "Maximale Auslöser/Trigger pro Skript (bis zur Warnung)
- Du verzichtest auf historische Servicemeldungen (nur aktuelle werden gespeichert) und stellst das script auf:
const GeraeteIDTrigger = false (vorgegeben ist hier true). Dann gibt es nur 1 Subscription
Die Fehlermeldung erscheint wahrscheinlich nur beim ersten Aufruf des Scripts. Da hakt es wohl beim Timing vom Erstellen der States und dem Versuch diese zu beschreiben. (eigentlich sollte das abgefangen sein aber , na ja)
vG Looxer
-
@flkontakt
Hi,
(falls noch interessant)
ich habe nochmal geforscht. Das Coding ist im Prinzip ok. Es kann aber sein, dass ein wenig performantes System Probleme verursacht, wenn "asynchron" verarbeitet wird, was hier der Fall ist.
-Übersetzt: ich erstelle die Datenpunkte und möchte warten bis die fertig erstellt sind. Dann werden diese auch schon beschriebenWas kann man in diesem Fall tun ?
- Die nächste Version wird keinen harten "error" erzeugen sondern nur eine Warnmeldung. Dann werden auf jeden Fall alle notwendigen Datenpunkte erstellt, wenngleich verzögert
Für dich würde ich empfehlen folgende Einstellung im Script vorzunehmen: const GeraeteIDTrigger = false
Die neue Version kommt heute noch.
vG Looxer
-
Hi,
Version 1.09. ist online.- Ueberfluessiges log fuer Json String entfernt
- moegliche ungueltige StatusMeldung mit mehr Infos versehen
- Create states WarnMeldung statt ErrorMeldung
vG Looxer
-
@looxer01 vielen Dank für die schnelle Rückmeldung und Anpassung des Scripts. Bei mir hakt es aber immer noch, wenn ich eine Sabotage an einem Fensterkontakt durchführe, ändern sich der Datenpunkt Anzahl_SABOTAGE nicht und es werden Fehlermeldungen angezeigt. Hättest Du hierzu eine Idee, einen Tipp? In der JS-Instanz habe ich die Maximale Auslöser/Trigger pro Skript (bis zur Warnung) auf 100 (Default) gelassen.
avascript.0 2024-11-16 17:34:51.799 error at processTimers (node:internal/timers:519:7) javascript.0 2024-11-16 17:34:51.799 error at listOnTimeout (node:internal/timers:581:17) javascript.0 2024-11-16 17:34:51.799 error at Timeout._onTimeout (/opt/iobroker/node_modules/iobroker.javascript/lib/sandbox.js:3219:34) javascript.0 2024-11-16 17:34:51.799 error at Object.<anonymous> (script.js.Telegram_Meldungen.Fehlermeldungen:334:13) javascript.0 2024-11-16 17:34:51.799 error at Servicemeldung (script.js.Telegram_Meldungen.Fehlermeldungen:407:26) javascript.0 2024-11-16 17:34:51.798 error at Check_All (script.js.Telegram_Meldungen.Fehlermeldungen:521:15) javascript.0 2024-11-16 17:34:51.798 error at Array.forEach (<anonymous>) javascript.0 2024-11-16 17:34:51.798 error at script.js.Telegram_Meldungen.Fehlermeldungen:536:89 javascript.0 2024-11-16 17:34:51.798 error Error in callback: TypeError: Cannot read properties of undefined (reading 'TYPE')
-
@flkontakt
sehr eigenartig.kannst du mir bitte folgendes zeigen
- Die Liste der angelegten Datenpunkte
- Deine Einstellungen innerhalb des scriptes
Ausserdem:
kannst du bitte einen Test machen mit dieser Einstellung im Script:
const GeraeteIDTrigger = falsevG Looxer
-
hier die Infos, kannst du damit etwas anfangen?
javascript.0.ServicemeldungenVol2.json
// Servicemeldungen Script zum erfassen von aktuellen Servicemeldungen und halten der historie fuer einen definierten Zeitraum (Historie) // Servicemeldungen koennen ueber bekannte services gesendet werden // Trigger kann ausgewaehlt werden (entweder REGA anzahl = Servicemeldungen oder einzelne IDs) // States werden vom script angelegt // Autor Looxer01 02.11.2024 Version 1.0 (initiale Version) // Version 1.01 - 02.11.24 Sabotage Alarm fuer HM-Classic Sensoren angepasst. (Error >= 1 und <= 7) // formatierung mit Zeilenumbruch korrigiert // Version 1.02 - 03.11.24 Replacements als Funktion // Handling von geloeschten Datenpunkten // Ausschlussliste bei subscription der Geraete ID // Kosmetik // Version 1.03 - 04.11.24 Stringumwandlung gefixt / JSON fuer aktuelle Meldungen und historische Meldungen hinzugefuegt. // Version 1.04 - 05.11.24 im Datenpunkt id_JSON_Servicemeldung_Aktuell wird ein falscher Text gezeigt // Quick Fix - keine historische Meldung bei Status 0 // Version 1.05 - 10.11.24 Fix fuer Status 0 fuer historische Meldungen. Text aus Tabelle: StandardstatusMessages verwendet // Text angepasst in Tabelle fuer 0 // Batteriemeldung erweitert // Telegram Instanz und User hinzugefügt // WICHTIGE Aenderung fuer REGA subscription: Intelligenterer Umgang bei vielen Aenderungen von Anzahl der Servicmeldungen aus der CCU // Version 1.06 - 12.11.24 GruppenSelektoren auskommentiert fuer unreach // korrektur fuer REGA subcription:Timer variable zuruecksetzen // HM-Classic Sabotage counts werden umgeleitet von error auf Sabotage // Instanzen zur Selektion sind jetzt als Variabel definiert - z.B. um CuxD auszuschliessen // Version 1.07 - 13.11.24 Zähler für Sabotage funktioniert jetzt für HMClassic und HMIP // Text StandardMessages angepasst // Fuer alle Messenger Services kann die gewuenschte Instanz angegeben werden // Version 1.08 - 14.11.24 Einstellungsbereich aufgeraeumt- weitere Kosmetik // Fix Low_Bat Meldung // Version 1.09 - 15.11.24 Ueberfluessiges log fuer Json String entfernt // moegliche ungueltige StatusMeldung mit mehr Infos versehen // Create states WarnMeldung statt ErrorMeldung // //--------------------------------------------------------------------------------------------------------------------------------------------------------------- // Einstellungen (alle Einstellungen sind optional - Das heisst, dass das script läuft ohne weitere Einstellungen) //--------------------------------------------------------------------------------------------------------------------------------------------------------------- // Pfad kann angepasst werden fuer userdata pfad einfach // entfernen const path = "javascript.0.ServicemeldungenVol2."; //const path = "0_userdata.0.ServicemeldungenVol2."; // alternativ zum javascript pfad // schreibt einen logeintrag in ein externes file (Excel Format) / nur bei GeraeteIDTrigger = true const logflag = true; const LogPath = "/opt/iobroker/log/ServicemeldungenVol2.csv"; // Pfad und Dateiname des externen Logsconstst / nur bei GeraeteIDTrigger = true //const LogPath = "/iobroker/log/ServicemeldungenVol2.csv";"; // Pfad fuer Windows/ nur bei GeraeteIDTrigger = true // iobroker ist der angenommene iobroker home-pfad // Text der erscheinen soll, wenn keine SM vorliegen const MessageBeiKeinerSM = 'Derzeit keine Servicemeldungen' // auf '' setzen wenn kein Text gezeigt werden soll //Geraete die nicht ueberwacht werden sollen. Geraete-IDs eingeben - Komma getrennt erfassen const Ausschlussliste = ['003660xxx62C5D', '00091D8xxx7410']; // immer mit Komma trennen // debug level kann eingestellt werden - wenn alles laeuft dann 0 = ruhe im log // debug level 0 kein log // debug level 1 - nur die wichtigsten Meldungen werden gelistet // debug level 2 - mehr als nur die wichtigsten Meldungen aber ohne einzelne IDs // debug level 3 - hier werden auch einzelne IDs gelistet (koennten lange listen werden) const debugLevel = 0 ; // wenn GeraeteIDTrigger auf true gestellt wird, dann wird fuer jeden Datenpukt mit Relevanz fuer eine Servicemeldung eine subscription angelegt. // Vorteil ist, dass auch eine Historie und ein Log fuer Servicemeldungen geschrieben werden kann: Nachteil: bei 80 CCU Geraeten ungefaehr 300 Susbsriptions // Wenn die variable auf false steht, dann wird auf hm.rega.0.maintenance eine subsription angelegt: Vorteil: 1 Subscription , Nachteil: keine Servicemeldungs Historie const GeraeteIDTrigger = false; // true = viele subscriptions - false = 1 subscritpion // fuer alle Spalten mit true werden die Nachrichten ueber den zugeordneten Dienst versendet // Voraussetzung ist, dass der entsprechende Adapter installiert und konfiguriert ist const services = ['email', 'whatsApp', 'Signal', 'Telegram', 'Pushover', 'Pushsafer']; const MessengerScope = { 'UNREACH_ALARM': [false, true, false, false, false, false], 'LOWBAT_ALARM': [false, true, false, false, false, false], 'SABOTAGE_ALARM': [false, true, false, true, false, false], 'CONFIG_PENDING': [false, true, false, false, false, false], 'Sonstige': [false, false, false, false, false, false], 'keineSM': [false, true, false, false, false, false], } const MessengerInstanz = [0, 0, 0, 0, 0, 0 ]; // Instanz des Messengers // email-Einstellungen const emailAddresse = "Vorname-Nachname@web.de" const Headline = "ioBroker Servicemeldung"; // Ueberschrift Messages fuer email und Pushsafer // telegram Einstellungen const TelegramUser = ""; //----------------------------------------------------------------------------------------------------- //Experten Einstellungen //----------------------------------------------------------------------------------------------------- // Texte werden in "history" hinzugefuegt und etsprechend des schedules wieder geloescht -- nur relvant wenn GeraeteIDTrigger = false const scheduleTimeClearSMTexte = "2 0 1 * *"; // Sam 1. tag des monats um 00:02 morgens - sollen alle Servicemeldungen der Woche datenpunkt der SM-Texte geloescht werden // const scheduleTimeClearSMTexte = "58 23 * * 0"; // alernative Sonntags um 23:58 Uhr sollen alle Servicemeldungen der Woche im datenpunkt der SM-Texte geloescht werden // Im folgenden sind die Instanzen gelistet fuer die die Selektion erfolgt - Vorgabe ist Standard = 0,1,2 . Mit CuxD wuerde es 1,2,3 sein. const HMClassicInstanz = 0; const HMIPInstanz = 1; const GruppenInstanz = 2; // Gruppen sind im Standard nicht aktiviert. nicht unbedingt notwendig // Pfade const PathRega = 'hm-rega.0.maintenance'; const id_Text_ServicemeldungLang = path+'TextLangAktuelleSM'; // Objekt wo die Servicemeldung hingeschrieben werden soll (String) = path+'TextLang'; // Objekt wo die Servicemeldung hingeschrieben werden soll (String) Lange (normale) Version const id_Text_ServicemeldungKurz = path+'TextKurzAktuelleSM'; // Objekt wo die Servicemeldung hingeschrieben werden soll (String) - kurze Version const id_Text_Servicemeldung_History = path+'TestLangVergangeneSM'; // Objekt wo die Servicemeldung hinzugefuegt werden soll (String) - Lange Version (es gibt nur lang) const id_JSON_Servicemeldung_Aktuell = path+'JSONAktuelleSM'; // JSON Tabelle Datenpunkt Aktuelle SM const id_JSON_Servicemeldung_Historie = path+'JSONVergangeneSM'; // JSON Tabelle Datenpunkt Historische SM const id_IST_LOWBAT = path+'Anzahl_LOWBAT' // HM classic; & HMIP = const id_IST_UNREACH = path+'Anzahl_UNREACH' const id_IST_STICKY_UNREACH = path+'Anzahl_STICKY_UNREACH' //*Anzahl Sticky Unreach (zu bestaetigende unreach) const id_IST_CONFIG_PENDING = path+'Anzahl_CONFIG_PENDING'; const id_IST_UPDATE_PENDING = path+'Anzahl_Update_PENDING'; const id_IST_DEVICE_IN_BOOTLOADER = path+'Anzahl_DEVICE_IN_BOOTLOADER'; const id_IST_ERROR = path+'Anzahl_in_ERROR'; const id_IST_ERROR_NON_FLAT_POSITIONING = path+'Anzahl_NON_FLAT_POSITIONING'; const id_IST_FAULT_REPORTING = path+'Anzahl_FAULT_REPORTING'; const id_IST_SABOTAGE = path+'Anzahl_SABOTAGE'; const id_IST_ERROR_REDUCED = path+'Anzahl_ERROR_REDUCED'; const id_IST_STICKY_SABOTAGE = path+'Anzahl_Sticky_SABOTAGE'; const id_IST_USBH_POWERFAIL = path+'Anzahl_USBH_POWERFAIL'; const id_IST_U_SOURCE_FAIL = path+'Anzahl_U_SOURCE_FAIL '; const id_IST_Gesamt = path+'Anzahl_GESAMT' const id_IST_SMAktuell = path+'Anzahl_SM-Aktuell' //Batterie-Zuordnungen fuer Servicmeldungen const batteryTypes = { '1x CR2016': ['HM-RC-4', 'HM-RC-4-B', 'HM-RC-Key3', 'HM-RC-Key3-B', 'HM-RC-P1', 'HM-RC-Sec3', 'HM-RC-Sec3-B', 'ZEL STG RM HS 4'], '1x CR2032': ['HM-PB-2-WM', 'HM-PB-4-WM', 'HM-PBI-4-FM', 'HM-SCI-3-FM', 'HM-Sec-TiS', 'HM-SwI-3-FM', 'HmIP-FCI1'], '2x LR14': ['HM-Sec-Sir-WM', 'HM-OU-CFM-TW', 'HM-OU-CFM-Pl', 'HM-OU-CF-Pl'], '2x LR44/AG13': ['HM-Sec-SC', 'HM-Sec-SC2L', 'HM-Sec-SC-2', 'HM-Sec-RHS'], '2x LR6/AA': ['HM-CC-VD', 'HM-CC-RT-DN', 'HM-Sec-WDS', 'HM-Sec-WDS-2', 'HM-CC-TC', 'HM-Dis-TD-T', 'HB-UW-Sen-THPL-I', 'HM-WDS40-TH-I', 'HM-WDS40-TH-I-2', 'HM-WDS10-TH-O', 'HmIP-SMI', 'HMIP-eTRV', 'HM-WDS30-OT2-SM-2', 'HmIP-SMO', 'HmIP-SMO-A', 'HmIP-SPI', 'HmIP-eTRV-2', 'HmIP-SPDR', 'HmIP-STHO-A', 'HmIP-eTRV-B', 'HmIP-PCBS-BAT', 'HmIP-STHO', 'HmIP-eTRV-C', 'HmIP-WGC', 'HmIP-eTRV-C-2', 'HmIP-eTRV-E', 'HmIP-eTRV-2 I9F', 'HmIP-eTRV-E-S', 'ELV-SH-SW1-BAT'], '3x LR6/AA': ['HmIP-SWO-PL', 'HM-Sec-MDIR', 'HM-Sec-MDIR-2', 'HM-Sec-SD', 'HM-Sec-Key', 'HM-Sec-Key-S', 'HM-Sec-Key-O', 'HM-Sen-Wa-Od', 'HM-Sen-MDIR', 'HM-Sen-MDIR-O', 'HM-Sen-MDIR-O-2', 'HM-WDS100-C6-O', 'HM-WDS100-C6-O-2', 'HmIP-ASIR', 'HmIP-SWO-B', 'HM-Sen-MDIR-O-3', 'HM-Sec-MDIR-3', 'HmIP-SWO-PR', 'HmIP-DLD', 'HmIP-ASIR-2'], '4x LR6/AA': ['HM-CCU-1', 'HM-ES-TX-WM', 'HM-WDC7000'], '1x LR3/AAA': ['HM-RC-4-2', 'HM-RC-4-3', 'HM-RC-Key4-2', 'HM-RC-Key4-3', 'HM-RC-Sec4-2', 'HM-RC-Sec4-3', 'HM-Sec-RHS-2', 'HM-Sec-SCo', 'HmIP-KRC4', 'HmIP-KRCA', 'HmIP-SRH', 'HMIP-SWDO', 'HmIP-DBB', 'HmIP-RCB1', 'HmIP-KRCK', 'HmIP-SWDO-2'], '2x LR3/AAA': ['HmIP-WRCR', 'HmIP-SWD','HM-TC-IT-WM-W-EU', 'HM-Dis-WM55', 'HM-Dis-EP-WM55', 'HM-PB-2-WM55', 'HM-PB-2-WM55-2', 'HM-PB-6-WM55', 'HM-PBI-2-FM', 'HM-RC-8', 'HM-Sen-DB-PCB', 'HM-Sen-EP', 'HM-Sen-MDIR-SM', 'HM-Sen-MDIR-WM55', 'HM-WDS30-T-O', 'HM-WDS30-OT2-SM', 'HmIP-STH', 'HmIP-STHD', 'HmIP-WRC2', 'HmIP-WRC6', 'HmIP-WTH', 'HmIP-WTH-2', 'HmIP-SAM', 'HmIP-SLO', 'HMIP-SWDO-I', 'HmIP-FCI6', 'HmIP-SMI55', 'HM-PB-2-FM', 'HmIP-SWDM', 'HmIP-SCI', 'HmIP-SWDM-B2', 'HmIP-RC8', 'ALPHA-IP-RBG', 'HmIP-DSD-PCB', 'HmIP-WRCD', 'HmIP-WRC2-A', 'HmIP-WTH-B-2', 'HmIP-WTH-A', 'HmIP-STV', 'HmIP-WKP'], '3x LR3/AAA': ['HM-PB-4Dis-WM', 'HM-PB-4Dis-WM-2', 'HM-RC-Dis-H-x-EU', 'HM-Sen-LI-O'], '3x AAA Akkus - bitte laden': ['HM-RC-19', 'HM-RC-19-B', 'HM-RC-12', 'HM-RC-12-B', 'HM-RC-12-W'], '3x LR14/C': ['HmIP-MP3P'], '9Volt Block leer oder unbestimmt': ['HM-LC-Sw1-Ba-PCB', 'HM-LC-Sw4-PCB', 'HM-MOD-EM-8', 'HM-MOD-Re-8', 'HM-Sen-RD-O', 'HM-OU-CM-PCB', 'HM-LC-Sw4-WM'], 'Festbatterie leer': ['HmIP-STE2-PCB', 'HM-Sec-SD-2', 'HmIP-SWSD', 'HmIP-PCBS'], 'ohne Batterie': ['HM-LC-Sw1PBU-FM', 'HM-LC-Sw1-Pl-DN-R1', 'HM-LC-Sw1-DR', 'HM-LC-RGBW-WM', 'HM-LC-Sw1-Pl-CT-R1', 'HmIP-HEATING', 'HM-LC-Sw1-FM', 'HM-LC-Sw2-FM', 'HM-LC-Sw4-DR', 'HM-LC-Sw1-Pl', 'HM-LC-Sw1-Pl-2', 'HM-LC-Sw4-Ba-PCB', 'HM-LC-Sw1-SM', 'HM-LC-Sw4-SM', 'HM-Sys-sRP-Pl', 'HM-LC-Sw2PBU-FM', 'HM-LC-Sw1-PCB', 'HM-LC-Sw4-DR-2'], 'Akku entladen - bitte aufladen': ['HM-Sec-Win', 'HM-Sec-SFA-SM', 'HM-RC-19-SW'] }; // Standard Servicemeldungen, wenn alle anderen nicht zutreffen const StandardstatusMessages = ['keine Stoerung', 'Stoerung', 'bestaetigte Servicemeldung']; // hier sind alle bekannten Servicemeldungen zugeordnet (ueber Status-Datenpunkte des Geraetes) const statusMessages = { UNREACH_ALARM: ['keine Kommunikationsfehler', 'Kommunikation gestoert', 'Kommunikation war gestoert'], STICKY_UNREACH_ALARM: ['keine Kommunikationsfehler', 'Kommunikation gestoert', 'Kommunikation war gestoert'], SABOTAGE_ALARM: ['Keine Sabotage', 'Sabotage', 'Sabotage aufgehoben'], LOWBAT_ALARM: ['Batterie ok', 'Batterie niedrig', 'Batterie ok'], LOW_BAT_ALARM: ['Batterie ok', 'Batterie niedrig', 'Batterie ok'], ERROR_NON_FLAT_POSITIONING_ALARM: ['Keine Meldung', 'Geraet wurde angehoben.', 'Geraet wurde angehoben: Bestaetigt'], CONFIG_PENDING_ALARM: ['keine Meldung', 'Konfigurationsdaten stehen zur Uebertragung an', 'Konfigurationsdaten standen zur Uebertragung an'], UPDATE_PENDING_ALARM: ['kein Update verfuegbar', 'Update verfuegbar', 'Update wurde eingespielt'], DEVICE_IN_BOOTLOADER_ALARM: ['Keine Meldung', 'Geraet startet neu', 'Geraet wurde neu gestartet'], }; const errorMessages = { 'HM-Sec-RHS': { 7: 'Sabotage' }, 'HM-Sec-RHS-2': { 7: 'Sabotage' }, 'HM-Sec-SC': { 7: 'Sabotage' }, 'HM-Sec-SC-2': { 7: 'Sabotage' }, 'HM-Sec-SCo': { 7: 'Sabotage' }, 'HM-Sec-MD': { 7: 'Sabotage' }, 'HM-Sec-MDIR': { 7: 'Sabotage' }, 'HM-Sec-MDIR-2':{ 7: 'Sabotage' }, 'HM-Sec-Key': { 1: 'Einkuppeln fehlgeschlagen', 2: 'Motorlauf abgebrochen' }, 'HM-Sec-Key-S': { 1: 'Einkuppeln fehlgeschlagen', 2: 'Motorlauf abgebrochen' }, 'HM-Sec-Key-O': { 1: 'Einkuppeln fehlgeschlagen', 2: 'Motorlauf abgebrochen' }, 'HM-CC-VD': { 1: 'Ventil Antrieb blockiert', 2: 'Ventil nicht montiert', 3: 'Stellbereich zu klein', 4: 'Batteriezustand niedrig' } }; const faultMessages = { 'HM-CC-RT-DN': { 0: 'keine Stoerung', 1: 'Ventil blockiert', 2: 'Einstellbereich Ventil zu gross', 3: 'Einstellbereich Ventil zu klein', 4: 'Kommunikationsfehler', 6: 'Spannung Batterien/Akkus gering', 7: 'Fehlstellung Ventil' } }; // Umlaut Umwandlung und entfernung PUnkte - kann aber auch erweitert werden const replacements = { // Umwandlung fuer Namen der Geraete (common.name) '.': ' ', 'ä': 'ae', 'ü': 'ue', 'ö': 'oe', 'ß': 'ss' }; const idsUNREACH = []; // @ts-ignore $('state[id=hm-rpc.' + HMClassicInstanz + '.*.UNREACH_ALARM]').each(id => idsUNREACH.push(id)); // @ts-ignore $('state[id=hm-rpc.' + HMIPInstanz + '.*.UNREACH_ALARM]').each(id => idsUNREACH.push(id)); // @ts-ignore // $('state[id=hm-rpc.' + GruppenInstanz + '.*.UNREACH_ALARM]').each(id => idsUNREACH.push(id)); // auskommentiert keine Gruppenmeldungen const idsSTICKY_UNREACH = []; // @ts-ignore $('state[id=hm-rpc.' + HMClassicInstanz + '.*.STICKY_UNREACH_ALARM]').each(id => idsSTICKY_UNREACH.push(id)); // @ts-ignore $('state[id=hm-rpc.' + HMIPInstanz + '.*.STICKY_UNREACH_ALARM]').each(id => idsSTICKY_UNREACH.push(id)); // @ts-ignore // $('state[id=hm-rpc.' + GruppenInstanz + '.*.STICKY_UNREACH_ALARM]').each(id => idsSTICKY_UNREACH.push(id)); // auskommentiert keine Gruppenmeldungen const idsConfig_Pending = []; // @ts-ignore $('state[id=hm-rpc.' + HMClassicInstanz + '.*.CONFIG_PENDING_ALARM]').each(id => idsConfig_Pending.push(id)); // @ts-ignore $('state[id=hm-rpc.' + HMIPInstanz + '.*.CONFIG_PENDING_ALARM]').each(id => idsConfig_Pending.push(id)); // @ts-ignore // $('state[id=hm-rpc.' + GruppenInstanz + '.*.CONFIG_PENDING_ALARM]').each(id => idsConfig_Pending.push(id)); // auskommentiert keine Gruppenmeldungen const idsUPDATE_PENDING_ALARM = []; // @ts-ignore $('state[id=hm-rpc.' + HMClassicInstanz + '.*.UPDATE_PENDING_ALARM]').each(id => idsUPDATE_PENDING_ALARM.push(id)); // @ts-ignore $('state[id=hm-rpc.' + HMIPInstanz + '.*.UPDATE_PENDING_ALARM]').each(id => idsUPDATE_PENDING_ALARM.push(id)); // @ts-ignore // $('state[id=hm-rpc.' + GruppenInstanz + '.*.UPDATE_PENDING_ALARM]').each(id => idsUPDATE_PENDING_ALARM.push(id)); // auskommentiert keine Gruppenmeldungen const idsLOWBAT_ALARM = []; // @ts-ignore $('state[id=hm-rpc.' + HMClassicInstanz + '.*.LOWBAT_ALARM]').each(id => idsLOWBAT_ALARM.push(id)); // @ts-ignore $('state[id=hm-rpc.' + HMIPInstanz + '.*.LOW_BAT_ALARM]').each(id => idsLOWBAT_ALARM.push(id)); // @ts-ignore // $('state[id=hm-rpc.' + GruppenInstanz + '.*.LOW_BAT_ALARM]').each(id => idsLOWBAT_ALARM.push(id)); // auskommentiert keine Gruppenmeldungen const idsDEVICE_IN_BOOTLOADER_ALARM = []; // @ts-ignore $('state[id=hm-rpc.' + HMClassicInstanz + '.*.DEVICE_IN_BOOTLOADER_ALARM]').each(id => idsDEVICE_IN_BOOTLOADER_ALARM.push(id)); // nur HM-Classic const idsERROR = []; // @ts-ignore $('state[id=hm-rpc.' + HMClassicInstanz + '.*.ERROR]').each(id => idsERROR.push(id)); // @ts-ignore $('state[id=hm-rpc.' + HMIPInstanz + '.*.ERROR]').each(id => idsERROR.push(id)); // @ts-ignore // $('state[id=hm-rpc.' + GruppenInstanz + '.*.ERROR]').each(id => idsERROR.push(id)); // auskommentiert keine Gruppenmeldungen const idsFAULT_REPORTING = []; // @ts-ignore $('state[id=hm-rpc.' + HMClassicInstanz + '.*.FAULT_REPORTING]').each(id => idsFAULT_REPORTING.push(id)); // nur HM-Classic const idsSABOTAGE_ALARM = []; // @ts-ignore $('state[id=hm-rpc.' + HMClassicInstanz + '.*.SABOTAGE_ALARM]').each(id => idsSABOTAGE_ALARM.push(id)); // @ts-ignore $('state[id=hm-rpc.' + HMIPInstanz + '.*.SABOTAGE_ALARM]').each(id => idsSABOTAGE_ALARM.push(id)); // @ts-ignore // $('state[id=hm-rpc.' + GruppenInstanz + '.*.SABOTAGE_ALARM]').each(id => idsSABOTAGE_ALARM.push(id)); // auskommentiert keine Gruppenmeldungen const idsERROR_NON_FLAT_POSITIONING_ALARM = []; // @ts-ignore $('state[id=hm-rpc.' + HMClassicInstanz + '.*.ERROR_NON_FLAT_POSITIONING_ALARM]').each(id => idsERROR_NON_FLAT_POSITIONING_ALARM.push(id)); // @ts-ignore $('state[id=hm-rpc.' + HMIPInstanz + '.*.ERROR_NON_FLAT_POSITIONING_ALARM]').each(id => idsERROR_NON_FLAT_POSITIONING_ALARM.push(id)); const selectors = [ { ids: idsUNREACH, name: 'UNREACH_ALARM' }, { ids: idsSTICKY_UNREACH, name: 'STICKY_UNREACH_ALARM' }, { ids: idsConfig_Pending, name: 'CONFIG_PENDING_ALARM' }, { ids: idsUPDATE_PENDING_ALARM, name: 'UPDATE_PENDING_ALARM' }, { ids: idsLOWBAT_ALARM, name: 'LOWBAT_ALARM' }, { ids: idsDEVICE_IN_BOOTLOADER_ALARM, name: 'DEVICE_IN_BOOTLOADER_ALARM' }, { ids: idsERROR, name: 'ERROR' }, { ids: idsFAULT_REPORTING, name: 'FAULT_REPORTING' }, { ids: idsSABOTAGE_ALARM, name: 'SABOTAGE_ALARM' }, { ids: idsERROR_NON_FLAT_POSITIONING_ALARM, name: 'ERROR_NON_FLAT_POSITIONING_ALARM' }, ]; //----------------------------------------------------------------------------------------------------- //Hauptprogramm //----------------------------------------------------------------------------------------------------- let AktuelleSMjsonString = [] // alle aktuellen Servicemeldungen als JSON let MessageSendCollector = {}; // alle aktuellen Servicemeldungen zum senden an messaging services MessageSendCollector = { 'UNREACH_ALARM': [], 'Sticky_UNREACH_ALARM': [], 'UPDATE_PENDING_ALARM': [], 'LOWBAT_ALARM': [], 'DEVICE_IN_BOOTLOADER_ALARM': [], 'ERROR': [], 'FAULT_REPORTING': [], 'SABOTAGE_ALARM': [], 'ERROR_NON_FLAT_POSITIONING_ALARM': [], 'CONFIG_PENDING': [], 'ERROR_REDUCED': [], 'STICKY_SABOTAGE': [], 'USBH_POWERFAIL': [], 'U_SOURCE_FAIL': [] }; // Variable für den Timer, um die 5-Sekunden-Wartezeit zu steuern let changeTimeout = null; let countIdsInnerhalbTimeout = 0; // create States CreateStates(() => { Check_All() }); // Subscriptions erstellen if (GeraeteIDTrigger) { SubscribeGeraeteID(); }else{ SubscribeRegaDP(); } //----------------------------------------------------------------------------------------------------- // Schedule zum Loeschen des Datenpunktwertes der Histore //----------------------------------------------------------------------------------------------------- schedule(scheduleTimeClearSMTexte, function() { setState(id_Text_Servicemeldung_History, ''); setState(id_JSON_Servicemeldung_Historie, []); log(`Datenpunkt ${id_Text_Servicemeldung_History} geloescht`); }); //----------------------------------------------------------------------------------------------------- // Funktion SubscribeRegaDP // Erstellung der Subscriptions auf REGA Datenpunkt // es werden 5 Sekunden lang vorliegende Aenderungen gesammelt //----------------------------------------------------------------------------------------------------- function SubscribeRegaDP() { if (debugLevel >= 2) { log(`Routine SubscribeRegaDP wird ausgefuehrt - Pfad des Datenpunkts: ${PathRega}`, "info"); } on({id: PathRega, change: 'any'}, function (obj) { if (obj.state.val === obj.oldState.val) { // Überprüfen, ob sich der Wert des Datenpunkts geändert hat return; // Keine Änderung, also nichts tun } countIdsInnerhalbTimeout++; if (debugLevel >= 2) { log(`Datenpunkt ${PathRega} hat sich geaendert. Neuer Wert: ${obj.state.val}`, "info");} // Falls schon ein Timer läuft, diesen abbrechen if (changeTimeout) { clearTimeout(changeTimeout); } // Setze einen neuen Timer auf 5 Sekunden, um die Funktion Servicemeldung aufzurufen changeTimeout = setTimeout(function() { Servicemeldung(); // Funktion wird nach 5 Sekunden ohne weitere Änderungen aufgerufen }, 5000); // 5000 ms = 5 Sekunden }); } // ende funktion //----------------------------------------------------------------------------------------------------- // Funktion Subscribe GeraeteID // Erstellung der Subscriptions auf GeraeteID und Datenpunkt Ebene //----------------------------------------------------------------------------------------------------- function SubscribeGeraeteID() { if(debugLevel >= 2) { log(`Routine SubscribeGeraeteID wird ausgefuehrt`, "info");} let callCount = 0; // fuer Timer Funktion let timeoutActive = false; // fuer Timer Funktion selectors.forEach(selector => { if (selector.ids.length > 0) { if(debugLevel >= 2) {log(`SubscribeGeraeteID: Prozessiere selector: ${selector.name}`);}; const filteredIds = selector.ids.filter(id => { // IDs filtern: nur IDs behalten, deren Geraete-ID nicht in der Ausschlussliste ist const parts = id.split('.'); // Extrahiere die Geraete-ID aus der vollstaendigen ID (dritte Stelle) const deviceId = parts[2]; // Hier ist die Geraete-ID das dritte Element if (Ausschlussliste.includes(deviceId)) { // ueberpruefen, ob die Geraete-ID in der Ausschlussliste ist if(debugLevel >= 2) { log(`ID ${deviceId} aus den subscriptions entfernt (wegen Ausschlussliste) : ${id}`);}; return false; // Diese ID wird gefiltert } return true; // Diese ID bleibt }); filteredIds.forEach(id => { // @ts-ignore if( debugLevel >= 3 ) { log(`Routine Subscription per ID: Creating subscription for ID: ${id}`);}; on({ id: id, change: "any" }, obj => { if (obj.state.val === obj.oldState.val) { return; } if (timeoutActive) { return; // Wenn der Timeout aktiv ist, keine weitere Verarbeitung } callCount++; // Wenn mehr als 10 Aufrufe innerhalb von 1 Sekunde if (callCount >= 50) { timeoutActive = true; // Wartezeit aktivieren log("SubscribeGeraeteID: Servicemeldungen: Zu viele Servicemeldungen wurden generiert, warte 5 Minuten.","warn"); setTimeout(() => { timeoutActive = false; // Timeout beenden callCount = 0; // Zaehler zuruecksetzen log("Servicemeldungen: Wartezeit beendet, weitere Servicemeldungen sind jetzt moeglich."); }, 5 * 60 * 1000); // 5 Minuten in Millisekunden } Servicemeldung(obj, selector.name); // "Servicemeldung" aufrufen setTimeout(() => { // Reset des Zaehlers nach 1 Sekunde callCount = Math.max(0, callCount - 1); }, 1000); }); }); // EndIDLoop } else { if(debugLevel >= 1 ) {log(`SubscribeGeraeteID: No matching states found for ${selector.name}`);}; } }); //endSelectorLoop } // EndFunction //----------------------------------------------------------------------------------------------------- // Kernfunktion Sevicemeldung // erstmal die aktuelle Servicemeldung analysieren und loggen //----------------------------------------------------------------------------------------------------- function Servicemeldung(obj, Selektor_Name) { if (debugLevel >= 2) log(`Routine Servicemeldung wird ausgefuehrt`, "info"); if (!GeraeteIDTrigger) { // nur wenn ueber REGA Servicemeldungen von der CCU reagiert werden soll if (debugLevel >= 1) { log(`Routine Servicemeldung wird ausgefuehrt - Es wurden insgesamt ${countIdsInnerhalbTimeout} Änderungen festgestellt.`, "info"); } countIdsInnerhalbTimeout = 0; // Reset der Zählung changeTimeout = null; // Reset des Timeouts fuer den REGA Trigger const AnzahlSM = Check_All(); const regaState = getState(PathRega).val; if (debugLevel >= 1) { log("REGA Anzahl SM " + regaState + " anzahlSM " + AnzahlSM);}; if (regaState === 0 || AnzahlSM === 0) { setState(id_Text_ServicemeldungLang, MessageBeiKeinerSM); setState(id_Text_ServicemeldungKurz, MessageBeiKeinerSM); collectMessage('keineSM', MessageBeiKeinerSM); sendMessage('keineSM'); return; } sendMessage(); return; } // jetzt die subscriptions die ueber Aenderungen von Datenpunkten laufen also bei GeraeteIDTrigger = true - Servicemeldungen in die Historie schreiben const AnzahlSM = Check_All(); const id_name = obj.id.split('.')[2]; if (!existsState(obj.id)) { log("Routine Servicemeldungen - Geraet " + id_name +" scheint zwischenzeitlich nicht mehr zu existieren - Empfehlung: script neu starten","warn") return; } if (AnzahlSM === 0) { // keine Servicmeldungen delete MessageSendCollector['keineSM']; collectMessage('keineSM', MessageBeiKeinerSM) sendMessage('keineSM'); } if (Ausschlussliste.includes(id_name)) { if(debugLevel >= 2) { log(`Routine Servicemeldung ID ${id_name} hat eine Aenderung gemeldet wird aber uebersprungen wegen Ausschlussliste`, "info");} return; } let commonObj = getObject(obj.id.substring(0, obj.id.lastIndexOf('.') - 2)); let common_name = ReplaceString(commonObj.common.name); const meldungsart = obj.id.split('.')[4]; const status = obj.newState.val; const native_type = getObject(obj.id.substring(0, obj.id.lastIndexOf('.') - 2)).native.TYPE; let status_text = DefineServiceMessage(meldungsart, native_type, status,obj.id,"lang"); if(debugLevel >= 1 ) { log(`ServicemeldungenVol2: neue Servicemeldung ist ${status_text} Meldungsart ist ${meldungsart} `);} const datum_seit = func_get_datum(obj.id); // Status "0" wurde gesetzt. Bei HM-Classic war das der Status um zu melden, dass die Servicemeldung zurueckgesetzt wurde if(status === 0 ) { status_text = DefineServiceMessage(meldungsart, native_type, status, obj.id, "lang") if(debugLevel >= 2 ) { log(`Routine Servicemeldung - status ist 0 - status_text ist ${status_text} Meldungsart ist ${meldungsart} `);} } // externes log erzeugen writelog(common_name, id_name, meldungsart, status, status_text); // Historische Servicemeldung als Text speichern appendToState(id_Text_Servicemeldung_History, status_text); //historische Servicemeldung als Json speichern (additiv) let HistorischeSMjsonString = [] const stateValue = getState(id_JSON_Servicemeldung_Historie).val; if (stateValue) { try { HistorischeSMjsonString = JSON.parse(stateValue); } catch (error) { log(`Fehler beim Parsen des JSON: ${error}`); HistorischeSMjsonString = []; // Fallback auf leeres Array } } HistorischeSMjsonString.push(createJsonEntry(datum_seit, meldungsart, common_name, id_name, status,status_text)); const jsonString = JSON.stringify(HistorischeSMjsonString); setState(id_JSON_Servicemeldung_Historie, jsonString); // Messenger Dienste aktivieren delete MessageSendCollector[meldungsart]; collectMessage(meldungsart, status_text) sendMessage(meldungsart); } //----------------------------------------------------------------------------------------------------- // Kompeletter Durchgang // jetzt alle Servicemeldungen durchzaehlen //----------------------------------------------------------------------------------------------------- function Check_All() { if(debugLevel >= 2) { log(`Routine Check_All wird ausgefuehrt`, "info");} let count_all = 0; let count_Akut = 0; let count_Akut_UNREACH_ALARM = 0; let count_Akut_Sticky_UNREACH_ALARM = 0; let count_Akut_CONFIG_PENDING_ALARM = 0; let count_Akut_UPDATE_PENDING_ALARM = 0; let count_Akut_LOWBAT_ALARM = 0; let count_Akut_DEVICE_IN_BOOTLOADER_ALARM = 0; let count_Akut_ERROR = 0; let count_Akut_FAULT_REPORTING = 0; let count_Akut_SABOTAGE_ALARM = 0; let count_Akut_Sticky_SABOTAGE_ALARM = 0; let count_Akut_ERROR_NON_FLAT_POSITIONING_ALARM = 0; let count_Akut_ERROR_REDUCED = 0; let count_Akut_USBH_POWERFAIL = 0; let count_Akut_U_SOURCE_FAIL = 0; let count_Akut_STICKY_SABOTAGE = 0; let id; let parts; let common_name; let id_name; let native_type; let GeraeteID; let meldungsart; let ServiceMeldungTextKurz; let ServiceMeldungTextLang; let status; let datum_seit; let commonObj; let ServicemeldungMessagesLang = []; let ServicemeldungMessagesKurz = []; AktuelleSMjsonString = []; selectors.forEach(selector => { if (selector.ids.length > 0) { for (let i = 0; i < selector.ids.length; i++) { id = selector.ids[i]; parts = id.split('.'); // Extrahiere die Geraete-ID aus der vollstaendigen ID (dritte Stelle) GeraeteID = parts[2]; // Hier ist die Geraete-ID das dritte Element if (!existsState(id)) { log("Routine Check_All - Geraet "+GeraeteID +" scheint zwischenzeitlich nicht mehr zu existieren - Empfehlung: script neu starten","warn") continue; } // ueberpruefen, ob die Geraete-ID in der Ausschlussliste ist if (Ausschlussliste.includes(GeraeteID)) { if(debugLevel >= 2) { log(`Routine Check_All ID ${GeraeteID} wird uebersprungen wegen Ausschlussliste`, "info");} continue; // ueberspringe die ID, wenn sie in der Ausschlussliste ist } native_type = getObject(id.substring(0, id.lastIndexOf('.') - 2)).native.TYPE; commonObj = getObject(id.substring(0, id.lastIndexOf('.') - 2)); common_name = ReplaceString(commonObj.common.name); id_name = id.split('.')[2]; meldungsart = id.split('.')[4]; status = getState(id).val; datum_seit = func_get_datum(id); switch (selector.name) { case 'UNREACH_ALARM': if(status === 1) { ServiceMeldungTextLang =DefineServiceMessage(selector.name, native_type, status,id,"lang"); ServicemeldungMessagesLang.push(ServiceMeldungTextLang); ServiceMeldungTextKurz =DefineServiceMessage(selector.name, native_type, status,id,"kurz"); ServicemeldungMessagesKurz.push(ServiceMeldungTextLang); collectMessage('UNREACH_ALARM', ServiceMeldungTextLang) count_Akut_UNREACH_ALARM++; count_Akut++; } break; case 'Sticky_UNREACH_ALARM': if(status === 1) { ServiceMeldungTextLang =DefineServiceMessage(selector.name, native_type, status,id,"lang"); ServicemeldungMessagesLang.push(ServiceMeldungTextLang); ServiceMeldungTextKurz =DefineServiceMessage(selector.name, native_type, status,id,"kurz"); ServicemeldungMessagesKurz.push(ServiceMeldungTextKurz); collectMessage('Sticky_UNREACH_ALARM', ServiceMeldungTextLang) count_Akut_Sticky_UNREACH_ALARM++; count_Akut++; } break; case 'UPDATE_PENDING_ALARM': if(status === 1) { ServiceMeldungTextLang =DefineServiceMessage(selector.name, native_type, status,id,"lang"); ServicemeldungMessagesLang.push(ServiceMeldungTextLang); ServiceMeldungTextKurz =DefineServiceMessage(selector.name, native_type, status,id,"kurz"); ServicemeldungMessagesKurz.push(ServiceMeldungTextKurz); collectMessage('UPDATE_PENDING_ALARM', ServiceMeldungTextLang) count_Akut_UPDATE_PENDING_ALARM++; count_Akut++; } break; case 'LOWBAT_ALARM': if(status === 1) { ServiceMeldungTextLang =DefineServiceMessage(selector.name, native_type, status,id,"lang"); ServicemeldungMessagesLang.push(ServiceMeldungTextLang); ServiceMeldungTextKurz =DefineServiceMessage(selector.name, native_type, status,id,"kurz"); ServicemeldungMessagesKurz.push(ServiceMeldungTextKurz); collectMessage('LOWBAT_ALARM', ServiceMeldungTextLang) count_Akut_LOWBAT_ALARM++; count_Akut++; } break; case 'DEVICE_IN_BOOTLOADER_ALARM': if(status === 1) { ServiceMeldungTextLang =DefineServiceMessage(selector.name, native_type, status,id,"lang"); ServicemeldungMessagesLang.push(ServiceMeldungTextLang); ServiceMeldungTextKurz =DefineServiceMessage(selector.name, native_type, status,id,"kurz"); ServicemeldungMessagesKurz.push(ServiceMeldungTextKurz); collectMessage('DEVICE_IN_BOOTLOADER_ALARM', ServiceMeldungTextLang) count_Akut_DEVICE_IN_BOOTLOADER_ALARM++; count_Akut++; } break; case 'ERROR': if (status >= 1 && status <= 7) { ServiceMeldungTextLang =DefineServiceMessage(selector.name, native_type, status,id,"lang"); ServicemeldungMessagesLang.push(ServiceMeldungTextLang); ServiceMeldungTextKurz =DefineServiceMessage(selector.name, native_type, status,id,"kurz"); ServicemeldungMessagesKurz.push(ServiceMeldungTextKurz); collectMessage('ERROR', ServiceMeldungTextLang) if (status === 7) { count_Akut_SABOTAGE_ALARM++; // nur fuer HM-Classic-messagetype = error status = 7 entspricht sabotage } else { count_Akut_ERROR++; } count_Akut++; } break; case 'FAULT_REPORTING': if(status === 1) { ServiceMeldungTextLang =DefineServiceMessage(selector.name, native_type, status,id,"lang"); ServicemeldungMessagesLang.push(ServiceMeldungTextLang); ServiceMeldungTextKurz =DefineServiceMessage(selector.name, native_type, status,id,"kurz"); ServicemeldungMessagesKurz.push(ServiceMeldungTextKurz); collectMessage('FAULT_REPORTING', ServiceMeldungTextLang) count_Akut_FAULT_REPORTING++; count_Akut++; } break; case 'SABOTAGE_ALARM': if(status === 1) { ServiceMeldungTextLang =DefineServiceMessage(selector.name, native_type, status,id,"lang"); ServicemeldungMessagesLang.push(ServiceMeldungTextLang); ServiceMeldungTextKurz =DefineServiceMessage(selector.name, native_type, status,id,"kurz"); ServicemeldungMessagesKurz.push(ServiceMeldungTextKurz); collectMessage('SABOTAGE_ALARM', ServiceMeldungTextLang) count_Akut_SABOTAGE_ALARM++; count_Akut++; } break; case 'ERROR_NON_FLAT_POSITIONING_ALARM': if(status === 1) { ServiceMeldungTextLang =DefineServiceMessage(selector.name, native_type, status,id,"lang"); ServicemeldungMessagesLang.push(ServiceMeldungTextLang); ServiceMeldungTextKurz =DefineServiceMessage(selector.name, native_type, status,id,"kurz"); ServicemeldungMessagesKurz.push(ServiceMeldungTextKurz); collectMessage('ERROR_NON_FLAT_POSITIONING_ALARM', ServiceMeldungTextLang) count_Akut_ERROR_NON_FLAT_POSITIONING_ALARM++; count_Akut++; } break; case 'CONFIG_PENDING': if(status === 1) { ServiceMeldungTextLang =DefineServiceMessage(selector.name, native_type, status,id,"lang"); ServicemeldungMessagesLang.push(ServiceMeldungTextLang); ServiceMeldungTextKurz =DefineServiceMessage(selector.name, native_type, status,id,"kurz"); ServicemeldungMessagesKurz.push(ServiceMeldungTextKurz); collectMessage('CONFIG_PENDING', ServiceMeldungTextLang) count_Akut_CONFIG_PENDING_ALARM++ count_Akut++; } break; case 'STICKY_SABOTAGE': if(status === 2) { ServiceMeldungTextLang =DefineServiceMessage(selector.name, native_type, status,id,"lang"); ServicemeldungMessagesLang.push(ServiceMeldungTextLang); ServiceMeldungTextKurz =DefineServiceMessage(selector.name, native_type, status,id,"kurz"); ServicemeldungMessagesKurz.push(ServiceMeldungTextKurz); collectMessage('STICKY_SABOTAGE', ServiceMeldungTextLang) count_Akut_STICKY_SABOTAGE++ count_Akut++; } break; case 'ERROR_REDUCED': //count_Akut_ERROR_REDUCED++ //count_Akut++; log("Servicemeldung -ERROR_REDUCED- ist nicht implementiert","warn") break; case 'USBH_POWERFAIL': //count_Akut_USBH_POWERFAIL++ //count_Akut++; log("Servicemeldung -USBH_POWERFAIL- ist nicht implementiert","warn") break; case 'U_SOURCE_FAIL': // count_Akut_U_SOURCE_FAIL++ // count_Akut++; log("Servicemeldung -U_SOURCE_FAIL- ist nicht implementiert","warn") break default: break; } count_all++; // Jetzt ausserhalb des Switch-Blocks } } else { if (debugLevel >= 1 ) {log(`No matching states found for ${selector.name}`);} } }); // ende selectors loop const jsonString = JSON.stringify(AktuelleSMjsonString); setState(id_JSON_Servicemeldung_Aktuell, jsonString); // Gehe durch das Array und fuege jede Nachricht mit einem Zeilenumbruch hinzu let formattedMessagesLang = ServicemeldungMessagesLang.join('<br>'); let formattedMessagesKurz = ServicemeldungMessagesKurz.join('<br>'); // Speichere den formatierten String im Datenpunkt if(count_Akut === 0){ setState(id_Text_ServicemeldungLang,MessageBeiKeinerSM); setState(id_Text_ServicemeldungKurz,MessageBeiKeinerSM); }else{ setState(id_Text_ServicemeldungLang, formattedMessagesLang); setState(id_Text_ServicemeldungKurz, formattedMessagesKurz); } // jetzt die Einzelcounts speichern setState(id_IST_UNREACH,count_Akut_UNREACH_ALARM ); setState(id_IST_STICKY_UNREACH,count_Akut_Sticky_UNREACH_ALARM ); setState(id_IST_LOWBAT,count_Akut_LOWBAT_ALARM ); setState(id_IST_CONFIG_PENDING,count_Akut_CONFIG_PENDING_ALARM ); setState(id_IST_UPDATE_PENDING,count_Akut_UPDATE_PENDING_ALARM ); setState(id_IST_DEVICE_IN_BOOTLOADER,count_Akut_DEVICE_IN_BOOTLOADER_ALARM ); setState(id_IST_ERROR,count_Akut_ERROR ); setState(id_IST_ERROR_NON_FLAT_POSITIONING,count_Akut_ERROR_NON_FLAT_POSITIONING_ALARM ); setState(id_IST_FAULT_REPORTING,count_Akut_FAULT_REPORTING ); setState(id_IST_SABOTAGE,count_Akut_SABOTAGE_ALARM ); setState(id_IST_ERROR_REDUCED,count_Akut_ERROR_REDUCED ); setState(id_IST_STICKY_SABOTAGE,count_Akut_Sticky_SABOTAGE_ALARM ); setState(id_IST_USBH_POWERFAIL, count_Akut_USBH_POWERFAIL); setState(id_IST_U_SOURCE_FAIL, count_Akut_U_SOURCE_FAIL); // Gesamtcounts setState(id_IST_Gesamt,count_all ); setState(id_IST_SMAktuell,count_Akut ); if(debugLevel >= 1) { log(`es wurden insgesamt ${count_all} ids gecheckt - insgesamt gibt es ${count_Akut} Servicemeldungen`, "info"); log("davon gibt es zur Zeit aktuelle Servicemeldungen: " + count_Akut); log("SM count_Akut_UNREACH_ALARM " + count_Akut_UNREACH_ALARM + " count_akut " + count_Akut); log("SM count_Akut_CONFIG_PENDING_ALARM " + count_Akut_CONFIG_PENDING_ALARM); log("SM count_Akut_UPDATE_PENDING_ALARM " + count_Akut_UPDATE_PENDING_ALARM); log("SM count_Akut_LOWBAT_ALARM " + count_Akut_LOWBAT_ALARM); log("SM count_Akut_DEVICE_IN_BOOTLOADER_ALARM " + count_Akut_DEVICE_IN_BOOTLOADER_ALARM); log("SM count_Akut_ERROR " + count_Akut_ERROR); log("SM count_Akut_FAULT_REPORTING " + count_Akut_FAULT_REPORTING); log("SM count_Akut_SABOTAGE_ALARM " + count_Akut_SABOTAGE_ALARM); log("SM count_Akut_ERROR_NON_FLAT_POSITIONING_ALARM " + count_Akut_ERROR_NON_FLAT_POSITIONING_ALARM); log("SM count_Akut_ERROR_REDUCED " + count_Akut_ERROR_REDUCED); log("SM count_Akut_STICKY_SABOTAGE " + count_Akut_STICKY_SABOTAGE); log("SM count_Akut_U_SOURCE_FAIL " + count_Akut_U_SOURCE_FAIL); log("SM count_Akut_USBH_POWERFAIL " + count_Akut_USBH_POWERFAIL); } if(debugLevel >= 3) { console.log(`gesammelte Servicemeldungen Lang: ${ServicemeldungMessagesLang}`) console.log(`gesammelte Servicemeldungen Lang: ${ServicemeldungMessagesKurz}`) } return count_Akut } // endfunction //----------------------------------------------------------------------------------------------------- // Message ERmittlung //----------------------------------------------------------------------------------------------------- function DefineServiceMessage(meldungsart, native_type, status, id, version) { if (debugLevel >= 2) { log(`Routine DefineServiceMessage wird ausgefuehrt meldungsart ${meldungsart}`, "info"); } let ServiceMessage; // Rueckgabewert let parts = id.split('.'); // Extrahiere die Geraete-ID aus der vollstaendigen ID (dritte Stelle) let commonObj = getObject(id.substring(0, id.lastIndexOf('.') - 2)); let common_name = ReplaceString(commonObj.common.name); let id_name = parts[2]; let datum_seit = func_get_datum(id); // Im Folgenden werden lange und kurze Versionen von Servicemeldungen erzeugt switch (meldungsart) { case "CONFIG_PENDING": ServiceMessage = version === "lang" ? `${datum_seit} - ${meldungsart} - ${common_name} - (${id_name}) - ${status} - ${statusMessages.CONFIG_PENDING_ALARM[status]}` : `${common_name} ${statusMessages.CONFIG_PENDING_ALARM[status]}`; if (version === "lang") { AktuelleSMjsonString.push( createJsonEntry ( datum_seit, meldungsart, common_name, id_name, status, statusMessages.CONFIG_PENDING_ALARM[status], null) ); } break; case "LOW_BAT_ALARM": case "LOWBAT_ALARM": ServiceMessage = version === "lang" ? `${datum_seit} - ${meldungsart} - ${common_name} - (${id_name}) - ${status} - ${statusMessages.LOWBAT_ALARM[status]} - Batteriebezeichnung: ${func_Batterie(native_type)}` : `${common_name} ${statusMessages.LOWBAT_ALARM[status]}`; if (version === "lang") { AktuelleSMjsonString.push( createJsonEntry ( datum_seit, meldungsart, common_name, id_name,status,statusMessages.LOWBAT_ALARM[status],func_Batterie(native_type) )); } break; case "STICKY_UNREACH_ALARM": ServiceMessage = version === "lang" ? `${datum_seit} - ${meldungsart} - ${common_name} - (${id_name}) - ${status} - ${statusMessages.STICKY_UNREACH_ALARM[status]}` : `${common_name} ${statusMessages.STICKY_UNREACH_ALARM[status]}`; if (version === "lang") { AktuelleSMjsonString.push(createJsonEntry(datum_seit, meldungsart, common_name, id_name,status,statusMessages.STICKY_UNREACH_ALARM[status],null )); } break; case "UNREACH_ALARM": ServiceMessage = version === "lang" ? `${datum_seit} - ${meldungsart} - ${common_name} - (${id_name}) - ${status} - ${statusMessages.UNREACH_ALARM[status]}` : `${common_name} ${statusMessages.UNREACH_ALARM[status]}`; if (version === "lang") { AktuelleSMjsonString.push(createJsonEntry(datum_seit, meldungsart, common_name, id_name,status,statusMessages.UNREACH_ALARM[status],null )); } break; case "DEVICE_IN_BOOTLOADER_ALARM": ServiceMessage = version === "lang" ? `${datum_seit} - ${meldungsart} - ${common_name} - (${id_name}) - ${status} - ${statusMessages.DEVICE_IN_BOOTLOADER_ALARM[status]}` : `${common_name} ${statusMessages.DEVICE_IN_BOOTLOADER_ALARM[status]}`; if (version === "lang") { AktuelleSMjsonString.push(createJsonEntry(datum_seit, meldungsart, common_name, id_name,status,statusMessages.DEVICE_IN_BOOTLOADER_ALARM[status],null )); } break; case "UPDATE_PENDING_ALARM": ServiceMessage = version === "lang" ? `${datum_seit} - ${meldungsart} - ${common_name} - (${id_name}) - ${status} - ${statusMessages.UPDATE_PENDING_ALARM[status]}` : `${common_name} ${statusMessages.UPDATE_PENDING_ALARM[status]}`; if (version === "lang") { AktuelleSMjsonString.push(createJsonEntry(datum_seit, meldungsart, common_name, id_name,status,statusMessages.UPDATE_PENDING_ALARM[status],null )); } break; case "SABOTAGE_ALARM": case "SABOTAGE": ServiceMessage = version === "lang" ? `${datum_seit} - ${meldungsart} - ${common_name} - (${id_name}) - ${status} - ${statusMessages.SABOTAGE_ALARM[status]}` : `${common_name} ${statusMessages.SABOTAGE_ALARM[status]}`; if (version === "lang") { AktuelleSMjsonString.push(createJsonEntry(datum_seit, meldungsart, common_name, id_name,status,statusMessages.SABOTAGE_ALARM[status],null )); } break; case "ERROR_NON_FLAT_POSITIONING_ALARM": ServiceMessage = version === "lang" ? `${datum_seit} - ${meldungsart} - ${common_name} - (${id_name}) - ${status} - ${statusMessages.ERROR_NON_FLAT_POSITIONING_ALARM[status]}` : `${common_name} ${statusMessages.ERROR_NON_FLAT_POSITIONING_ALARM[status]}`; if (version === "lang") { AktuelleSMjsonString.push(createJsonEntry(datum_seit, meldungsart, common_name, id_name,status,statusMessages.ERROR_NON_FLAT_POSITIONING_ALARM[status],null )); } break; case "ERROR": if (status >= 1 && status <= 7) { // nur wenn kein status = 0 if (errorMessages[native_type] && errorMessages[native_type][status]) { ServiceMessage = version === "lang" ? `${datum_seit} - ${meldungsart} - ${common_name} - (${id_name}) - ${status} - ${errorMessages[native_type][status]}` : `${common_name} ${errorMessages[native_type][status]}`; if (version === "lang") { AktuelleSMjsonString.push(createJsonEntry(datum_seit, meldungsart, common_name, id_name,status,errorMessages[native_type][status],null )); } } // endif errorMessages } // endif Status >=1... if (status === 0) { // nicht HIMIP Geräte die auf Error und status 0 stehen - Message aufgehoben fuer Historie ServiceMessage = version === "lang" ? `${datum_seit} - ${meldungsart} - ${common_name} - (${id_name}) - ${status} - $StandardstatusMessages[status]}` : `${common_name} ${errorMessages[native_type][status]}`; if (version === "lang") { AktuelleSMjsonString.push(createJsonEntry(datum_seit, meldungsart, common_name, id_name,status,StandardstatusMessages[status],null )); } } break; case "FAULT_REPORTING": if (faultMessages[native_type] && faultMessages[native_type][status]) { ServiceMessage = version === "lang" ? `${datum_seit} - ${meldungsart} - ${common_name} - (${id_name}) - ${status} - ${faultMessages[native_type][status]}` : `${common_name} ${faultMessages[native_type][status]}`; if (version === "lang") { AktuelleSMjsonString.push(createJsonEntry(datum_seit, meldungsart, common_name, id_name,status,faultMessages[native_type][status],null )); } } break; default: if (status < 0 || status >= StandardstatusMessages.length) { ServiceMessage = `datum_seit, meldungsart, common_name, id_name,- Ungueltiger Status`; // fuer ungueltige Statuswerte } else { ServiceMessage = version === "lang" ? `${datum_seit} - ${meldungsart} - ${common_name} - (${id_name}) - ${status} - ${StandardstatusMessages[status]}` : `${common_name} ${StandardstatusMessages[status]}`; if (version === "lang") { AktuelleSMjsonString.push(createJsonEntry(datum_seit, meldungsart, common_name, id_name,status,StandardstatusMessages[status],null )); } } } return ServiceMessage; // Nur einmal am Ende zurueckgeben } //----------------------------------------------------------------------------------------------------- // sendMessage Hier werden die Nachrichten fuer den jeweiligen Service aufbereitet //----------------------------------------------------------------------------------------------------- function sendMessage(messageType = null) { if (debugLevel >= 2) { log(`Routine sendMessage wird ausgefuehrt fuer messagetype ${messageType}`, "info"); } if (debugLevel >= 2) { console.log(MessageSendCollector); } const messageTypesToProcess = messageType ? [messageType] : Object.keys(MessageSendCollector); messageTypesToProcess.forEach((type) => { const messagesToSend = MessageSendCollector[type] || []; if (messagesToSend.length === 0) { if (debugLevel >= 2) { log(`Keine Nachrichten zum Senden fuer "${type}".`, "info"); } return; } const combinedMessage = messagesToSend.join('<br>'); const messageServices = MessengerScope[type] || MessengerScope['Sonstige']; services.forEach((service, index) => { if (messageServices[index]) { if (debugLevel >= 2) { log("Messagetype " + type + " wird versendet fuer Service " + service, "info"); } sendToService(service, combinedMessage); } }); // Nach dem Senden die Nachrichten aus dem Collector entfernen delete MessageSendCollector[type]; }); // Spezielle Behandlung fuer "Sonstige" Nachrichten if (MessageSendCollector['Sonstige'] && MessageSendCollector['Sonstige'].length > 0) { const combinedOtherMessage = MessageSendCollector['Sonstige'].join('br'); services.forEach((service, index) => { if (MessengerScope['Sonstige'][index]) { sendToService(service, combinedOtherMessage); if (debugLevel >= 2) { log("Nachricht vom Typ 'Sonstige' wird versendet fuer Service " + service, "info"); } } }); // Leere das "Sonstige" Array nach dem Senden delete MessageSendCollector['Sonstige']; } } //----------------------------------------------------------------------------------------------------- // sendToService - hier wird der Versand vorgenommen // Reihenfolge: Email, WhatsApp, Signal, Telegram, Pushover, Pushsafer // MessengerInstanz = [0, 0, 0, 0, 0, 0] Instanzen der Messenger-Dienste in //----------------------------------------------------------------------------------------------------- function sendToService(service, combinedMessage) { switch (service) { case "email": sendTo(`email.${MessengerInstanz[0]}`, "send", { text: combinedMessage, to: emailAddresse, subject: Headline }); break; case "whatsApp": sendTo(`whatsapp-cmb.${MessengerInstanz[1]}`, "send", { text: combinedMessage }); break; case "Signal": sendTo(`signal-cmb.${MessengerInstanz[2]}`, "send", { text: combinedMessage }); break; case "Telegram": sendTo(`telegram.${MessengerInstanz[3]}`, "send", { text: combinedMessage, user: TelegramUser // Telegram User ID, um den Nachrichteneempfänger festzulegen }); break; case "Pushover": sendTo(`pushover.${MessengerInstanz[4]}`, "send", { message: combinedMessage, sound: "" }); break; case "Pushsafer": sendTo(`pushsafer.${MessengerInstanz[5]}`, "send", { message: combinedMessage, title: Headline }); break; default: log(`Unbekannter Service: ${service}`, "warn"); } } //----------------------------------------------------------------------------------------------------- // collectMessage Messxages werden in MessageSendCollector gesammelt //----------------------------------------------------------------------------------------------------- function collectMessage(messageType, Nachricht) { if (!MessageSendCollector.hasOwnProperty(messageType)) { MessageSendCollector[messageType] = []; } MessageSendCollector[messageType].push(Nachricht); } //----------------------------------------------------------------------------------------------------- // ReplaceString // ersetzen entsprechend tabelle replacements //----------------------------------------------------------------------------------------------------- function ReplaceString(string) { for (const [key, value] of Object.entries(replacements)) { // Escape den Punkt (.) für den regulären Ausdruck const escapedKey = key.replace('.', '\\.'); string = string.replace(new RegExp(escapedKey, 'g'), value); } return string; } //----------------------------------------------------------------------------------------------------- // func_get_datum aktuelles Datum formatiert //----------------------------------------------------------------------------------------------------- function func_get_datum(id) { // const datum = formatDate(getState(id).lc, "TT.MM.JJ SS:mm:ss"); const datum = formatDate(getState(id).ts, "TT.MM.JJ SS:mm:ss"); return datum < '01.01.71 01:00:00' ? '' : `${datum} Uhr`; } //----------------------------------------------------------------------------------------------------- // func_Batterie Batterieermittlung //----------------------------------------------------------------------------------------------------- function func_Batterie(native_type) { if(debugLevel >= 2) { log(`Routine func_Batterie wird ausgefuehrt`, "info");} const normalizedType = native_type.toUpperCase(); return Object.keys(batteryTypes).find(battery => batteryTypes[battery].some(device => device.toUpperCase() === normalizedType) ) || 'unbekannt'; } //----------------------------------------------------------------------------------------------------- // Funktion createJsonEntry erzeugen einer JSON Tabelle //----------------------------------------------------------------------------------------------------- function createJsonEntry(datum_seit, meldungsart, common_name, id_name, status, statusMessages, Batterie) { // Erstelle das JSON-Objekt return { datum_seit: datum_seit, meldungsart: meldungsart, common_name: common_name, id_name: id_name, status: status, status_message: statusMessages, batterie_bezeichnung: Batterie }; } //----------------------------------------------------------------------------------------------------- // Funktion schreibt einen Logeintrag in das Filesystem und auch in das interne Log-System (looxer) //----------------------------------------------------------------------------------------------------- function writelog(Name, id_name, SMType, SMStatus, SMStatus_Text) { if(debugLevel >= 2) { log(`Routine writelog wird ausgefuehrt`, "info");} const fs = require('fs'); // enable write fuer externes log if (!logflag) return; const logdate = formatDate(new Date(), "TT.MM.JJJJ"); const logtime = formatDate(new Date(), "SS:mm:ss"); const logEntry = `${logdate} ;${logtime} ;${Name} ;${id_name} ; ${SMType} ;${SMStatus} ;${SMStatus_Text}\n`; const headerLine = "Datum;Uhrzeit;Name;ID-Name;Meldungssart;Status;Servicemeldung\n"; fs.readFile(LogPath, 'utf8', function(err, data) { if (!err) { fs.appendFileSync(LogPath, logEntry, 'utf8'); } else { log("Logfile nicht gefunden - wird angelegt", "info"); fs.writeFileSync(LogPath, headerLine + logEntry, 'utf8'); } }); } //----------------------------------------------------------------------------------------------------- // Funktion zum Hinzufuegen einer neuen Zeile am Anfang des bestehenden State (looxer) //----------------------------------------------------------------------------------------------------- function appendToState(id, newText) { if(debugLevel >= 2) { log(`Routine appendToState wird ausgefuehrt`, "info");} const updatedText = newText + '<br>' + getState(id).val; setState(id, updatedText); } //----------------------------------------------------------------------------------------------------- // Funktion Create States //----------------------------------------------------------------------------------------------------- async function CreateStates(callback) { if (debugLevel >= 2) { log(`Routine CreateStates wird ausgefuehrt`, "info"); } try { await createStateAsync(id_Text_ServicemeldungLang, "", { read: true, write: true, type: 'string', name: 'Servicemeldungen LangText', desc: 'LangText Servicemeldung' }); await createStateAsync(id_Text_ServicemeldungKurz, "", { read: true, write: true, type: 'string', name: 'Servicemeldungen KurzText', desc: 'KurzText Servicemeldung' }); await createStateAsync(id_JSON_Servicemeldung_Aktuell, "", { read: true, write: true, type: 'string', name: 'Aktuelle Servicemeldungen als JSON', desc: 'Vergangene Servicemeldung JSON' }); await createStateAsync(id_JSON_Servicemeldung_Historie, "", { read: true, write: true, type: 'string', name: 'Servicemeldungen History', desc: 'History Servicemeldung' }); await createStateAsync(id_Text_Servicemeldung_History, "", { read: true, write: true, type: 'string', name: 'Servicemeldungen History', desc: 'History Servicemeldung' }); await createStateAsync(id_IST_Gesamt, 0, { read: true, write: true, type: 'number', name: 'Servicemeldungen Anzahl Total', desc: 'Anzahl Servicemeldungen' }); await createStateAsync(id_IST_SMAktuell, 0, { read: true, write: true, type: 'number', name: 'Servicemeldungen Anzahl Aktuelle SM', desc: 'Anzahl Aktuelle Servicemeldungen' }); await createStateAsync(id_IST_LOWBAT, 0, { read: true, write: true, type: 'number', name: 'Servicemeldungen Lowbat Anzahl Total', desc: 'Lowbat Anzahl Servicemeldungen' }); await createStateAsync(id_IST_UNREACH, 0, { read: true, write: true, type: 'number', name: 'Servicemeldungen Unreach Anzahl Total', desc: 'Unreach Anzahl Servicemeldungen' }); await createStateAsync(id_IST_STICKY_UNREACH, 0, { read: true, write: true, type: 'number', name: 'Servicemeldungen Sticky Unreach Anzahl Total', desc: 'Sticky Unreach Anzahl Servicemeldungen' }); await createStateAsync(id_IST_ERROR, 0, { read: true, write: true, type: 'number', name: 'Servicemeldungen ERROR Anzahl Total', desc: 'ERROR Anzahl Servicemeldungen' }); await createStateAsync(id_IST_CONFIG_PENDING, 0, { read: true, write: true, type: 'number', name: 'Servicemeldungen ausstehende Konfig Anzahl Total', desc: 'Ausstehende Konfig Anzahl Servicemeldungen' }); await createStateAsync(id_IST_UPDATE_PENDING, 0, { read: true, write: true, type: 'number', name: 'Servicemeldungen ausstehende Updates Anzahl Total', desc: 'Ausstehende Updates Anzahl Servicemeldungen' }); await createStateAsync(id_IST_DEVICE_IN_BOOTLOADER, 0, { read: true, write: true, type: 'number', name: 'Servicemeldungen DEVICE_IN_BOOTLOADER Anzahl Total', desc: 'DEVICE_IN_BOOTLOADER Anzahl Servicemeldungen' }); await createStateAsync(id_IST_ERROR_NON_FLAT_POSITIONING, 0, { read: true, write: true, type: 'number', name: 'Servicemeldungen ERROR_NON_FLAT_POSITIONING Anzahl Total', desc: 'ERROR_NON_FLAT_POSITIONING Anzahl Servicemeldungen' }); await createStateAsync(id_IST_FAULT_REPORTING, 0, { read: true, write: true, type: 'number', name: 'Servicemeldungen FAULT_REPORTING Anzahl Total', desc: 'FAULT_REPORTING Anzahl Servicemeldungen' }); await createStateAsync(id_IST_SABOTAGE, 0, { read: true, write: true, type: 'number', name: 'Servicemeldungen SABOTAGE Anzahl Total', desc: 'SABOTAGE Anzahl Servicemeldungen' }); await createStateAsync(id_IST_ERROR_REDUCED, 0, { read: true, write: true, type: 'number', name: 'Servicemeldungen ERROR_REDUCED Anzahl Total', desc: 'ERROR_REDUCED Anzahl Servicemeldungen' }); await createStateAsync(id_IST_STICKY_SABOTAGE, 0, { read: true, write: true, type: 'number', name: 'Servicemeldungen STICKY_SABOTAGE Anzahl Total', desc: 'STICKY_SABOTAGE Anzahl Servicemeldungen' }); await createStateAsync(id_IST_USBH_POWERFAIL , 0, { read: true, write: true, type: 'number', name: 'Servicemeldungen USBH_POWERFAIL Anzahl Total', desc: 'USBH_POWERFAIL Anzahl Servicemeldungen' }); await createStateAsync(id_IST_U_SOURCE_FAIL, 0, { read: true, write: true, type: 'number', name: 'Servicemeldungen SOURCE_FAIL Anzahl Total', desc: 'SOURCE_FAIL Servicemeldungen' }); // Aufruf des Callbacks nach Abschluss aller Operationen if (callback) await callback(); } catch (error) { log(`Routine Create States - Fehler beim Erstellen der Zustaende: ${error}`, "warn"); } }