Skip to content
  • Home
  • Aktuell
  • Tags
  • 0 Ungelesen 0
  • Kategorien
  • Unreplied
  • Beliebt
  • GitHub
  • Docu
  • Hilfe
Skins
  • Light
  • Brite
  • Cerulean
  • Cosmo
  • Flatly
  • Journal
  • Litera
  • Lumen
  • Lux
  • Materia
  • Minty
  • Morph
  • Pulse
  • Sandstone
  • Simplex
  • Sketchy
  • Spacelab
  • United
  • Yeti
  • Zephyr
  • Dark
  • Cyborg
  • Darkly
  • Quartz
  • Slate
  • Solar
  • Superhero
  • Vapor

  • Standard: (Kein Skin)
  • Kein Skin
Einklappen
ioBroker Logo

Community Forum

donate donate
  1. ioBroker Community Home
  2. Deutsch
  3. Skripten / Logik
  4. [Vorlage] Servicemeldungen Volume2

NEWS

  • UPDATE 31.10.: Amazon Alexa - ioBroker Skill läuft aus ?
    apollon77A
    apollon77
    48
    3
    8.8k

  • Monatsrückblick – September 2025
    BluefoxB
    Bluefox
    13
    1
    2.2k

  • Neues Video "KI im Smart Home" - ioBroker plus n8n
    BluefoxB
    Bluefox
    16
    1
    3.2k

[Vorlage] Servicemeldungen Volume2

Geplant Angeheftet Gesperrt Verschoben Skripten / Logik
224 Beiträge 14 Kommentatoren 44.4k Aufrufe 24 Watching
  • Älteste zuerst
  • Neuste zuerst
  • Meiste Stimmen
Antworten
  • In einem neuen Thema antworten
Anmelden zum Antworten
Dieses Thema wurde gelöscht. Nur Nutzer mit entsprechenden Rechten können es sehen.
  • flkontaktF Online
    flkontaktF Online
    flkontakt
    schrieb am zuletzt editiert von
    #68

    hier die Infos, kannst du damit etwas anfangen?

    javascript.0.ServicemeldungenVol2.json

    hm.JPG

    // 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");
        }
    }
    
    L 2 Antworten Letzte Antwort
    0
    • flkontaktF flkontakt

      hier die Infos, kannst du damit etwas anfangen?

      javascript.0.ServicemeldungenVol2.json

      hm.JPG

      // 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");
          }
      }
      
      L Offline
      L Offline
      looxer01
      schrieb am zuletzt editiert von looxer01
      #69

      @flkontakt
      Hi,
      vielen Dank fuer deine Geduld.
      Es könnte möglich sein, dass der Fehler mit deiner Umgebung zu tun hat bzw augenblicklichen Set-Up.
      Mögliche Fehlerquellen

      • Deine Node-JS Version untestützt das Statement "continue" in forEach nicht
        Ich habe daher den Code umgeschrieben und eine Standard Schleife verwendet
      • Es gibt ein Problem bei einer oder mehreren Geräte-IDs in deinem ioBroker
        Ich habe einen Check eingebaut, der die jeweilige ID mit einer Warnmeldung überspringen sollte
        Wenn dies der Fall sein sollte, dann sollte ein Neustart von HM-Rega und RPC Instanzen helfen (oder neustart ioBroker)
        aber bitte voher das neue Script (version 1.10 ) checken. und dann erst die vorgenannten aktionen umsetzen

      neue Version folgt.

      lets check.

      vG Looxer

      EDIT:
      aaah gerade gesehen du verwendest CuxD. und hast wired.
      versuche bitte folgende Einstellungen:
      const HMClassicInstanz = 0;
      const HMIPInstanz = 2;

      EDIT2
      koenntest du mir sagen welche Servicemeldungen generell fuer Wired Geraete in Frage kommen ?
      z.B. keine LowBat
      oder keine UNREACH
      überhaupt irgendwelche ?

      flkontaktF 1 Antwort Letzte Antwort
      0
      • L Offline
        L Offline
        looxer01
        schrieb am zuletzt editiert von
        #70

        Version 1.10 ist online

        • CheckAll Schleife geaendert und ForEach ersetzt
        • Versuch der Behandlung von Fehlern, wenn die ID nicht existiert
        • Log fuer DebugLevel1 angepasst

        vG Looxer

        1 Antwort Letzte Antwort
        0
        • L Offline
          L Offline
          looxer01
          schrieb am zuletzt editiert von
          #71

          Version 1.11 ist online

          • Instanz Wired hinzugefuegt
          • Instanzen koennen jetzt eingestellt werden:
            const HMClassicInstanz = 0;
            const HMIPInstanz = 1;
            const GruppenInstanz = 9; // 9 = nicht relevant
            const WiredInstanz = 9; // 9 = nicht relevant

          vG Looxer

          1 Antwort Letzte Antwort
          0
          • flkontaktF flkontakt

            hier die Infos, kannst du damit etwas anfangen?

            javascript.0.ServicemeldungenVol2.json

            hm.JPG

            // 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");
                }
            }
            
            L Offline
            L Offline
            looxer01
            schrieb am zuletzt editiert von looxer01
            #72

            @flkontakt
            Bitte nutze Version 1.11
            Wired war bisher nicht berücksichtig. Dafür habe ich eine eigene Einstellung hinzugefügt.
            Ich bin nicht sicher, ob es überhaupt Servicemeldungen gibt. Dafür bräuchte ich deine Hilfe das herauszufinden und natürlich welche das sind. Dafür wären die Datenstrukturen für Wired hilfreich. Aso gibt es datenpunkte für:

            LOWBAT
            UNREACH
            STICKY_UNREACH
            CONFIG_PENDING
            UPDATE_PENDING
            DEVICE_IN_BOOTLOADER
            ERROR
            ERROR_NON_FLAT_POSITIONING
            FAULT_REPORTING
            SABOTAGE (ist wahrscheinlich relevant)
            ERROR_REDUCED
            STICKY_SABOTAGE
            USBH_POWERFAIL
            U_SOURCE_FAIL

            Wenn ich weiß welche Datenpunke es fuer Alarm-Situationen gibt, dann kann ich das Coding für Wired entsprechend anpassen.
            Trotzdem sollte die 1.11 schon einigermaßen laufen.

            vG Looxer

            flkontaktF Z 2 Antworten Letzte Antwort
            0
            • L looxer01

              @flkontakt
              Hi,
              vielen Dank fuer deine Geduld.
              Es könnte möglich sein, dass der Fehler mit deiner Umgebung zu tun hat bzw augenblicklichen Set-Up.
              Mögliche Fehlerquellen

              • Deine Node-JS Version untestützt das Statement "continue" in forEach nicht
                Ich habe daher den Code umgeschrieben und eine Standard Schleife verwendet
              • Es gibt ein Problem bei einer oder mehreren Geräte-IDs in deinem ioBroker
                Ich habe einen Check eingebaut, der die jeweilige ID mit einer Warnmeldung überspringen sollte
                Wenn dies der Fall sein sollte, dann sollte ein Neustart von HM-Rega und RPC Instanzen helfen (oder neustart ioBroker)
                aber bitte voher das neue Script (version 1.10 ) checken. und dann erst die vorgenannten aktionen umsetzen

              neue Version folgt.

              lets check.

              vG Looxer

              EDIT:
              aaah gerade gesehen du verwendest CuxD. und hast wired.
              versuche bitte folgende Einstellungen:
              const HMClassicInstanz = 0;
              const HMIPInstanz = 2;

              EDIT2
              koenntest du mir sagen welche Servicemeldungen generell fuer Wired Geraete in Frage kommen ?
              z.B. keine LowBat
              oder keine UNREACH
              überhaupt irgendwelche ?

              flkontaktF Online
              flkontaktF Online
              flkontakt
              schrieb am zuletzt editiert von
              #73

              @looxer01 vielen Dank für deine Unterstützung!!!

              Hier die aktuelle Situation mit Version 1.11:

              -habe Debug im Sript ausgeschaltet, Sabotage am Fensterkontakt erhöht DP um 1, Rücknahme der Sabotage Reduzierung DP um 1. Funktioniert mit dem ersten Test soweit

              -DP Anzahl Gesamt zeigt >450 an, auch nach Neustart der Instanzen und CCU2

              -neue Fehlermeldungen im Log, dich ich bisher nicht hatte

              Frage: müsste ich meine HM-Einstellungen so anpassen?

              const HMClassicInstanz = 0;
              const HMIPInstanz = 1; (bei mir Cuxd)
              const GruppenInstanz = 3; (bei mir die Heizungsgruppen)
              const WiredInstanz = 2; (bei mir Wired)

              17.11.2024, 13:03:22.977	[warn ]: javascript.0 (1291461) script.js.Telegram_Meldungen.Fehlermeldungen: Routine Check_All - Geraet LEQ1243126 scheint zwischenzeitlich nicht mehr zu existieren - Empfehlung: script neu starten
              17.11.2024, 13:03:22.978	[warn ]: javascript.0 (1291461) script.js.Telegram_Meldungen.Fehlermeldungen: Routine Check_All - Geraet LEQ1252005 scheint zwischenzeitlich nicht mehr zu existieren - Empfehlung: script neu starten
              17.11.2024, 13:03:22.978	[warn ]: javascript.0 (1291461) script.js.Telegram_Meldungen.Fehlermeldungen: Routine Check_All - Geraet LEQ1253456 scheint zwischenzeitlich nicht mehr zu existieren - Empfehlung: script neu starten
              17.11.2024, 13:03:22.978	[warn ]: javascript.0 (1291461) script.js.Telegram_Meldungen.Fehlermeldungen: Routine Check_All - Geraet MEQ0221223 scheint zwischenzeitlich nicht mehr zu existieren - Empfehlung: script neu starten
              17.11.2024, 13:03:22.978	[warn ]: javascript.0 (1291461) script.js.Telegram_Meldungen.Fehlermeldungen: Routine Check_All - Geraet MEQ0221247 scheint zwischenzeitlich nicht mehr zu existieren - Empfehlung: script neu starten
              17.11.2024, 13:03:22.978	[warn ]: javascript.0 (1291461) script.js.Telegram_Meldungen.Fehlermeldungen: Routine Check_All - Geraet MEQ0221526 scheint zwischenzeitlich nicht mehr zu existieren - Empfehlung: script neu starten
              17.11.2024, 13:03:22.978	[warn ]: javascript.0 (1291461) script.js.Telegram_Meldungen.Fehlermeldungen: Routine Check_All - Geraet MEQ0221931 scheint zwischenzeitlich nicht mehr zu existieren - Empfehlung: script neu starten
              17.11.2024, 13:03:22.978	[warn ]: javascript.0 (1291461) script.js.Telegram_Meldungen.Fehlermeldungen: Routine Check_All - Geraet MEQ0222793 scheint zwischenzeitlich nicht mehr zu existieren - Empfehlung: script neu starten
              17.11.2024, 13:03:22.978	[warn ]: javascript.0 (1291461) script.js.Telegram_Meldungen.Fehlermeldungen: Routine Check_All - Geraet MEQ1830183 scheint zwischenzeitlich nicht mehr zu existieren - Empfehlung: script neu starten
              17.11.2024, 13:03:22.978	[warn ]: javascript.0 (1291461) script.js.Telegram_Meldungen.Fehlermeldungen: Routine Check_All - Geraet MEQ1830566 scheint zwischenzeitlich nicht mehr zu existieren - Empfehlung: script neu starten
              17.11.2024, 13:03:22.978	[warn ]: javascript.0 (1291461) script.js.Telegram_Meldungen.Fehlermeldungen: Routine Check_All - Geraet MEQ1830568 scheint zwischenzeitlich nicht mehr zu existieren - Empfehlung: script neu starten
              17.11.2024, 13:03:22.978	[warn ]: javascript.0 (1291461) script.js.Telegram_Meldungen.Fehlermeldungen: Routine Check_All - Geraet MEQ1830581 scheint zwischenzeitlich nicht mehr zu existieren - Empfehlung: script neu starten
              17.11.2024, 13:03:53.077	[warn ]: javascript.0 (1291461) script.js.Telegram_Meldungen.Fehlermeldungen: Routine Check_All - Geraet LEQ1243126 scheint zwischenzeitlich nicht mehr zu existieren - Empfehlung: script neu starten
              17.11.2024, 13:03:53.078	[warn ]: javascript.0 (1291461) script.js.Telegram_Meldungen.Fehlermeldungen: Routine Check_All - Geraet LEQ1252005 scheint zwischenzeitlich nicht mehr zu existieren - Empfehlung: script neu starten
              17.11.2024, 13:03:53.078	[warn ]: javascript.0 (1291461) script.js.Telegram_Meldungen.Fehlermeldungen: Routine Check_All - Geraet LEQ1253456 scheint zwischenzeitlich nicht mehr zu existieren - Empfehlung: script neu starten
              17.11.2024, 13:03:53.078	[warn ]: javascript.0 (1291461) script.js.Telegram_Meldungen.Fehlermeldungen: Routine Check_All - Geraet MEQ0221223 scheint zwischenzeitlich nicht mehr zu existieren - Empfehlung: script neu starten
              17.11.2024, 13:03:53.078	[warn ]: javascript.0 (1291461) script.js.Telegram_Meldungen.Fehlermeldungen: Routine Check_All - Geraet MEQ0221247 scheint zwischenzeitlich nicht mehr zu existieren - Empfehlung: script neu starten
              17.11.2024, 13:03:53.078	[warn ]: javascript.0 (1291461) script.js.Telegram_Meldungen.Fehlermeldungen: Routine Check_All - Geraet MEQ0221526 scheint zwischenzeitlich nicht mehr zu existieren - Empfehlung: script neu starten
              17.11.2024, 13:03:53.078	[warn ]: javascript.0 (1291461) script.js.Telegram_Meldungen.Fehlermeldungen: Routine Check_All - Geraet MEQ0221931 scheint zwischenzeitlich nicht mehr zu existieren - Empfehlung: script neu starten
              17.11.2024, 13:03:53.078	[warn ]: javascript.0 (1291461) script.js.Telegram_Meldungen.Fehlermeldungen: Routine Check_All - Geraet MEQ0222793 scheint zwischenzeitlich nicht mehr zu existieren - Empfehlung: script neu starten
              17.11.2024, 13:03:53.078	[warn ]: javascript.0 (1291461) script.js.Telegram_Meldungen.Fehlermeldungen: Routine Check_All - Geraet MEQ1830183 scheint zwischenzeitlich nicht mehr zu existieren - Empfehlung: script neu starten
              17.11.2024, 13:03:53.078	[warn ]: javascript.0 (1291461) script.js.Telegram_Meldungen.Fehlermeldungen: Routine Check_All - Geraet MEQ1830566 scheint zwischenzeitlich nicht mehr zu existieren - Empfehlung: script neu starten
              17.11.2024, 13:03:53.078	[warn ]: javascript.0 (1291461) script.js.Telegram_Meldungen.Fehlermeldungen: Routine Check_All - Geraet MEQ1830568 scheint zwischenzeitlich nicht mehr zu existieren - Empfehlung: script neu starten
              17.11.2024, 13:03:53.078	[warn ]: javascript.0 (1291461) script.js.Telegram_Meldungen.Fehlermeldungen: Routine Check_All - Geraet MEQ1830581 scheint zwischenzeitlich nicht mehr zu existieren - Empfehlung: script neu starten
              

              Anzahl.JPG

              L 1 Antwort Letzte Antwort
              0
              • L looxer01

                @flkontakt
                Bitte nutze Version 1.11
                Wired war bisher nicht berücksichtig. Dafür habe ich eine eigene Einstellung hinzugefügt.
                Ich bin nicht sicher, ob es überhaupt Servicemeldungen gibt. Dafür bräuchte ich deine Hilfe das herauszufinden und natürlich welche das sind. Dafür wären die Datenstrukturen für Wired hilfreich. Aso gibt es datenpunkte für:

                LOWBAT
                UNREACH
                STICKY_UNREACH
                CONFIG_PENDING
                UPDATE_PENDING
                DEVICE_IN_BOOTLOADER
                ERROR
                ERROR_NON_FLAT_POSITIONING
                FAULT_REPORTING
                SABOTAGE (ist wahrscheinlich relevant)
                ERROR_REDUCED
                STICKY_SABOTAGE
                USBH_POWERFAIL
                U_SOURCE_FAIL

                Wenn ich weiß welche Datenpunke es fuer Alarm-Situationen gibt, dann kann ich das Coding für Wired entsprechend anpassen.
                Trotzdem sollte die 1.11 schon einigermaßen laufen.

                vG Looxer

                flkontaktF Online
                flkontaktF Online
                flkontakt
                schrieb am zuletzt editiert von
                #74

                @looxer01 hm-rpc.2.LEQ0117581.0.json

                1 Antwort Letzte Antwort
                0
                • flkontaktF flkontakt

                  @looxer01 vielen Dank für deine Unterstützung!!!

                  Hier die aktuelle Situation mit Version 1.11:

                  -habe Debug im Sript ausgeschaltet, Sabotage am Fensterkontakt erhöht DP um 1, Rücknahme der Sabotage Reduzierung DP um 1. Funktioniert mit dem ersten Test soweit

                  -DP Anzahl Gesamt zeigt >450 an, auch nach Neustart der Instanzen und CCU2

                  -neue Fehlermeldungen im Log, dich ich bisher nicht hatte

                  Frage: müsste ich meine HM-Einstellungen so anpassen?

                  const HMClassicInstanz = 0;
                  const HMIPInstanz = 1; (bei mir Cuxd)
                  const GruppenInstanz = 3; (bei mir die Heizungsgruppen)
                  const WiredInstanz = 2; (bei mir Wired)

                  17.11.2024, 13:03:22.977	[warn ]: javascript.0 (1291461) script.js.Telegram_Meldungen.Fehlermeldungen: Routine Check_All - Geraet LEQ1243126 scheint zwischenzeitlich nicht mehr zu existieren - Empfehlung: script neu starten
                  17.11.2024, 13:03:22.978	[warn ]: javascript.0 (1291461) script.js.Telegram_Meldungen.Fehlermeldungen: Routine Check_All - Geraet LEQ1252005 scheint zwischenzeitlich nicht mehr zu existieren - Empfehlung: script neu starten
                  17.11.2024, 13:03:22.978	[warn ]: javascript.0 (1291461) script.js.Telegram_Meldungen.Fehlermeldungen: Routine Check_All - Geraet LEQ1253456 scheint zwischenzeitlich nicht mehr zu existieren - Empfehlung: script neu starten
                  17.11.2024, 13:03:22.978	[warn ]: javascript.0 (1291461) script.js.Telegram_Meldungen.Fehlermeldungen: Routine Check_All - Geraet MEQ0221223 scheint zwischenzeitlich nicht mehr zu existieren - Empfehlung: script neu starten
                  17.11.2024, 13:03:22.978	[warn ]: javascript.0 (1291461) script.js.Telegram_Meldungen.Fehlermeldungen: Routine Check_All - Geraet MEQ0221247 scheint zwischenzeitlich nicht mehr zu existieren - Empfehlung: script neu starten
                  17.11.2024, 13:03:22.978	[warn ]: javascript.0 (1291461) script.js.Telegram_Meldungen.Fehlermeldungen: Routine Check_All - Geraet MEQ0221526 scheint zwischenzeitlich nicht mehr zu existieren - Empfehlung: script neu starten
                  17.11.2024, 13:03:22.978	[warn ]: javascript.0 (1291461) script.js.Telegram_Meldungen.Fehlermeldungen: Routine Check_All - Geraet MEQ0221931 scheint zwischenzeitlich nicht mehr zu existieren - Empfehlung: script neu starten
                  17.11.2024, 13:03:22.978	[warn ]: javascript.0 (1291461) script.js.Telegram_Meldungen.Fehlermeldungen: Routine Check_All - Geraet MEQ0222793 scheint zwischenzeitlich nicht mehr zu existieren - Empfehlung: script neu starten
                  17.11.2024, 13:03:22.978	[warn ]: javascript.0 (1291461) script.js.Telegram_Meldungen.Fehlermeldungen: Routine Check_All - Geraet MEQ1830183 scheint zwischenzeitlich nicht mehr zu existieren - Empfehlung: script neu starten
                  17.11.2024, 13:03:22.978	[warn ]: javascript.0 (1291461) script.js.Telegram_Meldungen.Fehlermeldungen: Routine Check_All - Geraet MEQ1830566 scheint zwischenzeitlich nicht mehr zu existieren - Empfehlung: script neu starten
                  17.11.2024, 13:03:22.978	[warn ]: javascript.0 (1291461) script.js.Telegram_Meldungen.Fehlermeldungen: Routine Check_All - Geraet MEQ1830568 scheint zwischenzeitlich nicht mehr zu existieren - Empfehlung: script neu starten
                  17.11.2024, 13:03:22.978	[warn ]: javascript.0 (1291461) script.js.Telegram_Meldungen.Fehlermeldungen: Routine Check_All - Geraet MEQ1830581 scheint zwischenzeitlich nicht mehr zu existieren - Empfehlung: script neu starten
                  17.11.2024, 13:03:53.077	[warn ]: javascript.0 (1291461) script.js.Telegram_Meldungen.Fehlermeldungen: Routine Check_All - Geraet LEQ1243126 scheint zwischenzeitlich nicht mehr zu existieren - Empfehlung: script neu starten
                  17.11.2024, 13:03:53.078	[warn ]: javascript.0 (1291461) script.js.Telegram_Meldungen.Fehlermeldungen: Routine Check_All - Geraet LEQ1252005 scheint zwischenzeitlich nicht mehr zu existieren - Empfehlung: script neu starten
                  17.11.2024, 13:03:53.078	[warn ]: javascript.0 (1291461) script.js.Telegram_Meldungen.Fehlermeldungen: Routine Check_All - Geraet LEQ1253456 scheint zwischenzeitlich nicht mehr zu existieren - Empfehlung: script neu starten
                  17.11.2024, 13:03:53.078	[warn ]: javascript.0 (1291461) script.js.Telegram_Meldungen.Fehlermeldungen: Routine Check_All - Geraet MEQ0221223 scheint zwischenzeitlich nicht mehr zu existieren - Empfehlung: script neu starten
                  17.11.2024, 13:03:53.078	[warn ]: javascript.0 (1291461) script.js.Telegram_Meldungen.Fehlermeldungen: Routine Check_All - Geraet MEQ0221247 scheint zwischenzeitlich nicht mehr zu existieren - Empfehlung: script neu starten
                  17.11.2024, 13:03:53.078	[warn ]: javascript.0 (1291461) script.js.Telegram_Meldungen.Fehlermeldungen: Routine Check_All - Geraet MEQ0221526 scheint zwischenzeitlich nicht mehr zu existieren - Empfehlung: script neu starten
                  17.11.2024, 13:03:53.078	[warn ]: javascript.0 (1291461) script.js.Telegram_Meldungen.Fehlermeldungen: Routine Check_All - Geraet MEQ0221931 scheint zwischenzeitlich nicht mehr zu existieren - Empfehlung: script neu starten
                  17.11.2024, 13:03:53.078	[warn ]: javascript.0 (1291461) script.js.Telegram_Meldungen.Fehlermeldungen: Routine Check_All - Geraet MEQ0222793 scheint zwischenzeitlich nicht mehr zu existieren - Empfehlung: script neu starten
                  17.11.2024, 13:03:53.078	[warn ]: javascript.0 (1291461) script.js.Telegram_Meldungen.Fehlermeldungen: Routine Check_All - Geraet MEQ1830183 scheint zwischenzeitlich nicht mehr zu existieren - Empfehlung: script neu starten
                  17.11.2024, 13:03:53.078	[warn ]: javascript.0 (1291461) script.js.Telegram_Meldungen.Fehlermeldungen: Routine Check_All - Geraet MEQ1830566 scheint zwischenzeitlich nicht mehr zu existieren - Empfehlung: script neu starten
                  17.11.2024, 13:03:53.078	[warn ]: javascript.0 (1291461) script.js.Telegram_Meldungen.Fehlermeldungen: Routine Check_All - Geraet MEQ1830568 scheint zwischenzeitlich nicht mehr zu existieren - Empfehlung: script neu starten
                  17.11.2024, 13:03:53.078	[warn ]: javascript.0 (1291461) script.js.Telegram_Meldungen.Fehlermeldungen: Routine Check_All - Geraet MEQ1830581 scheint zwischenzeitlich nicht mehr zu existieren - Empfehlung: script neu starten
                  

                  Anzahl.JPG

                  L Offline
                  L Offline
                  looxer01
                  schrieb am zuletzt editiert von
                  #75

                  @flkontakt sagte in [Vorlage] Servicemeldungen Volume2:

                  Frage: müsste ich meine HM-Einstellungen so anpassen?
                  const HMClassicInstanz = 0;
                  const HMIPInstanz = 1; (bei mir Cuxd)
                  const GruppenInstanz = 3; (bei mir die Heizungsgruppen)
                  const WiredInstanz = 2; (bei mir Wired)

                  Hi,

                  bitte erstmal so einstellen:

                  const HMClassicInstanz = 0;
                  const HMIPInstanz = 9
                  const GruppenInstanz = 9
                  const WiredInstanz = 9

                  Bitte so einstellen. Wired erstmal rauslassen und Gruppen brauchst du nicht und IP hast du nicht.
                  Für wired muss ich noch eine neue Version machen, aufgrund deiner Infos. Wenn die da ist, dann kannst du
                  wiredInstanz auf 2 stellen.

                  vG Looxer

                  flkontaktF 1 Antwort Letzte Antwort
                  0
                  • L looxer01

                    @flkontakt
                    Bitte nutze Version 1.11
                    Wired war bisher nicht berücksichtig. Dafür habe ich eine eigene Einstellung hinzugefügt.
                    Ich bin nicht sicher, ob es überhaupt Servicemeldungen gibt. Dafür bräuchte ich deine Hilfe das herauszufinden und natürlich welche das sind. Dafür wären die Datenstrukturen für Wired hilfreich. Aso gibt es datenpunkte für:

                    LOWBAT
                    UNREACH
                    STICKY_UNREACH
                    CONFIG_PENDING
                    UPDATE_PENDING
                    DEVICE_IN_BOOTLOADER
                    ERROR
                    ERROR_NON_FLAT_POSITIONING
                    FAULT_REPORTING
                    SABOTAGE (ist wahrscheinlich relevant)
                    ERROR_REDUCED
                    STICKY_SABOTAGE
                    USBH_POWERFAIL
                    U_SOURCE_FAIL

                    Wenn ich weiß welche Datenpunke es fuer Alarm-Situationen gibt, dann kann ich das Coding für Wired entsprechend anpassen.
                    Trotzdem sollte die 1.11 schon einigermaßen laufen.

                    vG Looxer

                    Z Offline
                    Z Offline
                    zahnheinrich
                    schrieb am zuletzt editiert von
                    #76

                    @looxer01
                    Datenpunkte HM wired alt:

                    Screenshot (6).png

                    Datenpunkte HM wired neu:

                    Screenshot (7).png

                    Vielen Dank für das tolle script!!

                    Ulrich

                    MfG Ulrich

                    1 Antwort Letzte Antwort
                    0
                    • L Offline
                      L Offline
                      looxer01
                      schrieb am zuletzt editiert von
                      #77

                      super, vielen Dank für die Infos. Habe ich auch gleich eingebaut.
                      Testen kann ich ja leider nicht. Ich hoffe, dass es jetzt bei euch läuft.
                      Ich habe auch Overheat_Alarm und under_voltage Alarm für die HMIP/Classic Geräte gleich mit eingebaut

                      Script kommt gleich

                      vG Looxer

                      Z 1 Antwort Letzte Antwort
                      0
                      • L Offline
                        L Offline
                        looxer01
                        schrieb am zuletzt editiert von
                        #78

                        Version 1.12 ist online

                        • Für Wired sind die jetzt bekannten Alarme hinzugefügt
                        • für HMIP und Classic sind die Alarme erweitert auf Overheat und Undervoltage

                        vG Looxer

                        1 Antwort Letzte Antwort
                        0
                        • L looxer01

                          @flkontakt sagte in [Vorlage] Servicemeldungen Volume2:

                          Frage: müsste ich meine HM-Einstellungen so anpassen?
                          const HMClassicInstanz = 0;
                          const HMIPInstanz = 1; (bei mir Cuxd)
                          const GruppenInstanz = 3; (bei mir die Heizungsgruppen)
                          const WiredInstanz = 2; (bei mir Wired)

                          Hi,

                          bitte erstmal so einstellen:

                          const HMClassicInstanz = 0;
                          const HMIPInstanz = 9
                          const GruppenInstanz = 9
                          const WiredInstanz = 9

                          Bitte so einstellen. Wired erstmal rauslassen und Gruppen brauchst du nicht und IP hast du nicht.
                          Für wired muss ich noch eine neue Version machen, aufgrund deiner Infos. Wenn die da ist, dann kannst du
                          wiredInstanz auf 2 stellen.

                          vG Looxer

                          flkontaktF Online
                          flkontaktF Online
                          flkontakt
                          schrieb am zuletzt editiert von
                          #79

                          @looxer01 nochmal vielen Dank für den tollen Support, Script läuft soweit stabil. Kann man ggf. noch einstellen, dass z.B. per Telegram nur der TextKurzAktuelleSM übermittelt wird? Siehe auch Bild, hier würde mir der Kurztext reichen, Details lasse ich mir dann per JSON in Jarvis anzeigen.

                          Telegram.JPG

                          L 1 Antwort Letzte Antwort
                          0
                          • L looxer01

                            super, vielen Dank für die Infos. Habe ich auch gleich eingebaut.
                            Testen kann ich ja leider nicht. Ich hoffe, dass es jetzt bei euch läuft.
                            Ich habe auch Overheat_Alarm und under_voltage Alarm für die HMIP/Classic Geräte gleich mit eingebaut

                            Script kommt gleich

                            vG Looxer

                            Z Offline
                            Z Offline
                            zahnheinrich
                            schrieb am zuletzt editiert von
                            #80

                            @looxer01
                            Bei HM classic wired gibt es NUR die 6 Datenpunkte, welche ich oben gepostet habe, also nix undervoltage usw...

                            MfG Ulrich

                            L 1 Antwort Letzte Antwort
                            0
                            • flkontaktF flkontakt

                              @looxer01 nochmal vielen Dank für den tollen Support, Script läuft soweit stabil. Kann man ggf. noch einstellen, dass z.B. per Telegram nur der TextKurzAktuelleSM übermittelt wird? Siehe auch Bild, hier würde mir der Kurztext reichen, Details lasse ich mir dann per JSON in Jarvis anzeigen.

                              Telegram.JPG

                              L Offline
                              L Offline
                              looxer01
                              schrieb am zuletzt editiert von
                              #81

                              @flkontakt
                              Hi,
                              vielen Dank für die Rückmeldung. Freut mich, dass es zunächst mal läuft.
                              Das mit dem Kurztext hatte ich schon auf der Liste. Dauert aber noch etwas.

                              vG Looxer

                              flkontaktF 1 Antwort Letzte Antwort
                              0
                              • Z zahnheinrich

                                @looxer01
                                Bei HM classic wired gibt es NUR die 6 Datenpunkte, welche ich oben gepostet habe, also nix undervoltage usw...

                                L Offline
                                L Offline
                                looxer01
                                schrieb am zuletzt editiert von looxer01
                                #82

                                @zahnheinrich
                                bei HMIPW hast du im screen print einmal "Error_Undervoltage_Alarm"

                                Frage:
                                gibt es bei HM wired auch 2 instanzen, also je eine für HM-Classic und eine fuer HMIP?
                                Das wäre ja noch gar nicht eingebaut.

                                vG Looxer

                                Z 1 Antwort Letzte Antwort
                                0
                                • L looxer01

                                  @flkontakt
                                  Hi,
                                  vielen Dank für die Rückmeldung. Freut mich, dass es zunächst mal läuft.
                                  Das mit dem Kurztext hatte ich schon auf der Liste. Dauert aber noch etwas.

                                  vG Looxer

                                  flkontaktF Online
                                  flkontaktF Online
                                  flkontakt
                                  schrieb am zuletzt editiert von
                                  #83

                                  @looxer01 :+1: :santa:

                                  1 Antwort Letzte Antwort
                                  0
                                  • L looxer01

                                    Hi,
                                    Das vorliegende Script logged Servicemeldungen von der CCU/AccessPoint/HCU-

                                    Für welche Umgebungen eignet sich das Skript?

                                    • CCU (bzw. Raspberry Pi-Ersatz)
                                    • CCU FUNK
                                    • CCU Wired
                                    • HMIP Access Point (Achtung: „GeraeteIDTrigger“ muss auf „true“ gesetzt sein)
                                    • HMIP HCU Cloud (Achtung: „GeraeteIDTrigger“ muss auf „true“ gesetzt sein)

                                    Es handelt sich dabei nicht um ein „entweder-oder“ – die Instanzen werden parallel überwacht.

                                    Was kann das Skript?

                                    • Überprüfung der Servicemeldungen: Das Skript prüft, ob Servicemeldungen vorliegen.
                                    • Speicherung der Servicemeldungen: Servicemeldungen werden in Lang- und Kurztexten (Text, JSON, HTML) gespeichert.
                                    • Zählung von Servicemeldungen: Es werden Zählungen nach Meldungsarten und insgesamt gespeichert.
                                    • Erstellung der erforderlichen Datenpunkte: Das Skript legt automatisch die notwendigen Datenpunkte an.
                                    • Reaktion auf Geräteänderungen: Es reagiert entweder auf Veränderungen auf Geräteebene (viele Subscriptions – z.B. 298 bei 80 Geräten) oder, standardmäßig, auf Veränderungen der Anzahl der in der CCU gemeldeten Servicemeldungen (1 Subscription)
                                    • Historie: Es wird eine Historie geführt, die auch zeigt, wann Servicemeldungen wieder aufgehoben wurden.
                                    • HMIP Access Point/HCU Support: Wenn der Access Point genutzt wird, muss auf die Geräte-ID getriggert werden (da der REGA-Datenpunkt fehlt).
                                    • Externe Log-Datei: Es kann ein externes Log im Excel-Format fortgeschrieben werden. Hierin werden alle Servicemeldungen langfristig fortgeschrieben
                                    • Heizungsgruppenmeldungen: Heizungsgruppenmeldungen sind standardmäßig deaktiviert. Sie können jedoch bei Bedarf aktiviert werden.
                                    • Servicemeldungen Bestätigung: Das Skript bestätigt auf Wunsch CCU Servicemeldungen.
                                    • Flexible Messaging Services: Es können email', 'whatsApp', 'Signal','Telegram', 'Pushover', 'Pushsafer oder auch SPRACHE zum versenden von Servicemeldungen eingestellt werden. Das Versenden kann per MessageType vereinbart werden.
                                    • Flexibles Tabellenwerk: Anpassungen für z.B. neue MessageTypes von Servicemeldungen bei neuen Geräten können ohne Programmierung im Tabellenwerk konfiguriert werden

                                    Einfache Nutzung: Das Skript ist sofort lauffähig, vorausgesetzt, die Instanzen (CCU etc.) sind korrekt eingerichtet.
                                    Das Skript arbeitet in der aktuellen Version stabil und zuverlässig.

                                    Zusätzliche Hinweise:

                                    In der Standardkonfiguration des Skripts werden 2 Subscriptions und 1 Schedule erstellt.
                                    Ich verwende das Skript mit einer Subscription auf Ebene Einzel-ID (Einstellung „GeraeteIDTrigger“). Bei dieser Konfiguration wird eine Warnung im Log angezeigt, wenn mehr als 100 Subscriptions von dem Servicemeldungs-Skript erstellt werden.
                                    Diese Grenze kann in den „Instanzen JavaScript“-Einstellungen angepasst werden. Für diesen Anwendungsfall sind keine Performance-Probleme zu erwarten.
                                    Channel Selector: Das Skript verwendet statische Channel-Selector. Das bedeutet, dass Änderungen an den Datenstrukturen durch die CCU (z.B. das Löschen oder Hinzufügen von Geräten) nicht bekannt sind, solange das Skript nicht neu gestartet wird.
                                    Falls Geräte hinzugefügt oder gelöscht werden, muss das Skript neu gestartet werden.

                                    und hier das Script:
                                    Servicemeldungen_Vol2_3-32.txt

                                    Dazu stelle ich zwei Views für VIS zur Verfügung:
                                    Screenshot 2025-01-24 211730.png
                                    Den View gibt es für das JSON Format also auch für das HTML Format. Beide sehen weitestgehend identisch aus

                                    1. JSON View: Diese View ist für die Darstellung der JSON-Datenpunkte gedacht. Die Datenpunkte sind auf „javascript.0....“ ausgerichtet, was ggf. angepasst werden muss. Die View kann in VIS über „view importieren“ geladen werden. Der Inventwo-Adapter muss installiert sein. Falls du VIS2 nutzt, empfiehlt sich momentan die HTML-Variante.
                                      View_SM_JSON.txt

                                    2. HTML View: Diese View zeigt die HTML-Datenpunkte an. Auch hier müssen die Datenpunkte ggf. angepasst werden. Die View kann ebenfalls in VIS über „view importieren“ geladen werden. Die verwendeten Widgets sind klassische ioBroker-Widgets und funktionieren sowohl in VIS1 als auch in VIS2.
                                      View_SM_HTML.txt

                                    Die Views enthalten einen Push-Button. Wenn der gedrückt wird, wird die Meldungshistorie ohne Nachfrage gelöscht

                                    Da das Skript bei niedrigem Batteriestand automatisch die erforderlichen Batterien überprüft, müssen die Geräte mit den Batterien in eine Liste eingetragen werden. Mit dem folgenden Script kannst du überprüfen, ob die Liste vollständig ist. Alle Geräte mit unbekannten Batterien werden aufgelistet. Du kannst mir diese Liste dann zur Verfügung stellen, und ich pflege sie gerne ein.
                                    hier das Checkscript:
                                    Batterie-Check-1-1.txt

                                    Zusätzlich stelle ich ein Tool zur Verfügung, das alle ioBroker-Subscriptions auflistet. Dies steht nicht direkt im Zusammenhang mit dem Servicemeldungsskript, ist aber hilfreich, um transparent zu sehen, was insgesamt abonniert wurde. Über eine Variable kann die Liste auch auf ein bestimmtes Skript eingeschränkt werden. Das Ergebnis kann in eine externe Datei geschrieben werden.
                                    Hier das script
                                    ListSubscriptions_1.0

                                    sigi234S Online
                                    sigi234S Online
                                    sigi234
                                    Forum Testing Most Active
                                    schrieb am zuletzt editiert von sigi234
                                    #84

                                    @looxer01 sagte in [Vorlage] Servicemeldungen Volume2:

                                    hier das Checkscript:
                                    Servicemeldungen_Vol2_1-10.txt

                                    Sollte es nicht das Batterieskript sein?

                                    Bitte benutzt das Voting rechts unten im Beitrag wenn er euch geholfen hat.
                                    Immer Daten sichern!

                                    L 1 Antwort Letzte Antwort
                                    1
                                    • sigi234S sigi234

                                      @looxer01 sagte in [Vorlage] Servicemeldungen Volume2:

                                      hier das Checkscript:
                                      Servicemeldungen_Vol2_1-10.txt

                                      Sollte es nicht das Batterieskript sein?

                                      L Offline
                                      L Offline
                                      looxer01
                                      schrieb am zuletzt editiert von
                                      #85

                                      @sigi234
                                      Danke dir. habe ich korrigiert.
                                      vG Looxer

                                      1 Antwort Letzte Antwort
                                      0
                                      • L looxer01

                                        @zahnheinrich
                                        bei HMIPW hast du im screen print einmal "Error_Undervoltage_Alarm"

                                        Frage:
                                        gibt es bei HM wired auch 2 instanzen, also je eine für HM-Classic und eine fuer HMIP?
                                        Das wäre ja noch gar nicht eingebaut.

                                        vG Looxer

                                        Z Offline
                                        Z Offline
                                        zahnheinrich
                                        schrieb am zuletzt editiert von zahnheinrich
                                        #86

                                        @looxer01
                                        Das classic wired läuft in einer separaten Instanz nach dem hs485d Protokoll, das neue ist IP-wired läuft in der HMIP Instanz zusammen mit anderen HMIP Geräten wie z.B. Thermostaten o.ä. nach dem HM IP Protokoll

                                        MfG Ulrich

                                        L 1 Antwort Letzte Antwort
                                        0
                                        • Z zahnheinrich

                                          @looxer01
                                          Das classic wired läuft in einer separaten Instanz nach dem hs485d Protokoll, das neue ist IP-wired läuft in der HMIP Instanz zusammen mit anderen HMIP Geräten wie z.B. Thermostaten o.ä. nach dem HM IP Protokoll

                                          L Offline
                                          L Offline
                                          looxer01
                                          schrieb am zuletzt editiert von
                                          #87

                                          @zahnheinrich
                                          Danke für den Hinweis.
                                          Es ist also auch nicht möglich Wired separariert von der HMIP Instanz als eigene Instanz zu konfigurieren ?

                                          vG Looer

                                          Z 2 Antworten Letzte Antwort
                                          0
                                          Antworten
                                          • In einem neuen Thema antworten
                                          Anmelden zum Antworten
                                          • Älteste zuerst
                                          • Neuste zuerst
                                          • Meiste Stimmen


                                          Support us

                                          ioBroker
                                          Community Adapters
                                          Donate

                                          804

                                          Online

                                          32.4k

                                          Benutzer

                                          81.5k

                                          Themen

                                          1.3m

                                          Beiträge
                                          Community
                                          Impressum | Datenschutz-Bestimmungen | Nutzungsbedingungen | Einwilligungseinstellungen
                                          ioBroker Community 2014-2025
                                          logo
                                          • Anmelden

                                          • Du hast noch kein Konto? Registrieren

                                          • Anmelden oder registrieren, um zu suchen
                                          • Erster Beitrag
                                            Letzter Beitrag
                                          0
                                          • Home
                                          • Aktuell
                                          • Tags
                                          • Ungelesen 0
                                          • Kategorien
                                          • Unreplied
                                          • Beliebt
                                          • GitHub
                                          • Docu
                                          • Hilfe