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. JavaScript
  5. Skript AlleStörungen

NEWS

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

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

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

Skript AlleStörungen

Geplant Angeheftet Gesperrt Verschoben JavaScript
13 Beiträge 5 Kommentatoren 1.3k Aufrufe 13 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.
  • Ro75R Ro75

    Hallo. Heute stelle ich euch einmal mein Skript "Alle Störungen" vor. Dieses Skript liest Daten einer Website (in diesem Falle allestörungen.de [at] [ch]) aus. Es ermittelt wie auch andere Skripts (z.B. Wetter, Luftdaten, Pollen, Biowetter, usw.) Daten und schreibt diese zur Weiterverarbeitung in einzelne Datenpunkte.

    Habe zwar nicht daran gedacht gleich ein Skript zu erstellen, aber man hatte bei Problemen doch dann schon mal auf der genannten Seite nachgesehen.

    Da wir ja viele Daten sammeln, speichern und visualisieren - ist dies vielleicht ein weiteres Skript für Nutzer vom ioBroker.

    //Version 1.0.1 - 20.09.2024
    //Ersteller Ro75.
    
    //Voraussetzungen (Version 1.0.0 getestet mit)
    //NodeJS: 20.x
    //Javascript-Adapter: 8.7.6
    //Admin-Adapter: 7.0.23
    //JS-Controller: 6.0.11
    
    
    
    const sMainPath = '0_userdata.0.allestoerungen.'; //Zentraler Datenpunkt zur Datenablage
    const sMainURL  = 'https://xn--allestrungen-9ib.de/stoerung/'; //Website die ausgelesen wird
    
    //Konfiguration der auszulesenden Dienste - kann frei zusammengestellt werden (Suche auf https://xn--allestrungen-9ib.de/ verwenden)
    //Dienste werden durch ein "," (KOMMA) getrennt
    //Innterhalb eines Dienstes gibt es zwie Werte, gertrennt durch ":" (Doppelpunkt)
    //Die linke Seite repräsentiert die Bezeichnung, die rechte Seite den Unterpfad in der Website
    const aDienste  = 'Amazon Alexa:amazon-alexa,Amazon:amazon,Amazon Music:amazon-music,Amazon Prime Video:amazon-prime-instant-video,Amazon Web Services:aws-amazon-web-services,Blau:blau-de,Cloudflare:cloudflare,DHL:dhl,Disney+:disney-plus,EA:ea,Facebook:facebook,Facebook Messenger:facebook-messenger,Gmail:gmail,GMX:gmx,Google:google,Google Calendar:google-calendar,Hue:hue,Instagram:instagram,Microsoft 365:microsoft-365,Netatmo:netatmo,Netflix:netflix,Paramount+:paramountplus,Paypal:paypal,Playstation Network:playstation-network,Snapchat:snapchat,SKY:sky,Telekom:deutsche-telekom,TikTok:tiktok,TuneIn:tunein,Visa:visa,Volksbanken Raiffeisenbanken:volksbanken-und-raiffeisenbanken,Whatsapp:whatsapp,X (Twitter):Twitter,Xbox Live:xbox-live,YouTube:youtube';
    
    //Anlage der Datenpunkte, basierend auf const aDienste
    function Initalisierung(){
        let dienste = aDienste.split(',');
        for (let i = 0; i <= dienste.length-1; i++) {
            let dienste_data = dienste[i].split(':');
            //Hauptordner
            createState(sMainPath+dienste_data[0], '', {name: dienste_data[0],type: 'string', read: true, write: true});
            //Name vom Dienst
            createState(sMainPath+dienste_data[0]+'.name', dienste_data[0], {name: 'Dienst', type: 'string', read: true, write: true, desc: 'Dienst'});
            //Logo vom Dienst
            createState(sMainPath+dienste_data[0]+'.image_url', '', {name: 'Logo',type: 'string', read: true, write: true, desc: 'Logo'});
            //Störung laut Website (Datum + Uhrzeit)
            createState(sMainPath+dienste_data[0]+'.disruption', '', {name: 'Störung',type: 'string', read: true, write: true, desc: 'Störung'});
            // Störung % Satz 1
            createState(sMainPath+dienste_data[0]+'.disruption_1', 0, {name: 'Störung 1',type: 'number', read: true, write: true, desc: 'Störung Satz 1', unit: '%'});
            createState(sMainPath+dienste_data[0]+'.disruption_desc_1', '', {name: 'Beschreibung Störung 1',type: 'string', read: true, write: true, desc: 'Beschreibung Störung Satz 1'});
            // Störung % Satz 2
            createState(sMainPath+dienste_data[0]+'.disruption_2', 0, {name: 'Störung 2',type: 'number', read: true, write: true, desc: 'Störung Satz 2', unit: '%'});
            createState(sMainPath+dienste_data[0]+'.disruption_desc_2', '', {name: 'Beschreibung Störung 2',type: 'string', read: true, write: true, desc: 'Beschreibung Störung Satz 1'});
            // Störung % Satz 3
            createState(sMainPath+dienste_data[0]+'.disruption_3', 0, {name: 'Störung 3',type: 'number', read: true, write: true, desc: 'Störung Satz 3', unit: '%'});
            createState(sMainPath+dienste_data[0]+'.disruption_desc_3', '', {name: 'Beschreibung Störung 3',type: 'string', read: true, write: true, desc: 'Beschreibung Störung Satz 1'});
            // Daten-Array der letztes 24 Stunden bezogen auf Werte
            createState(sMainPath+dienste_data[0]+'.data_plain', '', {name: 'Werte',type: 'string', read: true, write: true, desc: 'Werte'});
            // Daten-Array der letztes 24 Stunden bezogen auf Zeit
            createState(sMainPath+dienste_data[0]+'.data_time_plain', '', {name: 'Zeit',type: 'string', read: true, write: true, desc: 'Zeit'});
            // Daten-Array der letztes 24 Stunden als JSON - kann direkt weiter verarbeitet werden (auch Grafana)
            createState(sMainPath+dienste_data[0]+'.data_json', '', {name: 'JSON',type: 'string', def: '[]', read: true, write: true, desc: 'JSON Widget/Simple-API/Grafana'});
            // Min Meldungen der letzten 24 Stunden
            createState(sMainPath+dienste_data[0]+'.min', 0, {name: 'Min',type: 'number', read: true, write: true, desc: 'kleinster Wert'});
            // Max Meldungen der letzten 24 Stunden
            createState(sMainPath+dienste_data[0]+'.max', 0, {name: 'Max',type: 'number', read: true, write: true, desc: 'größter Wert'});
            // Meldungen letzter Stand
            createState(sMainPath+dienste_data[0]+'.last', 0, {name: 'Last',type: 'number', read: true, write: true, desc: 'letzter Wert'});
            // Schwellenpunkt für eigenen Alarm - standardmäßig sind je Dienst 300 eingetragen, kann individuell im DP angepasst werden
            createState(sMainPath+dienste_data[0]+'.alarm_threshold', 300, {name: 'Threshold',type: 'number', read: true, write: true, desc: 'Schwelle Alarm'});
            // Alarm, resultierend aus 'alarm_threshold' und 'last'
            createState(sMainPath+dienste_data[0]+'.alarm', false, {name: 'Alarm',type: 'boolean', read: true, write: true, desc: 'Alarm'});
            // stand der Daten
            createState(sMainPath+dienste_data[0]+'.lasttimestand', '', {name: 'letzter Stand',type: 'string', read: true, write: true, desc: 'letzter Stand'});
    
            //Hinweis: mit den Werten 'data_*', min, max, last, alarm ist eine umfangreiche Visualisierung möglich
        }
        //JSON
        createState(sMainPath+'data_json', '', {name: 'JSON',type: 'string', def: '[]', read: true, write: true, desc: 'JSON Widget'});
    
        //erster Datenabruf
        Dienste_Main();
    }
    //START
    Initalisierung();
    
    //automatisierte Datenabfrage: standard sind 30 Minuten - kann geändert werden (aber nicht zu oft - keine Erfahrung mit blocken)
    schedule('*/30 * * * *', Dienste_Main);
    
    //Hauptfunktion
    async function Dienste_Main(){
        let dienste = aDienste.split(',');
        for (let i = 0; i <= dienste.length-1; i++) {
            let dienste_data = dienste[i].split(':');
            let dienst_url = dienste_data[1];
    
            try {
                let response = await httpGetAsync(sMainURL+dienst_url+'/', {timeout: 10000});
                if (response.statusCode == 200) {
                    //Logo vom Dienst
                    await Dienst_Image(response.data,sMainPath+dienste_data[0]);
                    //Wann war letzte Störung, laut Website
                    await Dienst_letzte_stoerung(response.data,sMainPath+dienste_data[0]);
                    //Abruf der Hauptdaten ()
                    await Dienst_Data(response.data,sMainPath+dienste_data[0]);
                    //Indikator in % für Probleme mit Festnetz Internet
                    await IndicatorChart(1,response.data,sMainPath+dienste_data[0]);
                    //Indikator in % für Probleme mit Mobiles Internet
                    await IndicatorChart(2,response.data,sMainPath+dienste_data[0]);
                    //Indikator in % für Probleme mit Total Blackout
                    await IndicatorChart(3,response.data,sMainPath+dienste_data[0]);
                    setState(sMainPath+dienste_data[0]+'.lasttimestand',new Date().toDateString() + ' '+ new Date().toTimeString(),true);
                }
                response = null;
            } catch (error) {
                console.error('AlleStörungen:', error);
            }
        }
        setTimeout(function(){
            CreateJSON();
        },1000);
    }
    
    async function Dienst_Data(sData,sMainDP){
        let Position = sData.indexOf("data: [");
        if (Position > 0) {
            var info = sData.substr(Position+7, 10000);
            var pos = info.indexOf("],");
            var str = info.substr(0, pos).trim();
            var daten = await Dienst_Data_Details(str);
            var Splitdaten = daten.split('||');
            setState(sMainDP+'.data_json',Splitdaten[0],true);
            setState(sMainDP+'.data_plain',Splitdaten[1],true);
            setState(sMainDP+'.data_time_plain',Splitdaten[2],true);
            setState(sMainDP+'.min',parseInt(Splitdaten[3]),true);
            setState(sMainDP+'.max',parseInt(Splitdaten[4]),true);
            setState(sMainDP+'.last',parseInt(Splitdaten[5]),true);
    
            var bAlert = false;
            if (parseInt(Splitdaten[5]) >= getState(sMainDP+'.alarm_threshold').val) {
                bAlert = true;
            }
            setState(sMainDP+'.alarm',bAlert,true);
    
            info = null;
        } 
    }
    async function Dienst_Data_Details(sData){
        let JSON_List   = [];
        var Plain_List  = '';
        var Time_List   = '';
        var lMin        = 100000000;
        var lMax        = 0;
        var lLast       = 0;
    
        let sDataDetail = sData.split('},');
        for (let i = 0; i <= sDataDetail.length-2; i++) {
            let dData = sDataDetail[i].replace('{ x: ','').replace(' y: ','').replace('+00:00','.000Z').replace(/[&\/\\'"*?<>{}]/g,'').replace('\n','').trim();
            dData = dData.split(',');
    
            JSON_List.push({"time": dData[0], "value": dData[1]});
    
            if (Plain_List == '') {
                Plain_List = dData[1];
            } else {
                Plain_List = Plain_List+','+dData[1];
            }
            if (lMax < parseFloat(dData[1])) {
                lMax = parseFloat(dData[1]);
            }
            if (lMin > parseFloat(dData[1])) {
                lMin = parseFloat(dData[1]);
            }
    
            if (Time_List == '') {
                Time_List = dData[0];
            } else {
                Time_List = Time_List+','+dData[0];
            }
    
            lLast = dData[1];
        }
        return JSON.stringify(JSON_List)+'||'+Plain_List+'||'+Time_List+'||'+lMin+'||'+lMax+'||'+lLast;
    }
    
    async function Dienst_Image(sData,sMainDP){
        let Position = sData.indexOf("'og:image' content='");
        if (Position > 0) {
            var info = sData.substr(Position+20, 200);
            var pos = info.indexOf("'>");
            var str = info.substr(0, pos);
            setState(sMainDP+'.image_url',str,true);
            info = null;
        } 
    }
    
    async function Dienst_letzte_stoerung(sData,sMainDP){
        let Position = sData.indexOf("<p class='text-danger'>");
        if (Position > 0) {
            var info = sData.substr(Position+23, 200);
            var pos=info.indexOf("</p>");
            var str = info.substr(0, pos).replace('Letzte Störung: ','');
            setState(sMainDP+'.disruption',str.trim(),true);
            info = null;
        } else {
            setState(sMainDP+'.disruption','',true);
        } 
    }
    
    async function IndicatorChart(lItem,sData,sMainDP){
        var lValue = 0;
        var Position = sData.indexOf("<div class='col-4'>");
        var info = sData.substr(Position+19, 30000);
        var Position2 = info.indexOf("indicator_"+lItem);
        if (Position2 > 0) {
            var info2 = info.substr(Position2+11, 5000);
            var Position3 = info2.indexOf("tage'>");
            if (Position3 > 0) {
                var info3 = info2.substr(Position3+6, 50);
                var pos=info3.indexOf("</div>");
                var str = info3.substr(0, pos);
                lValue = parseInt(str);
            }
        }
        setState(sMainDP+'.disruption_'+lItem,lValue,true);
    
        //Beschreibung
        var sInfo = '';
        if (Position2 > 0) {
            var info2 = info.substr(Position2+11, 5000);
            var Position3 = info2.indexOf("_name'>");
            if (Position3 > 0) {
                var info3 = info2.substr(Position3+7, 200);
                var pos=info3.indexOf("</div>");
                var str = info3.substr(0, pos);
                sInfo = str.trim();
            }
        }
        setState(sMainDP+'.disruption_desc_'+lItem,sInfo,true);
    }
    
    function CreateJSON() {
        let JSON_List   = [];
        let dienste = aDienste.split(',');
        for (let i = 0; i <= dienste.length-1; i++) {
            var rDienst = sMainPath+dienste[i].split(':')[0];
            var dis1 = getState(rDienst+'.disruption_desc_1').val;
            if (dis1 != '') {
                dis1 = dis1 + ': '+getState(rDienst+'.disruption_1').val+'%';
            }
            var dis2 = getState(rDienst+'.disruption_desc_2').val;
            if (dis2 != '') {
                dis2 = dis2 + ': '+getState(rDienst+'.disruption_2').val+'%';
            }
            var dis3 = getState(rDienst+'.disruption_desc_3').val;
            if (dis3 != '') {
                dis3 = dis3 + ': '+getState(rDienst+'.disruption_3').val+'%';
            }
            var alarm = '';
            if (getState(rDienst+'.alarm').val == false) {
                alarm = 'nein';
            } else {
                alarm = 'ja';
            }
            JSON_List.push({"dienst": dienste[i].split(':')[0], "logo": getState(rDienst+'.image_url').val, "min": getState(rDienst+'.min').val, "max": getState(rDienst+'.max').val, "last": getState(rDienst+'.last').val, "stoerung1": dis1, "stoerung2": dis2, "stoerung3": dis3, "alarm": alarm});
        }
        setState(sMainPath+'data_json', JSON.stringify(JSON_List), true);
        JSON_List = [];
    }
    

    Im Grunde sollte alles selbsterklärend sein. Die hinzugefügten Kommentare geben Info und Einstellmöglichkeiten. Für Anregungen bin ich offen, auch wenn es ggfs. nicht gleich umgesetzt werden kann (die gute Zeit).

    5ce0143a-0086-42bc-a8d5-1ef9618cb8b6-image.png Visualisierung als Liste

    b7dba355-071c-46b7-8d67-ef95ab55ca1c-image.png Visualisierung mit Grafana (via Simple-API)

    Ich wünsche euch viel Spaß.

    Ro75.

    NACHTRAG 20.09.2024:

    Das Skript kann auch für Österreich und Schweiz Anwendung finden. Dazu muss die Konstante "sMainURL" angepasst werden.

    Österreich: const sMainURL  = 'https://xn--allestrungen-9ib.at/stoerung/';
    Schweiz: const sMainURL  = 'https://xn--allestrungen-9ib.ch/stoerung/';
    

    ACHTUNG:
    Die Auflistung der Dienste in der Konstante "aDienste" muss aber für das jeweilige Land individuell angepasst werden, da es in jedem Land spezifische Dienste gibt, die in anderen Ländern nicht bekannt sind. Wird also ein Dienst in Österreich verwendet, welcher nur in Deutschland verfügbar ist (z.B. All-Inkl), wird es zu Fehlermeldungen bei der Auswerung kommen.

    Version 1.01 - 20.09.2024

    1. Zentrale JSON hinzugefügt
    2. Fehlerbehandlung
    sigi234S Online
    sigi234S Online
    sigi234
    Forum Testing Most Active
    schrieb am zuletzt editiert von sigi234
    #2

    @ro75 sagte in Skript AlleStörungen:

    const sMainURL = 'https://allestörungen.de/stoerung/'; //Website die ausgelesen wird

    allestrungen

    Stimmt die Url?

    Geht das auch für Österreich?

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

    Ro75R 1 Antwort Letzte Antwort
    0
    • sigi234S sigi234

      @ro75 sagte in Skript AlleStörungen:

      const sMainURL = 'https://allestörungen.de/stoerung/'; //Website die ausgelesen wird

      allestrungen

      Stimmt die Url?

      Geht das auch für Österreich?

      Ro75R Online
      Ro75R Online
      Ro75
      schrieb am zuletzt editiert von Ro75
      #3

      @sigi234 die von mir angegebene URL ist korrekt, wegen dem Umlaut. Sollte aber auch allestoerungen.de gehen.

      Gibt es für Österreich eine separate Adresse? Hab ich jetzt noch nicht geschaut. Aber ändere es mal statt .de in .at ab

      Edit: eventuell musst du aber die Liste der Dienste anpassen, da es einige in Österreich nicht gibt.

      Ro75

      SERVER = Beelink U59 16GB DDR4 RAM 512GB SSD, FB 7490, FritzDect 200+301+440, ConBee II, Zigbee Aqara Sensoren + NOUS A1Z, NOUS A1T, Philips Hue ** ioBroker, REDIS, influxdb2, Grafana, PiHole, Plex-Mediaserver, paperless-ngx (Docker), MariaDB + phpmyadmin *** VIS-Runtime = Intel NUC 8GB RAM 128GB SSD + 24" Touchscreen

      sigi234S 1 Antwort Letzte Antwort
      0
      • Ro75R Ro75

        Hallo. Heute stelle ich euch einmal mein Skript "Alle Störungen" vor. Dieses Skript liest Daten einer Website (in diesem Falle allestörungen.de [at] [ch]) aus. Es ermittelt wie auch andere Skripts (z.B. Wetter, Luftdaten, Pollen, Biowetter, usw.) Daten und schreibt diese zur Weiterverarbeitung in einzelne Datenpunkte.

        Habe zwar nicht daran gedacht gleich ein Skript zu erstellen, aber man hatte bei Problemen doch dann schon mal auf der genannten Seite nachgesehen.

        Da wir ja viele Daten sammeln, speichern und visualisieren - ist dies vielleicht ein weiteres Skript für Nutzer vom ioBroker.

        //Version 1.0.1 - 20.09.2024
        //Ersteller Ro75.
        
        //Voraussetzungen (Version 1.0.0 getestet mit)
        //NodeJS: 20.x
        //Javascript-Adapter: 8.7.6
        //Admin-Adapter: 7.0.23
        //JS-Controller: 6.0.11
        
        
        
        const sMainPath = '0_userdata.0.allestoerungen.'; //Zentraler Datenpunkt zur Datenablage
        const sMainURL  = 'https://xn--allestrungen-9ib.de/stoerung/'; //Website die ausgelesen wird
        
        //Konfiguration der auszulesenden Dienste - kann frei zusammengestellt werden (Suche auf https://xn--allestrungen-9ib.de/ verwenden)
        //Dienste werden durch ein "," (KOMMA) getrennt
        //Innterhalb eines Dienstes gibt es zwie Werte, gertrennt durch ":" (Doppelpunkt)
        //Die linke Seite repräsentiert die Bezeichnung, die rechte Seite den Unterpfad in der Website
        const aDienste  = 'Amazon Alexa:amazon-alexa,Amazon:amazon,Amazon Music:amazon-music,Amazon Prime Video:amazon-prime-instant-video,Amazon Web Services:aws-amazon-web-services,Blau:blau-de,Cloudflare:cloudflare,DHL:dhl,Disney+:disney-plus,EA:ea,Facebook:facebook,Facebook Messenger:facebook-messenger,Gmail:gmail,GMX:gmx,Google:google,Google Calendar:google-calendar,Hue:hue,Instagram:instagram,Microsoft 365:microsoft-365,Netatmo:netatmo,Netflix:netflix,Paramount+:paramountplus,Paypal:paypal,Playstation Network:playstation-network,Snapchat:snapchat,SKY:sky,Telekom:deutsche-telekom,TikTok:tiktok,TuneIn:tunein,Visa:visa,Volksbanken Raiffeisenbanken:volksbanken-und-raiffeisenbanken,Whatsapp:whatsapp,X (Twitter):Twitter,Xbox Live:xbox-live,YouTube:youtube';
        
        //Anlage der Datenpunkte, basierend auf const aDienste
        function Initalisierung(){
            let dienste = aDienste.split(',');
            for (let i = 0; i <= dienste.length-1; i++) {
                let dienste_data = dienste[i].split(':');
                //Hauptordner
                createState(sMainPath+dienste_data[0], '', {name: dienste_data[0],type: 'string', read: true, write: true});
                //Name vom Dienst
                createState(sMainPath+dienste_data[0]+'.name', dienste_data[0], {name: 'Dienst', type: 'string', read: true, write: true, desc: 'Dienst'});
                //Logo vom Dienst
                createState(sMainPath+dienste_data[0]+'.image_url', '', {name: 'Logo',type: 'string', read: true, write: true, desc: 'Logo'});
                //Störung laut Website (Datum + Uhrzeit)
                createState(sMainPath+dienste_data[0]+'.disruption', '', {name: 'Störung',type: 'string', read: true, write: true, desc: 'Störung'});
                // Störung % Satz 1
                createState(sMainPath+dienste_data[0]+'.disruption_1', 0, {name: 'Störung 1',type: 'number', read: true, write: true, desc: 'Störung Satz 1', unit: '%'});
                createState(sMainPath+dienste_data[0]+'.disruption_desc_1', '', {name: 'Beschreibung Störung 1',type: 'string', read: true, write: true, desc: 'Beschreibung Störung Satz 1'});
                // Störung % Satz 2
                createState(sMainPath+dienste_data[0]+'.disruption_2', 0, {name: 'Störung 2',type: 'number', read: true, write: true, desc: 'Störung Satz 2', unit: '%'});
                createState(sMainPath+dienste_data[0]+'.disruption_desc_2', '', {name: 'Beschreibung Störung 2',type: 'string', read: true, write: true, desc: 'Beschreibung Störung Satz 1'});
                // Störung % Satz 3
                createState(sMainPath+dienste_data[0]+'.disruption_3', 0, {name: 'Störung 3',type: 'number', read: true, write: true, desc: 'Störung Satz 3', unit: '%'});
                createState(sMainPath+dienste_data[0]+'.disruption_desc_3', '', {name: 'Beschreibung Störung 3',type: 'string', read: true, write: true, desc: 'Beschreibung Störung Satz 1'});
                // Daten-Array der letztes 24 Stunden bezogen auf Werte
                createState(sMainPath+dienste_data[0]+'.data_plain', '', {name: 'Werte',type: 'string', read: true, write: true, desc: 'Werte'});
                // Daten-Array der letztes 24 Stunden bezogen auf Zeit
                createState(sMainPath+dienste_data[0]+'.data_time_plain', '', {name: 'Zeit',type: 'string', read: true, write: true, desc: 'Zeit'});
                // Daten-Array der letztes 24 Stunden als JSON - kann direkt weiter verarbeitet werden (auch Grafana)
                createState(sMainPath+dienste_data[0]+'.data_json', '', {name: 'JSON',type: 'string', def: '[]', read: true, write: true, desc: 'JSON Widget/Simple-API/Grafana'});
                // Min Meldungen der letzten 24 Stunden
                createState(sMainPath+dienste_data[0]+'.min', 0, {name: 'Min',type: 'number', read: true, write: true, desc: 'kleinster Wert'});
                // Max Meldungen der letzten 24 Stunden
                createState(sMainPath+dienste_data[0]+'.max', 0, {name: 'Max',type: 'number', read: true, write: true, desc: 'größter Wert'});
                // Meldungen letzter Stand
                createState(sMainPath+dienste_data[0]+'.last', 0, {name: 'Last',type: 'number', read: true, write: true, desc: 'letzter Wert'});
                // Schwellenpunkt für eigenen Alarm - standardmäßig sind je Dienst 300 eingetragen, kann individuell im DP angepasst werden
                createState(sMainPath+dienste_data[0]+'.alarm_threshold', 300, {name: 'Threshold',type: 'number', read: true, write: true, desc: 'Schwelle Alarm'});
                // Alarm, resultierend aus 'alarm_threshold' und 'last'
                createState(sMainPath+dienste_data[0]+'.alarm', false, {name: 'Alarm',type: 'boolean', read: true, write: true, desc: 'Alarm'});
                // stand der Daten
                createState(sMainPath+dienste_data[0]+'.lasttimestand', '', {name: 'letzter Stand',type: 'string', read: true, write: true, desc: 'letzter Stand'});
        
                //Hinweis: mit den Werten 'data_*', min, max, last, alarm ist eine umfangreiche Visualisierung möglich
            }
            //JSON
            createState(sMainPath+'data_json', '', {name: 'JSON',type: 'string', def: '[]', read: true, write: true, desc: 'JSON Widget'});
        
            //erster Datenabruf
            Dienste_Main();
        }
        //START
        Initalisierung();
        
        //automatisierte Datenabfrage: standard sind 30 Minuten - kann geändert werden (aber nicht zu oft - keine Erfahrung mit blocken)
        schedule('*/30 * * * *', Dienste_Main);
        
        //Hauptfunktion
        async function Dienste_Main(){
            let dienste = aDienste.split(',');
            for (let i = 0; i <= dienste.length-1; i++) {
                let dienste_data = dienste[i].split(':');
                let dienst_url = dienste_data[1];
        
                try {
                    let response = await httpGetAsync(sMainURL+dienst_url+'/', {timeout: 10000});
                    if (response.statusCode == 200) {
                        //Logo vom Dienst
                        await Dienst_Image(response.data,sMainPath+dienste_data[0]);
                        //Wann war letzte Störung, laut Website
                        await Dienst_letzte_stoerung(response.data,sMainPath+dienste_data[0]);
                        //Abruf der Hauptdaten ()
                        await Dienst_Data(response.data,sMainPath+dienste_data[0]);
                        //Indikator in % für Probleme mit Festnetz Internet
                        await IndicatorChart(1,response.data,sMainPath+dienste_data[0]);
                        //Indikator in % für Probleme mit Mobiles Internet
                        await IndicatorChart(2,response.data,sMainPath+dienste_data[0]);
                        //Indikator in % für Probleme mit Total Blackout
                        await IndicatorChart(3,response.data,sMainPath+dienste_data[0]);
                        setState(sMainPath+dienste_data[0]+'.lasttimestand',new Date().toDateString() + ' '+ new Date().toTimeString(),true);
                    }
                    response = null;
                } catch (error) {
                    console.error('AlleStörungen:', error);
                }
            }
            setTimeout(function(){
                CreateJSON();
            },1000);
        }
        
        async function Dienst_Data(sData,sMainDP){
            let Position = sData.indexOf("data: [");
            if (Position > 0) {
                var info = sData.substr(Position+7, 10000);
                var pos = info.indexOf("],");
                var str = info.substr(0, pos).trim();
                var daten = await Dienst_Data_Details(str);
                var Splitdaten = daten.split('||');
                setState(sMainDP+'.data_json',Splitdaten[0],true);
                setState(sMainDP+'.data_plain',Splitdaten[1],true);
                setState(sMainDP+'.data_time_plain',Splitdaten[2],true);
                setState(sMainDP+'.min',parseInt(Splitdaten[3]),true);
                setState(sMainDP+'.max',parseInt(Splitdaten[4]),true);
                setState(sMainDP+'.last',parseInt(Splitdaten[5]),true);
        
                var bAlert = false;
                if (parseInt(Splitdaten[5]) >= getState(sMainDP+'.alarm_threshold').val) {
                    bAlert = true;
                }
                setState(sMainDP+'.alarm',bAlert,true);
        
                info = null;
            } 
        }
        async function Dienst_Data_Details(sData){
            let JSON_List   = [];
            var Plain_List  = '';
            var Time_List   = '';
            var lMin        = 100000000;
            var lMax        = 0;
            var lLast       = 0;
        
            let sDataDetail = sData.split('},');
            for (let i = 0; i <= sDataDetail.length-2; i++) {
                let dData = sDataDetail[i].replace('{ x: ','').replace(' y: ','').replace('+00:00','.000Z').replace(/[&\/\\'"*?<>{}]/g,'').replace('\n','').trim();
                dData = dData.split(',');
        
                JSON_List.push({"time": dData[0], "value": dData[1]});
        
                if (Plain_List == '') {
                    Plain_List = dData[1];
                } else {
                    Plain_List = Plain_List+','+dData[1];
                }
                if (lMax < parseFloat(dData[1])) {
                    lMax = parseFloat(dData[1]);
                }
                if (lMin > parseFloat(dData[1])) {
                    lMin = parseFloat(dData[1]);
                }
        
                if (Time_List == '') {
                    Time_List = dData[0];
                } else {
                    Time_List = Time_List+','+dData[0];
                }
        
                lLast = dData[1];
            }
            return JSON.stringify(JSON_List)+'||'+Plain_List+'||'+Time_List+'||'+lMin+'||'+lMax+'||'+lLast;
        }
        
        async function Dienst_Image(sData,sMainDP){
            let Position = sData.indexOf("'og:image' content='");
            if (Position > 0) {
                var info = sData.substr(Position+20, 200);
                var pos = info.indexOf("'>");
                var str = info.substr(0, pos);
                setState(sMainDP+'.image_url',str,true);
                info = null;
            } 
        }
        
        async function Dienst_letzte_stoerung(sData,sMainDP){
            let Position = sData.indexOf("<p class='text-danger'>");
            if (Position > 0) {
                var info = sData.substr(Position+23, 200);
                var pos=info.indexOf("</p>");
                var str = info.substr(0, pos).replace('Letzte Störung: ','');
                setState(sMainDP+'.disruption',str.trim(),true);
                info = null;
            } else {
                setState(sMainDP+'.disruption','',true);
            } 
        }
        
        async function IndicatorChart(lItem,sData,sMainDP){
            var lValue = 0;
            var Position = sData.indexOf("<div class='col-4'>");
            var info = sData.substr(Position+19, 30000);
            var Position2 = info.indexOf("indicator_"+lItem);
            if (Position2 > 0) {
                var info2 = info.substr(Position2+11, 5000);
                var Position3 = info2.indexOf("tage'>");
                if (Position3 > 0) {
                    var info3 = info2.substr(Position3+6, 50);
                    var pos=info3.indexOf("</div>");
                    var str = info3.substr(0, pos);
                    lValue = parseInt(str);
                }
            }
            setState(sMainDP+'.disruption_'+lItem,lValue,true);
        
            //Beschreibung
            var sInfo = '';
            if (Position2 > 0) {
                var info2 = info.substr(Position2+11, 5000);
                var Position3 = info2.indexOf("_name'>");
                if (Position3 > 0) {
                    var info3 = info2.substr(Position3+7, 200);
                    var pos=info3.indexOf("</div>");
                    var str = info3.substr(0, pos);
                    sInfo = str.trim();
                }
            }
            setState(sMainDP+'.disruption_desc_'+lItem,sInfo,true);
        }
        
        function CreateJSON() {
            let JSON_List   = [];
            let dienste = aDienste.split(',');
            for (let i = 0; i <= dienste.length-1; i++) {
                var rDienst = sMainPath+dienste[i].split(':')[0];
                var dis1 = getState(rDienst+'.disruption_desc_1').val;
                if (dis1 != '') {
                    dis1 = dis1 + ': '+getState(rDienst+'.disruption_1').val+'%';
                }
                var dis2 = getState(rDienst+'.disruption_desc_2').val;
                if (dis2 != '') {
                    dis2 = dis2 + ': '+getState(rDienst+'.disruption_2').val+'%';
                }
                var dis3 = getState(rDienst+'.disruption_desc_3').val;
                if (dis3 != '') {
                    dis3 = dis3 + ': '+getState(rDienst+'.disruption_3').val+'%';
                }
                var alarm = '';
                if (getState(rDienst+'.alarm').val == false) {
                    alarm = 'nein';
                } else {
                    alarm = 'ja';
                }
                JSON_List.push({"dienst": dienste[i].split(':')[0], "logo": getState(rDienst+'.image_url').val, "min": getState(rDienst+'.min').val, "max": getState(rDienst+'.max').val, "last": getState(rDienst+'.last').val, "stoerung1": dis1, "stoerung2": dis2, "stoerung3": dis3, "alarm": alarm});
            }
            setState(sMainPath+'data_json', JSON.stringify(JSON_List), true);
            JSON_List = [];
        }
        

        Im Grunde sollte alles selbsterklärend sein. Die hinzugefügten Kommentare geben Info und Einstellmöglichkeiten. Für Anregungen bin ich offen, auch wenn es ggfs. nicht gleich umgesetzt werden kann (die gute Zeit).

        5ce0143a-0086-42bc-a8d5-1ef9618cb8b6-image.png Visualisierung als Liste

        b7dba355-071c-46b7-8d67-ef95ab55ca1c-image.png Visualisierung mit Grafana (via Simple-API)

        Ich wünsche euch viel Spaß.

        Ro75.

        NACHTRAG 20.09.2024:

        Das Skript kann auch für Österreich und Schweiz Anwendung finden. Dazu muss die Konstante "sMainURL" angepasst werden.

        Österreich: const sMainURL  = 'https://xn--allestrungen-9ib.at/stoerung/';
        Schweiz: const sMainURL  = 'https://xn--allestrungen-9ib.ch/stoerung/';
        

        ACHTUNG:
        Die Auflistung der Dienste in der Konstante "aDienste" muss aber für das jeweilige Land individuell angepasst werden, da es in jedem Land spezifische Dienste gibt, die in anderen Ländern nicht bekannt sind. Wird also ein Dienst in Österreich verwendet, welcher nur in Deutschland verfügbar ist (z.B. All-Inkl), wird es zu Fehlermeldungen bei der Auswerung kommen.

        Version 1.01 - 20.09.2024

        1. Zentrale JSON hinzugefügt
        2. Fehlerbehandlung
        K Offline
        K Offline
        Kuddel
        schrieb am zuletzt editiert von
        #4

        @ro75 die Idee selber finde ich spannend.

        Ohne das Skript jetzt am PC angeschaut zu haben (etwas nervig auf dem Handy), würde ich es gut finden, wenn man seine PLZ sowie die genutzten Dienste angeben könnte.

        Vllt. findet sich ja jemand, der das Skript später zu einem Adapter macht

        Ro75R 1 Antwort Letzte Antwort
        0
        • Ro75R Ro75

          @sigi234 die von mir angegebene URL ist korrekt, wegen dem Umlaut. Sollte aber auch allestoerungen.de gehen.

          Gibt es für Österreich eine separate Adresse? Hab ich jetzt noch nicht geschaut. Aber ändere es mal statt .de in .at ab

          Edit: eventuell musst du aber die Liste der Dienste anpassen, da es einige in Österreich nicht gibt.

          Ro75

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

          @ro75 sagte in Skript AlleStörungen:

          @sigi234 die von mir angegebene URL ist korrekt, wegen dem Umlaut. Sollte aber auch allestoerungen.de gehen.

          Gibt es für Österreich eine separate Adresse? Hab ich jetzt noch nicht geschaut. Aber ändere es mal statt .de in .at ab

          Edit: eventuell musst du aber die Liste der Dienste anpassen, da es einige in Österreich nicht gibt.

          Ro75

          Funktioniert mit at wunderbar, Danke :+1:

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

          1 Antwort Letzte Antwort
          1
          • K Kuddel

            @ro75 die Idee selber finde ich spannend.

            Ohne das Skript jetzt am PC angeschaut zu haben (etwas nervig auf dem Handy), würde ich es gut finden, wenn man seine PLZ sowie die genutzten Dienste angeben könnte.

            Vllt. findet sich ja jemand, der das Skript später zu einem Adapter macht

            Ro75R Online
            Ro75R Online
            Ro75
            schrieb am zuletzt editiert von
            #6

            @kuddel schaue es dir an. Die Dienste kannst du selbst bestimmen.

            Ro75

            SERVER = Beelink U59 16GB DDR4 RAM 512GB SSD, FB 7490, FritzDect 200+301+440, ConBee II, Zigbee Aqara Sensoren + NOUS A1Z, NOUS A1T, Philips Hue ** ioBroker, REDIS, influxdb2, Grafana, PiHole, Plex-Mediaserver, paperless-ngx (Docker), MariaDB + phpmyadmin *** VIS-Runtime = Intel NUC 8GB RAM 128GB SSD + 24" Touchscreen

            sigi234S 1 Antwort Letzte Antwort
            0
            • Ro75R Ro75

              Hallo. Heute stelle ich euch einmal mein Skript "Alle Störungen" vor. Dieses Skript liest Daten einer Website (in diesem Falle allestörungen.de [at] [ch]) aus. Es ermittelt wie auch andere Skripts (z.B. Wetter, Luftdaten, Pollen, Biowetter, usw.) Daten und schreibt diese zur Weiterverarbeitung in einzelne Datenpunkte.

              Habe zwar nicht daran gedacht gleich ein Skript zu erstellen, aber man hatte bei Problemen doch dann schon mal auf der genannten Seite nachgesehen.

              Da wir ja viele Daten sammeln, speichern und visualisieren - ist dies vielleicht ein weiteres Skript für Nutzer vom ioBroker.

              //Version 1.0.1 - 20.09.2024
              //Ersteller Ro75.
              
              //Voraussetzungen (Version 1.0.0 getestet mit)
              //NodeJS: 20.x
              //Javascript-Adapter: 8.7.6
              //Admin-Adapter: 7.0.23
              //JS-Controller: 6.0.11
              
              
              
              const sMainPath = '0_userdata.0.allestoerungen.'; //Zentraler Datenpunkt zur Datenablage
              const sMainURL  = 'https://xn--allestrungen-9ib.de/stoerung/'; //Website die ausgelesen wird
              
              //Konfiguration der auszulesenden Dienste - kann frei zusammengestellt werden (Suche auf https://xn--allestrungen-9ib.de/ verwenden)
              //Dienste werden durch ein "," (KOMMA) getrennt
              //Innterhalb eines Dienstes gibt es zwie Werte, gertrennt durch ":" (Doppelpunkt)
              //Die linke Seite repräsentiert die Bezeichnung, die rechte Seite den Unterpfad in der Website
              const aDienste  = 'Amazon Alexa:amazon-alexa,Amazon:amazon,Amazon Music:amazon-music,Amazon Prime Video:amazon-prime-instant-video,Amazon Web Services:aws-amazon-web-services,Blau:blau-de,Cloudflare:cloudflare,DHL:dhl,Disney+:disney-plus,EA:ea,Facebook:facebook,Facebook Messenger:facebook-messenger,Gmail:gmail,GMX:gmx,Google:google,Google Calendar:google-calendar,Hue:hue,Instagram:instagram,Microsoft 365:microsoft-365,Netatmo:netatmo,Netflix:netflix,Paramount+:paramountplus,Paypal:paypal,Playstation Network:playstation-network,Snapchat:snapchat,SKY:sky,Telekom:deutsche-telekom,TikTok:tiktok,TuneIn:tunein,Visa:visa,Volksbanken Raiffeisenbanken:volksbanken-und-raiffeisenbanken,Whatsapp:whatsapp,X (Twitter):Twitter,Xbox Live:xbox-live,YouTube:youtube';
              
              //Anlage der Datenpunkte, basierend auf const aDienste
              function Initalisierung(){
                  let dienste = aDienste.split(',');
                  for (let i = 0; i <= dienste.length-1; i++) {
                      let dienste_data = dienste[i].split(':');
                      //Hauptordner
                      createState(sMainPath+dienste_data[0], '', {name: dienste_data[0],type: 'string', read: true, write: true});
                      //Name vom Dienst
                      createState(sMainPath+dienste_data[0]+'.name', dienste_data[0], {name: 'Dienst', type: 'string', read: true, write: true, desc: 'Dienst'});
                      //Logo vom Dienst
                      createState(sMainPath+dienste_data[0]+'.image_url', '', {name: 'Logo',type: 'string', read: true, write: true, desc: 'Logo'});
                      //Störung laut Website (Datum + Uhrzeit)
                      createState(sMainPath+dienste_data[0]+'.disruption', '', {name: 'Störung',type: 'string', read: true, write: true, desc: 'Störung'});
                      // Störung % Satz 1
                      createState(sMainPath+dienste_data[0]+'.disruption_1', 0, {name: 'Störung 1',type: 'number', read: true, write: true, desc: 'Störung Satz 1', unit: '%'});
                      createState(sMainPath+dienste_data[0]+'.disruption_desc_1', '', {name: 'Beschreibung Störung 1',type: 'string', read: true, write: true, desc: 'Beschreibung Störung Satz 1'});
                      // Störung % Satz 2
                      createState(sMainPath+dienste_data[0]+'.disruption_2', 0, {name: 'Störung 2',type: 'number', read: true, write: true, desc: 'Störung Satz 2', unit: '%'});
                      createState(sMainPath+dienste_data[0]+'.disruption_desc_2', '', {name: 'Beschreibung Störung 2',type: 'string', read: true, write: true, desc: 'Beschreibung Störung Satz 1'});
                      // Störung % Satz 3
                      createState(sMainPath+dienste_data[0]+'.disruption_3', 0, {name: 'Störung 3',type: 'number', read: true, write: true, desc: 'Störung Satz 3', unit: '%'});
                      createState(sMainPath+dienste_data[0]+'.disruption_desc_3', '', {name: 'Beschreibung Störung 3',type: 'string', read: true, write: true, desc: 'Beschreibung Störung Satz 1'});
                      // Daten-Array der letztes 24 Stunden bezogen auf Werte
                      createState(sMainPath+dienste_data[0]+'.data_plain', '', {name: 'Werte',type: 'string', read: true, write: true, desc: 'Werte'});
                      // Daten-Array der letztes 24 Stunden bezogen auf Zeit
                      createState(sMainPath+dienste_data[0]+'.data_time_plain', '', {name: 'Zeit',type: 'string', read: true, write: true, desc: 'Zeit'});
                      // Daten-Array der letztes 24 Stunden als JSON - kann direkt weiter verarbeitet werden (auch Grafana)
                      createState(sMainPath+dienste_data[0]+'.data_json', '', {name: 'JSON',type: 'string', def: '[]', read: true, write: true, desc: 'JSON Widget/Simple-API/Grafana'});
                      // Min Meldungen der letzten 24 Stunden
                      createState(sMainPath+dienste_data[0]+'.min', 0, {name: 'Min',type: 'number', read: true, write: true, desc: 'kleinster Wert'});
                      // Max Meldungen der letzten 24 Stunden
                      createState(sMainPath+dienste_data[0]+'.max', 0, {name: 'Max',type: 'number', read: true, write: true, desc: 'größter Wert'});
                      // Meldungen letzter Stand
                      createState(sMainPath+dienste_data[0]+'.last', 0, {name: 'Last',type: 'number', read: true, write: true, desc: 'letzter Wert'});
                      // Schwellenpunkt für eigenen Alarm - standardmäßig sind je Dienst 300 eingetragen, kann individuell im DP angepasst werden
                      createState(sMainPath+dienste_data[0]+'.alarm_threshold', 300, {name: 'Threshold',type: 'number', read: true, write: true, desc: 'Schwelle Alarm'});
                      // Alarm, resultierend aus 'alarm_threshold' und 'last'
                      createState(sMainPath+dienste_data[0]+'.alarm', false, {name: 'Alarm',type: 'boolean', read: true, write: true, desc: 'Alarm'});
                      // stand der Daten
                      createState(sMainPath+dienste_data[0]+'.lasttimestand', '', {name: 'letzter Stand',type: 'string', read: true, write: true, desc: 'letzter Stand'});
              
                      //Hinweis: mit den Werten 'data_*', min, max, last, alarm ist eine umfangreiche Visualisierung möglich
                  }
                  //JSON
                  createState(sMainPath+'data_json', '', {name: 'JSON',type: 'string', def: '[]', read: true, write: true, desc: 'JSON Widget'});
              
                  //erster Datenabruf
                  Dienste_Main();
              }
              //START
              Initalisierung();
              
              //automatisierte Datenabfrage: standard sind 30 Minuten - kann geändert werden (aber nicht zu oft - keine Erfahrung mit blocken)
              schedule('*/30 * * * *', Dienste_Main);
              
              //Hauptfunktion
              async function Dienste_Main(){
                  let dienste = aDienste.split(',');
                  for (let i = 0; i <= dienste.length-1; i++) {
                      let dienste_data = dienste[i].split(':');
                      let dienst_url = dienste_data[1];
              
                      try {
                          let response = await httpGetAsync(sMainURL+dienst_url+'/', {timeout: 10000});
                          if (response.statusCode == 200) {
                              //Logo vom Dienst
                              await Dienst_Image(response.data,sMainPath+dienste_data[0]);
                              //Wann war letzte Störung, laut Website
                              await Dienst_letzte_stoerung(response.data,sMainPath+dienste_data[0]);
                              //Abruf der Hauptdaten ()
                              await Dienst_Data(response.data,sMainPath+dienste_data[0]);
                              //Indikator in % für Probleme mit Festnetz Internet
                              await IndicatorChart(1,response.data,sMainPath+dienste_data[0]);
                              //Indikator in % für Probleme mit Mobiles Internet
                              await IndicatorChart(2,response.data,sMainPath+dienste_data[0]);
                              //Indikator in % für Probleme mit Total Blackout
                              await IndicatorChart(3,response.data,sMainPath+dienste_data[0]);
                              setState(sMainPath+dienste_data[0]+'.lasttimestand',new Date().toDateString() + ' '+ new Date().toTimeString(),true);
                          }
                          response = null;
                      } catch (error) {
                          console.error('AlleStörungen:', error);
                      }
                  }
                  setTimeout(function(){
                      CreateJSON();
                  },1000);
              }
              
              async function Dienst_Data(sData,sMainDP){
                  let Position = sData.indexOf("data: [");
                  if (Position > 0) {
                      var info = sData.substr(Position+7, 10000);
                      var pos = info.indexOf("],");
                      var str = info.substr(0, pos).trim();
                      var daten = await Dienst_Data_Details(str);
                      var Splitdaten = daten.split('||');
                      setState(sMainDP+'.data_json',Splitdaten[0],true);
                      setState(sMainDP+'.data_plain',Splitdaten[1],true);
                      setState(sMainDP+'.data_time_plain',Splitdaten[2],true);
                      setState(sMainDP+'.min',parseInt(Splitdaten[3]),true);
                      setState(sMainDP+'.max',parseInt(Splitdaten[4]),true);
                      setState(sMainDP+'.last',parseInt(Splitdaten[5]),true);
              
                      var bAlert = false;
                      if (parseInt(Splitdaten[5]) >= getState(sMainDP+'.alarm_threshold').val) {
                          bAlert = true;
                      }
                      setState(sMainDP+'.alarm',bAlert,true);
              
                      info = null;
                  } 
              }
              async function Dienst_Data_Details(sData){
                  let JSON_List   = [];
                  var Plain_List  = '';
                  var Time_List   = '';
                  var lMin        = 100000000;
                  var lMax        = 0;
                  var lLast       = 0;
              
                  let sDataDetail = sData.split('},');
                  for (let i = 0; i <= sDataDetail.length-2; i++) {
                      let dData = sDataDetail[i].replace('{ x: ','').replace(' y: ','').replace('+00:00','.000Z').replace(/[&\/\\'"*?<>{}]/g,'').replace('\n','').trim();
                      dData = dData.split(',');
              
                      JSON_List.push({"time": dData[0], "value": dData[1]});
              
                      if (Plain_List == '') {
                          Plain_List = dData[1];
                      } else {
                          Plain_List = Plain_List+','+dData[1];
                      }
                      if (lMax < parseFloat(dData[1])) {
                          lMax = parseFloat(dData[1]);
                      }
                      if (lMin > parseFloat(dData[1])) {
                          lMin = parseFloat(dData[1]);
                      }
              
                      if (Time_List == '') {
                          Time_List = dData[0];
                      } else {
                          Time_List = Time_List+','+dData[0];
                      }
              
                      lLast = dData[1];
                  }
                  return JSON.stringify(JSON_List)+'||'+Plain_List+'||'+Time_List+'||'+lMin+'||'+lMax+'||'+lLast;
              }
              
              async function Dienst_Image(sData,sMainDP){
                  let Position = sData.indexOf("'og:image' content='");
                  if (Position > 0) {
                      var info = sData.substr(Position+20, 200);
                      var pos = info.indexOf("'>");
                      var str = info.substr(0, pos);
                      setState(sMainDP+'.image_url',str,true);
                      info = null;
                  } 
              }
              
              async function Dienst_letzte_stoerung(sData,sMainDP){
                  let Position = sData.indexOf("<p class='text-danger'>");
                  if (Position > 0) {
                      var info = sData.substr(Position+23, 200);
                      var pos=info.indexOf("</p>");
                      var str = info.substr(0, pos).replace('Letzte Störung: ','');
                      setState(sMainDP+'.disruption',str.trim(),true);
                      info = null;
                  } else {
                      setState(sMainDP+'.disruption','',true);
                  } 
              }
              
              async function IndicatorChart(lItem,sData,sMainDP){
                  var lValue = 0;
                  var Position = sData.indexOf("<div class='col-4'>");
                  var info = sData.substr(Position+19, 30000);
                  var Position2 = info.indexOf("indicator_"+lItem);
                  if (Position2 > 0) {
                      var info2 = info.substr(Position2+11, 5000);
                      var Position3 = info2.indexOf("tage'>");
                      if (Position3 > 0) {
                          var info3 = info2.substr(Position3+6, 50);
                          var pos=info3.indexOf("</div>");
                          var str = info3.substr(0, pos);
                          lValue = parseInt(str);
                      }
                  }
                  setState(sMainDP+'.disruption_'+lItem,lValue,true);
              
                  //Beschreibung
                  var sInfo = '';
                  if (Position2 > 0) {
                      var info2 = info.substr(Position2+11, 5000);
                      var Position3 = info2.indexOf("_name'>");
                      if (Position3 > 0) {
                          var info3 = info2.substr(Position3+7, 200);
                          var pos=info3.indexOf("</div>");
                          var str = info3.substr(0, pos);
                          sInfo = str.trim();
                      }
                  }
                  setState(sMainDP+'.disruption_desc_'+lItem,sInfo,true);
              }
              
              function CreateJSON() {
                  let JSON_List   = [];
                  let dienste = aDienste.split(',');
                  for (let i = 0; i <= dienste.length-1; i++) {
                      var rDienst = sMainPath+dienste[i].split(':')[0];
                      var dis1 = getState(rDienst+'.disruption_desc_1').val;
                      if (dis1 != '') {
                          dis1 = dis1 + ': '+getState(rDienst+'.disruption_1').val+'%';
                      }
                      var dis2 = getState(rDienst+'.disruption_desc_2').val;
                      if (dis2 != '') {
                          dis2 = dis2 + ': '+getState(rDienst+'.disruption_2').val+'%';
                      }
                      var dis3 = getState(rDienst+'.disruption_desc_3').val;
                      if (dis3 != '') {
                          dis3 = dis3 + ': '+getState(rDienst+'.disruption_3').val+'%';
                      }
                      var alarm = '';
                      if (getState(rDienst+'.alarm').val == false) {
                          alarm = 'nein';
                      } else {
                          alarm = 'ja';
                      }
                      JSON_List.push({"dienst": dienste[i].split(':')[0], "logo": getState(rDienst+'.image_url').val, "min": getState(rDienst+'.min').val, "max": getState(rDienst+'.max').val, "last": getState(rDienst+'.last').val, "stoerung1": dis1, "stoerung2": dis2, "stoerung3": dis3, "alarm": alarm});
                  }
                  setState(sMainPath+'data_json', JSON.stringify(JSON_List), true);
                  JSON_List = [];
              }
              

              Im Grunde sollte alles selbsterklärend sein. Die hinzugefügten Kommentare geben Info und Einstellmöglichkeiten. Für Anregungen bin ich offen, auch wenn es ggfs. nicht gleich umgesetzt werden kann (die gute Zeit).

              5ce0143a-0086-42bc-a8d5-1ef9618cb8b6-image.png Visualisierung als Liste

              b7dba355-071c-46b7-8d67-ef95ab55ca1c-image.png Visualisierung mit Grafana (via Simple-API)

              Ich wünsche euch viel Spaß.

              Ro75.

              NACHTRAG 20.09.2024:

              Das Skript kann auch für Österreich und Schweiz Anwendung finden. Dazu muss die Konstante "sMainURL" angepasst werden.

              Österreich: const sMainURL  = 'https://xn--allestrungen-9ib.at/stoerung/';
              Schweiz: const sMainURL  = 'https://xn--allestrungen-9ib.ch/stoerung/';
              

              ACHTUNG:
              Die Auflistung der Dienste in der Konstante "aDienste" muss aber für das jeweilige Land individuell angepasst werden, da es in jedem Land spezifische Dienste gibt, die in anderen Ländern nicht bekannt sind. Wird also ein Dienst in Österreich verwendet, welcher nur in Deutschland verfügbar ist (z.B. All-Inkl), wird es zu Fehlermeldungen bei der Auswerung kommen.

              Version 1.01 - 20.09.2024

              1. Zentrale JSON hinzugefügt
              2. Fehlerbehandlung
              D4vED Offline
              D4vED Offline
              D4vE
              schrieb am zuletzt editiert von D4vE
              #7

              @ro75 sehr starke Arbeit!

              könnte man da noch Telegram mit rein hauen? das bei einer neuen Störung eine Nachricht bekommt? wer Hammer!

              Danke für deine Arbeit!

              Iobroker Installation date 2021-08-16
              Platform: linux init system: Docker
              cod.m Zigbee Coordinator: CZC v1.0

              1 Antwort Letzte Antwort
              0
              • Ro75R Ro75

                @kuddel schaue es dir an. Die Dienste kannst du selbst bestimmen.

                Ro75

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

                @ro75

                Zu Vis2 muss ich mir noch so meine Gedanken machen, aber es wird

                Screenshot (965).png

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

                1 Antwort Letzte Antwort
                3
                • Ro75R Online
                  Ro75R Online
                  Ro75
                  schrieb am zuletzt editiert von
                  #9

                  Einganspost um den NACHTRAG 20.09.2024: erweitert.

                  Ro75.

                  SERVER = Beelink U59 16GB DDR4 RAM 512GB SSD, FB 7490, FritzDect 200+301+440, ConBee II, Zigbee Aqara Sensoren + NOUS A1Z, NOUS A1T, Philips Hue ** ioBroker, REDIS, influxdb2, Grafana, PiHole, Plex-Mediaserver, paperless-ngx (Docker), MariaDB + phpmyadmin *** VIS-Runtime = Intel NUC 8GB RAM 128GB SSD + 24" Touchscreen

                  1 Antwort Letzte Antwort
                  2
                  • Ro75R Online
                    Ro75R Online
                    Ro75
                    schrieb am zuletzt editiert von
                    #10

                    Eingangspost um Visualisierungsbeispiele erweitert.

                    Ro75.

                    SERVER = Beelink U59 16GB DDR4 RAM 512GB SSD, FB 7490, FritzDect 200+301+440, ConBee II, Zigbee Aqara Sensoren + NOUS A1Z, NOUS A1T, Philips Hue ** ioBroker, REDIS, influxdb2, Grafana, PiHole, Plex-Mediaserver, paperless-ngx (Docker), MariaDB + phpmyadmin *** VIS-Runtime = Intel NUC 8GB RAM 128GB SSD + 24" Touchscreen

                    O 1 Antwort Letzte Antwort
                    0
                    • Ro75R Ro75

                      Eingangspost um Visualisierungsbeispiele erweitert.

                      Ro75.

                      O Online
                      O Online
                      Oli
                      schrieb am zuletzt editiert von Oli
                      #11

                      @Ro75
                      funktioniert das Skript noch?

                      Bei mir werden alle Datenpunkte angelegt, ab sowie es scheint nicht befüllt

                      0ec88837-0570-41cf-a977-f9d0760f616b-image.png

                      Gruß
                      Oliver

                      1 Antwort Letzte Antwort
                      0
                      • Ro75R Online
                        Ro75R Online
                        Ro75
                        schrieb am zuletzt editiert von
                        #12

                        Hallo, Nein - anscheinend wird erkannt, dass es sich um keinen regulären Aufruf handelt und wird blockiert. Ich habe auch mit anderen Browserkennunungen versucht, ohne Erfolg.

                        Ro75.

                        SERVER = Beelink U59 16GB DDR4 RAM 512GB SSD, FB 7490, FritzDect 200+301+440, ConBee II, Zigbee Aqara Sensoren + NOUS A1Z, NOUS A1T, Philips Hue ** ioBroker, REDIS, influxdb2, Grafana, PiHole, Plex-Mediaserver, paperless-ngx (Docker), MariaDB + phpmyadmin *** VIS-Runtime = Intel NUC 8GB RAM 128GB SSD + 24" Touchscreen

                        O 1 Antwort Letzte Antwort
                        0
                        • Ro75R Ro75

                          Hallo, Nein - anscheinend wird erkannt, dass es sich um keinen regulären Aufruf handelt und wird blockiert. Ich habe auch mit anderen Browserkennunungen versucht, ohne Erfolg.

                          Ro75.

                          O Online
                          O Online
                          Oli
                          schrieb am zuletzt editiert von
                          #13

                          @Ro75
                          Danke für die Info, dann liegt es zumindest nicht an mir

                          Gruß
                          Oliver

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


                          Support us

                          ioBroker
                          Community Adapters
                          Donate

                          867

                          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