Weiter zum Inhalt
  • Home
  • Aktuell
  • Tags
  • 0 Ungelesen 0
  • Kategorien
  • Unreplied
  • Beliebt
  • GitHub
  • Docu
  • Hilfe
Skins
  • Hell
  • Brite
  • Cerulean
  • Cosmo
  • Flatly
  • Journal
  • Litera
  • Lumen
  • Lux
  • Materia
  • Minty
  • Morph
  • Pulse
  • Sandstone
  • Simplex
  • Sketchy
  • Spacelab
  • United
  • Yeti
  • Zephyr
  • Dunkel
  • 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. HowTo: Zusatz-Programme fuer jarvis v3

NEWS

  • Neuer ioBroker-Blog online: Monatsrückblick März/April 2026
    BluefoxB
    Bluefox
    6
    1
    253

  • Verwendung von KI bitte immer deutlich kennzeichnen
    HomoranH
    Homoran
    9
    1
    245

  • Monatsrückblick Januar/Februar 2026 ist online!
    BluefoxB
    Bluefox
    18
    1
    901

HowTo: Zusatz-Programme fuer jarvis v3

Geplant Angeheftet Gesperrt Verschoben JavaScript
javascript
894 Beiträge 33 Kommentatoren 234.2k Aufrufe 37 Beobachtet
  • Ä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.
  • M Meikie

    @mcu admin.0
    2024-01-05 23:47:34.290 info <== Disconnect system.user.admin from ::ffff:192.168.178.51 javascript

    Das Einzige.

    M Offline
    M Offline
    Meikie
    schrieb am zuletzt editiert von
    #401

    @meikie ```
    // *********************************
    // tibberHTML v1.0.24
    // *********************************
    // Copyright ©MCU
    // v1.0.1 - Erweiterung Umschaltung Line/bar im Graph, Anzeige der Werte in Tabelle
    // v1.0.2 - Vis Auswahl -> fete Breite für VIS, darkMode
    // v1.0.3 - Min,max,avg kleiner, untereinander, rechts Breite kleiner
    // v1.0.4 - ShowMinMaxAvgTexte optional
    // v1.0.5 - toolBox -Speichern mit Namen+Datum
    // v1.0.6 - y-Skala auf beiden Kurven gleich
    // v1.0.7 - splitNumber auf 10 vorher 3, grid rechts 10 statt 30, visualMap - mobile optimiert
    // v1.0.8 - CurveArea optional, Korrektur wenn tomorrow.mim = 0 -> graphMin =0
    // v1.0.9 - graphMax angepasst auf nächste 0.01
    // v1.0.10- graphMin angepassz auf nächste 0.01
    // v1.0.11- Label optional, falls man schon Widget-Title nutzt
    // v1.0.12 - Trennung Label Today und Tomorrow
    // v1.0.13 - optionaler Text für Tomorrow Wait
    // v1.0.14 - automatischer Reload bei Umschaltung wait-Text Tomorrow
    // v1.0.15 - aktuelle Zeit highlightCurrentHour
    // v1.0.16 - Symbol für Line aktuelle Stunde angepasst
    // v1.0.17 - stepped line hinzugefügt, Korrekturen graphMin
    // v1.0.18 - Korrektur showwait
    // v1.0.19 - Korrektur showwait
    // v1.0.20 - Abschaltung Anzeige Graph, wenn leer, Korrektur highlightPoint
    // v1.0.21 - Korrektur dataNull für visualMapPieces
    // v1.0.22 - Inhalt von DPs als Datei speichern
    // v1.0.23 - Korrektur 1.Farbelement lte > maxValue
    // v1.0.24 - Korrektur 1. Farbelement Umstellung Linie, falsche Berechnung
    // ToDo
    // - optionale Zeit vor günstiger Stunde telegram senden, alexa info, pushOver senden
    // - Ersparnis in Prozent -> Tabelle / Anzeige?
    // - Stunden erweitern für steppedLine?

    let logging = true;
    let tibberDP = '0_userdata.0.Strom.tibberHistory';
    let dbHistoryDP = tibberDP + '.historyDB';
    let tibberGraphTypeDP = tibberDP + '.graphTyp'; // bar oder line
    let tibberInstDP = tibberDP + '.instanz'; // 0
    let tibberColorDP = tibberDP + '.colorJSON'; // visualMapPieces [ {gt: 0, lte: 0.15, color: "lightgreen"},]
    let tibberHTMLTodayDP = tibberDP + '.htmlToday';
    let tibberHTMLTomorrowDP = tibberDP + '.htmlTomorrow';
    let tibberShowTaxEnergyDP = tibberDP + '.showTaxEnergy'; // boolean
    let tibberShowMinMaxAvgDP = tibberDP + '.showMinMaxAvg'; // boolean
    let visDP = tibberDP + '.vis';
    let darkModeDP = tibberDP + '.darkMode';
    let tibberShowMinMaxAvgTextDP = tibberDP + '.showMinMaxAvgText';
    let tibberAreaDP = tibberDP + '.curveArea';
    let tibberShowLabelTodayDP = tibberDP + '.showLabelToday';
    let tibberLabelTodayDP = tibberDP + '.labelToday';
    let tibberShowLabelTomorrowDP = tibberDP + '.showLabelTomorrow';
    let tibberLabelTomorrowDP = tibberDP + '.labelTomorrow';
    let tibberWaitTomorrowTextDP = tibberDP + '.labelTomorrowWait';
    let tibberShowWaitLabelTomorrowDP = tibberDP + '.showLabelTomorrowWait';
    let tibberHighlightCurrentHourDP = tibberDP +'.highlightCurrentHour';
    let tibberHighlightColorDarkDP = tibberDP + '.highlightColorDark';
    let tibberHighlightColorLightDP = tibberDP + '.highlightColorLight';
    let tibberSteppedLineDP = tibberDP + '.steppedLine';
    let tibberShowGraphIfEmptyDP = tibberDP + '.showGraphIfEmpty';

    let dpArray = [];

    createStateAsync(tibberHTMLTodayDP, {read: true, write: true, name: "Tibber HTML für Heute", desc:"HTML-DP", type: "string", role: "", def: "" });
    createStateAsync(tibberHTMLTomorrowDP, {read: true, write: true, name: "Tibber HTML für Morgen", desc:"HTML-DP", type: "string", role: "", def: "" });
    createStateAsync(tibberColorDP, {read: true, write: true, name: "Farbdefinition für Balken", desc:"JSON-DP", type: "string", role: "",
    def: JSON.stringify([{ 'gt': 0,'lte': 0.15, 'color': 'lightgreen' },
    {'gt': 0.15,'lte': 0.22,'color': 'green'},
    {'gt': 0.22,'lte': 0.29,'color': 'yellow'},
    {'gt': 0.29,'lte': 0.35,'color': 'orange'},
    {'gt': 0.35,'color': 'red'}]) });
    createStateAsync(tibberGraphTypeDP, {read: true, write: true, name: "Tibber Graph Typ Auswahl", desc:"GraphType-DP", type: "string", role: "", states: {"bar":"bar","line":"line"} ,def: "bar" });
    createStateAsync(tibberInstDP, {read: true, write: true, name: "Tibber Instanz", desc:"Instanz-DP", type: "string", role: "", def: "0" });
    createStateAsync(tibberShowTaxEnergyDP, {read: true, write: true, name: "Tax und Energy anzeigen bei Hover", desc:"Show-DP", type: "boolean", role: "", def: false });
    createStateAsync(tibberShowMinMaxAvgDP, {read: true, write: true, name: "Min, Max und Mittelwert anzeigen", desc:"Show-DP", type: "boolean", role: "", def: false });
    createStateAsync(tibberShowMinMaxAvgTextDP, {read: true, write: true, name: "Min, Max und Mittelwert Texte anzeigen", desc:"ShowText-DP", type: "boolean", role: "", def: false });
    createStateAsync(visDP, {read: true, write: true, name: "Welche VIS soll genutzt werden?", desc:"VIS-DP", type: "string", role: "",states: {"jarvis":"jarvis","VIS":"VIS"} , def: "jarvis" });
    createStateAsync(darkModeDP, {read: true, write: true, name: "DarkMode an?", desc:"DarkMode-DP", type: "boolean", role: "", def: false });
    createStateAsync(tibberAreaDP, {read: true, write: true, name: "Fläche unter Kurve?", desc:"CurveArea-DP", type: "boolean", role: "", def: false });
    createStateAsync(tibberShowLabelTodayDP, {read: true, write: true, name: "Label Today anzeigen?", desc:"showLabel-DP", type: "boolean", role: "", def: false });
    createStateAsync(tibberLabelTodayDP, {read: true, write: true, name: "Label Today für das Chart", desc:"Label-DP", type: "string", role: "", def: "Today-Tageswerte" });
    createStateAsync(tibberShowLabelTomorrowDP, {read: true, write: true, name: "Label Tomorrow anzeigen?", desc:"showLabel-DP", type: "boolean", role: "", def: false });
    createStateAsync(tibberLabelTomorrowDP, {read: true, write: true, name: "Label Tomorrow für das Chart", desc:"Label-DP", type: "string", role: "", def: "Tomorrow-Tageswerte" });
    createStateAsync(tibberShowWaitLabelTomorrowDP, {read: true, write: true, name: "Label Wait Tomorrow anzeigen?", desc:"showLabel-DP", type: "boolean", role: "", def: false });
    createStateAsync(tibberWaitTomorrowTextDP, {read: true, write: true, name: "Label Wait Tomorrow für das Chart", desc:"Label-DP", type: "string", role: "", def: "Werte erst ab 14.00 Uhr verfügbar" });
    createStateAsync(tibberHighlightCurrentHourDP, {read: true, write: true, name: "Aktuelle Stunde markieren?", desc:"HighlightAktHour-DP", type: "boolean", role: "", def: false });
    createStateAsync(tibberHighlightColorDarkDP, {read: true, write: true, name: "HighLight Color DarkMode", desc:"HighLight Dark-DP", type: "string", role: "", def: "white" });
    createStateAsync(tibberHighlightColorLightDP, {read: true, write: true, name: "HighLight Color LightMode", desc:"HighLight Light-DP", type: "string", role: "", def: "grey" });
    createStateAsync(tibberSteppedLineDP, {read: true, write: true, name: "Gestufte Linie?", desc:"SteppedLine-DP", type: "boolean", role: "", def: false });

    createStateAsync(tibberShowGraphIfEmptyDP, {read: true, write: true, name: "Graph anzeigen ohne Daten?", desc:"showGraph-DP", type: "boolean", role: "", def: false });

    // getHistoryAdapter();

    // setDPs('0'); // -> dpArray

    setTimeout(function(){
    getTibberData(dpArray);
    let inst = getState(tibberInstDP).val;
    $('tibberlink.'+inst+'.Homes.*.PricesTomorrow.json').on(function(obj) {
    setTimeout(function(){
    getTibberData(dpArray);
    },3000)
    });

    $('tibberlink.'+inst+'.Homes.*.PricesToday.json').on(function(obj) {
        setTimeout(function(){
            getTibberData(dpArray);
        },3000);
    });
    

    },3000);

    let scheduleId ;
    if(getState(tibberHighlightColorDarkDP).val){
    scheduleId = schedule('00 * * * *', () => {

        getTibberData(dpArray);
    })
    

    }

    on({id: tibberHighlightCurrentHourDP, change: "any"}, function (obj) {
    let value = obj.state.val;
    if(value){
    getTibberData(dpArray);
    clearSchedule(scheduleId);
    scheduleId = schedule('00 * * * *', () => {
    getTibberData(dpArray);
    })
    }else{
    clearSchedule(scheduleId);
    getTibberData(dpArray);
    }
    })
    on({id: tibberShowTaxEnergyDP, change: "any"}, function (obj) {
    getTibberData(dpArray);
    });
    on({id: tibberColorDP, change: "any"}, function (obj) {
    getTibberData(dpArray);
    });

    on({id: tibberShowMinMaxAvgDP, change: "any"}, function (obj) {
    getTibberData(dpArray);
    });
    on({id: tibberShowMinMaxAvgTextDP, change: "any"}, function (obj) {
    getTibberData(dpArray);
    });

    on({id: tibberGraphTypeDP, change: "any"}, function (obj) {
    getTibberData(dpArray);
    });
    on({id: darkModeDP, change: "any"}, function (obj) {
    getTibberData(dpArray);
    });
    on({id: tibberAreaDP, change: "any"}, function (obj) {
    getTibberData(dpArray);
    });
    on({id: tibberShowLabelTodayDP, change: "any"}, function (obj) {
    getTibberData(dpArray);
    });
    on({id: tibberShowLabelTomorrowDP, change: "any"}, function (obj) {
    getTibberData(dpArray);
    });

    on({id: tibberShowWaitLabelTomorrowDP, change: "any"}, function (obj) {
    getTibberData(dpArray);
    });

    on({id: tibberHighlightColorDarkDP, change: "any"}, function (obj) {
    getTibberData(dpArray);
    });

    on({id: tibberHighlightColorLightDP, change: "any"}, function (obj) {
    getTibberData(dpArray);
    });
    on({id: tibberSteppedLineDP, change: "any"}, function (obj) {
    getTibberData(dpArray);
    });
    on({id: tibberShowGraphIfEmptyDP, change: "any"}, function (obj) {
    getTibberData(dpArray);
    });

    function getTibberData(arr){
    // arr wird nur für eCharts benötigt

    // tibberDataDP selbst ermitteln
    let tibberInst = getState(tibberInstDP).val;
    let priceArr = ['PricesToday','PricesTomorrow'];
    for(let x=0;x< priceArr.length;x++){
        let tibberData = [];
        let tibberLink = $('tibberlink.'+tibberInst+'.Homes.*.'+priceArr[x]+'.json')
        if(tibberLink[0] != undefined){
            let tblLevel = levelObject(tibberLink[0]);
            let dpLeveltbl = getDPLevel(tblLevel,4);
            let tibberJSON = JSON.parse(getState(dpLeveltbl+'.json').val);
            // tibberJSON
            for(let i=0;i<tibberJSON.length;i++){
                let obj = {};
                obj.hour     = parseInt(tibberJSON[i].startsAt.substring(11,13));
                obj.start   = tibberJSON[i].startsAt
                obj.startTS = new Date(obj.start).getTime();
                obj.value   = tibberJSON[i].total;
                obj.energy   = tibberJSON[i].energy;
                obj.tax   = tibberJSON[i].tax;
                obj.min = false;
                obj.max = false;
                obj.average = false;
                obj.level = tibberJSON[i].level;
                tibberData.push(obj);
            }
            // average, minium, maximum direkt holen
            
            let eleArr = ['average','minimum','maximum'];
            for(let i=0;i<eleArr.length;i++){
                let obj = {};
                switch (eleArr[i]) {
                        case 'average':
                            obj.hour     = 'non'
                            obj.start   = ''
                            obj.startTS = 0;
                            obj.value   = getState(dpLeveltbl+'.'+eleArr[i]+'.total').val
                            obj.energy   = getState(dpLeveltbl+'.'+eleArr[i]+'.energy').val
                            obj.tax   = getState(dpLeveltbl+'.'+eleArr[i]+'.tax').val
                            obj.min = false;
                            obj.max = false;
                            obj.average = true;
                            obj.level = '';
                            tibberData.push(obj);
                            break;
                        case 'minimum':
                            obj.hour    = 'non';
                            obj.start   = getState(dpLeveltbl+'.'+eleArr[i]+'.startsAt').val
                            obj.startTS = new Date(obj.start).getTime();
                            obj.value   = getState(dpLeveltbl+'.'+eleArr[i]+'.total').val
                            obj.energy   = getState(dpLeveltbl+'.'+eleArr[i]+'.energy').val
                            obj.tax   = getState(dpLeveltbl+'.'+eleArr[i]+'.tax').val
                            obj.min = true;
                            obj.max = false;
                            obj.average = false;
                            tibberData.push(obj);
                            break;
                        case 'maximum':
                            obj.hour    = 'non';
                            obj.start   = getState(dpLeveltbl+'.'+eleArr[i]+'.startsAt').val
                            obj.startTS = new Date(obj.start).getTime();
                            obj.value   = getState(dpLeveltbl+'.'+eleArr[i]+'.total').val
                            obj.energy   = getState(dpLeveltbl+'.'+eleArr[i]+'.energy').val
                            obj.tax   = getState(dpLeveltbl+'.'+eleArr[i]+'.tax').val
                            obj.min = false;
                            obj.max = true;
                            obj.average = false;
                            tibberData.push(obj);
                            break;
                        default: 
                            break;
                    }
            }
            // log(tibberData);
            let setechart = false;
            if(setechart){
                for(let i=0;i<dpArray.length;i++){
                    setHistoryData(dpArray[i],tibberObj[levelObject(dpArray[i])[3]]);
                }
                seteChartsDP(dpArray);
            }
            // log('setHTML');
            setHTML(tibberData,priceArr[x]);
            if(getState(visDP).val=='VIS'){
                createHtmlFile(priceArr[x])
            }
        }
        
    }
    

    }
    // createHtmlFile();
    async function createHtmlFile(name) {
    let dp = '';
    let file = '';
    if(name == 'PricesToday'){
    dp = '0_userdata.0.Strom.tibberHistory.htmlToday';
    file = 'today';
    }else{
    dp = '0_userdata.0.Strom.tibberHistory.htmlTomorrow';
    file = 'tomorrow';
    }
    const htmlContent = getState(dp).val;
    writeFile('vis.0', '/tibber/'+file+'.html',htmlContent, (err) => {
    if (err) {
    console.error('Fehler beim Speichern der HTML-Datei, tibber-Verzeichnis angelegt?', err);
    } else {
    console.log('HTML-Datei '+file+'.html erfolgreich gespeichert');
    }
    });
    }

    function setHTML(origData,priceDP){
    let data = [];
    let dataMin = '';
    let dataMinTime = '';
    let dataMax = '';
    let dataMaxTime = '';
    let dataAvg = '';
    let dataNull = false;
    // log(priceDP);
    let tibberInst = getState(tibberInstDP).val;
    let tibberLink = $('tibberlink.'+tibberInst+'.Homes.*.PricesToday.json')
    let tblLevel = levelObject(tibberLink[0]);
    let dpLeveltbl = getDPLevel(tblLevel,3);

    let minToday = getState(dpLeveltbl + '.PricesToday.minimum.total').val;
    //minToday = minToday-(Math.trunc(minToday*0.1))
    // log(minToday)
    let maxToday = getState(dpLeveltbl + '.PricesToday.maximum.total').val
    let minTomorrow = getState(dpLeveltbl + '.PricesTomorrow.minimum.total').val
    //minTomorrow = minTomorrow-(Math.trunc(minTomorrow*0.1))
    let maxTomorrow = getState(dpLeveltbl + '.PricesTomorrow.maximum.total').val
    let jsonTomorrow = JSON.parse(getState(dpLeveltbl + '.PricesTomorrow.json').val);
    
    let graphMin = 0;
    if(minToday >= minTomorrow){
        if(minTomorrow != 0){
            graphMin = minTomorrow;
        }else{
            graphMin = minToday;
        }
    }else{
        graphMin = minToday;
    }
    let graphMax = 0;
    if(maxToday >= maxTomorrow){
        graphMax = maxToday;
    }else{
        graphMax = maxTomorrow;
    }
    // graphMax = Math.round((graphMax + parseFloat((graphMax / 20).toFixed(2))) * 100) / 100;
    // graphMax = Math.max(Math.ceil(graphMax * 100) / 100, 0.35);
    if(jsonTomorrow.length ==0 ){
        graphMin = minToday;
        graphMax = maxToday
    }
    graphMin = Math.ceil(graphMin * 50) / 50 - 0.02;
    graphMax = Math.ceil(graphMax * 50) / 50 + 0.01;
    //log(graphMin)
    
    for(let i=0;i<origData.length;i++){
        if(origData[i].min){
            dataMin = origData[i].value;
            //log(dataMin);
            dataMinTime =origData[i].startTS;
            //log(dataMinTime)
        }
        if(origData[i].max){
            dataMax = origData[i].value;
            dataMaxTime =origData[i].startTS;
        }
        if(origData[i].average){
            dataAvg = origData[i].value;
        }
    }
    if(origData.length>3){
        for(let i=0;i<origData.length;i++){
            if(!origData[i].average && !origData[i].max && !origData[i].min ){
                if( origData[i].value < dataAvg){ 
                    if(origData[i].level == 'NORMAL' ){
                        data.push({time:origData[i].startTS,value: origData[i].value,tax: origData[i].tax,energy: origData[i].energy, level: origData[i].level})//, color: 'rgba(0,255,0,0.2)', border: levelColor(origData[i].level)
                    }else{
                        data.push({time:origData[i].startTS,value: origData[i].value,tax: origData[i].tax,energy: origData[i].energy,level: origData[i].level}) //,  color: levelColor(origData[i].level), border: 'lime'
                    }
                }else{
                    data.push({time:origData[i].startTS,value: origData[i].value,tax: origData[i].tax,energy: origData[i].energy, level: origData[i].level}) //,color: levelColor(origData[i].level), border: 'red'
                }
            }else{
                if(origData[i].min){
                    dataMin = origData[i].value;
                    dataMinTime =origData[i].startTS;
                }
                if(origData[i].max){
                    //log(origData[i]);
                    dataMax = origData[i].value;
                    dataMaxTime =origData[i].startTS;
                    //log(dataMaxTime);
                }
                if(origData[i].average){
                    dataAvg = origData[i].value;
                }
            }
            
        }
        // log('oben '+graphMin)
    }else{
        dataNull = true;
        //dataMin = String(graphMin);
        //dataMax = String(graphMax);
        //dataMax = "0";
        //dataAvg = '0.01';
        //graphMin = minToday;
        //graphMax = maxToday;
        //graphMin = Math.ceil(graphMin * 50) / 50 - 0.01;
        //graphMax = Math.ceil(graphMax * 50) / 50 + 0.01;
    }
    // Werte holen
    let showTaxEnergy = getState(tibberShowTaxEnergyDP).val;
    let minMaxAvg = getState(tibberShowMinMaxAvgDP).val;
    let colorJSON = getState(tibberColorDP).val;
    
    let html = '';
    html += '<!DOCTYPE html>';
    html += '<html lang="en">';
    html += '<head>';
    html += '<meta charset="UTF-8">';
    html += '<meta name="viewport" content="width=device-width, initial-scale=1.0">';
    html += '<title>Tibber-Tageswert</title>';
    html += '<script src="https://cdn.jsdelivr.net/npm/echarts@5.4.3/dist/echarts.min.js"></script>';
    html += '<script src="https://cdnjs.cloudflare.com/ajax/libs/moment.js/2.29.1/moment.min.js"></script>';
    html += '</head>';
    html += '<body>'
    if(getState(visDP).val == 'VIS'){
        html += '<div id="chart-container" style="width: 600px; height:400px;"></div>';
    }else{
        html += '<div id="chart-container" style="width: 100%; height:400px;"></div>';
    }
    //log(data);
    html += '<script>'
    html += '    var data = '+JSON.stringify(data)+';';
    html += '    var chartContainer = document.getElementById("chart-container");'
    html += '    var myChart = echarts.init(chartContainer);';
    
    
    html += '    function formatTime(time) {';
    html += '        return moment(time).format("HH");'
    html += '    }';
    html += '    function calculateArrowPosition(hour){'
    //html += '       console.log((hour) * (100 / 24) + "%");'
    html += '       return (hour / 24) * 100 +1 + "%";'
    html += '    }'
    html += '    function updateChart() {';
    html += '        var minValue = Math.min.apply(null, data.map(function (item) {';
    html += '          return item.value;';
    html += '        }));';
    //html += '        console.log(minValue);'
    // html += '        var yAxisMin = minValue - (minValue/10);'
    html += '        var yAxisMin = '+graphMin+';';
    html += '        var maxValue = '+dataMax+';'
    //html += '        var maxValue = '+graphMax+';'
    //html += '        console.log(maxValue);'
    // html += '        var yAxisMax = maxValue + (maxValue/10);'
    html += '        let avgValue = '+dataAvg+';'
    html += '        var visualMapPieces =' + colorJSON +';';
    html += '        var values = data.map(item => (item.value-minValue).toFixed(2));'
    html += '        var maxLineValue = Math.max.apply(null, values);'
    html += '        var maxLineIndex = values.indexOf(maxLineValue);'
    html += '        var maxLineData = {time:'+dataMaxTime+',value:'+dataMax+'};'
    html += '        var currentHour = new Date().getHours() ;'
    // html += '        console.log(currentHour);'
    //html += '        console.log(maxLineData.time);'
    // html += '        var maxV = parseFloat((Math.max(...values)));'
    //html += '        console.log(maxV);'
    //html += '        let pro = values.map((value) => (value/maxV).toFixed(2));'
    //html += '        console.log(values);'
    //html += '        console.log(pro);'
    html += '        var colorStops = [];'
    //html += '        console.log(yAxisMin +" "+maxValue);'
    if(!dataNull){
    html += '        visualMapPieces.map(piece => {'
    html += '          if(piece["lte"] >=yAxisMin && piece["gt"]<=maxValue){ '
    //html += '            console.log(piece["lte"] + " "+maxValue + " "+ yAxisMin);'
    html += '            if(piece["gt"]>=yAxisMin){'
    //html += '             console.log(piece["gt"] +" gt gesetzt " +yAxisMin);'
    html += '             colorStops.push({'
    html += '              offset:  ((piece["gt"]-yAxisMin)/(maxValue-yAxisMin)),'//  /((maxValue-minValue)/maxValue)  /(visualMapPieces[visualMapPieces.length - 1]["gt"])
    html += '              color: piece.color'
    html += '             });'
    html += '            }'
    html += '            if(piece["lte"]<=maxValue){'
    //html += '            console.log(piece["lte"] +" lte gesetzt "+yAxisMin);'
    html += '             colorStops.push({'
    html += '              offset:  ((piece["lte"]-yAxisMin)/(maxValue-yAxisMin)),'//  /((maxValue-minValue)/maxValue)  /(visualMapPieces[visualMapPieces.length - 1]["gt"])
    html += '              color: piece.color'
    html += '             });'
    html += '            }'
    html += '            if(piece["lte"]>maxValue ){'
    //html += '            console.log(piece["lte"] +" lte gesetzt "+yAxisMin);'
    html += '            colorStops.push({'
    html += '              offset:  1,'//  /((maxValue-minValue)/maxValue)  /(visualMapPieces[visualMapPieces.length - 1]["gt"])
    html += '              color: piece.color'
    html += '             });'
    //html += '            }'
    html += '           };'
    html += '          }else{'
    //html += '            console.log(piece["lte"] + " " + piece["gt"]);'
    html += '           if(piece["lte"]>=maxValue && piece["gt"]<=maxValue ){'
    //html += '            console.log(piece["lte"] +" lte gesetzt "+yAxisMin);'
    html += '            colorStops.push({'
    html += '              offset:  ((piece["lte"]-yAxisMin)/(maxValue-yAxisMin)),'//  /((maxValue-minValue)/maxValue)  /(visualMapPieces[visualMapPieces.length - 1]["gt"])
    html += '              color: piece.color'
    html += '            });'
    
    html += '           }else if(piece["lte"]>=maxValue && piece["gt"] <= maxValue){'
    // html += '            console.log("Drin");'
    html += '            colorStops.push({'
    html += '              offset:  ((piece["lte"]-yAxisMin)/(maxValue-yAxisMin)),'//  /((maxValue-minValue)/maxValue)  /(visualMapPieces[visualMapPieces.length - 1]["gt"])
    html += '              color: piece.color'
    html += '            });'
    html += '           }'
    html += '          }; ' 
    html += '        });'
    //html += '        console.log(colorStops);'
    //html += '        console.log(colorStops[colorStops.length-1].color);'
    html += '        colorStops.push({'
    html += '            offset: 1,' //visualMapPieces[visualMapPieces.length - 1]["gt"]
    html += '            color: colorStops[colorStops.length-1].color'// visualMapPieces[visualMapPieces.length - 1].color'
    html += '        });'
    //html += '        console.log(colorStops);'
    html += '        colorStops.splice(0, 0, {offset: 0,color:colorStops[0].color});'
    //html += '        colorStops.splice(0, 0, {offset: 0,color:colorStops[0].color});'
    //html += '        colorStops.splice(2, 0, {offset: colorStops[1].offset,color:colorStops[2].color});'
    //html += '        colorStops.splice(4, 0, {offset: colorStops[3].offset,color:colorStops[4].color});'
    //html += '        console.log(colorStops);'
    }
    if(dataNull && !getState(tibberShowGraphIfEmptyDP).val){
        html += '        myChart.setOption({';
    html += '            title: {';
    if(priceDP== 'PricesToday'){
        html += '                text: "'+getState(tibberLabelTodayDP).val+'",';
        if(getState(tibberShowLabelTodayDP).val){
            html += '            show: true'
        }else{
            html += '            show: false'
        }
    }else{
        if(dataNull && getState(tibberShowWaitLabelTomorrowDP).val){
              html += '          textAlign: "auto", '
              html += '          textStyle: { '
              html += '             color: "red"'
              html += '          },'
              html += '          left: "50px",'
              html += '          text: "'+getState(tibberWaitTomorrowTextDP).val +'",';
        }else{
            html += '            text: "'+getState(tibberLabelTomorrowDP).val+'",';
            if(getState(tibberShowLabelTomorrowDP).val){
                html += '        show: true,'
            }else{
                html += '        show: false,'        
            }
        }
        
        
    }
    
    html += '                 },});';
    }else{
    
    html += '        myChart.setOption({';
    html += '            title: {';
    if(priceDP== 'PricesToday'){
        html += '                text: "'+getState(tibberLabelTodayDP).val+'",';
        if(getState(tibberShowLabelTodayDP).val){
            html += '                show: true'
        }else{
            html += '                show: false'
        }
    }else{
        if(dataNull && getState(tibberShowWaitLabelTomorrowDP).val){
              html += '            textAlign: "auto", '
              html += '            textStyle: { '
              html += '               color: "red"'
              html += '            },'
              html += '            left: "50px",'
              html += '            text: "'+getState(tibberWaitTomorrowTextDP).val +'",';
        }else{
            html += '                text: "'+getState(tibberLabelTomorrowDP).val+'",';
            if(getState(tibberShowLabelTomorrowDP).val){
                html += '                show: true,'
            }else{
                html += '                show: false,'        
            }
        }
        
        
    }
    
    html += '            },';
    html += '            visualMap: {';
    html += '              type: "piecewise",'
    html += '              pieces: visualMapPieces,'
    html += '              dimension: 1,' // Mapping to the 'value' dimension'
    html += '              showLabel: true,'
    html += '              precision: 2,'
    html += '              itemWidth: 6,'
    html += '              orient: "horizontal",'
    html += '              left: "center", calculable: true,selectedMode: "multiple",'
    html += '              bottom: 10,'
    html += '              text: ["High", "Low"],'
    html += '              textStyle: {'
    if(getState(darkModeDP).val){
        html += '                color: "white"'
    }else{
        html += '                color: "black"'
    }
    html += '              },'
    //html += '              inRange: {'
    //html += '                color: colorStops.map(stop => stop.color)';//visualMapPieces.map(piece => piece.color)'
    //html += '              },'
    /* bringt nichts
    html += '              itemStyle:{'
    html += '                 symbol:"pin",'
    html += '                 symbolSize: 30,'
    html += '                 markPoint: {'
    html += '                   data: [{'
    html += '                    symbol: "circle",'
    html += '                       coord: [data.time, data.value], itemStyle:{ color:"red"}'
    html += '                    }]'
    html += '                 },'
    html += '               }'
    */
    html += '            },'
    
    if(minMaxAvg){
        html += '            grid: {';
        if(getState(tibberShowMinMaxAvgTextDP).val){
            html += '              right: 50,'; // Vergrößern Sie diesen Wert nach Bedarf
        }else{
            html += '              right: 10,';
        }
        html += '              left: 10,';
        html += '              containLabel: true'; // Stellen Sie sicher, dass das Label innerhalb des Diagramms bleibt
        html += '            },';
    }else{
        html += '            grid: {';
        html += '              right: 10,'; // Vergrößern Sie diesen Wert nach Bedarf
        html += '              left: 10,'; // Vergrößern Sie diesen Wert nach Bedarf
        html += '              containLabel: true'; // Stellen Sie sicher, dass das Label innerhalb des Diagramms bleibt
        html += '            },';
    }
    html += '            areaStyle: {'
    html += '              color: colorStops';//"red"'; visualMapPieces.map(piece => piece.color)'
    //html += '              color: "blue", '
    html += '            },'
    // Option für Pfeil unter Kurve
    /*
    if(!dataNull && getState(tibberHighlightCurrentHourDP).val){
    html += 'graphic: [{'
    html += '    type: "image",'
    html += '    id: "arrow",'
    html += '    bounding: "all",'
    html += '    z:100,'
    //html += '    origin: [calculateArrowPosition(currentHour), "10%"],'
    //html += '    origin: [0.5, 0],'  // Koordinaten für den Pfeil
    html += '    bottom: "10%", '
    html += '    left: calculateArrowPosition(currentHour),';//"50px",'
    html += '    '
    html += '    style: {'
    html += '        image: "https://api.iconify.design/mdi/arrow-up-bold.svg?width=24&height=24&color=blue", ' // Pfad zum Bild deines Pfeils
    html += '        width: 30,'
    html += '        height: 30,'
    html += '    }'
    html += '}],'
    }
    */
    // ToolBox
    html += '            toolbox: {';
    html += '              feature: {';
    html += '                saveAsImage: {';
    html += '                   backgroundColor: "rgba(38, 37, 37, 1)",';
    html += '                   title: "Speichern",';
    let fileName = priceDP.replace('Prices','') 
    if(fileName == 'Today'){
        fileName += ' '+ formatDate(new Date(),'DD.MM.YYYY'); 
    }else{
        fileName += ' '+ formatDate(new Date().getTime()+86400000,'DD.MM.YYYY'); 
    }
    html += '                   name: "TibberHTML '+fileName+'"'
    html += '                },'
    html += '                magicType: {';
    html += '                  type: ["line", "bar"],';
    html += '                  title:{';
    html += '                     line: "Line-Chart",';
    html += '                     bar: "Bar-Chart",';
    html += '                  }'
    
    html += '                },';
    html += '                dataView: {';
    html += '                  title: "Daten aus der Serie",';
    html += '                  lang: ["Daten der Kurve", "Schließen", "Aktualisieren"],'
    html += '                  optionToContent: function (opt) {';
    html += "                      var table = '<table style=\"width:100%;\"><tbody><tr style=\"text-align: left;\"><th>Stunde</th><th>Wert</th><th>Energie</th><th>Steuer</th><th>Level</th></tr>';";
    //html += '                      console.log(opt.series.length); '
    //html += '                      console.log(opt.series[0].data); '
    html += '                      for (var i = 0; i< opt.series[0].data.length;i++) {';
    html += '                          table += "<tr>";';
    html += '                         for(let x =0; x < opt.series[0].data[i].value.length; x++){'
    html += '                            if(x==0){';
    html += '                               table +=  "<td>" + ("0"+new Date(opt.series[0].data[i].value[x]).getHours()).slice(-2) + "</td>";';
    html += '                            }else{';
    html += '                               table +=  "<td>" + opt.series[0].data[i].value[x] + "</td>";';
    html += '                            } '
    html += '                         }';
    html += '                           table += "</tr>";';
    html += '                      }';
    html += '                      table += "</tbody></table>";'
    html += '                      return table;';
    html += '                  },';
    html += '                  readOnly: true';
    html += '                },'
    html += '              }';
    html += '            },'
    
    html += '            xAxis: {';
    html += '                type: "time",';
    html += '                axisLabel: {';
    html += '                    show: true,'
    html += '                    formatter: function (value) {';
    html += '                        return formatTime(value);';
    html += '                    }';
    html += '                },';
    html += '                splitNumber: 10,';
    html += '            },';
    html += '            yAxis: {';
    html += '                type: "value",';
    html += '                axisLabel: {'; 
    
    html += '                  formatter: function (value) {';
    html += '                     return value.toFixed(3) + " €";';
    html += '                  }';
    
    html += '                },';
    
    html += '               min: '+graphMin+','; //
    html += '               max: '+graphMax+',' //yAxisMax
    html += '            },';
    
    
    
    
    
    html += '            series: [{';
    
    html += '                data: data.map(function (item) {';
    html += '                    var hour = new Date(item.time).getHours();'
    html += '                    return {';
    html += '                       value: [item.time, item.value, item.energy, item.tax, item.level],';
    //html += '                       lineStyle: {width: hour === currentHour ? 10:null},'
    
    // Symbol für Line einstellen
    
    html += '                        symbol: "circle",'
    
    if(getState(tibberHighlightCurrentHourDP).val && priceDP == 'PricesToday'){
        html += '                    symbolSize: hour === currentHour ? 10:null, '
        html += '                    itemStyle: {'
           
        if(getState(darkModeDP).val){
            //html += '                           backgroundColor: hour === currentHour ? "'+getState(tibberHighlightColorDarkDP).val+'":null,'
            html += '                           borderColor: hour === currentHour ? "'+getState(tibberHighlightColorDarkDP).val+'":null,'
            html += '                           shadowColor: hour === currentHour ? "'+getState(tibberHighlightColorDarkDP).val+'":null,'
            html += '                           borderWidth: hour === currentHour ? 2:null,'
            html += '                           shadowBlur: hour === currentHour ? 20:null,'
        }else{
            html += '                           borderColor: hour === currentHour ? "'+getState(tibberHighlightColorLightDP).val+'":null,'
            html += '                           shadowColor: hour === currentHour ? "'+getState(tibberHighlightColorLightDP).val+'":null,'
            html += '                           borderWidth: hour === currentHour ? 1:null,'
            html += '                           shadowBlur: hour === currentHour ? 10:null,'
        }
        //html += '                           borderWidth: hour === currentHour ? 1:null,'
        //html += '                           shadowBlur: hour === currentHour ? 10:null,'
        
        html += '                     },'
        
    }
    // Aria für Schraffierung
    //html += 'aria: {'
    //html +='    enabled: true,'
    //html += '   decal: {'
    //html +='        show: hour === currentHour'
    //html += '   }'
    //html +='},'
    html += '                        emphasis: {';
    html += '                          itemStyle: {';
    html += '                            color: "white" '; // Füge die Farbe in die Betonung ein
    html += '                          },';
    html += '                          label: {';
    html += '                            show: true,';
    html += '                            formatter: function (params) {';
    html += '                               return params.data.value[1].toFixed(3) + " €";'; //console.log(params);
    html += '                            },';
    html += '                            color: "black",';
    html += '                            fontWeight: "bold", ';
    html += '                            backgroundColor: "white"';
    html += '                          }';
    html += '                        }';
    html += '                     } ';
    html += '                }),'; // end data
    
    if(getState(tibberSteppedLineDP).val){
        html += '            step: "end",'
    }
    // ItemStyle
    //html += '                itemStyle:{'
    //html += '                  color: function (params) {'
                // Färbe den Balken der aktuellen Stunde anders ein
    //html += '                    console.log(new Date(params.value[0]).getHours());'
    //html += '                    console.log(currentHour);'
    //html += 'console.log(new Date(params.value[0]).getHours() === currentHour ? "red" : "blue");'
    //html += '                    return new Date(params.value[0]).getHours() === currentHour ? "red" : "blue";'
    //html += '                  }'
    //html += '                },'
    if(getState(tibberAreaDP).val){
    html += '                areaStyle:{'
    html += '                    color: new echarts.graphic.LinearGradient(0, 1, 0, 0, colorStops),' ;
    
    //html += '                    color:  colorStops,'
    // html += '                    max: maxValue, '
    /*
    html += '                    color: function (params) {'
    html += '                       console.log(params);'
    html += '                       var wert = params.data.value[1];'
    html += '                       var col = "red";'
    html += '                       for (var i = 0; i < visualMapPieces.length; i++) {'
    html += '                           var piece = visualMapPieces[i];'
    html += '                           if (wert >= piece.gt && wert <= piece.lte) {'
    html += '                               col = piece.color;'
    html += '                               break;'
    html += '                           }'
    html += '                       }'
    html += '                       return col;'
    html += '                   },'
    */
    html += '                },'
    }
    html += '                type: "'+getState(tibberGraphTypeDP).val+'",';
    //html += '               markArea: {'
    //html += '                   silent: true,'
    //html += '                   data: ['
    //html += '                       [{'
    //html += '                           xAxis: "min",'
    //html += '                           itemStyle: {'
    //html += '                               color: "rgba(0, 0, 0, 0.7)"'
    //html += '                           }'
    //html += '                           }, {'
    //html += '                               xAxis: "max",'
    //html += '                       }]'
    //html += '                   ]'
    //html += '               },'
    
    if(minMaxAvg){
        html += '                markLine: {';
        html += '                  symbol: "none",';  // Kein Symbol für die Markierungslinie
        html += '                  lineStyle: {';
        html += '                    color: "red",';   // Farbe der Markierungslinie
        html += '                    type: "dashed"';  // Art der Linie (gestrichelt)
        html += '                  },';
        
        if(getState(tibberShowMinMaxAvgTextDP).val){ //coord: [maxLineData.time, maxLineData.value] ,)
            if(!dataNull){
            html += '                  data: [';
            html += '                   {yAxis: minValue ,name: "MIN", lineStyle: { color: "lime" },label: { show: true, position: "end", formatter: "Min\\n"+ minValue.toFixed(3)+" €",textStyle: { fontSize: 12,fontWeight: "bold", color:"white"  } }  },';
            html += '                   {yAxis: maxValue,name: "MAX", lineStyle: { color: "red" },label: { show: true, position: "end", formatter: "Max\\n"+ maxValue.toFixed(3)+" €",textStyle: { fontSize: 12,fontWeight: "bold", color:"white"  } } },';
            html += '                   {yAxis: avgValue ,name: "AVG", lineStyle: { color: "blue" },label: { show: true, position: "end", formatter: "Avg\\n"+ avgValue.toFixed(3)+" €",textStyle: { fontSize: 12,fontWeight: "bold", color:"white"  } } }';
            html += '                  ], '
            }
        }else{
            if(!dataNull){
            html += '                  data: [';
            // funktioniert nicht !,tooltip: {show: true,formatter: "Min\\n\\n" + params.value.toFixed(3) + " €",textStyle: {fontSize: 12,fontWeight: "bold",color: "white"}}  ,formatter: "Min " + minValue.toFixed(3) + " €"
            html += '                   {yAxis: minValue ,name: "MIN", lineStyle: { color: "lime" },label: { show: false, position: "end", formatter: "Min\\n\\n"+ minValue.toFixed(3)+" €",textStyle: { fontSize: 12,fontWeight: "bold", color:"white"  } }  },';
            html += '                   {yAxis: maxValue,name: "MAX", lineStyle: { color: "red" },label: { show: false, position: "end", formatter: "Max\\n\\n"+ maxValue.toFixed(3)+" €",textStyle: { fontSize: 12,fontWeight: "bold", color:"white"  } } },';
            html += '                   {yAxis: avgValue ,name: "AVG", lineStyle: { color: "blue" },label: { show: false, position: "end", formatter: "Avg\\n\\n"+ avgValue.toFixed(3)+" €",textStyle: { fontSize: 12,fontWeight: "bold", color:"white"  } } }';
            html += '                  ], '    
            }    
        }
        html += '                }';
    }
    html += '            }],'; // Ende Series
    
    
    
    
    html += '            tooltip: {';
    html += '              trigger: "axis",';
    html += '              axisPointer: {';
    html += '               type: "shadow"';
    html += '              },';
    html += '              textStyle: {';
    html += '                fontFamily: "Courier",';
    html += '                fontWeight: "bold"'; // Hinzugefügt
    html += '              },'
    html += '              formatter: function (params) {';
    html += '                let time = "Start ab: "+ moment(params[0].axisValue).format("HH:mm")+ " Uhr";';
    html += '                let value = "Preis:&nbsp&nbsp&nbsp&nbsp"+params[0].value[1].toFixed(4) + " €";';
    if(showTaxEnergy){
        html += '            let energy = "Energie:&nbsp&nbsp"+params[0].value[2].toFixed(4) + " €";'
        html += '            let tax    = "Steuer:&nbsp&nbsp&nbsp"+params[0].value[3].toFixed(4) + " €";'
        html += '            let lev    = "Level:&nbsp&nbsp&nbsp&nbsp"+ params[0].value[4];'
        html += "            return  `${time}<br/>${value}<br/>${energy}<br/>${tax}<br/>${lev}` ;";
    }else{
        //html += "            return `<span style=\"font-family: 'Arial'; font-weight: 'bold';\" >${time}<br/>${value}</span>` ;";
        html += "            return `${time}<br/>${value}` ;";
    }
    
    html += '              }';
    html += '            },';
    
    html += '        }) ';// end setOption
    }
    html += '    }'; 
    
    
    html += '    updateChart(); ';
    html +='     var updateInterval = setInterval(updateChart, 3600000);'
    html += '</script>';
    html += '</body>';
    html += '</html>';
    
    // log(html);
    if(priceDP == 'PricesToday'){
        setState(tibberHTMLTodayDP,html);
    }else{
        setState(tibberHTMLTomorrowDP,html);
    }
    

    }

    function sortByName(x, y) {
    // Wenn x oder y nicht-numerisch sind, setze sie an das Ende
    if (isNaN(x.hour) || isNaN(y.hour)) {
    return isNaN(x.hour) ? 1 : -1;
    }

    // Vergleiche numerische Werte
    return x.hour - y.hour;
    

    }

    on({id: dbHistoryDP, change: "any"}, function (obj) {
    let value = obj.state.val;
    // history für die DPs aktiv?
    if (value!=''){
    if (getState('system.adapter.'+value+'.alive').val){
    if (isHistoryActiveAllDPs(dpArray)){
    if(logging){
    log('History-Future-DPs sind angelegt und History aktiviert!');
    }
    // getPVData(dpArray);
    //runScript();
    }else{
    if(logging){
    log('History wird angelegt für die future-DPs!');
    }
    activateDPsHistory(dpArray);
    setTimeout(function(){
    deleteAllHistoryDPs(dpArray);
    // log('gelöscht');
    // getPVData(dpArray);
    },3000)
    //runScript();
    }
    }else{
    log('Der History-Adapter ist nicht gestartet! -> Es werden keine DPs mit History aktiviert','warn');
    }
    }
    });

    function setDPs(tibberInst){
    // Ist der Adapter aktiv
    //
    //let pvAliveDP = 'system.adapter.pvForecast.'+tibberInst+'.alive';
    //if(existsState(pvAliveDP)){
    // if(getState(pvAliveDP).val){
    // Adapter ist gestartet
    let tibberKeys = ['Value','Tax','Energy']
    for(let i=0;i<tibberKeys.length;i++){
    dpArray.push(tibberDP+'.future'+tibberKeys[i]);
    }

    //    }else{
    //        log('Der Adapter tibberlink.'+tibberInst+' ist nicht gestartet!');
    //    }
    //}else{
    //    log('Der Adapter pvForecast ist nicht installiert')
    //}
    // Alte erst löschen
    // Nur löschen, wenn sich die DPs geändert haben
    let delItems = false;
    if(dpArray.length >0){
        // delDPs(dpArray);
        
        for(let i=0;i<dpArray.length;i++){
            if(existsState(dpArray[i])){
    
            }else{
                delItems = true;
                delDPs(dpArray);
                break;
            }
        }
    }
    if(delItems){
        setTimeout(function() {
            if(dpArray.length >0){
                createDPs(dpArray);
            }
        },3000);
    }else{
        createDPs(dpArray);
    }
    

    }

    function delDPs(arr){
    for(let i=0; i<arr.length;i++){
    if(existsState(arr[i])){
    deleteStateAsync(arr[i]);
    }
    }
    }
    // createStateAsync(futureTempDP, {read: true, write: false, name: "daswetter temperature", type: "number", role: "", def: 0 });

    function createDPs(arr){
    for(let i=0; i<arr.length;i++){
    // 0_userdata.0.pvForecastHistory.historyDB
    let name = levelObject(arr[i])[3];
    createStateAsync(arr[i], {read: true, write: false, name: "tibber"+name, type: "number", role: "", def: 0 });
    }
    }

    function seteChartsDP(dpArray){
    let startDT = getDateObject('00:00').getTime(); // heute 00:00
    // pvForecast hat nur 2 Tage im Array
    let endDT = startDT + 24160601000;
    // start_time, end_time, start, end, timeType
    for(let i=0;i<dpArray.length;i++){
    let echartDP = 'echarts.0.tibber'+levelObject(dpArray[i])[3];
    let obj;
    if (existsObject(echartDP)){
    obj = getObject(echartDP);
    //log(obj);
    if (obj.native.data.timeType == 'static'){
    obj.native.data.start = formatDate(startDT,'YYYY-MM-DD');
    obj.native.data.end = formatDate(endDT,'YYYY-MM-DD');
    obj.native.data.start_time = '00:00';
    obj.native.data.end_time = '00:00';
    setObject(echartDP,obj);
    }
    }
    }
    }

    function isHistoryActiveAllDPs(dpArray){
    // dparray automatisch gesetzt
    let active = false;
    let dbHistory = getState(dbHistoryDP).val;
    if (dbHistory != ''){
    for(let i= 0;i<dpArray.length;i++){
    let dpPara = levelObject(dpArray[i])[3];
    // log('dpPara: '+dpPara);
    // log(pvForecastDP+'.future'+dpPara);
    // setActiveHistory(pvForecastDP+'.future'+dpPara);
    active = isHistoryActive(tibberDP+'.'+dpPara,dbHistory);
    if(active == false){
    return false;
    }
    }

        log('Tibber-DPs History aktiv');
        return true;
    }else{
        log('DB Auswahl fehlt');
        return false;
    }
    

    }

    function isHistoryActive(dp,db){
    let obj = getObject(dp);
    if (obj.common.custom != undefined){
    //log(obj.common.custom);
    let custom = obj.common.custom;

        for (let key in custom){
            //log(key);
            if (key.indexOf(db)>=0){  //'history'
                return true;
            }
        }
    }
    return false;
    

    }

    function activateDPsHistory(dpArray){
    let historyDB = getState(dbHistoryDP).val;
    //log('HistoryDB: '+historyDB);
    if (historyDB != ''){
    if (getState('system.adapter.'+historyDB+'.alive').val){

            if (historyDB!=''){
                for(let i= 0;i<dpArray.length;i++){
                    //log('DParray[i]: '+dpArray[i]);
                    let dpPara = levelObject(dpArray[i])[3];
                    //log('dpPara: '+dpPara);
                    //log(pvForecastDP+'.'+dpPara);
                    setActiveHistory(tibberDP+'.'+dpPara);
                    setTimeout(function(){
                        deleteAllHistoryData(tibberDP+'.'+dpPara);
                    },2000)
                }
                log('Future-DPs History aktiviert');
            }else{
                log('Es wurde keine DB für Future-History ausgewählt!','warn');
            }
        }else{
            log('Der Adapter ist nicht gestartet! -> keine Aktivierung möglich','warn');
        }
    }else{
        log('Aktivierung der DPs für die DB erst möglich, wenn man eine DB ausgewählt hat!','warn');
    }
    

    }

    // deleteAllHistoryDPs();

    function deleteAllHistoryDPs(dpArray){
    let dbHistory = getState(dbHistoryDP).val;
    if (getState('system.adapter.'+dbHistory+'.alive').val){
    log('History DPs dpArray löschen!');
    for(let i= 0;i<dpArray.length;i++){
    //log('DParray[i]: '+dpArray[i]);
    let dpPara = levelObject(dpArray[i])[3];
    //log('dpPara: '+dpPara);
    //log(pvForecastDP+'.'+dpPara);
    deleteAllHistoryData(tibberDP+'.'+dpPara);

        }
        log('Future-DPs History gelöscht');
    }else{
        log('Adapter nicht gestartet!');
    }
    

    }

    function deleteAllHistoryData(dp){
    let dbHistory = getState(dbHistoryDP).val;
    if (dbHistory!=''){
    //let dtStart= getDateObject('00:00').getTime(); // heute 00:00 Uhr
    //let dtStop = dtStart + 24660601000;
    sendTo(dbHistory, 'deleteAll', [ // 'history.0' 'deleteRange'
    {id: dp}//, start: dtStart, end: dtStop

        ], result => {//console.log('deleted')
        });
    }else{
        log('Löschen nicht durchgeführt, da keine HistoryDB festgelegt');
    }
    

    }

    function getHistoryAdapter(){
    // history, influxdb, sql
    log('Einlesen der vorhandenen History-DBs.');
    let histArr = ['history','influxdb','sql'];
    let arr =[];
    for (let i=0; i<histArr.length;i++){
    let dp = $('system.adapter.'+histArr[i]+'.*.alive');
    //log(dp);
    for(let x=0;x<dp.length;x++){
    //log(dp[x]);
    let dpID = dp[x];

            if (getObject(dpID).common != undefined){
                //log(getState(dpID).val);
                if (getState(dpID).val != null && getState(dpID).val){
                    dp[x] = dp[x].substring(15,dp[x].length-6);
                    // log(dp[x]);
                    arr.push(dp[x]);
                }
                if (getState(dpID).val == null){
                    log('History-Adapter ist fehlerhaft: '+dp[x] +' -> alive auf false setzen');
                }
            }
        }
    
    }
    let devStates = {'':'keine Auswahl'};
    for (let i=0; i< arr.length;i++){
        devStates[arr[i]] = arr[i];
    }
    //log(devStates);
    if (existsState(dbHistoryDP)){
        let obj = getObject(dbHistoryDP);
        obj.common.states = devStates;
        setObject(dbHistoryDP,obj);
    }else{
        createStateAsync(dbHistoryDP, {read: true, write: true, name: "DB-Auswahl", type: "string", role: "", def: '',states:devStates });    
    }
    

    }

    function setActiveHistory(dp){
    let dbHistory = getState(dbHistoryDP).val;
    //log('dbHistory setActive: '+dbHistory);
    if (dbHistory !=''){
    sendTo(dbHistory, 'enableHistory', { // 'history.0'
    id: dp, // 'system.adapter.history.0.memRss'
    options: {
    changesOnly: true,
    debounce: 0,
    retention: 31536000,
    maxLength: 3,
    changesMinDelta: 0,
    //ignoreZero: true,
    aliasId: '',
    enabled: true,
    debounceTime: 0,
    blockTime: 0,
    changesRelogInterval: "0",
    ignoreBelowNumber: "",
    disableSkippedValueLogging: false,
    customRetentionDuration: 365,
    enableDebugLogs: false

            }
        }, function (result) {
            if (result.error) {
                console.log(result.error);
            }
            if (result.success) {
                //successfull enabled
                //log(dp +' wurde in history aktiviert');
            }
        });
    }
    

    }

    // setHistoryData(futureHumidityDP,dpValueArr);

    function setHistoryData(dp,states){
    let dbHistory = getState(dbHistoryDP).val;
    if (dbHistory!=''){
    sendTo(dbHistory, 'storeState', { // 'history.0'
    id: dp,
    state: states
    }, result => {
    // console.log('added')
    });
    }
    }

    function levelObject(id){
    // 0_userdata.0.jarvis.system.tabWidgetStateEffects.0.Desktop.0.Bad.0b5dd758-8d7d-4259-8945-821b1c942960.states.0.displayOff
    let idArr=id.split('.');
    return idArr; //log(idArr[10]);
    }

    // log(getDPLevel(levelObject('0_userdata.0.jarvis.system.tabWidgetStateEffects.0.Desktop.0.Bad.0b5dd758-8d7d-4259-8945-821b1c942960.states.0.displayOff'),9));
    function getDPLevel(idArr,level){
    let id ='';
    for (let i=0;i<=level;i++){
    id += idArr[i] +'.'
    }
    id = id.substr(0,id.length-1); // letzten Punkt wegnehmen
    return id;
    }

    1 Antwort Letzte Antwort
    0
    • M Meikie

      @mcu admin.0
      2024-01-05 23:47:34.290 info <== Disconnect system.user.admin from ::ffff:192.168.178.51 javascript

      Das Einzige.

      M Online
      M Online
      MCU
      schrieb am zuletzt editiert von MCU
      #402

      @meikie Die kommt ja nur, wenn man den javascript TAB schließt.
      Bitte in CODE-TAG.
      oder in ein txt-Datei

      NUC i7 64GB mit Proxmox ---- Jarvis Infos Aktualisierungen der Doku auf Instagram verfolgen -> mcuiobroker Instagram
      Wenn Euch mein Vorschlag geholfen hat, bitte rechts "^" klicken.

      M 1 Antwort Letzte Antwort
      0
      • M MCU

        @meikie Die kommt ja nur, wenn man den javascript TAB schließt.
        Bitte in CODE-TAG.
        oder in ein txt-Datei

        M Offline
        M Offline
        Meikie
        schrieb am zuletzt editiert von
        #403
        // *********************************
        // tibberHTML v1.0.24
        // *********************************
        // Copyright ©MCU
        // v1.0.1 - Erweiterung Umschaltung Line/bar im Graph, Anzeige der Werte in Tabelle
        // v1.0.2 - Vis Auswahl -> fete Breite für VIS, darkMode
        // v1.0.3 - Min,max,avg kleiner, untereinander, rechts Breite kleiner
        // v1.0.4 - ShowMinMaxAvgTexte optional
        // v1.0.5 - toolBox -Speichern mit Namen+Datum
        // v1.0.6 - y-Skala auf beiden Kurven gleich 
        // v1.0.7 - splitNumber auf 10 vorher 3, grid rechts 10 statt 30, visualMap - mobile optimiert
        // v1.0.8 - CurveArea optional, Korrektur wenn tomorrow.mim = 0 -> graphMin =0
        // v1.0.9 - graphMax angepasst auf nächste 0.01
        // v1.0.10- graphMin angepassz auf nächste 0.01
        // v1.0.11- Label optional, falls man schon Widget-Title nutzt 
        // v1.0.12 - Trennung Label Today und Tomorrow
        // v1.0.13 - optionaler Text für Tomorrow Wait
        // v1.0.14 - automatischer Reload bei Umschaltung wait-Text Tomorrow
        // v1.0.15 - aktuelle Zeit highlightCurrentHour
        // v1.0.16 - Symbol für Line aktuelle Stunde angepasst
        // v1.0.17 - stepped line hinzugefügt, Korrekturen graphMin
        // v1.0.18 - Korrektur showwait
        // v1.0.19 - Korrektur showwait
        // v1.0.20 - Abschaltung Anzeige Graph, wenn leer, Korrektur highlightPoint
        // v1.0.21 - Korrektur dataNull für visualMapPieces
        // v1.0.22 - Inhalt von DPs als Datei speichern
        // v1.0.23 - Korrektur 1.Farbelement lte > maxValue
        // v1.0.24 - Korrektur 1. Farbelement Umstellung Linie, falsche Berechnung
        // ToDo
        // - optionale Zeit vor günstiger Stunde telegram senden, alexa info, pushOver senden
        // - Ersparnis in Prozent -> Tabelle / Anzeige?
        // - Stunden erweitern für steppedLine?
        
        let logging                     = true;
        let tibberDP                    = '0_userdata.0.Strom.tibberHistory';
        let dbHistoryDP                 = tibberDP + '.historyDB';
        let tibberGraphTypeDP           = tibberDP + '.graphTyp'; // bar  oder line
        let tibberInstDP                = tibberDP + '.instanz'; // 0
        let tibberColorDP               = tibberDP + '.colorJSON'; // visualMapPieces [ {gt: 0, lte: 0.15, color: "lightgreen"},]
        let tibberHTMLTodayDP           = tibberDP + '.htmlToday';
        let tibberHTMLTomorrowDP        = tibberDP + '.htmlTomorrow';
        let tibberShowTaxEnergyDP       = tibberDP + '.showTaxEnergy'; // boolean
        let tibberShowMinMaxAvgDP       = tibberDP + '.showMinMaxAvg'; // boolean
        let visDP                       = tibberDP + '.vis';
        let darkModeDP                  = tibberDP + '.darkMode';
        let tibberShowMinMaxAvgTextDP   = tibberDP + '.showMinMaxAvgText';
        let tibberAreaDP                = tibberDP + '.curveArea';
        let tibberShowLabelTodayDP      = tibberDP + '.showLabelToday';
        let tibberLabelTodayDP          = tibberDP + '.labelToday';
        let tibberShowLabelTomorrowDP   = tibberDP + '.showLabelTomorrow';
        let tibberLabelTomorrowDP       = tibberDP + '.labelTomorrow';
        let tibberWaitTomorrowTextDP    = tibberDP + '.labelTomorrowWait';
        let tibberShowWaitLabelTomorrowDP = tibberDP + '.showLabelTomorrowWait';
        let tibberHighlightCurrentHourDP = tibberDP +'.highlightCurrentHour';
        let tibberHighlightColorDarkDP   = tibberDP + '.highlightColorDark';
        let tibberHighlightColorLightDP  = tibberDP + '.highlightColorLight';
        let tibberSteppedLineDP         = tibberDP + '.steppedLine';
        let tibberShowGraphIfEmptyDP    = tibberDP + '.showGraphIfEmpty';
        
        let dpArray                 = [];
        
        createStateAsync(tibberHTMLTodayDP, {read: true, write: true, name: "Tibber HTML für Heute", desc:"HTML-DP", type: "string", role: "", def: "" });
        createStateAsync(tibberHTMLTomorrowDP, {read: true, write: true, name: "Tibber HTML für Morgen", desc:"HTML-DP", type: "string", role: "", def: "" });
        createStateAsync(tibberColorDP, {read: true, write: true, name: "Farbdefinition für Balken", desc:"JSON-DP", type: "string", role: "", 
        def: JSON.stringify([{ 'gt': 0,'lte': 0.15, 'color': 'lightgreen' },
                            {'gt': 0.15,'lte': 0.22,'color': 'green'},
                            {'gt': 0.22,'lte': 0.29,'color': 'yellow'},
                            {'gt': 0.29,'lte': 0.35,'color': 'orange'},
                            {'gt': 0.35,'color': 'red'}]) });
        createStateAsync(tibberGraphTypeDP, {read: true, write: true, name: "Tibber Graph Typ Auswahl", desc:"GraphType-DP", type: "string", role: "", states: {"bar":"bar","line":"line"} ,def: "bar" });
        createStateAsync(tibberInstDP, {read: true, write: true, name: "Tibber Instanz", desc:"Instanz-DP", type: "string", role: "", def: "0" });
        createStateAsync(tibberShowTaxEnergyDP, {read: true, write: true, name: "Tax und Energy anzeigen bei Hover", desc:"Show-DP", type: "boolean", role: "", def: false });
        createStateAsync(tibberShowMinMaxAvgDP, {read: true, write: true, name: "Min, Max und Mittelwert anzeigen", desc:"Show-DP", type: "boolean", role: "", def: false });
        createStateAsync(tibberShowMinMaxAvgTextDP, {read: true, write: true, name: "Min, Max und Mittelwert Texte anzeigen", desc:"ShowText-DP", type: "boolean", role: "", def: false });
        createStateAsync(visDP, {read: true, write: true, name: "Welche VIS soll genutzt werden?", desc:"VIS-DP", type: "string", role: "",states: {"jarvis":"jarvis","VIS":"VIS"} , def: "jarvis" });
        createStateAsync(darkModeDP, {read: true, write: true, name: "DarkMode an?", desc:"DarkMode-DP", type: "boolean", role: "", def: false });
        createStateAsync(tibberAreaDP, {read: true, write: true, name: "Fläche unter Kurve?", desc:"CurveArea-DP", type: "boolean", role: "", def: false });
        createStateAsync(tibberShowLabelTodayDP, {read: true, write: true, name: "Label Today anzeigen?", desc:"showLabel-DP", type: "boolean", role: "", def: false });
        createStateAsync(tibberLabelTodayDP, {read: true, write: true, name: "Label Today für das Chart", desc:"Label-DP", type: "string", role: "", def: "Today-Tageswerte" });
        createStateAsync(tibberShowLabelTomorrowDP, {read: true, write: true, name: "Label Tomorrow anzeigen?", desc:"showLabel-DP", type: "boolean", role: "", def: false });
        createStateAsync(tibberLabelTomorrowDP, {read: true, write: true, name: "Label Tomorrow für das Chart", desc:"Label-DP", type: "string", role: "", def: "Tomorrow-Tageswerte" });
        createStateAsync(tibberShowWaitLabelTomorrowDP, {read: true, write: true, name: "Label Wait Tomorrow anzeigen?", desc:"showLabel-DP", type: "boolean", role: "", def: false });
        createStateAsync(tibberWaitTomorrowTextDP, {read: true, write: true, name: "Label Wait Tomorrow für das Chart", desc:"Label-DP", type: "string", role: "", def: "Werte erst ab 14.00 Uhr verfügbar" });
        createStateAsync(tibberHighlightCurrentHourDP, {read: true, write: true, name: "Aktuelle Stunde markieren?", desc:"HighlightAktHour-DP", type: "boolean", role: "", def: false });
        createStateAsync(tibberHighlightColorDarkDP, {read: true, write: true, name: "HighLight Color DarkMode", desc:"HighLight Dark-DP", type: "string", role: "", def: "white" });
        createStateAsync(tibberHighlightColorLightDP, {read: true, write: true, name: "HighLight Color LightMode", desc:"HighLight Light-DP", type: "string", role: "", def: "grey" });
        createStateAsync(tibberSteppedLineDP, {read: true, write: true, name: "Gestufte Linie?", desc:"SteppedLine-DP", type: "boolean", role: "", def: false });
        
        createStateAsync(tibberShowGraphIfEmptyDP, {read: true, write: true, name: "Graph anzeigen ohne Daten?", desc:"showGraph-DP", type: "boolean", role: "", def: false });
        
        // getHistoryAdapter();
        
        // setDPs('0'); // -> dpArray 
        
        setTimeout(function(){
            getTibberData(dpArray);
            let inst = getState(tibberInstDP).val;
            $('tibberlink.'+inst+'.Homes.*.PricesTomorrow.json').on(function(obj) {
                setTimeout(function(){
                    getTibberData(dpArray);
                },3000)
            });
        
            $('tibberlink.'+inst+'.Homes.*.PricesToday.json').on(function(obj) {
                setTimeout(function(){
                    getTibberData(dpArray);
                },3000);
            });
        
        },3000);
        
        let scheduleId ;
        if(getState(tibberHighlightColorDarkDP).val){
            scheduleId = schedule('00 * * * *', () => {
                        
                getTibberData(dpArray);
            })
        }
        
        on({id: tibberHighlightCurrentHourDP, change: "any"}, function (obj) {
            let value = obj.state.val;
            if(value){
                getTibberData(dpArray);
                clearSchedule(scheduleId);
                scheduleId = schedule('00 * * * *', () => {
                    getTibberData(dpArray);
                })
            }else{
                clearSchedule(scheduleId);
                getTibberData(dpArray);
            }
        })
        on({id: tibberShowTaxEnergyDP, change: "any"}, function (obj) {
            getTibberData(dpArray);
        });
        on({id: tibberColorDP, change: "any"}, function (obj) {
            getTibberData(dpArray);
        });
        
        on({id: tibberShowMinMaxAvgDP, change: "any"}, function (obj) {
            getTibberData(dpArray);
        });
        on({id: tibberShowMinMaxAvgTextDP, change: "any"}, function (obj) {
            getTibberData(dpArray);
        });
        
        on({id: tibberGraphTypeDP, change: "any"}, function (obj) {
            getTibberData(dpArray);
        });
        on({id: darkModeDP, change: "any"}, function (obj) {
            getTibberData(dpArray);
        });
        on({id: tibberAreaDP, change: "any"}, function (obj) {
            getTibberData(dpArray);
        });
        on({id: tibberShowLabelTodayDP, change: "any"}, function (obj) {
            getTibberData(dpArray);
        });
        on({id: tibberShowLabelTomorrowDP, change: "any"}, function (obj) {
            getTibberData(dpArray);
        });
        
        on({id: tibberShowWaitLabelTomorrowDP, change: "any"}, function (obj) {
            getTibberData(dpArray);
        });
        
        on({id: tibberHighlightColorDarkDP, change: "any"}, function (obj) {
            getTibberData(dpArray);
        });
        
        on({id: tibberHighlightColorLightDP, change: "any"}, function (obj) {
            getTibberData(dpArray);
        });
        on({id: tibberSteppedLineDP, change: "any"}, function (obj) {
            getTibberData(dpArray);
        });
        on({id: tibberShowGraphIfEmptyDP, change: "any"}, function (obj) {
            getTibberData(dpArray);
        });
        
        
        function getTibberData(arr){
            // arr wird nur für eCharts benötigt
            
            // tibberDataDP selbst ermitteln
            let tibberInst = getState(tibberInstDP).val;
            let priceArr = ['PricesToday','PricesTomorrow'];
            for(let x=0;x< priceArr.length;x++){
                let tibberData = [];
                let tibberLink = $('tibberlink.'+tibberInst+'.Homes.*.'+priceArr[x]+'.json')
                if(tibberLink[0] != undefined){
                    let tblLevel = levelObject(tibberLink[0]);
                    let dpLeveltbl = getDPLevel(tblLevel,4);
                    let tibberJSON = JSON.parse(getState(dpLeveltbl+'.json').val);
                    // tibberJSON
                    for(let i=0;i<tibberJSON.length;i++){
                        let obj = {};
                        obj.hour     = parseInt(tibberJSON[i].startsAt.substring(11,13));
                        obj.start   = tibberJSON[i].startsAt
                        obj.startTS = new Date(obj.start).getTime();
                        obj.value   = tibberJSON[i].total;
                        obj.energy   = tibberJSON[i].energy;
                        obj.tax   = tibberJSON[i].tax;
                        obj.min = false;
                        obj.max = false;
                        obj.average = false;
                        obj.level = tibberJSON[i].level;
                        tibberData.push(obj);
                    }
                    // average, minium, maximum direkt holen
                    
                    let eleArr = ['average','minimum','maximum'];
                    for(let i=0;i<eleArr.length;i++){
                        let obj = {};
                        switch (eleArr[i]) {
                                case 'average':
                                    obj.hour     = 'non'
                                    obj.start   = ''
                                    obj.startTS = 0;
                                    obj.value   = getState(dpLeveltbl+'.'+eleArr[i]+'.total').val
                                    obj.energy   = getState(dpLeveltbl+'.'+eleArr[i]+'.energy').val
                                    obj.tax   = getState(dpLeveltbl+'.'+eleArr[i]+'.tax').val
                                    obj.min = false;
                                    obj.max = false;
                                    obj.average = true;
                                    obj.level = '';
                                    tibberData.push(obj);
                                    break;
                                case 'minimum':
                                    obj.hour    = 'non';
                                    obj.start   = getState(dpLeveltbl+'.'+eleArr[i]+'.startsAt').val
                                    obj.startTS = new Date(obj.start).getTime();
                                    obj.value   = getState(dpLeveltbl+'.'+eleArr[i]+'.total').val
                                    obj.energy   = getState(dpLeveltbl+'.'+eleArr[i]+'.energy').val
                                    obj.tax   = getState(dpLeveltbl+'.'+eleArr[i]+'.tax').val
                                    obj.min = true;
                                    obj.max = false;
                                    obj.average = false;
                                    tibberData.push(obj);
                                    break;
                                case 'maximum':
                                    obj.hour    = 'non';
                                    obj.start   = getState(dpLeveltbl+'.'+eleArr[i]+'.startsAt').val
                                    obj.startTS = new Date(obj.start).getTime();
                                    obj.value   = getState(dpLeveltbl+'.'+eleArr[i]+'.total').val
                                    obj.energy   = getState(dpLeveltbl+'.'+eleArr[i]+'.energy').val
                                    obj.tax   = getState(dpLeveltbl+'.'+eleArr[i]+'.tax').val
                                    obj.min = false;
                                    obj.max = true;
                                    obj.average = false;
                                    tibberData.push(obj);
                                    break;
                                default: 
                                    break;
                            }
                    }
                    // log(tibberData);
                    let setechart = false;
                    if(setechart){
                        for(let i=0;i<dpArray.length;i++){
                            setHistoryData(dpArray[i],tibberObj[levelObject(dpArray[i])[3]]);
                        }
                        seteChartsDP(dpArray);
                    }
                    // log('setHTML');
                    setHTML(tibberData,priceArr[x]);
                    if(getState(visDP).val=='VIS'){
                        createHtmlFile(priceArr[x])
                    }
                }
                
            }
            
        }
        // createHtmlFile();
        async function createHtmlFile(name) {
            let dp = '';
            let file = '';
            if(name == 'PricesToday'){
                dp = '0_userdata.0.Strom.tibberHistory.htmlToday';
                file = 'today';
            }else{
                dp = '0_userdata.0.Strom.tibberHistory.htmlTomorrow';
                file = 'tomorrow';
            }
            const htmlContent = getState(dp).val;
            writeFile('vis.0', '/tibber/'+file+'.html',htmlContent, (err) => {
                if (err) {
                console.error('Fehler beim Speichern der HTML-Datei, tibber-Verzeichnis angelegt?', err);
                } else {
                console.log('HTML-Datei '+file+'.html erfolgreich gespeichert');
                }
            });
        }
        
        
        
        function setHTML(origData,priceDP){
            let data = [];
            let dataMin = '';
            let dataMinTime = '';
            let dataMax = '';
            let dataMaxTime = '';
            let dataAvg = '';
            let dataNull = false;
            // log(priceDP);
            let tibberInst = getState(tibberInstDP).val;
            let tibberLink = $('tibberlink.'+tibberInst+'.Homes.*.PricesToday.json')
            let tblLevel = levelObject(tibberLink[0]);
            let dpLeveltbl = getDPLevel(tblLevel,3);
            
            let minToday = getState(dpLeveltbl + '.PricesToday.minimum.total').val;
            //minToday = minToday-(Math.trunc(minToday*0.1))
            // log(minToday)
            let maxToday = getState(dpLeveltbl + '.PricesToday.maximum.total').val
            let minTomorrow = getState(dpLeveltbl + '.PricesTomorrow.minimum.total').val
            //minTomorrow = minTomorrow-(Math.trunc(minTomorrow*0.1))
            let maxTomorrow = getState(dpLeveltbl + '.PricesTomorrow.maximum.total').val
            let jsonTomorrow = JSON.parse(getState(dpLeveltbl + '.PricesTomorrow.json').val);
            
            let graphMin = 0;
            if(minToday >= minTomorrow){
                if(minTomorrow != 0){
                    graphMin = minTomorrow;
                }else{
                    graphMin = minToday;
                }
            }else{
                graphMin = minToday;
            }
            let graphMax = 0;
            if(maxToday >= maxTomorrow){
                graphMax = maxToday;
            }else{
                graphMax = maxTomorrow;
            }
            // graphMax = Math.round((graphMax + parseFloat((graphMax / 20).toFixed(2))) * 100) / 100;
            // graphMax = Math.max(Math.ceil(graphMax * 100) / 100, 0.35);
            if(jsonTomorrow.length ==0 ){
                graphMin = minToday;
                graphMax = maxToday
            }
            graphMin = Math.ceil(graphMin * 50) / 50 - 0.02;
            graphMax = Math.ceil(graphMax * 50) / 50 + 0.01;
            //log(graphMin)
        
            for(let i=0;i<origData.length;i++){
                if(origData[i].min){
                    dataMin = origData[i].value;
                    //log(dataMin);
                    dataMinTime =origData[i].startTS;
                    //log(dataMinTime)
                }
                if(origData[i].max){
                    dataMax = origData[i].value;
                    dataMaxTime =origData[i].startTS;
                }
                if(origData[i].average){
                    dataAvg = origData[i].value;
                }
            }
            if(origData.length>3){
                for(let i=0;i<origData.length;i++){
                    if(!origData[i].average && !origData[i].max && !origData[i].min ){
                        if( origData[i].value < dataAvg){ 
                            if(origData[i].level == 'NORMAL' ){
                                data.push({time:origData[i].startTS,value: origData[i].value,tax: origData[i].tax,energy: origData[i].energy, level: origData[i].level})//, color: 'rgba(0,255,0,0.2)', border: levelColor(origData[i].level)
                            }else{
                                data.push({time:origData[i].startTS,value: origData[i].value,tax: origData[i].tax,energy: origData[i].energy,level: origData[i].level}) //,  color: levelColor(origData[i].level), border: 'lime'
                            }
                        }else{
                            data.push({time:origData[i].startTS,value: origData[i].value,tax: origData[i].tax,energy: origData[i].energy, level: origData[i].level}) //,color: levelColor(origData[i].level), border: 'red'
                        }
                    }else{
                        if(origData[i].min){
                            dataMin = origData[i].value;
                            dataMinTime =origData[i].startTS;
                        }
                        if(origData[i].max){
                            //log(origData[i]);
                            dataMax = origData[i].value;
                            dataMaxTime =origData[i].startTS;
                            //log(dataMaxTime);
                        }
                        if(origData[i].average){
                            dataAvg = origData[i].value;
                        }
                    }
                    
                }
                // log('oben '+graphMin)
            }else{
                dataNull = true;
                //dataMin = String(graphMin);
                //dataMax = String(graphMax);
                //dataMax = "0";
                //dataAvg = '0.01';
                //graphMin = minToday;
                //graphMax = maxToday;
                //graphMin = Math.ceil(graphMin * 50) / 50 - 0.01;
                //graphMax = Math.ceil(graphMax * 50) / 50 + 0.01;
            }
            // Werte holen
            let showTaxEnergy = getState(tibberShowTaxEnergyDP).val;
            let minMaxAvg = getState(tibberShowMinMaxAvgDP).val;
            let colorJSON = getState(tibberColorDP).val;
        
            let html = '';
            html += '<!DOCTYPE html>';
            html += '<html lang="en">';
            html += '<head>';
            html += '<meta charset="UTF-8">';
            html += '<meta name="viewport" content="width=device-width, initial-scale=1.0">';
            html += '<title>Tibber-Tageswert</title>';
            html += '<script src="https://cdn.jsdelivr.net/npm/echarts@5.4.3/dist/echarts.min.js"></script>';
            html += '<script src="https://cdnjs.cloudflare.com/ajax/libs/moment.js/2.29.1/moment.min.js"></script>';
            html += '</head>';
            html += '<body>'
            if(getState(visDP).val == 'VIS'){
                html += '<div id="chart-container" style="width: 600px; height:400px;"></div>';
            }else{
                html += '<div id="chart-container" style="width: 100%; height:400px;"></div>';
            }
            //log(data);
            html += '<script>'
            html += '    var data = '+JSON.stringify(data)+';';
            html += '    var chartContainer = document.getElementById("chart-container");'
            html += '    var myChart = echarts.init(chartContainer);';
        
           
            html += '    function formatTime(time) {';
            html += '        return moment(time).format("HH");'
            html += '    }';
            html += '    function calculateArrowPosition(hour){'
            //html += '       console.log((hour) * (100 / 24) + "%");'
            html += '       return (hour / 24) * 100 +1 + "%";'
            html += '    }'
            html += '    function updateChart() {';
            html += '        var minValue = Math.min.apply(null, data.map(function (item) {';
            html += '          return item.value;';
            html += '        }));';
            //html += '        console.log(minValue);'
            // html += '        var yAxisMin = minValue - (minValue/10);'
            html += '        var yAxisMin = '+graphMin+';';
            html += '        var maxValue = '+dataMax+';'
            //html += '        var maxValue = '+graphMax+';'
            //html += '        console.log(maxValue);'
            // html += '        var yAxisMax = maxValue + (maxValue/10);'
            html += '        let avgValue = '+dataAvg+';'
            html += '        var visualMapPieces =' + colorJSON +';';
            html += '        var values = data.map(item => (item.value-minValue).toFixed(2));'
            html += '        var maxLineValue = Math.max.apply(null, values);'
            html += '        var maxLineIndex = values.indexOf(maxLineValue);'
            html += '        var maxLineData = {time:'+dataMaxTime+',value:'+dataMax+'};'
            html += '        var currentHour = new Date().getHours() ;'
            // html += '        console.log(currentHour);'
            //html += '        console.log(maxLineData.time);'
            // html += '        var maxV = parseFloat((Math.max(...values)));'
            //html += '        console.log(maxV);'
            //html += '        let pro = values.map((value) => (value/maxV).toFixed(2));'
            //html += '        console.log(values);'
            //html += '        console.log(pro);'
            html += '        var colorStops = [];'
            //html += '        console.log(yAxisMin +" "+maxValue);'
            if(!dataNull){
            html += '        visualMapPieces.map(piece => {'
            html += '          if(piece["lte"] >=yAxisMin && piece["gt"]<=maxValue){ '
            //html += '            console.log(piece["lte"] + " "+maxValue + " "+ yAxisMin);'
            html += '            if(piece["gt"]>=yAxisMin){'
            //html += '             console.log(piece["gt"] +" gt gesetzt " +yAxisMin);'
            html += '             colorStops.push({'
            html += '              offset:  ((piece["gt"]-yAxisMin)/(maxValue-yAxisMin)),'//  /((maxValue-minValue)/maxValue)  /(visualMapPieces[visualMapPieces.length - 1]["gt"])
            html += '              color: piece.color'
            html += '             });'
            html += '            }'
            html += '            if(piece["lte"]<=maxValue){'
            //html += '            console.log(piece["lte"] +" lte gesetzt "+yAxisMin);'
            html += '             colorStops.push({'
            html += '              offset:  ((piece["lte"]-yAxisMin)/(maxValue-yAxisMin)),'//  /((maxValue-minValue)/maxValue)  /(visualMapPieces[visualMapPieces.length - 1]["gt"])
            html += '              color: piece.color'
            html += '             });'
            html += '            }'
            html += '            if(piece["lte"]>maxValue ){'
            //html += '            console.log(piece["lte"] +" lte gesetzt "+yAxisMin);'
            html += '            colorStops.push({'
            html += '              offset:  1,'//  /((maxValue-minValue)/maxValue)  /(visualMapPieces[visualMapPieces.length - 1]["gt"])
            html += '              color: piece.color'
            html += '             });'
            //html += '            }'
            html += '           };'
            html += '          }else{'
            //html += '            console.log(piece["lte"] + " " + piece["gt"]);'
            html += '           if(piece["lte"]>=maxValue && piece["gt"]<=maxValue ){'
            //html += '            console.log(piece["lte"] +" lte gesetzt "+yAxisMin);'
            html += '            colorStops.push({'
            html += '              offset:  ((piece["lte"]-yAxisMin)/(maxValue-yAxisMin)),'//  /((maxValue-minValue)/maxValue)  /(visualMapPieces[visualMapPieces.length - 1]["gt"])
            html += '              color: piece.color'
            html += '            });'
        
            html += '           }else if(piece["lte"]>=maxValue && piece["gt"] <= maxValue){'
            // html += '            console.log("Drin");'
            html += '            colorStops.push({'
            html += '              offset:  ((piece["lte"]-yAxisMin)/(maxValue-yAxisMin)),'//  /((maxValue-minValue)/maxValue)  /(visualMapPieces[visualMapPieces.length - 1]["gt"])
            html += '              color: piece.color'
            html += '            });'
            html += '           }'
            html += '          }; ' 
            html += '        });'
            //html += '        console.log(colorStops);'
            //html += '        console.log(colorStops[colorStops.length-1].color);'
            html += '        colorStops.push({'
            html += '            offset: 1,' //visualMapPieces[visualMapPieces.length - 1]["gt"]
            html += '            color: colorStops[colorStops.length-1].color'// visualMapPieces[visualMapPieces.length - 1].color'
            html += '        });'
            //html += '        console.log(colorStops);'
            html += '        colorStops.splice(0, 0, {offset: 0,color:colorStops[0].color});'
            //html += '        colorStops.splice(0, 0, {offset: 0,color:colorStops[0].color});'
            //html += '        colorStops.splice(2, 0, {offset: colorStops[1].offset,color:colorStops[2].color});'
            //html += '        colorStops.splice(4, 0, {offset: colorStops[3].offset,color:colorStops[4].color});'
            //html += '        console.log(colorStops);'
            }
            if(dataNull && !getState(tibberShowGraphIfEmptyDP).val){
                html += '        myChart.setOption({';
            html += '            title: {';
            if(priceDP== 'PricesToday'){
                html += '                text: "'+getState(tibberLabelTodayDP).val+'",';
                if(getState(tibberShowLabelTodayDP).val){
                    html += '            show: true'
                }else{
                    html += '            show: false'
                }
            }else{
                if(dataNull && getState(tibberShowWaitLabelTomorrowDP).val){
                      html += '          textAlign: "auto", '
                      html += '          textStyle: { '
                      html += '             color: "red"'
                      html += '          },'
                      html += '          left: "50px",'
                      html += '          text: "'+getState(tibberWaitTomorrowTextDP).val +'",';
                }else{
                    html += '            text: "'+getState(tibberLabelTomorrowDP).val+'",';
                    if(getState(tibberShowLabelTomorrowDP).val){
                        html += '        show: true,'
                    }else{
                        html += '        show: false,'        
                    }
                }
                
                
            }
            
            html += '                 },});';
            }else{
        
            html += '        myChart.setOption({';
            html += '            title: {';
            if(priceDP== 'PricesToday'){
                html += '                text: "'+getState(tibberLabelTodayDP).val+'",';
                if(getState(tibberShowLabelTodayDP).val){
                    html += '                show: true'
                }else{
                    html += '                show: false'
                }
            }else{
                if(dataNull && getState(tibberShowWaitLabelTomorrowDP).val){
                      html += '            textAlign: "auto", '
                      html += '            textStyle: { '
                      html += '               color: "red"'
                      html += '            },'
                      html += '            left: "50px",'
                      html += '            text: "'+getState(tibberWaitTomorrowTextDP).val +'",';
                }else{
                    html += '                text: "'+getState(tibberLabelTomorrowDP).val+'",';
                    if(getState(tibberShowLabelTomorrowDP).val){
                        html += '                show: true,'
                    }else{
                        html += '                show: false,'        
                    }
                }
                
                
            }
            
            html += '            },';
            html += '            visualMap: {';
            html += '              type: "piecewise",'
            html += '              pieces: visualMapPieces,'
            html += '              dimension: 1,' // Mapping to the 'value' dimension'
            html += '              showLabel: true,'
            html += '              precision: 2,'
            html += '              itemWidth: 6,'
            html += '              orient: "horizontal",'
            html += '              left: "center", calculable: true,selectedMode: "multiple",'
            html += '              bottom: 10,'
            html += '              text: ["High", "Low"],'
            html += '              textStyle: {'
            if(getState(darkModeDP).val){
                html += '                color: "white"'
            }else{
                html += '                color: "black"'
            }
            html += '              },'
            //html += '              inRange: {'
            //html += '                color: colorStops.map(stop => stop.color)';//visualMapPieces.map(piece => piece.color)'
            //html += '              },'
            /* bringt nichts
            html += '              itemStyle:{'
            html += '                 symbol:"pin",'
            html += '                 symbolSize: 30,'
            html += '                 markPoint: {'
            html += '                   data: [{'
            html += '                    symbol: "circle",'
            html += '                       coord: [data.time, data.value], itemStyle:{ color:"red"}'
            html += '                    }]'
            html += '                 },'
            html += '               }'
            */
            html += '            },'
            
            if(minMaxAvg){
                html += '            grid: {';
                if(getState(tibberShowMinMaxAvgTextDP).val){
                    html += '              right: 50,'; // Vergrößern Sie diesen Wert nach Bedarf
                }else{
                    html += '              right: 10,';
                }
                html += '              left: 10,';
                html += '              containLabel: true'; // Stellen Sie sicher, dass das Label innerhalb des Diagramms bleibt
                html += '            },';
            }else{
                html += '            grid: {';
                html += '              right: 10,'; // Vergrößern Sie diesen Wert nach Bedarf
                html += '              left: 10,'; // Vergrößern Sie diesen Wert nach Bedarf
                html += '              containLabel: true'; // Stellen Sie sicher, dass das Label innerhalb des Diagramms bleibt
                html += '            },';
            }
            html += '            areaStyle: {'
            html += '              color: colorStops';//"red"'; visualMapPieces.map(piece => piece.color)'
            //html += '              color: "blue", '
            html += '            },'
            // Option für Pfeil unter Kurve
            /*
            if(!dataNull && getState(tibberHighlightCurrentHourDP).val){
            html += 'graphic: [{'
            html += '    type: "image",'
            html += '    id: "arrow",'
            html += '    bounding: "all",'
            html += '    z:100,'
            //html += '    origin: [calculateArrowPosition(currentHour), "10%"],'
            //html += '    origin: [0.5, 0],'  // Koordinaten für den Pfeil
            html += '    bottom: "10%", '
            html += '    left: calculateArrowPosition(currentHour),';//"50px",'
            html += '    '
            html += '    style: {'
            html += '        image: "https://api.iconify.design/mdi/arrow-up-bold.svg?width=24&height=24&color=blue", ' // Pfad zum Bild deines Pfeils
            html += '        width: 30,'
            html += '        height: 30,'
            html += '    }'
            html += '}],'
            }
            */
            // ToolBox
            html += '            toolbox: {';
            html += '              feature: {';
            html += '                saveAsImage: {';
            html += '                   backgroundColor: "rgba(38, 37, 37, 1)",';
            html += '                   title: "Speichern",';
            let fileName = priceDP.replace('Prices','') 
            if(fileName == 'Today'){
                fileName += ' '+ formatDate(new Date(),'DD.MM.YYYY'); 
            }else{
                fileName += ' '+ formatDate(new Date().getTime()+86400000,'DD.MM.YYYY'); 
            }
            html += '                   name: "TibberHTML '+fileName+'"'
            html += '                },'
            html += '                magicType: {';
            html += '                  type: ["line", "bar"],';
            html += '                  title:{';
            html += '                     line: "Line-Chart",';
            html += '                     bar: "Bar-Chart",';
            html += '                  }'
            
            html += '                },';
            html += '                dataView: {';
            html += '                  title: "Daten aus der Serie",';
            html += '                  lang: ["Daten der Kurve", "Schließen", "Aktualisieren"],'
            html += '                  optionToContent: function (opt) {';
            html += "                      var table = '<table style=\"width:100%;\"><tbody><tr style=\"text-align: left;\"><th>Stunde</th><th>Wert</th><th>Energie</th><th>Steuer</th><th>Level</th></tr>';";
            //html += '                      console.log(opt.series.length); '
            //html += '                      console.log(opt.series[0].data); '
            html += '                      for (var i = 0; i< opt.series[0].data.length;i++) {';
            html += '                          table += "<tr>";';
            html += '                         for(let x =0; x < opt.series[0].data[i].value.length; x++){'
            html += '                            if(x==0){';
            html += '                               table +=  "<td>" + ("0"+new Date(opt.series[0].data[i].value[x]).getHours()).slice(-2) + "</td>";';
            html += '                            }else{';
            html += '                               table +=  "<td>" + opt.series[0].data[i].value[x] + "</td>";';
            html += '                            } '
            html += '                         }';
            html += '                           table += "</tr>";';
            html += '                      }';
            html += '                      table += "</tbody></table>";'
            html += '                      return table;';
            html += '                  },';
            html += '                  readOnly: true';
            html += '                },'
            html += '              }';
            html += '            },'
            
            html += '            xAxis: {';
            html += '                type: "time",';
            html += '                axisLabel: {';
            html += '                    show: true,'
            html += '                    formatter: function (value) {';
            html += '                        return formatTime(value);';
            html += '                    }';
            html += '                },';
            html += '                splitNumber: 10,';
        	html += '            },';
            html += '            yAxis: {';
            html += '                type: "value",';
            html += '                axisLabel: {'; 
            
            html += '                  formatter: function (value) {';
            html += '                     return value.toFixed(3) + " €";';
            html += '                  }';
            
            html += '                },';
            
            html += '               min: '+graphMin+','; //
            html += '               max: '+graphMax+',' //yAxisMax
            html += '            },';
            
            
        
        
        
            html += '            series: [{';
            
            html += '                data: data.map(function (item) {';
            html += '                    var hour = new Date(item.time).getHours();'
            html += '                    return {';
            html += '                       value: [item.time, item.value, item.energy, item.tax, item.level],';
            //html += '                       lineStyle: {width: hour === currentHour ? 10:null},'
            
            // Symbol für Line einstellen
        
            html += '                        symbol: "circle",'
            
            if(getState(tibberHighlightCurrentHourDP).val && priceDP == 'PricesToday'){
                html += '                    symbolSize: hour === currentHour ? 10:null, '
                html += '                    itemStyle: {'
                   
                if(getState(darkModeDP).val){
                    //html += '                           backgroundColor: hour === currentHour ? "'+getState(tibberHighlightColorDarkDP).val+'":null,'
                    html += '                           borderColor: hour === currentHour ? "'+getState(tibberHighlightColorDarkDP).val+'":null,'
                    html += '                           shadowColor: hour === currentHour ? "'+getState(tibberHighlightColorDarkDP).val+'":null,'
                    html += '                           borderWidth: hour === currentHour ? 2:null,'
                    html += '                           shadowBlur: hour === currentHour ? 20:null,'
                }else{
                    html += '                           borderColor: hour === currentHour ? "'+getState(tibberHighlightColorLightDP).val+'":null,'
                    html += '                           shadowColor: hour === currentHour ? "'+getState(tibberHighlightColorLightDP).val+'":null,'
                    html += '                           borderWidth: hour === currentHour ? 1:null,'
                    html += '                           shadowBlur: hour === currentHour ? 10:null,'
                }
                //html += '                           borderWidth: hour === currentHour ? 1:null,'
                //html += '                           shadowBlur: hour === currentHour ? 10:null,'
                
                html += '                     },'
                
            }
            // Aria für Schraffierung
            //html += 'aria: {'
            //html +='    enabled: true,'
            //html += '   decal: {'
            //html +='        show: hour === currentHour'
            //html += '   }'
            //html +='},'
            html += '                        emphasis: {';
            html += '                          itemStyle: {';
            html += '                            color: "white" '; // Füge die Farbe in die Betonung ein
            html += '                          },';
            html += '                          label: {';
            html += '                            show: true,';
            html += '                            formatter: function (params) {';
            html += '                               return params.data.value[1].toFixed(3) + " €";'; //console.log(params);
            html += '                            },';
            html += '                            color: "black",';
            html += '                            fontWeight: "bold", ';
            html += '                            backgroundColor: "white"';
            html += '                          }';
            html += '                        }';
            html += '                     } ';
            html += '                }),'; // end data
            
            if(getState(tibberSteppedLineDP).val){
                html += '            step: "end",'
            }
            // ItemStyle
            //html += '                itemStyle:{'
            //html += '                  color: function (params) {'
                        // Färbe den Balken der aktuellen Stunde anders ein
            //html += '                    console.log(new Date(params.value[0]).getHours());'
            //html += '                    console.log(currentHour);'
            //html += 'console.log(new Date(params.value[0]).getHours() === currentHour ? "red" : "blue");'
            //html += '                    return new Date(params.value[0]).getHours() === currentHour ? "red" : "blue";'
            //html += '                  }'
            //html += '                },'
            if(getState(tibberAreaDP).val){
            html += '                areaStyle:{'
            html += '                    color: new echarts.graphic.LinearGradient(0, 1, 0, 0, colorStops),' ;
            
            //html += '                    color:  colorStops,'
            // html += '                    max: maxValue, '
            /*
            html += '                    color: function (params) {'
            html += '                       console.log(params);'
            html += '                       var wert = params.data.value[1];'
            html += '                       var col = "red";'
            html += '                       for (var i = 0; i < visualMapPieces.length; i++) {'
            html += '                           var piece = visualMapPieces[i];'
            html += '                           if (wert >= piece.gt && wert <= piece.lte) {'
            html += '                               col = piece.color;'
            html += '                               break;'
            html += '                           }'
            html += '                       }'
            html += '                       return col;'
            html += '                   },'
            */
            html += '                },'
            }
            html += '                type: "'+getState(tibberGraphTypeDP).val+'",';
            //html += '               markArea: {'
            //html += '                   silent: true,'
            //html += '                   data: ['
            //html += '                       [{'
            //html += '                           xAxis: "min",'
            //html += '                           itemStyle: {'
            //html += '                               color: "rgba(0, 0, 0, 0.7)"'
            //html += '                           }'
            //html += '                           }, {'
            //html += '                               xAxis: "max",'
            //html += '                       }]'
            //html += '                   ]'
            //html += '               },'
            
            if(minMaxAvg){
                html += '                markLine: {';
                html += '                  symbol: "none",';  // Kein Symbol für die Markierungslinie
                html += '                  lineStyle: {';
                html += '                    color: "red",';   // Farbe der Markierungslinie
                html += '                    type: "dashed"';  // Art der Linie (gestrichelt)
                html += '                  },';
                
                if(getState(tibberShowMinMaxAvgTextDP).val){ //coord: [maxLineData.time, maxLineData.value] ,)
                    if(!dataNull){
                    html += '                  data: [';
                    html += '                   {yAxis: minValue ,name: "MIN", lineStyle: { color: "lime" },label: { show: true, position: "end", formatter: "Min\\n"+ minValue.toFixed(3)+" €",textStyle: { fontSize: 12,fontWeight: "bold", color:"white"  } }  },';
                    html += '                   {yAxis: maxValue,name: "MAX", lineStyle: { color: "red" },label: { show: true, position: "end", formatter: "Max\\n"+ maxValue.toFixed(3)+" €",textStyle: { fontSize: 12,fontWeight: "bold", color:"white"  } } },';
                    html += '                   {yAxis: avgValue ,name: "AVG", lineStyle: { color: "blue" },label: { show: true, position: "end", formatter: "Avg\\n"+ avgValue.toFixed(3)+" €",textStyle: { fontSize: 12,fontWeight: "bold", color:"white"  } } }';
                    html += '                  ], '
                    }
                }else{
                    if(!dataNull){
                    html += '                  data: [';
                    // funktioniert nicht !,tooltip: {show: true,formatter: "Min\\n\\n" + params.value.toFixed(3) + " €",textStyle: {fontSize: 12,fontWeight: "bold",color: "white"}}  ,formatter: "Min " + minValue.toFixed(3) + " €"
                    html += '                   {yAxis: minValue ,name: "MIN", lineStyle: { color: "lime" },label: { show: false, position: "end", formatter: "Min\\n\\n"+ minValue.toFixed(3)+" €",textStyle: { fontSize: 12,fontWeight: "bold", color:"white"  } }  },';
                    html += '                   {yAxis: maxValue,name: "MAX", lineStyle: { color: "red" },label: { show: false, position: "end", formatter: "Max\\n\\n"+ maxValue.toFixed(3)+" €",textStyle: { fontSize: 12,fontWeight: "bold", color:"white"  } } },';
                    html += '                   {yAxis: avgValue ,name: "AVG", lineStyle: { color: "blue" },label: { show: false, position: "end", formatter: "Avg\\n\\n"+ avgValue.toFixed(3)+" €",textStyle: { fontSize: 12,fontWeight: "bold", color:"white"  } } }';
                    html += '                  ], '    
                    }    
                }
                html += '                }';
            }
            html += '            }],'; // Ende Series
        
        
            
        
            html += '            tooltip: {';
            html += '              trigger: "axis",';
            html += '              axisPointer: {';
            html += '               type: "shadow"';
            html += '              },';
            html += '              textStyle: {';
            html += '                fontFamily: "Courier",';
            html += '                fontWeight: "bold"'; // Hinzugefügt
            html += '              },'
            html += '              formatter: function (params) {';
            html += '                let time = "Start ab: "+ moment(params[0].axisValue).format("HH:mm")+ " Uhr";';
            html += '                let value = "Preis:&nbsp&nbsp&nbsp&nbsp"+params[0].value[1].toFixed(4) + " €";';
            if(showTaxEnergy){
                html += '            let energy = "Energie:&nbsp&nbsp"+params[0].value[2].toFixed(4) + " €";'
                html += '            let tax    = "Steuer:&nbsp&nbsp&nbsp"+params[0].value[3].toFixed(4) + " €";'
                html += '            let lev    = "Level:&nbsp&nbsp&nbsp&nbsp"+ params[0].value[4];'
                html += "            return  `${time}<br/>${value}<br/>${energy}<br/>${tax}<br/>${lev}` ;";
            }else{
                //html += "            return `<span style=\"font-family: 'Arial'; font-weight: 'bold';\" >${time}<br/>${value}</span>` ;";
                html += "            return `${time}<br/>${value}` ;";
            }
            
            html += '              }';
            html += '            },';
            
            html += '        }) ';// end setOption
            }
            html += '    }'; 
            
        
            html += '    updateChart(); ';
            html +='     var updateInterval = setInterval(updateChart, 3600000);'
            html += '</script>';
            html += '</body>';
            html += '</html>';
        
            // log(html);
            if(priceDP == 'PricesToday'){
                setState(tibberHTMLTodayDP,html);
            }else{
                setState(tibberHTMLTomorrowDP,html);
            }
        }
        
        
        
        function sortByName(x, y) {
            // Wenn x oder y nicht-numerisch sind, setze sie an das Ende
            if (isNaN(x.hour) || isNaN(y.hour)) {
                return isNaN(x.hour) ? 1 : -1;
            }
            
            // Vergleiche numerische Werte
            return x.hour - y.hour;
        }
        
        
        
        on({id: dbHistoryDP, change: "any"}, function (obj) {
            let value = obj.state.val;
            // history für die DPs aktiv?
            if (value!=''){
                if (getState('system.adapter.'+value+'.alive').val){
                    if (isHistoryActiveAllDPs(dpArray)){
                        if(logging){
                            log('History-Future-DPs sind angelegt und History aktiviert!');
                        }
                        // getPVData(dpArray);
                        //runScript();
                    }else{
                        if(logging){
                            log('History wird angelegt für die future-DPs!');
                        }
                        activateDPsHistory(dpArray);
                        setTimeout(function(){
                            deleteAllHistoryDPs(dpArray);
                            // log('gelöscht');
                            // getPVData(dpArray);
                        },3000)
                        //runScript();
                    }
                }else{
                    log('Der History-Adapter ist nicht gestartet! -> Es werden keine DPs mit History aktiviert','warn');
                }
            }
        });
        
        
        function setDPs(tibberInst){
            // Ist der Adapter aktiv
            // 
            //let pvAliveDP = 'system.adapter.pvForecast.'+tibberInst+'.alive';
            //if(existsState(pvAliveDP)){
            //    if(getState(pvAliveDP).val){
                    // Adapter ist gestartet
                    let tibberKeys = ['Value','Tax','Energy']
                    for(let i=0;i<tibberKeys.length;i++){
                            dpArray.push(tibberDP+'.future'+tibberKeys[i]);
                    }
                    
            //    }else{
            //        log('Der Adapter tibberlink.'+tibberInst+' ist nicht gestartet!');
            //    }
            //}else{
            //    log('Der Adapter pvForecast ist nicht installiert')
            //}
            // Alte erst löschen
            // Nur löschen, wenn sich die DPs geändert haben
            let delItems = false;
            if(dpArray.length >0){
                // delDPs(dpArray);
                
                for(let i=0;i<dpArray.length;i++){
                    if(existsState(dpArray[i])){
        
                    }else{
                        delItems = true;
                        delDPs(dpArray);
                        break;
                    }
                }
            }
            if(delItems){
                setTimeout(function() {
                    if(dpArray.length >0){
                        createDPs(dpArray);
                    }
                },3000);
            }else{
                createDPs(dpArray);
            }
        }
        
        
        function delDPs(arr){
            for(let i=0; i<arr.length;i++){
                if(existsState(arr[i])){
                    deleteStateAsync(arr[i]);
                }
            }
        }
        // createStateAsync(futureTempDP, {read: true, write: false, name: "daswetter temperature", type: "number", role: "", def: 0 });
        
        function createDPs(arr){
            for(let i=0; i<arr.length;i++){
                // 0_userdata.0.pvForecastHistory.historyDB
                let name =  levelObject(arr[i])[3];
                createStateAsync(arr[i], {read: true, write: false, name: "tibber"+name, type: "number", role: "", def: 0 });
            }
        }
        
        
        function seteChartsDP(dpArray){
            let startDT = getDateObject('00:00').getTime(); // heute 00:00
            // pvForecast hat nur 2 Tage im Array
            let endDT = startDT + 24*1*60*60*1000;
            // start_time, end_time, start, end, timeType
            for(let i=0;i<dpArray.length;i++){
                let echartDP = 'echarts.0.tibber'+levelObject(dpArray[i])[3];
                let obj; 
                if (existsObject(echartDP)){
                    obj = getObject(echartDP);
                    //log(obj);
                    if (obj.native.data.timeType == 'static'){
                        obj.native.data.start = formatDate(startDT,'YYYY-MM-DD');
                        obj.native.data.end   = formatDate(endDT,'YYYY-MM-DD');
                        obj.native.data.start_time = '00:00';
                        obj.native.data.end_time = '00:00';
                        setObject(echartDP,obj);
                    }
                }
            }
        }
        
        
        
        function isHistoryActiveAllDPs(dpArray){
            // dparray automatisch gesetzt
            let active = false;
            let dbHistory = getState(dbHistoryDP).val;
            if (dbHistory != ''){
                for(let i= 0;i<dpArray.length;i++){
                    let dpPara = levelObject(dpArray[i])[3];
                    // log('dpPara: '+dpPara);
                    // log(pvForecastDP+'.future'+dpPara);
                    // setActiveHistory(pvForecastDP+'.future'+dpPara);
                    active = isHistoryActive(tibberDP+'.'+dpPara,dbHistory);
                    if(active == false){
                        return false;
                    }
                }
                
                log('Tibber-DPs History aktiv');
                return true;
            }else{
                log('DB Auswahl fehlt');
                return false;
            }
        }
        
        function isHistoryActive(dp,db){
            let obj = getObject(dp);
            if (obj.common.custom != undefined){
                //log(obj.common.custom);
                let custom = obj.common.custom;
                
                for (let key in custom){
                    //log(key);
                    if (key.indexOf(db)>=0){  //'history'
                        return true;
                    }
                }
            }
            return false;
        }
        
        function activateDPsHistory(dpArray){
            let historyDB = getState(dbHistoryDP).val;
            //log('HistoryDB: '+historyDB);
            if (historyDB != ''){
                if (getState('system.adapter.'+historyDB+'.alive').val){
        
                    if (historyDB!=''){
                        for(let i= 0;i<dpArray.length;i++){
                            //log('DParray[i]: '+dpArray[i]);
                            let dpPara = levelObject(dpArray[i])[3];
                            //log('dpPara: '+dpPara);
                            //log(pvForecastDP+'.'+dpPara);
                            setActiveHistory(tibberDP+'.'+dpPara);
                            setTimeout(function(){
                                deleteAllHistoryData(tibberDP+'.'+dpPara);
                            },2000)
                        }
                        log('Future-DPs History aktiviert');
                    }else{
                        log('Es wurde keine DB für Future-History ausgewählt!','warn');
                    }
                }else{
                    log('Der Adapter ist nicht gestartet! -> keine Aktivierung möglich','warn');
                }
            }else{
                log('Aktivierung der DPs für die DB erst möglich, wenn man eine DB ausgewählt hat!','warn');
            }
        }
        
        
        // deleteAllHistoryDPs();
        
        function deleteAllHistoryDPs(dpArray){
            let dbHistory = getState(dbHistoryDP).val;
            if (getState('system.adapter.'+dbHistory+'.alive').val){
                log('History DPs dpArray löschen!');
                for(let i= 0;i<dpArray.length;i++){
                    //log('DParray[i]: '+dpArray[i]);
                    let dpPara = levelObject(dpArray[i])[3];
                    //log('dpPara: '+dpPara);
                    //log(pvForecastDP+'.'+dpPara);
                    deleteAllHistoryData(tibberDP+'.'+dpPara);
                    
                }
                log('Future-DPs History gelöscht');
            }else{
                log('Adapter nicht gestartet!');
            }
        }
        
        
        function deleteAllHistoryData(dp){
            let dbHistory = getState(dbHistoryDP).val;
            if (dbHistory!=''){
                //let dtStart= getDateObject('00:00').getTime(); // heute 00:00 Uhr
                //let dtStop = dtStart + 24*6*60*60*1000;
                sendTo(dbHistory, 'deleteAll', [       // 'history.0' 'deleteRange'
                    {id: dp}//, start: dtStart, end: dtStop
                    
                ], result => {//console.log('deleted')
                });
            }else{
                log('Löschen nicht durchgeführt, da keine HistoryDB festgelegt');
            }
        }
        
        
        
        function getHistoryAdapter(){
            // history, influxdb, sql
            log('Einlesen der vorhandenen History-DBs.');
            let histArr = ['history','influxdb','sql'];
            let arr =[];
            for (let i=0; i<histArr.length;i++){
                let dp = $('system.adapter.'+histArr[i]+'.*.alive');
                //log(dp);
                for(let x=0;x<dp.length;x++){
                    //log(dp[x]);
                    let dpID = dp[x];
                   
                    if (getObject(dpID).common != undefined){
                        //log(getState(dpID).val);
                        if (getState(dpID).val != null && getState(dpID).val){
                            dp[x] = dp[x].substring(15,dp[x].length-6);
                            // log(dp[x]);
                            arr.push(dp[x]);
                        }
                        if (getState(dpID).val == null){
                            log('History-Adapter ist fehlerhaft: '+dp[x] +' -> alive auf false setzen');
                        }
                    }
                }
        
            }
            let devStates = {'':'keine Auswahl'};
            for (let i=0; i< arr.length;i++){
                devStates[arr[i]] = arr[i];
            }
            //log(devStates);
            if (existsState(dbHistoryDP)){
                let obj = getObject(dbHistoryDP);
                obj.common.states = devStates;
                setObject(dbHistoryDP,obj);
            }else{
                createStateAsync(dbHistoryDP, {read: true, write: true, name: "DB-Auswahl", type: "string", role: "", def: '',states:devStates });    
            }
        }
        
        
        
        
        function setActiveHistory(dp){
            let dbHistory = getState(dbHistoryDP).val;
            //log('dbHistory setActive: '+dbHistory);
            if (dbHistory !=''){
                sendTo(dbHistory, 'enableHistory', { // 'history.0'
                    id: dp,  // 'system.adapter.history.0.memRss'
                    options: {
                        changesOnly:  true,
                        debounce:     0,
                        retention:    31536000,
                        maxLength:    3,
                        changesMinDelta: 0,
                        //ignoreZero: true,
                        aliasId: '',
                        enabled: true,
                        debounceTime: 0,
                        blockTime: 0,
                        changesRelogInterval: "0",
                        ignoreBelowNumber: "",
                        disableSkippedValueLogging: false,
                        customRetentionDuration: 365,
                        enableDebugLogs: false
                
                    }
                }, function (result) {
                    if (result.error) {
                        console.log(result.error);
                    }
                    if (result.success) {
                        //successfull enabled
                        //log(dp +' wurde in history aktiviert');
                    }
                });
            }
        }
        
        // setHistoryData(futureHumidityDP,dpValueArr);
        
        function setHistoryData(dp,states){
            let dbHistory = getState(dbHistoryDP).val;
            if (dbHistory!=''){
                sendTo(dbHistory, 'storeState', { // 'history.0'
                    id: dp,
                    state: states
                    }, result => {
                        // console.log('added')
                    });
            }
        }
        
        
        
        function levelObject(id){
            // 0_userdata.0.jarvis.system.tabWidgetStateEffects.0.Desktop.0.Bad.0b5dd758-8d7d-4259-8945-821b1c942960.states.0.displayOff
            let idArr=id.split('.');
            return idArr; //log(idArr[10]);
        }
        
        // log(getDPLevel(levelObject('0_userdata.0.jarvis.system.tabWidgetStateEffects.0.Desktop.0.Bad.0b5dd758-8d7d-4259-8945-821b1c942960.states.0.displayOff'),9));
        function getDPLevel(idArr,level){
            let id ='';
            for (let i=0;i<=level;i++){
                id += idArr[i] +'.'
            }
            id = id.substr(0,id.length-1); // letzten Punkt wegnehmen
            return id;
        }
        
        M 1 Antwort Letzte Antwort
        0
        • M Meikie
          // *********************************
          // tibberHTML v1.0.24
          // *********************************
          // Copyright ©MCU
          // v1.0.1 - Erweiterung Umschaltung Line/bar im Graph, Anzeige der Werte in Tabelle
          // v1.0.2 - Vis Auswahl -> fete Breite für VIS, darkMode
          // v1.0.3 - Min,max,avg kleiner, untereinander, rechts Breite kleiner
          // v1.0.4 - ShowMinMaxAvgTexte optional
          // v1.0.5 - toolBox -Speichern mit Namen+Datum
          // v1.0.6 - y-Skala auf beiden Kurven gleich 
          // v1.0.7 - splitNumber auf 10 vorher 3, grid rechts 10 statt 30, visualMap - mobile optimiert
          // v1.0.8 - CurveArea optional, Korrektur wenn tomorrow.mim = 0 -> graphMin =0
          // v1.0.9 - graphMax angepasst auf nächste 0.01
          // v1.0.10- graphMin angepassz auf nächste 0.01
          // v1.0.11- Label optional, falls man schon Widget-Title nutzt 
          // v1.0.12 - Trennung Label Today und Tomorrow
          // v1.0.13 - optionaler Text für Tomorrow Wait
          // v1.0.14 - automatischer Reload bei Umschaltung wait-Text Tomorrow
          // v1.0.15 - aktuelle Zeit highlightCurrentHour
          // v1.0.16 - Symbol für Line aktuelle Stunde angepasst
          // v1.0.17 - stepped line hinzugefügt, Korrekturen graphMin
          // v1.0.18 - Korrektur showwait
          // v1.0.19 - Korrektur showwait
          // v1.0.20 - Abschaltung Anzeige Graph, wenn leer, Korrektur highlightPoint
          // v1.0.21 - Korrektur dataNull für visualMapPieces
          // v1.0.22 - Inhalt von DPs als Datei speichern
          // v1.0.23 - Korrektur 1.Farbelement lte > maxValue
          // v1.0.24 - Korrektur 1. Farbelement Umstellung Linie, falsche Berechnung
          // ToDo
          // - optionale Zeit vor günstiger Stunde telegram senden, alexa info, pushOver senden
          // - Ersparnis in Prozent -> Tabelle / Anzeige?
          // - Stunden erweitern für steppedLine?
          
          let logging                     = true;
          let tibberDP                    = '0_userdata.0.Strom.tibberHistory';
          let dbHistoryDP                 = tibberDP + '.historyDB';
          let tibberGraphTypeDP           = tibberDP + '.graphTyp'; // bar  oder line
          let tibberInstDP                = tibberDP + '.instanz'; // 0
          let tibberColorDP               = tibberDP + '.colorJSON'; // visualMapPieces [ {gt: 0, lte: 0.15, color: "lightgreen"},]
          let tibberHTMLTodayDP           = tibberDP + '.htmlToday';
          let tibberHTMLTomorrowDP        = tibberDP + '.htmlTomorrow';
          let tibberShowTaxEnergyDP       = tibberDP + '.showTaxEnergy'; // boolean
          let tibberShowMinMaxAvgDP       = tibberDP + '.showMinMaxAvg'; // boolean
          let visDP                       = tibberDP + '.vis';
          let darkModeDP                  = tibberDP + '.darkMode';
          let tibberShowMinMaxAvgTextDP   = tibberDP + '.showMinMaxAvgText';
          let tibberAreaDP                = tibberDP + '.curveArea';
          let tibberShowLabelTodayDP      = tibberDP + '.showLabelToday';
          let tibberLabelTodayDP          = tibberDP + '.labelToday';
          let tibberShowLabelTomorrowDP   = tibberDP + '.showLabelTomorrow';
          let tibberLabelTomorrowDP       = tibberDP + '.labelTomorrow';
          let tibberWaitTomorrowTextDP    = tibberDP + '.labelTomorrowWait';
          let tibberShowWaitLabelTomorrowDP = tibberDP + '.showLabelTomorrowWait';
          let tibberHighlightCurrentHourDP = tibberDP +'.highlightCurrentHour';
          let tibberHighlightColorDarkDP   = tibberDP + '.highlightColorDark';
          let tibberHighlightColorLightDP  = tibberDP + '.highlightColorLight';
          let tibberSteppedLineDP         = tibberDP + '.steppedLine';
          let tibberShowGraphIfEmptyDP    = tibberDP + '.showGraphIfEmpty';
          
          let dpArray                 = [];
          
          createStateAsync(tibberHTMLTodayDP, {read: true, write: true, name: "Tibber HTML für Heute", desc:"HTML-DP", type: "string", role: "", def: "" });
          createStateAsync(tibberHTMLTomorrowDP, {read: true, write: true, name: "Tibber HTML für Morgen", desc:"HTML-DP", type: "string", role: "", def: "" });
          createStateAsync(tibberColorDP, {read: true, write: true, name: "Farbdefinition für Balken", desc:"JSON-DP", type: "string", role: "", 
          def: JSON.stringify([{ 'gt': 0,'lte': 0.15, 'color': 'lightgreen' },
                              {'gt': 0.15,'lte': 0.22,'color': 'green'},
                              {'gt': 0.22,'lte': 0.29,'color': 'yellow'},
                              {'gt': 0.29,'lte': 0.35,'color': 'orange'},
                              {'gt': 0.35,'color': 'red'}]) });
          createStateAsync(tibberGraphTypeDP, {read: true, write: true, name: "Tibber Graph Typ Auswahl", desc:"GraphType-DP", type: "string", role: "", states: {"bar":"bar","line":"line"} ,def: "bar" });
          createStateAsync(tibberInstDP, {read: true, write: true, name: "Tibber Instanz", desc:"Instanz-DP", type: "string", role: "", def: "0" });
          createStateAsync(tibberShowTaxEnergyDP, {read: true, write: true, name: "Tax und Energy anzeigen bei Hover", desc:"Show-DP", type: "boolean", role: "", def: false });
          createStateAsync(tibberShowMinMaxAvgDP, {read: true, write: true, name: "Min, Max und Mittelwert anzeigen", desc:"Show-DP", type: "boolean", role: "", def: false });
          createStateAsync(tibberShowMinMaxAvgTextDP, {read: true, write: true, name: "Min, Max und Mittelwert Texte anzeigen", desc:"ShowText-DP", type: "boolean", role: "", def: false });
          createStateAsync(visDP, {read: true, write: true, name: "Welche VIS soll genutzt werden?", desc:"VIS-DP", type: "string", role: "",states: {"jarvis":"jarvis","VIS":"VIS"} , def: "jarvis" });
          createStateAsync(darkModeDP, {read: true, write: true, name: "DarkMode an?", desc:"DarkMode-DP", type: "boolean", role: "", def: false });
          createStateAsync(tibberAreaDP, {read: true, write: true, name: "Fläche unter Kurve?", desc:"CurveArea-DP", type: "boolean", role: "", def: false });
          createStateAsync(tibberShowLabelTodayDP, {read: true, write: true, name: "Label Today anzeigen?", desc:"showLabel-DP", type: "boolean", role: "", def: false });
          createStateAsync(tibberLabelTodayDP, {read: true, write: true, name: "Label Today für das Chart", desc:"Label-DP", type: "string", role: "", def: "Today-Tageswerte" });
          createStateAsync(tibberShowLabelTomorrowDP, {read: true, write: true, name: "Label Tomorrow anzeigen?", desc:"showLabel-DP", type: "boolean", role: "", def: false });
          createStateAsync(tibberLabelTomorrowDP, {read: true, write: true, name: "Label Tomorrow für das Chart", desc:"Label-DP", type: "string", role: "", def: "Tomorrow-Tageswerte" });
          createStateAsync(tibberShowWaitLabelTomorrowDP, {read: true, write: true, name: "Label Wait Tomorrow anzeigen?", desc:"showLabel-DP", type: "boolean", role: "", def: false });
          createStateAsync(tibberWaitTomorrowTextDP, {read: true, write: true, name: "Label Wait Tomorrow für das Chart", desc:"Label-DP", type: "string", role: "", def: "Werte erst ab 14.00 Uhr verfügbar" });
          createStateAsync(tibberHighlightCurrentHourDP, {read: true, write: true, name: "Aktuelle Stunde markieren?", desc:"HighlightAktHour-DP", type: "boolean", role: "", def: false });
          createStateAsync(tibberHighlightColorDarkDP, {read: true, write: true, name: "HighLight Color DarkMode", desc:"HighLight Dark-DP", type: "string", role: "", def: "white" });
          createStateAsync(tibberHighlightColorLightDP, {read: true, write: true, name: "HighLight Color LightMode", desc:"HighLight Light-DP", type: "string", role: "", def: "grey" });
          createStateAsync(tibberSteppedLineDP, {read: true, write: true, name: "Gestufte Linie?", desc:"SteppedLine-DP", type: "boolean", role: "", def: false });
          
          createStateAsync(tibberShowGraphIfEmptyDP, {read: true, write: true, name: "Graph anzeigen ohne Daten?", desc:"showGraph-DP", type: "boolean", role: "", def: false });
          
          // getHistoryAdapter();
          
          // setDPs('0'); // -> dpArray 
          
          setTimeout(function(){
              getTibberData(dpArray);
              let inst = getState(tibberInstDP).val;
              $('tibberlink.'+inst+'.Homes.*.PricesTomorrow.json').on(function(obj) {
                  setTimeout(function(){
                      getTibberData(dpArray);
                  },3000)
              });
          
              $('tibberlink.'+inst+'.Homes.*.PricesToday.json').on(function(obj) {
                  setTimeout(function(){
                      getTibberData(dpArray);
                  },3000);
              });
          
          },3000);
          
          let scheduleId ;
          if(getState(tibberHighlightColorDarkDP).val){
              scheduleId = schedule('00 * * * *', () => {
                          
                  getTibberData(dpArray);
              })
          }
          
          on({id: tibberHighlightCurrentHourDP, change: "any"}, function (obj) {
              let value = obj.state.val;
              if(value){
                  getTibberData(dpArray);
                  clearSchedule(scheduleId);
                  scheduleId = schedule('00 * * * *', () => {
                      getTibberData(dpArray);
                  })
              }else{
                  clearSchedule(scheduleId);
                  getTibberData(dpArray);
              }
          })
          on({id: tibberShowTaxEnergyDP, change: "any"}, function (obj) {
              getTibberData(dpArray);
          });
          on({id: tibberColorDP, change: "any"}, function (obj) {
              getTibberData(dpArray);
          });
          
          on({id: tibberShowMinMaxAvgDP, change: "any"}, function (obj) {
              getTibberData(dpArray);
          });
          on({id: tibberShowMinMaxAvgTextDP, change: "any"}, function (obj) {
              getTibberData(dpArray);
          });
          
          on({id: tibberGraphTypeDP, change: "any"}, function (obj) {
              getTibberData(dpArray);
          });
          on({id: darkModeDP, change: "any"}, function (obj) {
              getTibberData(dpArray);
          });
          on({id: tibberAreaDP, change: "any"}, function (obj) {
              getTibberData(dpArray);
          });
          on({id: tibberShowLabelTodayDP, change: "any"}, function (obj) {
              getTibberData(dpArray);
          });
          on({id: tibberShowLabelTomorrowDP, change: "any"}, function (obj) {
              getTibberData(dpArray);
          });
          
          on({id: tibberShowWaitLabelTomorrowDP, change: "any"}, function (obj) {
              getTibberData(dpArray);
          });
          
          on({id: tibberHighlightColorDarkDP, change: "any"}, function (obj) {
              getTibberData(dpArray);
          });
          
          on({id: tibberHighlightColorLightDP, change: "any"}, function (obj) {
              getTibberData(dpArray);
          });
          on({id: tibberSteppedLineDP, change: "any"}, function (obj) {
              getTibberData(dpArray);
          });
          on({id: tibberShowGraphIfEmptyDP, change: "any"}, function (obj) {
              getTibberData(dpArray);
          });
          
          
          function getTibberData(arr){
              // arr wird nur für eCharts benötigt
              
              // tibberDataDP selbst ermitteln
              let tibberInst = getState(tibberInstDP).val;
              let priceArr = ['PricesToday','PricesTomorrow'];
              for(let x=0;x< priceArr.length;x++){
                  let tibberData = [];
                  let tibberLink = $('tibberlink.'+tibberInst+'.Homes.*.'+priceArr[x]+'.json')
                  if(tibberLink[0] != undefined){
                      let tblLevel = levelObject(tibberLink[0]);
                      let dpLeveltbl = getDPLevel(tblLevel,4);
                      let tibberJSON = JSON.parse(getState(dpLeveltbl+'.json').val);
                      // tibberJSON
                      for(let i=0;i<tibberJSON.length;i++){
                          let obj = {};
                          obj.hour     = parseInt(tibberJSON[i].startsAt.substring(11,13));
                          obj.start   = tibberJSON[i].startsAt
                          obj.startTS = new Date(obj.start).getTime();
                          obj.value   = tibberJSON[i].total;
                          obj.energy   = tibberJSON[i].energy;
                          obj.tax   = tibberJSON[i].tax;
                          obj.min = false;
                          obj.max = false;
                          obj.average = false;
                          obj.level = tibberJSON[i].level;
                          tibberData.push(obj);
                      }
                      // average, minium, maximum direkt holen
                      
                      let eleArr = ['average','minimum','maximum'];
                      for(let i=0;i<eleArr.length;i++){
                          let obj = {};
                          switch (eleArr[i]) {
                                  case 'average':
                                      obj.hour     = 'non'
                                      obj.start   = ''
                                      obj.startTS = 0;
                                      obj.value   = getState(dpLeveltbl+'.'+eleArr[i]+'.total').val
                                      obj.energy   = getState(dpLeveltbl+'.'+eleArr[i]+'.energy').val
                                      obj.tax   = getState(dpLeveltbl+'.'+eleArr[i]+'.tax').val
                                      obj.min = false;
                                      obj.max = false;
                                      obj.average = true;
                                      obj.level = '';
                                      tibberData.push(obj);
                                      break;
                                  case 'minimum':
                                      obj.hour    = 'non';
                                      obj.start   = getState(dpLeveltbl+'.'+eleArr[i]+'.startsAt').val
                                      obj.startTS = new Date(obj.start).getTime();
                                      obj.value   = getState(dpLeveltbl+'.'+eleArr[i]+'.total').val
                                      obj.energy   = getState(dpLeveltbl+'.'+eleArr[i]+'.energy').val
                                      obj.tax   = getState(dpLeveltbl+'.'+eleArr[i]+'.tax').val
                                      obj.min = true;
                                      obj.max = false;
                                      obj.average = false;
                                      tibberData.push(obj);
                                      break;
                                  case 'maximum':
                                      obj.hour    = 'non';
                                      obj.start   = getState(dpLeveltbl+'.'+eleArr[i]+'.startsAt').val
                                      obj.startTS = new Date(obj.start).getTime();
                                      obj.value   = getState(dpLeveltbl+'.'+eleArr[i]+'.total').val
                                      obj.energy   = getState(dpLeveltbl+'.'+eleArr[i]+'.energy').val
                                      obj.tax   = getState(dpLeveltbl+'.'+eleArr[i]+'.tax').val
                                      obj.min = false;
                                      obj.max = true;
                                      obj.average = false;
                                      tibberData.push(obj);
                                      break;
                                  default: 
                                      break;
                              }
                      }
                      // log(tibberData);
                      let setechart = false;
                      if(setechart){
                          for(let i=0;i<dpArray.length;i++){
                              setHistoryData(dpArray[i],tibberObj[levelObject(dpArray[i])[3]]);
                          }
                          seteChartsDP(dpArray);
                      }
                      // log('setHTML');
                      setHTML(tibberData,priceArr[x]);
                      if(getState(visDP).val=='VIS'){
                          createHtmlFile(priceArr[x])
                      }
                  }
                  
              }
              
          }
          // createHtmlFile();
          async function createHtmlFile(name) {
              let dp = '';
              let file = '';
              if(name == 'PricesToday'){
                  dp = '0_userdata.0.Strom.tibberHistory.htmlToday';
                  file = 'today';
              }else{
                  dp = '0_userdata.0.Strom.tibberHistory.htmlTomorrow';
                  file = 'tomorrow';
              }
              const htmlContent = getState(dp).val;
              writeFile('vis.0', '/tibber/'+file+'.html',htmlContent, (err) => {
                  if (err) {
                  console.error('Fehler beim Speichern der HTML-Datei, tibber-Verzeichnis angelegt?', err);
                  } else {
                  console.log('HTML-Datei '+file+'.html erfolgreich gespeichert');
                  }
              });
          }
          
          
          
          function setHTML(origData,priceDP){
              let data = [];
              let dataMin = '';
              let dataMinTime = '';
              let dataMax = '';
              let dataMaxTime = '';
              let dataAvg = '';
              let dataNull = false;
              // log(priceDP);
              let tibberInst = getState(tibberInstDP).val;
              let tibberLink = $('tibberlink.'+tibberInst+'.Homes.*.PricesToday.json')
              let tblLevel = levelObject(tibberLink[0]);
              let dpLeveltbl = getDPLevel(tblLevel,3);
              
              let minToday = getState(dpLeveltbl + '.PricesToday.minimum.total').val;
              //minToday = minToday-(Math.trunc(minToday*0.1))
              // log(minToday)
              let maxToday = getState(dpLeveltbl + '.PricesToday.maximum.total').val
              let minTomorrow = getState(dpLeveltbl + '.PricesTomorrow.minimum.total').val
              //minTomorrow = minTomorrow-(Math.trunc(minTomorrow*0.1))
              let maxTomorrow = getState(dpLeveltbl + '.PricesTomorrow.maximum.total').val
              let jsonTomorrow = JSON.parse(getState(dpLeveltbl + '.PricesTomorrow.json').val);
              
              let graphMin = 0;
              if(minToday >= minTomorrow){
                  if(minTomorrow != 0){
                      graphMin = minTomorrow;
                  }else{
                      graphMin = minToday;
                  }
              }else{
                  graphMin = minToday;
              }
              let graphMax = 0;
              if(maxToday >= maxTomorrow){
                  graphMax = maxToday;
              }else{
                  graphMax = maxTomorrow;
              }
              // graphMax = Math.round((graphMax + parseFloat((graphMax / 20).toFixed(2))) * 100) / 100;
              // graphMax = Math.max(Math.ceil(graphMax * 100) / 100, 0.35);
              if(jsonTomorrow.length ==0 ){
                  graphMin = minToday;
                  graphMax = maxToday
              }
              graphMin = Math.ceil(graphMin * 50) / 50 - 0.02;
              graphMax = Math.ceil(graphMax * 50) / 50 + 0.01;
              //log(graphMin)
          
              for(let i=0;i<origData.length;i++){
                  if(origData[i].min){
                      dataMin = origData[i].value;
                      //log(dataMin);
                      dataMinTime =origData[i].startTS;
                      //log(dataMinTime)
                  }
                  if(origData[i].max){
                      dataMax = origData[i].value;
                      dataMaxTime =origData[i].startTS;
                  }
                  if(origData[i].average){
                      dataAvg = origData[i].value;
                  }
              }
              if(origData.length>3){
                  for(let i=0;i<origData.length;i++){
                      if(!origData[i].average && !origData[i].max && !origData[i].min ){
                          if( origData[i].value < dataAvg){ 
                              if(origData[i].level == 'NORMAL' ){
                                  data.push({time:origData[i].startTS,value: origData[i].value,tax: origData[i].tax,energy: origData[i].energy, level: origData[i].level})//, color: 'rgba(0,255,0,0.2)', border: levelColor(origData[i].level)
                              }else{
                                  data.push({time:origData[i].startTS,value: origData[i].value,tax: origData[i].tax,energy: origData[i].energy,level: origData[i].level}) //,  color: levelColor(origData[i].level), border: 'lime'
                              }
                          }else{
                              data.push({time:origData[i].startTS,value: origData[i].value,tax: origData[i].tax,energy: origData[i].energy, level: origData[i].level}) //,color: levelColor(origData[i].level), border: 'red'
                          }
                      }else{
                          if(origData[i].min){
                              dataMin = origData[i].value;
                              dataMinTime =origData[i].startTS;
                          }
                          if(origData[i].max){
                              //log(origData[i]);
                              dataMax = origData[i].value;
                              dataMaxTime =origData[i].startTS;
                              //log(dataMaxTime);
                          }
                          if(origData[i].average){
                              dataAvg = origData[i].value;
                          }
                      }
                      
                  }
                  // log('oben '+graphMin)
              }else{
                  dataNull = true;
                  //dataMin = String(graphMin);
                  //dataMax = String(graphMax);
                  //dataMax = "0";
                  //dataAvg = '0.01';
                  //graphMin = minToday;
                  //graphMax = maxToday;
                  //graphMin = Math.ceil(graphMin * 50) / 50 - 0.01;
                  //graphMax = Math.ceil(graphMax * 50) / 50 + 0.01;
              }
              // Werte holen
              let showTaxEnergy = getState(tibberShowTaxEnergyDP).val;
              let minMaxAvg = getState(tibberShowMinMaxAvgDP).val;
              let colorJSON = getState(tibberColorDP).val;
          
              let html = '';
              html += '<!DOCTYPE html>';
              html += '<html lang="en">';
              html += '<head>';
              html += '<meta charset="UTF-8">';
              html += '<meta name="viewport" content="width=device-width, initial-scale=1.0">';
              html += '<title>Tibber-Tageswert</title>';
              html += '<script src="https://cdn.jsdelivr.net/npm/echarts@5.4.3/dist/echarts.min.js"></script>';
              html += '<script src="https://cdnjs.cloudflare.com/ajax/libs/moment.js/2.29.1/moment.min.js"></script>';
              html += '</head>';
              html += '<body>'
              if(getState(visDP).val == 'VIS'){
                  html += '<div id="chart-container" style="width: 600px; height:400px;"></div>';
              }else{
                  html += '<div id="chart-container" style="width: 100%; height:400px;"></div>';
              }
              //log(data);
              html += '<script>'
              html += '    var data = '+JSON.stringify(data)+';';
              html += '    var chartContainer = document.getElementById("chart-container");'
              html += '    var myChart = echarts.init(chartContainer);';
          
             
              html += '    function formatTime(time) {';
              html += '        return moment(time).format("HH");'
              html += '    }';
              html += '    function calculateArrowPosition(hour){'
              //html += '       console.log((hour) * (100 / 24) + "%");'
              html += '       return (hour / 24) * 100 +1 + "%";'
              html += '    }'
              html += '    function updateChart() {';
              html += '        var minValue = Math.min.apply(null, data.map(function (item) {';
              html += '          return item.value;';
              html += '        }));';
              //html += '        console.log(minValue);'
              // html += '        var yAxisMin = minValue - (minValue/10);'
              html += '        var yAxisMin = '+graphMin+';';
              html += '        var maxValue = '+dataMax+';'
              //html += '        var maxValue = '+graphMax+';'
              //html += '        console.log(maxValue);'
              // html += '        var yAxisMax = maxValue + (maxValue/10);'
              html += '        let avgValue = '+dataAvg+';'
              html += '        var visualMapPieces =' + colorJSON +';';
              html += '        var values = data.map(item => (item.value-minValue).toFixed(2));'
              html += '        var maxLineValue = Math.max.apply(null, values);'
              html += '        var maxLineIndex = values.indexOf(maxLineValue);'
              html += '        var maxLineData = {time:'+dataMaxTime+',value:'+dataMax+'};'
              html += '        var currentHour = new Date().getHours() ;'
              // html += '        console.log(currentHour);'
              //html += '        console.log(maxLineData.time);'
              // html += '        var maxV = parseFloat((Math.max(...values)));'
              //html += '        console.log(maxV);'
              //html += '        let pro = values.map((value) => (value/maxV).toFixed(2));'
              //html += '        console.log(values);'
              //html += '        console.log(pro);'
              html += '        var colorStops = [];'
              //html += '        console.log(yAxisMin +" "+maxValue);'
              if(!dataNull){
              html += '        visualMapPieces.map(piece => {'
              html += '          if(piece["lte"] >=yAxisMin && piece["gt"]<=maxValue){ '
              //html += '            console.log(piece["lte"] + " "+maxValue + " "+ yAxisMin);'
              html += '            if(piece["gt"]>=yAxisMin){'
              //html += '             console.log(piece["gt"] +" gt gesetzt " +yAxisMin);'
              html += '             colorStops.push({'
              html += '              offset:  ((piece["gt"]-yAxisMin)/(maxValue-yAxisMin)),'//  /((maxValue-minValue)/maxValue)  /(visualMapPieces[visualMapPieces.length - 1]["gt"])
              html += '              color: piece.color'
              html += '             });'
              html += '            }'
              html += '            if(piece["lte"]<=maxValue){'
              //html += '            console.log(piece["lte"] +" lte gesetzt "+yAxisMin);'
              html += '             colorStops.push({'
              html += '              offset:  ((piece["lte"]-yAxisMin)/(maxValue-yAxisMin)),'//  /((maxValue-minValue)/maxValue)  /(visualMapPieces[visualMapPieces.length - 1]["gt"])
              html += '              color: piece.color'
              html += '             });'
              html += '            }'
              html += '            if(piece["lte"]>maxValue ){'
              //html += '            console.log(piece["lte"] +" lte gesetzt "+yAxisMin);'
              html += '            colorStops.push({'
              html += '              offset:  1,'//  /((maxValue-minValue)/maxValue)  /(visualMapPieces[visualMapPieces.length - 1]["gt"])
              html += '              color: piece.color'
              html += '             });'
              //html += '            }'
              html += '           };'
              html += '          }else{'
              //html += '            console.log(piece["lte"] + " " + piece["gt"]);'
              html += '           if(piece["lte"]>=maxValue && piece["gt"]<=maxValue ){'
              //html += '            console.log(piece["lte"] +" lte gesetzt "+yAxisMin);'
              html += '            colorStops.push({'
              html += '              offset:  ((piece["lte"]-yAxisMin)/(maxValue-yAxisMin)),'//  /((maxValue-minValue)/maxValue)  /(visualMapPieces[visualMapPieces.length - 1]["gt"])
              html += '              color: piece.color'
              html += '            });'
          
              html += '           }else if(piece["lte"]>=maxValue && piece["gt"] <= maxValue){'
              // html += '            console.log("Drin");'
              html += '            colorStops.push({'
              html += '              offset:  ((piece["lte"]-yAxisMin)/(maxValue-yAxisMin)),'//  /((maxValue-minValue)/maxValue)  /(visualMapPieces[visualMapPieces.length - 1]["gt"])
              html += '              color: piece.color'
              html += '            });'
              html += '           }'
              html += '          }; ' 
              html += '        });'
              //html += '        console.log(colorStops);'
              //html += '        console.log(colorStops[colorStops.length-1].color);'
              html += '        colorStops.push({'
              html += '            offset: 1,' //visualMapPieces[visualMapPieces.length - 1]["gt"]
              html += '            color: colorStops[colorStops.length-1].color'// visualMapPieces[visualMapPieces.length - 1].color'
              html += '        });'
              //html += '        console.log(colorStops);'
              html += '        colorStops.splice(0, 0, {offset: 0,color:colorStops[0].color});'
              //html += '        colorStops.splice(0, 0, {offset: 0,color:colorStops[0].color});'
              //html += '        colorStops.splice(2, 0, {offset: colorStops[1].offset,color:colorStops[2].color});'
              //html += '        colorStops.splice(4, 0, {offset: colorStops[3].offset,color:colorStops[4].color});'
              //html += '        console.log(colorStops);'
              }
              if(dataNull && !getState(tibberShowGraphIfEmptyDP).val){
                  html += '        myChart.setOption({';
              html += '            title: {';
              if(priceDP== 'PricesToday'){
                  html += '                text: "'+getState(tibberLabelTodayDP).val+'",';
                  if(getState(tibberShowLabelTodayDP).val){
                      html += '            show: true'
                  }else{
                      html += '            show: false'
                  }
              }else{
                  if(dataNull && getState(tibberShowWaitLabelTomorrowDP).val){
                        html += '          textAlign: "auto", '
                        html += '          textStyle: { '
                        html += '             color: "red"'
                        html += '          },'
                        html += '          left: "50px",'
                        html += '          text: "'+getState(tibberWaitTomorrowTextDP).val +'",';
                  }else{
                      html += '            text: "'+getState(tibberLabelTomorrowDP).val+'",';
                      if(getState(tibberShowLabelTomorrowDP).val){
                          html += '        show: true,'
                      }else{
                          html += '        show: false,'        
                      }
                  }
                  
                  
              }
              
              html += '                 },});';
              }else{
          
              html += '        myChart.setOption({';
              html += '            title: {';
              if(priceDP== 'PricesToday'){
                  html += '                text: "'+getState(tibberLabelTodayDP).val+'",';
                  if(getState(tibberShowLabelTodayDP).val){
                      html += '                show: true'
                  }else{
                      html += '                show: false'
                  }
              }else{
                  if(dataNull && getState(tibberShowWaitLabelTomorrowDP).val){
                        html += '            textAlign: "auto", '
                        html += '            textStyle: { '
                        html += '               color: "red"'
                        html += '            },'
                        html += '            left: "50px",'
                        html += '            text: "'+getState(tibberWaitTomorrowTextDP).val +'",';
                  }else{
                      html += '                text: "'+getState(tibberLabelTomorrowDP).val+'",';
                      if(getState(tibberShowLabelTomorrowDP).val){
                          html += '                show: true,'
                      }else{
                          html += '                show: false,'        
                      }
                  }
                  
                  
              }
              
              html += '            },';
              html += '            visualMap: {';
              html += '              type: "piecewise",'
              html += '              pieces: visualMapPieces,'
              html += '              dimension: 1,' // Mapping to the 'value' dimension'
              html += '              showLabel: true,'
              html += '              precision: 2,'
              html += '              itemWidth: 6,'
              html += '              orient: "horizontal",'
              html += '              left: "center", calculable: true,selectedMode: "multiple",'
              html += '              bottom: 10,'
              html += '              text: ["High", "Low"],'
              html += '              textStyle: {'
              if(getState(darkModeDP).val){
                  html += '                color: "white"'
              }else{
                  html += '                color: "black"'
              }
              html += '              },'
              //html += '              inRange: {'
              //html += '                color: colorStops.map(stop => stop.color)';//visualMapPieces.map(piece => piece.color)'
              //html += '              },'
              /* bringt nichts
              html += '              itemStyle:{'
              html += '                 symbol:"pin",'
              html += '                 symbolSize: 30,'
              html += '                 markPoint: {'
              html += '                   data: [{'
              html += '                    symbol: "circle",'
              html += '                       coord: [data.time, data.value], itemStyle:{ color:"red"}'
              html += '                    }]'
              html += '                 },'
              html += '               }'
              */
              html += '            },'
              
              if(minMaxAvg){
                  html += '            grid: {';
                  if(getState(tibberShowMinMaxAvgTextDP).val){
                      html += '              right: 50,'; // Vergrößern Sie diesen Wert nach Bedarf
                  }else{
                      html += '              right: 10,';
                  }
                  html += '              left: 10,';
                  html += '              containLabel: true'; // Stellen Sie sicher, dass das Label innerhalb des Diagramms bleibt
                  html += '            },';
              }else{
                  html += '            grid: {';
                  html += '              right: 10,'; // Vergrößern Sie diesen Wert nach Bedarf
                  html += '              left: 10,'; // Vergrößern Sie diesen Wert nach Bedarf
                  html += '              containLabel: true'; // Stellen Sie sicher, dass das Label innerhalb des Diagramms bleibt
                  html += '            },';
              }
              html += '            areaStyle: {'
              html += '              color: colorStops';//"red"'; visualMapPieces.map(piece => piece.color)'
              //html += '              color: "blue", '
              html += '            },'
              // Option für Pfeil unter Kurve
              /*
              if(!dataNull && getState(tibberHighlightCurrentHourDP).val){
              html += 'graphic: [{'
              html += '    type: "image",'
              html += '    id: "arrow",'
              html += '    bounding: "all",'
              html += '    z:100,'
              //html += '    origin: [calculateArrowPosition(currentHour), "10%"],'
              //html += '    origin: [0.5, 0],'  // Koordinaten für den Pfeil
              html += '    bottom: "10%", '
              html += '    left: calculateArrowPosition(currentHour),';//"50px",'
              html += '    '
              html += '    style: {'
              html += '        image: "https://api.iconify.design/mdi/arrow-up-bold.svg?width=24&height=24&color=blue", ' // Pfad zum Bild deines Pfeils
              html += '        width: 30,'
              html += '        height: 30,'
              html += '    }'
              html += '}],'
              }
              */
              // ToolBox
              html += '            toolbox: {';
              html += '              feature: {';
              html += '                saveAsImage: {';
              html += '                   backgroundColor: "rgba(38, 37, 37, 1)",';
              html += '                   title: "Speichern",';
              let fileName = priceDP.replace('Prices','') 
              if(fileName == 'Today'){
                  fileName += ' '+ formatDate(new Date(),'DD.MM.YYYY'); 
              }else{
                  fileName += ' '+ formatDate(new Date().getTime()+86400000,'DD.MM.YYYY'); 
              }
              html += '                   name: "TibberHTML '+fileName+'"'
              html += '                },'
              html += '                magicType: {';
              html += '                  type: ["line", "bar"],';
              html += '                  title:{';
              html += '                     line: "Line-Chart",';
              html += '                     bar: "Bar-Chart",';
              html += '                  }'
              
              html += '                },';
              html += '                dataView: {';
              html += '                  title: "Daten aus der Serie",';
              html += '                  lang: ["Daten der Kurve", "Schließen", "Aktualisieren"],'
              html += '                  optionToContent: function (opt) {';
              html += "                      var table = '<table style=\"width:100%;\"><tbody><tr style=\"text-align: left;\"><th>Stunde</th><th>Wert</th><th>Energie</th><th>Steuer</th><th>Level</th></tr>';";
              //html += '                      console.log(opt.series.length); '
              //html += '                      console.log(opt.series[0].data); '
              html += '                      for (var i = 0; i< opt.series[0].data.length;i++) {';
              html += '                          table += "<tr>";';
              html += '                         for(let x =0; x < opt.series[0].data[i].value.length; x++){'
              html += '                            if(x==0){';
              html += '                               table +=  "<td>" + ("0"+new Date(opt.series[0].data[i].value[x]).getHours()).slice(-2) + "</td>";';
              html += '                            }else{';
              html += '                               table +=  "<td>" + opt.series[0].data[i].value[x] + "</td>";';
              html += '                            } '
              html += '                         }';
              html += '                           table += "</tr>";';
              html += '                      }';
              html += '                      table += "</tbody></table>";'
              html += '                      return table;';
              html += '                  },';
              html += '                  readOnly: true';
              html += '                },'
              html += '              }';
              html += '            },'
              
              html += '            xAxis: {';
              html += '                type: "time",';
              html += '                axisLabel: {';
              html += '                    show: true,'
              html += '                    formatter: function (value) {';
              html += '                        return formatTime(value);';
              html += '                    }';
              html += '                },';
              html += '                splitNumber: 10,';
          	html += '            },';
              html += '            yAxis: {';
              html += '                type: "value",';
              html += '                axisLabel: {'; 
              
              html += '                  formatter: function (value) {';
              html += '                     return value.toFixed(3) + " €";';
              html += '                  }';
              
              html += '                },';
              
              html += '               min: '+graphMin+','; //
              html += '               max: '+graphMax+',' //yAxisMax
              html += '            },';
              
              
          
          
          
              html += '            series: [{';
              
              html += '                data: data.map(function (item) {';
              html += '                    var hour = new Date(item.time).getHours();'
              html += '                    return {';
              html += '                       value: [item.time, item.value, item.energy, item.tax, item.level],';
              //html += '                       lineStyle: {width: hour === currentHour ? 10:null},'
              
              // Symbol für Line einstellen
          
              html += '                        symbol: "circle",'
              
              if(getState(tibberHighlightCurrentHourDP).val && priceDP == 'PricesToday'){
                  html += '                    symbolSize: hour === currentHour ? 10:null, '
                  html += '                    itemStyle: {'
                     
                  if(getState(darkModeDP).val){
                      //html += '                           backgroundColor: hour === currentHour ? "'+getState(tibberHighlightColorDarkDP).val+'":null,'
                      html += '                           borderColor: hour === currentHour ? "'+getState(tibberHighlightColorDarkDP).val+'":null,'
                      html += '                           shadowColor: hour === currentHour ? "'+getState(tibberHighlightColorDarkDP).val+'":null,'
                      html += '                           borderWidth: hour === currentHour ? 2:null,'
                      html += '                           shadowBlur: hour === currentHour ? 20:null,'
                  }else{
                      html += '                           borderColor: hour === currentHour ? "'+getState(tibberHighlightColorLightDP).val+'":null,'
                      html += '                           shadowColor: hour === currentHour ? "'+getState(tibberHighlightColorLightDP).val+'":null,'
                      html += '                           borderWidth: hour === currentHour ? 1:null,'
                      html += '                           shadowBlur: hour === currentHour ? 10:null,'
                  }
                  //html += '                           borderWidth: hour === currentHour ? 1:null,'
                  //html += '                           shadowBlur: hour === currentHour ? 10:null,'
                  
                  html += '                     },'
                  
              }
              // Aria für Schraffierung
              //html += 'aria: {'
              //html +='    enabled: true,'
              //html += '   decal: {'
              //html +='        show: hour === currentHour'
              //html += '   }'
              //html +='},'
              html += '                        emphasis: {';
              html += '                          itemStyle: {';
              html += '                            color: "white" '; // Füge die Farbe in die Betonung ein
              html += '                          },';
              html += '                          label: {';
              html += '                            show: true,';
              html += '                            formatter: function (params) {';
              html += '                               return params.data.value[1].toFixed(3) + " €";'; //console.log(params);
              html += '                            },';
              html += '                            color: "black",';
              html += '                            fontWeight: "bold", ';
              html += '                            backgroundColor: "white"';
              html += '                          }';
              html += '                        }';
              html += '                     } ';
              html += '                }),'; // end data
              
              if(getState(tibberSteppedLineDP).val){
                  html += '            step: "end",'
              }
              // ItemStyle
              //html += '                itemStyle:{'
              //html += '                  color: function (params) {'
                          // Färbe den Balken der aktuellen Stunde anders ein
              //html += '                    console.log(new Date(params.value[0]).getHours());'
              //html += '                    console.log(currentHour);'
              //html += 'console.log(new Date(params.value[0]).getHours() === currentHour ? "red" : "blue");'
              //html += '                    return new Date(params.value[0]).getHours() === currentHour ? "red" : "blue";'
              //html += '                  }'
              //html += '                },'
              if(getState(tibberAreaDP).val){
              html += '                areaStyle:{'
              html += '                    color: new echarts.graphic.LinearGradient(0, 1, 0, 0, colorStops),' ;
              
              //html += '                    color:  colorStops,'
              // html += '                    max: maxValue, '
              /*
              html += '                    color: function (params) {'
              html += '                       console.log(params);'
              html += '                       var wert = params.data.value[1];'
              html += '                       var col = "red";'
              html += '                       for (var i = 0; i < visualMapPieces.length; i++) {'
              html += '                           var piece = visualMapPieces[i];'
              html += '                           if (wert >= piece.gt && wert <= piece.lte) {'
              html += '                               col = piece.color;'
              html += '                               break;'
              html += '                           }'
              html += '                       }'
              html += '                       return col;'
              html += '                   },'
              */
              html += '                },'
              }
              html += '                type: "'+getState(tibberGraphTypeDP).val+'",';
              //html += '               markArea: {'
              //html += '                   silent: true,'
              //html += '                   data: ['
              //html += '                       [{'
              //html += '                           xAxis: "min",'
              //html += '                           itemStyle: {'
              //html += '                               color: "rgba(0, 0, 0, 0.7)"'
              //html += '                           }'
              //html += '                           }, {'
              //html += '                               xAxis: "max",'
              //html += '                       }]'
              //html += '                   ]'
              //html += '               },'
              
              if(minMaxAvg){
                  html += '                markLine: {';
                  html += '                  symbol: "none",';  // Kein Symbol für die Markierungslinie
                  html += '                  lineStyle: {';
                  html += '                    color: "red",';   // Farbe der Markierungslinie
                  html += '                    type: "dashed"';  // Art der Linie (gestrichelt)
                  html += '                  },';
                  
                  if(getState(tibberShowMinMaxAvgTextDP).val){ //coord: [maxLineData.time, maxLineData.value] ,)
                      if(!dataNull){
                      html += '                  data: [';
                      html += '                   {yAxis: minValue ,name: "MIN", lineStyle: { color: "lime" },label: { show: true, position: "end", formatter: "Min\\n"+ minValue.toFixed(3)+" €",textStyle: { fontSize: 12,fontWeight: "bold", color:"white"  } }  },';
                      html += '                   {yAxis: maxValue,name: "MAX", lineStyle: { color: "red" },label: { show: true, position: "end", formatter: "Max\\n"+ maxValue.toFixed(3)+" €",textStyle: { fontSize: 12,fontWeight: "bold", color:"white"  } } },';
                      html += '                   {yAxis: avgValue ,name: "AVG", lineStyle: { color: "blue" },label: { show: true, position: "end", formatter: "Avg\\n"+ avgValue.toFixed(3)+" €",textStyle: { fontSize: 12,fontWeight: "bold", color:"white"  } } }';
                      html += '                  ], '
                      }
                  }else{
                      if(!dataNull){
                      html += '                  data: [';
                      // funktioniert nicht !,tooltip: {show: true,formatter: "Min\\n\\n" + params.value.toFixed(3) + " €",textStyle: {fontSize: 12,fontWeight: "bold",color: "white"}}  ,formatter: "Min " + minValue.toFixed(3) + " €"
                      html += '                   {yAxis: minValue ,name: "MIN", lineStyle: { color: "lime" },label: { show: false, position: "end", formatter: "Min\\n\\n"+ minValue.toFixed(3)+" €",textStyle: { fontSize: 12,fontWeight: "bold", color:"white"  } }  },';
                      html += '                   {yAxis: maxValue,name: "MAX", lineStyle: { color: "red" },label: { show: false, position: "end", formatter: "Max\\n\\n"+ maxValue.toFixed(3)+" €",textStyle: { fontSize: 12,fontWeight: "bold", color:"white"  } } },';
                      html += '                   {yAxis: avgValue ,name: "AVG", lineStyle: { color: "blue" },label: { show: false, position: "end", formatter: "Avg\\n\\n"+ avgValue.toFixed(3)+" €",textStyle: { fontSize: 12,fontWeight: "bold", color:"white"  } } }';
                      html += '                  ], '    
                      }    
                  }
                  html += '                }';
              }
              html += '            }],'; // Ende Series
          
          
              
          
              html += '            tooltip: {';
              html += '              trigger: "axis",';
              html += '              axisPointer: {';
              html += '               type: "shadow"';
              html += '              },';
              html += '              textStyle: {';
              html += '                fontFamily: "Courier",';
              html += '                fontWeight: "bold"'; // Hinzugefügt
              html += '              },'
              html += '              formatter: function (params) {';
              html += '                let time = "Start ab: "+ moment(params[0].axisValue).format("HH:mm")+ " Uhr";';
              html += '                let value = "Preis:&nbsp&nbsp&nbsp&nbsp"+params[0].value[1].toFixed(4) + " €";';
              if(showTaxEnergy){
                  html += '            let energy = "Energie:&nbsp&nbsp"+params[0].value[2].toFixed(4) + " €";'
                  html += '            let tax    = "Steuer:&nbsp&nbsp&nbsp"+params[0].value[3].toFixed(4) + " €";'
                  html += '            let lev    = "Level:&nbsp&nbsp&nbsp&nbsp"+ params[0].value[4];'
                  html += "            return  `${time}<br/>${value}<br/>${energy}<br/>${tax}<br/>${lev}` ;";
              }else{
                  //html += "            return `<span style=\"font-family: 'Arial'; font-weight: 'bold';\" >${time}<br/>${value}</span>` ;";
                  html += "            return `${time}<br/>${value}` ;";
              }
              
              html += '              }';
              html += '            },';
              
              html += '        }) ';// end setOption
              }
              html += '    }'; 
              
          
              html += '    updateChart(); ';
              html +='     var updateInterval = setInterval(updateChart, 3600000);'
              html += '</script>';
              html += '</body>';
              html += '</html>';
          
              // log(html);
              if(priceDP == 'PricesToday'){
                  setState(tibberHTMLTodayDP,html);
              }else{
                  setState(tibberHTMLTomorrowDP,html);
              }
          }
          
          
          
          function sortByName(x, y) {
              // Wenn x oder y nicht-numerisch sind, setze sie an das Ende
              if (isNaN(x.hour) || isNaN(y.hour)) {
                  return isNaN(x.hour) ? 1 : -1;
              }
              
              // Vergleiche numerische Werte
              return x.hour - y.hour;
          }
          
          
          
          on({id: dbHistoryDP, change: "any"}, function (obj) {
              let value = obj.state.val;
              // history für die DPs aktiv?
              if (value!=''){
                  if (getState('system.adapter.'+value+'.alive').val){
                      if (isHistoryActiveAllDPs(dpArray)){
                          if(logging){
                              log('History-Future-DPs sind angelegt und History aktiviert!');
                          }
                          // getPVData(dpArray);
                          //runScript();
                      }else{
                          if(logging){
                              log('History wird angelegt für die future-DPs!');
                          }
                          activateDPsHistory(dpArray);
                          setTimeout(function(){
                              deleteAllHistoryDPs(dpArray);
                              // log('gelöscht');
                              // getPVData(dpArray);
                          },3000)
                          //runScript();
                      }
                  }else{
                      log('Der History-Adapter ist nicht gestartet! -> Es werden keine DPs mit History aktiviert','warn');
                  }
              }
          });
          
          
          function setDPs(tibberInst){
              // Ist der Adapter aktiv
              // 
              //let pvAliveDP = 'system.adapter.pvForecast.'+tibberInst+'.alive';
              //if(existsState(pvAliveDP)){
              //    if(getState(pvAliveDP).val){
                      // Adapter ist gestartet
                      let tibberKeys = ['Value','Tax','Energy']
                      for(let i=0;i<tibberKeys.length;i++){
                              dpArray.push(tibberDP+'.future'+tibberKeys[i]);
                      }
                      
              //    }else{
              //        log('Der Adapter tibberlink.'+tibberInst+' ist nicht gestartet!');
              //    }
              //}else{
              //    log('Der Adapter pvForecast ist nicht installiert')
              //}
              // Alte erst löschen
              // Nur löschen, wenn sich die DPs geändert haben
              let delItems = false;
              if(dpArray.length >0){
                  // delDPs(dpArray);
                  
                  for(let i=0;i<dpArray.length;i++){
                      if(existsState(dpArray[i])){
          
                      }else{
                          delItems = true;
                          delDPs(dpArray);
                          break;
                      }
                  }
              }
              if(delItems){
                  setTimeout(function() {
                      if(dpArray.length >0){
                          createDPs(dpArray);
                      }
                  },3000);
              }else{
                  createDPs(dpArray);
              }
          }
          
          
          function delDPs(arr){
              for(let i=0; i<arr.length;i++){
                  if(existsState(arr[i])){
                      deleteStateAsync(arr[i]);
                  }
              }
          }
          // createStateAsync(futureTempDP, {read: true, write: false, name: "daswetter temperature", type: "number", role: "", def: 0 });
          
          function createDPs(arr){
              for(let i=0; i<arr.length;i++){
                  // 0_userdata.0.pvForecastHistory.historyDB
                  let name =  levelObject(arr[i])[3];
                  createStateAsync(arr[i], {read: true, write: false, name: "tibber"+name, type: "number", role: "", def: 0 });
              }
          }
          
          
          function seteChartsDP(dpArray){
              let startDT = getDateObject('00:00').getTime(); // heute 00:00
              // pvForecast hat nur 2 Tage im Array
              let endDT = startDT + 24*1*60*60*1000;
              // start_time, end_time, start, end, timeType
              for(let i=0;i<dpArray.length;i++){
                  let echartDP = 'echarts.0.tibber'+levelObject(dpArray[i])[3];
                  let obj; 
                  if (existsObject(echartDP)){
                      obj = getObject(echartDP);
                      //log(obj);
                      if (obj.native.data.timeType == 'static'){
                          obj.native.data.start = formatDate(startDT,'YYYY-MM-DD');
                          obj.native.data.end   = formatDate(endDT,'YYYY-MM-DD');
                          obj.native.data.start_time = '00:00';
                          obj.native.data.end_time = '00:00';
                          setObject(echartDP,obj);
                      }
                  }
              }
          }
          
          
          
          function isHistoryActiveAllDPs(dpArray){
              // dparray automatisch gesetzt
              let active = false;
              let dbHistory = getState(dbHistoryDP).val;
              if (dbHistory != ''){
                  for(let i= 0;i<dpArray.length;i++){
                      let dpPara = levelObject(dpArray[i])[3];
                      // log('dpPara: '+dpPara);
                      // log(pvForecastDP+'.future'+dpPara);
                      // setActiveHistory(pvForecastDP+'.future'+dpPara);
                      active = isHistoryActive(tibberDP+'.'+dpPara,dbHistory);
                      if(active == false){
                          return false;
                      }
                  }
                  
                  log('Tibber-DPs History aktiv');
                  return true;
              }else{
                  log('DB Auswahl fehlt');
                  return false;
              }
          }
          
          function isHistoryActive(dp,db){
              let obj = getObject(dp);
              if (obj.common.custom != undefined){
                  //log(obj.common.custom);
                  let custom = obj.common.custom;
                  
                  for (let key in custom){
                      //log(key);
                      if (key.indexOf(db)>=0){  //'history'
                          return true;
                      }
                  }
              }
              return false;
          }
          
          function activateDPsHistory(dpArray){
              let historyDB = getState(dbHistoryDP).val;
              //log('HistoryDB: '+historyDB);
              if (historyDB != ''){
                  if (getState('system.adapter.'+historyDB+'.alive').val){
          
                      if (historyDB!=''){
                          for(let i= 0;i<dpArray.length;i++){
                              //log('DParray[i]: '+dpArray[i]);
                              let dpPara = levelObject(dpArray[i])[3];
                              //log('dpPara: '+dpPara);
                              //log(pvForecastDP+'.'+dpPara);
                              setActiveHistory(tibberDP+'.'+dpPara);
                              setTimeout(function(){
                                  deleteAllHistoryData(tibberDP+'.'+dpPara);
                              },2000)
                          }
                          log('Future-DPs History aktiviert');
                      }else{
                          log('Es wurde keine DB für Future-History ausgewählt!','warn');
                      }
                  }else{
                      log('Der Adapter ist nicht gestartet! -> keine Aktivierung möglich','warn');
                  }
              }else{
                  log('Aktivierung der DPs für die DB erst möglich, wenn man eine DB ausgewählt hat!','warn');
              }
          }
          
          
          // deleteAllHistoryDPs();
          
          function deleteAllHistoryDPs(dpArray){
              let dbHistory = getState(dbHistoryDP).val;
              if (getState('system.adapter.'+dbHistory+'.alive').val){
                  log('History DPs dpArray löschen!');
                  for(let i= 0;i<dpArray.length;i++){
                      //log('DParray[i]: '+dpArray[i]);
                      let dpPara = levelObject(dpArray[i])[3];
                      //log('dpPara: '+dpPara);
                      //log(pvForecastDP+'.'+dpPara);
                      deleteAllHistoryData(tibberDP+'.'+dpPara);
                      
                  }
                  log('Future-DPs History gelöscht');
              }else{
                  log('Adapter nicht gestartet!');
              }
          }
          
          
          function deleteAllHistoryData(dp){
              let dbHistory = getState(dbHistoryDP).val;
              if (dbHistory!=''){
                  //let dtStart= getDateObject('00:00').getTime(); // heute 00:00 Uhr
                  //let dtStop = dtStart + 24*6*60*60*1000;
                  sendTo(dbHistory, 'deleteAll', [       // 'history.0' 'deleteRange'
                      {id: dp}//, start: dtStart, end: dtStop
                      
                  ], result => {//console.log('deleted')
                  });
              }else{
                  log('Löschen nicht durchgeführt, da keine HistoryDB festgelegt');
              }
          }
          
          
          
          function getHistoryAdapter(){
              // history, influxdb, sql
              log('Einlesen der vorhandenen History-DBs.');
              let histArr = ['history','influxdb','sql'];
              let arr =[];
              for (let i=0; i<histArr.length;i++){
                  let dp = $('system.adapter.'+histArr[i]+'.*.alive');
                  //log(dp);
                  for(let x=0;x<dp.length;x++){
                      //log(dp[x]);
                      let dpID = dp[x];
                     
                      if (getObject(dpID).common != undefined){
                          //log(getState(dpID).val);
                          if (getState(dpID).val != null && getState(dpID).val){
                              dp[x] = dp[x].substring(15,dp[x].length-6);
                              // log(dp[x]);
                              arr.push(dp[x]);
                          }
                          if (getState(dpID).val == null){
                              log('History-Adapter ist fehlerhaft: '+dp[x] +' -> alive auf false setzen');
                          }
                      }
                  }
          
              }
              let devStates = {'':'keine Auswahl'};
              for (let i=0; i< arr.length;i++){
                  devStates[arr[i]] = arr[i];
              }
              //log(devStates);
              if (existsState(dbHistoryDP)){
                  let obj = getObject(dbHistoryDP);
                  obj.common.states = devStates;
                  setObject(dbHistoryDP,obj);
              }else{
                  createStateAsync(dbHistoryDP, {read: true, write: true, name: "DB-Auswahl", type: "string", role: "", def: '',states:devStates });    
              }
          }
          
          
          
          
          function setActiveHistory(dp){
              let dbHistory = getState(dbHistoryDP).val;
              //log('dbHistory setActive: '+dbHistory);
              if (dbHistory !=''){
                  sendTo(dbHistory, 'enableHistory', { // 'history.0'
                      id: dp,  // 'system.adapter.history.0.memRss'
                      options: {
                          changesOnly:  true,
                          debounce:     0,
                          retention:    31536000,
                          maxLength:    3,
                          changesMinDelta: 0,
                          //ignoreZero: true,
                          aliasId: '',
                          enabled: true,
                          debounceTime: 0,
                          blockTime: 0,
                          changesRelogInterval: "0",
                          ignoreBelowNumber: "",
                          disableSkippedValueLogging: false,
                          customRetentionDuration: 365,
                          enableDebugLogs: false
                  
                      }
                  }, function (result) {
                      if (result.error) {
                          console.log(result.error);
                      }
                      if (result.success) {
                          //successfull enabled
                          //log(dp +' wurde in history aktiviert');
                      }
                  });
              }
          }
          
          // setHistoryData(futureHumidityDP,dpValueArr);
          
          function setHistoryData(dp,states){
              let dbHistory = getState(dbHistoryDP).val;
              if (dbHistory!=''){
                  sendTo(dbHistory, 'storeState', { // 'history.0'
                      id: dp,
                      state: states
                      }, result => {
                          // console.log('added')
                      });
              }
          }
          
          
          
          function levelObject(id){
              // 0_userdata.0.jarvis.system.tabWidgetStateEffects.0.Desktop.0.Bad.0b5dd758-8d7d-4259-8945-821b1c942960.states.0.displayOff
              let idArr=id.split('.');
              return idArr; //log(idArr[10]);
          }
          
          // log(getDPLevel(levelObject('0_userdata.0.jarvis.system.tabWidgetStateEffects.0.Desktop.0.Bad.0b5dd758-8d7d-4259-8945-821b1c942960.states.0.displayOff'),9));
          function getDPLevel(idArr,level){
              let id ='';
              for (let i=0;i<=level;i++){
                  id += idArr[i] +'.'
              }
              id = id.substr(0,id.length-1); // letzten Punkt wegnehmen
              return id;
          }
          
          M Online
          M Online
          MCU
          schrieb am zuletzt editiert von MCU
          #404

          @meikie Es werden sofort die HTML ermittelt.

          Setz mal ein LOG hier hin
          ce7ae63f-4fca-4b51-9afb-7af3da45e7f7-image.png

          if(logging){
             log(tibberLink);
          }
          

          NUC i7 64GB mit Proxmox ---- Jarvis Infos Aktualisierungen der Doku auf Instagram verfolgen -> mcuiobroker Instagram
          Wenn Euch mein Vorschlag geholfen hat, bitte rechts "^" klicken.

          M 1 Antwort Letzte Antwort
          0
          • M MCU

            @meikie Es werden sofort die HTML ermittelt.

            Setz mal ein LOG hier hin
            ce7ae63f-4fca-4b51-9afb-7af3da45e7f7-image.png

            if(logging){
               log(tibberLink);
            }
            
            M Offline
            M Offline
            Meikie
            schrieb am zuletzt editiert von
            #405

            @mcu

               // log(priceDP);
                let tibberInst = getState(tibberInstDP).val;
                let tibberLink = $('tibberlink.'+tibberInst+'.Homes.*.PricesToday.json')
                if(logging){
               log(tibberLink);
            }
                let tblLevel = levelObject(tibberLink[0]);
                let dpLeveltbl = getDPLevel(tblLevel,3);
            

            Ich finde leider keine Log. Oder wo müsste dieser zu finden sein?

            M 1 Antwort Letzte Antwort
            0
            • M Meikie

              @mcu

                 // log(priceDP);
                  let tibberInst = getState(tibberInstDP).val;
                  let tibberLink = $('tibberlink.'+tibberInst+'.Homes.*.PricesToday.json')
                  if(logging){
                 log(tibberLink);
              }
                  let tblLevel = levelObject(tibberLink[0]);
                  let dpLeveltbl = getDPLevel(tblLevel,3);
              

              Ich finde leider keine Log. Oder wo müsste dieser zu finden sein?

              M Online
              M Online
              MCU
              schrieb am zuletzt editiert von MCU
              #406

              @meikie Log wird im ioBroker-log angezeigt und unter dem script
              sonst setz noch ein anders log davor

              let tibberLink = $('tibberlink.'+tibberInst+'.Homes.*.PricesToday.json')
              if(logging){
                 log('TEST');
                 log(tibberLink);
              }
              

              NUC i7 64GB mit Proxmox ---- Jarvis Infos Aktualisierungen der Doku auf Instagram verfolgen -> mcuiobroker Instagram
              Wenn Euch mein Vorschlag geholfen hat, bitte rechts "^" klicken.

              M 1 Antwort Letzte Antwort
              0
              • M MCU

                @meikie Log wird im ioBroker-log angezeigt und unter dem script
                sonst setz noch ein anders log davor

                let tibberLink = $('tibberlink.'+tibberInst+'.Homes.*.PricesToday.json')
                if(logging){
                   log('TEST');
                   log(tibberLink);
                }
                
                M Offline
                M Offline
                Meikie
                schrieb am zuletzt editiert von Meikie
                #407

                @mcu

                00:45:54.312	info	javascript.0 (933464) Stop script script.js.Strom.tibberHTML
                00:45:54.496	info	javascript.0 (933464) Start javascript script.js.Strom.tibberHTML
                00:45:54.537	info	javascript.0 (933464) script.js.Strom.tibberHTML: registered 16 subscriptions, 1 schedule, 0 messages, 0 logs and 0 file subscriptions
                
                M 1 Antwort Letzte Antwort
                0
                • M Meikie

                  @mcu

                  00:45:54.312	info	javascript.0 (933464) Stop script script.js.Strom.tibberHTML
                  00:45:54.496	info	javascript.0 (933464) Start javascript script.js.Strom.tibberHTML
                  00:45:54.537	info	javascript.0 (933464) script.js.Strom.tibberHTML: registered 16 subscriptions, 1 schedule, 0 messages, 0 logs and 0 file subscriptions
                  
                  M Online
                  M Online
                  MCU
                  schrieb am zuletzt editiert von MCU
                  #408

                  @meikie Nach ca 3 Sekunden sollte jetzt wenigstens TEST auftauchen

                  NUC i7 64GB mit Proxmox ---- Jarvis Infos Aktualisierungen der Doku auf Instagram verfolgen -> mcuiobroker Instagram
                  Wenn Euch mein Vorschlag geholfen hat, bitte rechts "^" klicken.

                  M 1 Antwort Letzte Antwort
                  0
                  • M MCU

                    @meikie Nach ca 3 Sekunden sollte jetzt wenigstens TEST auftauchen

                    M Offline
                    M Offline
                    Meikie
                    schrieb am zuletzt editiert von
                    #409

                    @mcu Da war ausersehen die 308 kopiert. Diese habe ich jetzt gelöscht. Log:

                    Nein da passiert nix.

                    M 1 Antwort Letzte Antwort
                    0
                    • M Meikie

                      @mcu Da war ausersehen die 308 kopiert. Diese habe ich jetzt gelöscht. Log:

                      Nein da passiert nix.

                      M Online
                      M Online
                      MCU
                      schrieb am zuletzt editiert von
                      #410

                      @meikie Das ist aber in den Objekten zu sehen?
                      ddaec8b4-a4dc-4694-a7e5-42fcb878e84e-image.png

                      NUC i7 64GB mit Proxmox ---- Jarvis Infos Aktualisierungen der Doku auf Instagram verfolgen -> mcuiobroker Instagram
                      Wenn Euch mein Vorschlag geholfen hat, bitte rechts "^" klicken.

                      M 1 Antwort Letzte Antwort
                      0
                      • M MCU

                        @meikie Das ist aber in den Objekten zu sehen?
                        ddaec8b4-a4dc-4694-a7e5-42fcb878e84e-image.png

                        M Offline
                        M Offline
                        Meikie
                        schrieb am zuletzt editiert von
                        #411

                        @mcu Bei mir heißt der Ordner nicht tibberlink, sondern tibberconnect

                        M 1 Antwort Letzte Antwort
                        0
                        • M Meikie

                          @mcu Bei mir heißt der Ordner nicht tibberlink, sondern tibberconnect

                          M Online
                          M Online
                          MCU
                          schrieb am zuletzt editiert von
                          #412

                          @meikie Wie soll das auch funktionieren?

                          NUC i7 64GB mit Proxmox ---- Jarvis Infos Aktualisierungen der Doku auf Instagram verfolgen -> mcuiobroker Instagram
                          Wenn Euch mein Vorschlag geholfen hat, bitte rechts "^" klicken.

                          M 1 Antwort Letzte Antwort
                          0
                          • M MCU

                            @meikie Wie soll das auch funktionieren?

                            M Online
                            M Online
                            MCU
                            schrieb am zuletzt editiert von MCU
                            #413

                            @Meikie Dann hast du nicht den richtigen tibberlink-adapter installiert. Das ist die Grundlage.
                            Aber gut sind denn im tibberconnect auch die Preisdaten?

                            NUC i7 64GB mit Proxmox ---- Jarvis Infos Aktualisierungen der Doku auf Instagram verfolgen -> mcuiobroker Instagram
                            Wenn Euch mein Vorschlag geholfen hat, bitte rechts "^" klicken.

                            M 1 Antwort Letzte Antwort
                            0
                            • M MCU

                              @Meikie Dann hast du nicht den richtigen tibberlink-adapter installiert. Das ist die Grundlage.
                              Aber gut sind denn im tibberconnect auch die Preisdaten?

                              M Offline
                              M Offline
                              Meikie
                              schrieb am zuletzt editiert von Meikie
                              #414

                              @mcu Okay, bevor wir hier rumdoktern wäre es ja besser den tibberlink zu installieren. Aber unter Adapter ist der nicht zu finden.

                              M 2 Antworten Letzte Antwort
                              0
                              • M Meikie

                                @mcu Okay, bevor wir hier rumdoktern wäre es ja besser den tibberlink zu installieren. Aber unter Adapter ist der nicht zu finden.

                                M Online
                                M Online
                                MCU
                                schrieb am zuletzt editiert von
                                #415

                                @meikie Ich sehe den tibberConnect nicht
                                f29c377f-61b5-45b0-bf15-0e6df9a18e92-image.png

                                NUC i7 64GB mit Proxmox ---- Jarvis Infos Aktualisierungen der Doku auf Instagram verfolgen -> mcuiobroker Instagram
                                Wenn Euch mein Vorschlag geholfen hat, bitte rechts "^" klicken.

                                1 Antwort Letzte Antwort
                                0
                                • M Meikie

                                  @mcu Okay, bevor wir hier rumdoktern wäre es ja besser den tibberlink zu installieren. Aber unter Adapter ist der nicht zu finden.

                                  M Online
                                  M Online
                                  MCU
                                  schrieb am zuletzt editiert von MCU
                                  #416

                                  @meikie Sofort raus damit.
                                  Das Bild raus! Da ist Deine ID drin.
                                  Woher hast du den tibberConnect?

                                  NUC i7 64GB mit Proxmox ---- Jarvis Infos Aktualisierungen der Doku auf Instagram verfolgen -> mcuiobroker Instagram
                                  Wenn Euch mein Vorschlag geholfen hat, bitte rechts "^" klicken.

                                  M 1 Antwort Letzte Antwort
                                  0
                                  • M MCU

                                    @meikie Sofort raus damit.
                                    Das Bild raus! Da ist Deine ID drin.
                                    Woher hast du den tibberConnect?

                                    M Offline
                                    M Offline
                                    Meikie
                                    schrieb am zuletzt editiert von Meikie
                                    #417

                                    @mcu
                                    Habe es jetzt installiert. War unter Beta zu finden.

                                    M 1 Antwort Letzte Antwort
                                    0
                                    • M Meikie

                                      @mcu
                                      Habe es jetzt installiert. War unter Beta zu finden.

                                      M Offline
                                      M Offline
                                      Meikie
                                      schrieb am zuletzt editiert von
                                      #418

                                      @meikie Okay, jetzt ist was drin. Scheint zu funktionieren. Aber leider immer noch keine Graphen in Jarvis.

                                      M 1 Antwort Letzte Antwort
                                      0
                                      • M Meikie

                                        @meikie Okay, jetzt ist was drin. Scheint zu funktionieren. Aber leider immer noch keine Graphen in Jarvis.

                                        M Online
                                        M Online
                                        MCU
                                        schrieb am zuletzt editiert von MCU
                                        #419

                                        @meikie Nimm das Log raus da ist deine Id drin.
                                        Die Fehler sind sehr wahrscheinlich da, weil bestimmte Daten jetzt nicht verfügbar sind und erst ab 14:00 Uhr eingestellt werden.
                                        Melde Dich heute Nachmittag, wie es da aussieht.

                                        NUC i7 64GB mit Proxmox ---- Jarvis Infos Aktualisierungen der Doku auf Instagram verfolgen -> mcuiobroker Instagram
                                        Wenn Euch mein Vorschlag geholfen hat, bitte rechts "^" klicken.

                                        M 1 Antwort Letzte Antwort
                                        1
                                        • icebearI icebear

                                          @mcu said in HowTo: Zusatz-Programme fuer jarvis v3:

                                          Ich dachte nur die Kurven mit der Soll-temp-Einstellung.

                                          Ah ich verstehe, ja so wär es eigentlich für mich perfekt.

                                          Und beim Klick auf die Gauge kommt dann
                                          details.png

                                          M Online
                                          M Online
                                          MCU
                                          schrieb am zuletzt editiert von
                                          #420

                                          @icebear So ein Schritt weiter
                                          Für FritzDect
                                          b109649a-6167-471c-a20c-7e693bcaca57-image.png

                                          Für hm-rpc
                                          3067cbee-e5e1-4b5b-8f59-8af505745b89-image.png

                                          NUC i7 64GB mit Proxmox ---- Jarvis Infos Aktualisierungen der Doku auf Instagram verfolgen -> mcuiobroker Instagram
                                          Wenn Euch mein Vorschlag geholfen hat, bitte rechts "^" klicken.

                                          icebearI 1 Antwort Letzte Antwort
                                          1

                                          Hey! Du scheinst an dieser Unterhaltung interessiert zu sein, hast aber noch kein Konto.

                                          Hast du es satt, bei jedem Besuch durch die gleichen Beiträge zu scrollen? Wenn du dich für ein Konto anmeldest, kommst du immer genau dorthin zurück, wo du zuvor warst, und kannst dich über neue Antworten benachrichtigen lassen (entweder per E-Mail oder Push-Benachrichtigung). Du kannst auch Lesezeichen speichern und Beiträge positiv bewerten, um anderen Community-Mitgliedern deine Wertschätzung zu zeigen.

                                          Mit deinem Input könnte dieser Beitrag noch besser werden 💗

                                          Registrieren Anmelden
                                          Antworten
                                          • In einem neuen Thema antworten
                                          Anmelden zum Antworten
                                          • Älteste zuerst
                                          • Neuste zuerst
                                          • Meiste Stimmen


                                          Support us

                                          ioBroker
                                          Community Adapters
                                          Donate

                                          396

                                          Online

                                          32.8k

                                          Benutzer

                                          82.8k

                                          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