Navigation

    Logo
    • Register
    • Login
    • Search
    • Recent
    • Tags
    • Unread
    • Categories
    • Unreplied
    • Popular
    • GitHub
    • Docu
    • Hilfe
    1. Home
    2. stenmic

    NEWS

    • Amazon Alexa - ioBroker Skill läuft aus ?

    • Monatsrückblick – September 2025

    • Neues Video "KI im Smart Home" - ioBroker plus n8n

    S
    • Profile
    • Following 0
    • Followers 1
    • Topics 48
    • Posts 632
    • Best 64
    • Groups 2

    stenmic

    @stenmic

    Pro

    73
    Reputation
    164
    Profile views
    632
    Posts
    1
    Followers
    0
    Following
    Joined Last Online

    stenmic Follow
    Pro Starter

    Best posts made by stenmic

    • Script für Formel 1 - Kalender, Ergebnisse und Wertungen

      moin,
      Hier ein Script für die Formel 1

      was kann es:

      • Rennkalender (1950 - aktuelle Session)
      • Rennergebnisse (aktuelle Session)
      • Fahrer und Konstrukteur WM (aktuelle Session)

      Die Daten werden von "Ergast" über https://api.jolpi.ca/ergast/ geholt.

      Wer testen will kann gerne mitmachen.

      Als erstes müssen die Datenpunkte angelegt werden.
      Folgendes Skript unter Skripte/JavaScript anlegen und einmal ausführen.
      Damit werden die notwendigen Datenpunkte unter “ 0_userdata.0.Formel1“ angelegt.

      Datenpunkte

      // Kalender
      createState('0_userdata.0.Formel1.Kalender.json',{name: 'json',role: 'value',type: 'string'});
      createState('0_userdata.0.Formel1.Kalender.Jahr',parseFloat(formatDate(new Date(), 'JJJJ')),{name: 'Jahr',role: 'value',type: 'number'});
      createState('0_userdata.0.Formel1.Kalender.Ueberschrift_VIS','UEBERSCHRIFT VIS',{name: 'Ueberschrift_VIS',role: 'value',type: 'string'});
      createState('0_userdata.0.Formel1.Kalender.VIS_json',{name: 'VIS_json',role: 'value',type: 'string'});
      createState('0_userdata.0.Formel1.Kalender.Jahr_zurueck',false,{name: 'Jahr_zurueck',role: 'button',type: 'boolean'});
      createState('0_userdata.0.Formel1.Kalender.Jahr_vor',false,{name: 'Jahr_vor',role: 'button',type: 'boolean'});
      createState('0_userdata.0.Formel1.Kalender.Jahr_aktuell',false,{name: 'Jahr_aktuell',role: 'button',type: 'boolean'});
      createState('0_userdata.0.Formel1.Kalender.Anzahl_Rennen_Aktuelles_Jahr',0,{name: 'Anzahl_Rennen_Aktuelles_Jahr',role: 'value',type: 'number'});
      
      // Rennergebnisse
      createState('0_userdata.0.Formel1.Rennergebnisse.json',{name: 'json',role: 'value',type: 'string'});
      createState('0_userdata.0.Formel1.Rennergebnisse.VIS_json',{name: 'VIS_json',role: 'value',type: 'string'});
      createState('0_userdata.0.Formel1.Rennergebnisse.Rennen_Nr',0,{name: 'Rennen_Nr',role: 'value',type: 'number'});
      createState('0_userdata.0.Formel1.Rennergebnisse.Rennen_Jahr',parseFloat(formatDate(new Date(), 'JJJJ')),{name: 'Rennen_Jahr',role: 'value',type: 'number'});
      createState('0_userdata.0.Formel1.Rennergebnisse.Rennen_gefahren',0,{name: 'Rennen_gefahren',role: 'value',type: 'number'});
      createState('0_userdata.0.Formel1.Rennergebnisse.Ueberschrift_VIS','UEBERSCHRIFT VIS',{name: 'Ueberschrift_VIS',role: 'value',type: 'string'});
      createState('0_userdata.0.Formel1.Rennergebnisse.Rennen_zurueck',false,{name: 'Rennen_zurueck',role: 'button',type: 'boolean'});
      createState('0_userdata.0.Formel1.Rennergebnisse.Rennen_vor',false,{name: 'Rennen_vor',role: 'button',type: 'boolean'});
      createState('0_userdata.0.Formel1.Rennergebnisse.Rennen_aktuell',false,{name: 'Rennen_aktuell',role: 'button',type: 'boolean'});
      
      // Fahrerwertung
      createState('0_userdata.0.Formel1.Fahrerwertung.json',{name: 'json',role: 'value',type: 'string'});
      createState('0_userdata.0.Formel1.Fahrerwertung.json_letztes_Rennen',{name: 'json_letztes_Rennen',role: 'value',type: 'string'});
      createState('0_userdata.0.Formel1.Fahrerwertung.VIS_json',{name: 'VIS_json',role: 'value',type: 'string'});
      createState('0_userdata.0.Formel1.Fahrerwertung.Rennen_Nr',0,{name: 'Rennen_Nr',role: 'value',type: 'number'});
      createState('0_userdata.0.Formel1.Fahrerwertung.Rennen_gefahren',0,{name: 'Rennen_gefahren',role: 'value',type: 'number'});
      createState('0_userdata.0.Formel1.Fahrerwertung.Jahr',parseFloat(formatDate(new Date(), 'JJJJ')),{name: 'Jahr',role: 'value',type: 'number'});
      createState('0_userdata.0.Formel1.Fahrerwertung.Ueberschrift_VIS','UEBERSCHRIFT VIS',{name: 'Ueberschrift_VIS',role: 'value',type: 'string'});
      createState('0_userdata.0.Formel1.Fahrerwertung.Rennen_zurueck',false,{name: 'Rennen_zurueck',role: 'button',type: 'boolean'});
      createState('0_userdata.0.Formel1.Fahrerwertung.Rennen_vor',false,{name: 'Rennen_vor',role: 'button',type: 'boolean'});
      createState('0_userdata.0.Formel1.Fahrerwertung.Rennen_aktuell',false,{name: 'Rennen_aktuell',role: 'button',type: 'boolean'});
      
      // Konstrukteur
      createState('0_userdata.0.Formel1.Konstrukteur.json',{name: 'json',role: 'value',type: 'string'});
      createState('0_userdata.0.Formel1.Konstrukteur.json_letztes_Rennen',{name: 'json_letztes_Rennen',role: 'value',type: 'string'});
      createState('0_userdata.0.Formel1.Konstrukteur.VIS_json',{name: 'VIS_json',role: 'value',type: 'string'});
      createState('0_userdata.0.Formel1.Konstrukteur.Rennen_Nr',0,{name: 'Rennen_Nr',role: 'value',type: 'number'});
      createState('0_userdata.0.Formel1.Konstrukteur.Rennen_gefahren',0,{name: 'Rennen_gefahren',role: 'value',type: 'number'});
      createState('0_userdata.0.Formel1.Konstrukteur.Jahr',parseFloat(formatDate(new Date(), 'JJJJ')),{name: 'Jahr',role: 'value',type: 'number'});
      createState('0_userdata.0.Formel1.Konstrukteur.Ueberschrift_VIS','UEBERSCHRIFT VIS',{name: 'Ueberschrift_VIS',role: 'value',type: 'string'});
      createState('0_userdata.0.Formel1.Konstrukteur.Rennen_zurueck',false,{name: 'Rennen_zurueck',role: 'button',type: 'boolean'});
      createState('0_userdata.0.Formel1.Konstrukteur.Rennen_vor',false,{name: 'Rennen_vor',role: 'button',type: 'boolean'});
      createState('0_userdata.0.Formel1.Konstrukteur.Rennen_aktuell',false,{name: 'Rennen_aktuell',role: 'button',type: 'boolean'});
      

      Danach die folgenden 4 Skripte anlegen (unter Skripte/JavaScript) und starten.
      (am Anfang der Skripte können Farben eingestellt werden)

      Kalender

      // ################################################
      // Formel1 Kalender v1.01
      // by stenmic
      // ################################################
      
      var Farbe_fuer_naechstes_Rennen, Blocker_api, X, Kalender, Blocker_nextRace, Date2, spanIN, VIS, spanOUT;
      
      // ################################################
      Farbe_fuer_naechstes_Rennen = '#26b1e6';
      // ################################################
      
      function textReplace(haystack, needle, replacement) {
       needle = needle.replace(/([-()\[\]{}+?*.$\^|,:#<!\\])/g, '\\$1')
                      .replace(/\x08/g, '\\x08');
       return haystack.replace(new RegExp(needle, 'g'), replacement);
      }
      
      Blocker_api = false;
      on({ id: '0_userdata.0.Formel1.Kalender.Jahr' /* Jahr */, change: 'any' }, async (obj) => {
       let value = obj.state.val;
       let oldValue = obj.oldState.val;
       if ((1950 <= (obj.state ? obj.state.val : '')) && (Blocker_api == false)) {
         Blocker_api = true;
         httpGet((['https://api.jolpi.ca/ergast/f1/',(obj.state ? obj.state.val : ''),'/races/'].join('')), { timeout: 10000, responseType: 'text' }, async (err, response) => {
           if ((getAttr(response.data, 'MRData.RaceTable.Races.0.season') != null) && (response.statusCode == 200)) {
             setState('0_userdata.0.Formel1.Kalender.json' /* json */, response.data, true);
             await wait(500);
             Blocker_api = false;
           } else {
             await wait(500);
             setState('0_userdata.0.Formel1.Kalender.Jahr' /* Jahr */, (getState('0_userdata.0.Formel1.Kalender.Jahr').val - 1), true);
             Blocker_api = false;
           }
         });
       }
      });
      on({ id: '0_userdata.0.Formel1.Kalender.Jahr_zurueck' /* Jahr_zurueck */, change: 'any' }, async (obj) => {
       let value = obj.state.val;
       let oldValue = obj.oldState.val;
       if (1950 < getState('0_userdata.0.Formel1.Kalender.Jahr').val) {
         setState('0_userdata.0.Formel1.Kalender.Jahr' /* Jahr */, (getState('0_userdata.0.Formel1.Kalender.Jahr').val - 1), true);
       }
      });
      on({ id: '0_userdata.0.Formel1.Kalender.Jahr_vor' /* Jahr_vor */, change: 'any' }, async (obj) => {
       let value = obj.state.val;
       let oldValue = obj.oldState.val;
       setState('0_userdata.0.Formel1.Kalender.Jahr' /* Jahr */, (getState('0_userdata.0.Formel1.Kalender.Jahr').val + 1), true);
      });
      on({ id: '0_userdata.0.Formel1.Kalender.Jahr_aktuell' /* Jahr_aktuell */, change: 'any' }, async (obj) => {
       let value = obj.state.val;
       let oldValue = obj.oldState.val;
       setState('0_userdata.0.Formel1.Kalender.Jahr' /* Jahr */, parseFloat(formatDate(new Date(), 'JJJJ')), true);
      });
      schedule('{"time":{"exactTime":true,"start":"00:30"},"period":{"days":1}}', async () => {
       if (getState('0_userdata.0.Formel1.Kalender.Jahr').val != parseFloat(formatDate(new Date(), 'JJJJ'))) {
         setState('0_userdata.0.Formel1.Kalender.Jahr' /* Jahr */, parseFloat(formatDate(new Date(), 'JJJJ')), true);
       }
      });
      schedule("1,16,31,46 4-23 * * 0,6", async () => {
       setState('0_userdata.0.Formel1.Kalender.Jahr' /* Jahr */, parseFloat(formatDate(new Date(), 'JJJJ')), true);
      });
      on({ id: '0_userdata.0.Formel1.Kalender.json' /* json */, change: 'any' }, async (obj) => {
       let value = obj.state.val;
       let oldValue = obj.oldState.val;
       if (getState('0_userdata.0.Formel1.Kalender.Jahr').val == formatDate(new Date(), 'JJJJ')) {
         setState('0_userdata.0.Formel1.Kalender.Ueberschrift_VIS' /* Ueberschrift_VIS */, (['••• Rennkalender ',getState('0_userdata.0.Formel1.Kalender.Jahr').val,' •••'].join('')), true);
       } else {
         setState('0_userdata.0.Formel1.Kalender.Ueberschrift_VIS' /* Ueberschrift_VIS */, ('Rennkalender ' + String(getState('0_userdata.0.Formel1.Kalender.Jahr').val)), true);
       }
       X = 0;
       Kalender = [];
       Blocker_nextRace = false;
       while (!(getAttr((obj.state ? obj.state.val : ''), ('MRData.RaceTable.Races.' + String(X))) == null)) {
         if (getAttr((obj.state ? obj.state.val : ''), (['MRData.RaceTable.Races.',X,'.time'].join(''))) != null) {
           Date2 = [formatDate(getDateObject(getAttr((obj.state ? obj.state.val : ''), (['MRData.RaceTable.Races.',X,'.date'].join('')))), 'T.M.'),' • ',formatDate(getDateObject(([getAttr((obj.state ? obj.state.val : ''), (['MRData.RaceTable.Races.',X,'.date'].join(''))),' ',getAttr((obj.state ? obj.state.val : ''), (['MRData.RaceTable.Races.',X,'.time'].join('')))].join(''))), 'S.mm'),' Uhr'].join('');
         } else {
           Date2 = formatDate(getDateObject(getAttr((obj.state ? obj.state.val : ''), (['',X,'.date'].join('')))), 'T.M.');
         }
         if (getDateObject(([getAttr((obj.state ? obj.state.val : ''), (['MRData.RaceTable.Races.',X,'.date'].join(''))),' ',getAttr((obj.state ? obj.state.val : ''), (['MRData.RaceTable.Races.',X,'.time'].join('')))].join(''))).getTime() + 14400000 >= (new Date().getTime())) {
           if (Blocker_nextRace == false) {
             spanIN = ['<span style="color:',Farbe_fuer_naechstes_Rennen,';">'].join('');
             spanOUT = '</span>';
             Blocker_nextRace = true;
           } else {
             spanIN = '';
             spanOUT = '';
           }
         } else {
           spanIN = '';
           spanOUT = '';
         }
         VIS = { 'Rennen': [spanIN,X + 1,spanOUT].join(''), 'Datum': [spanIN,Date2,spanOUT].join(''), 'Grand Prix': [spanIN,getAttr((obj.state ? obj.state.val : ''), (['MRData.RaceTable.Races.',X,'.raceName'].join(''))),spanOUT].join(''), 'Strecke': [spanIN,[' <a href="',textReplace(getAttr((obj.state ? obj.state.val : ''), (['MRData.RaceTable.Races.',X,'.Circuit.url'].join(''))), '//en.', '//de.'),'" target="_blank" style="text-decoration: none; color: inherit;">',getAttr((obj.state ? obj.state.val : ''), (['MRData.RaceTable.Races.',X,'.Circuit.circuitName'].join(''))),'</a>'].join(''),spanOUT].join(''), 'Location': [spanIN,getAttr((obj.state ? obj.state.val : ''), (['MRData.RaceTable.Races.',X,'.Circuit.Location.locality'].join(''))),spanOUT].join('') };
         Kalender.push(VIS);
         X = (typeof X === 'number' ? X : 0) + 1;
       }
       setState('0_userdata.0.Formel1.Kalender.VIS_json' /* VIS_json */, JSON.stringify(Kalender), true);
       if (getState('0_userdata.0.Formel1.Kalender.Jahr').val == formatDate(new Date(), 'JJJJ')) {
         if (getState('0_userdata.0.Formel1.Kalender.Anzahl_Rennen_Aktuelles_Jahr').val != X) {
           setState('0_userdata.0.Formel1.Kalender.Anzahl_Rennen_Aktuelles_Jahr' /* Anzahl_Rennen_Aktuelles_Jahr */, X, true);
         }
       }
      });
      
      'MRData.RaceTable.Races.';
      

      Rennergebnisse

      // ################################################
      // Formel1 Rennergebnisse v1.02
      // by stenmic
      // ################################################
      
      var Farbe_fuer_Ausgefallen, Fahrer, Farbe_fuer_Fahrer, Team, Farbe_fuer_Team, Farbe_Fast_Lap, Farbe_Pfeil_UP, Farbe_Pfeil_Down, Blocker_api, X, Anzahl_Fahrer, Rennen, Position, Aenderung, Start, Zeit, spanINFahrer, spanOUTFahrer, spanINTeam, spanOUTTeam, Aenderung2, spanINFastLap, spanOUTFastLap, Punkte, VIS;
      
      // ################################################
      Farbe_fuer_Ausgefallen = '#e55a52';
      Fahrer = 'Nico Hülkenberg';
      Farbe_fuer_Fahrer = '#3bb273';
      Team = 'Haas F1 Team';
      Farbe_fuer_Team = '#26b1e6';
      Farbe_Fast_Lap = '#DA5EBA';
      Farbe_Pfeil_UP = '#3bb273';
      Farbe_Pfeil_Down = '#e55a52';
      // ################################################
      
      on({ id: '0_userdata.0.Formel1.Rennergebnisse.Rennen_zurueck' /* Rennen_zurueck */, change: 'any' }, async (obj) => {
       let value = obj.state.val;
       let oldValue = obj.oldState.val;
       if (1 < getState('0_userdata.0.Formel1.Rennergebnisse.Rennen_Nr').val) {
         setState('0_userdata.0.Formel1.Rennergebnisse.Rennen_Nr' /* Rennen_Nr */, (getState('0_userdata.0.Formel1.Rennergebnisse.Rennen_Nr').val - 1), true);
       }
      });
      on({ id: '0_userdata.0.Formel1.Rennergebnisse.Rennen_vor' /* Rennen_vor */, change: 'any' }, async (obj) => {
       let value = obj.state.val;
       let oldValue = obj.oldState.val;
       setState('0_userdata.0.Formel1.Rennergebnisse.Rennen_Nr' /* Rennen_Nr */, (getState('0_userdata.0.Formel1.Rennergebnisse.Rennen_Nr').val + 1), true);
      });
      on({ id: '0_userdata.0.Formel1.Rennergebnisse.Rennen_aktuell' /* Rennen_aktuell */, change: 'any' }, async (obj) => {
       let value = obj.state.val;
       let oldValue = obj.oldState.val;
       if (getState('0_userdata.0.Formel1.Rennergebnisse.Rennen_Nr').val == 0) {
         setState('0_userdata.0.Formel1.Rennergebnisse.Rennen_Nr' /* Rennen_Nr */, 30, true);
       } else {
         setState('0_userdata.0.Formel1.Rennergebnisse.Rennen_Nr' /* Rennen_Nr */, getState('0_userdata.0.Formel1.Rennergebnisse.Rennen_gefahren').val, true);
       }
      });
      schedule('{"time":{"exactTime":true,"start":"00:31"},"period":{"days":1}}', async () => {
       httpGet((['https://api.jolpi.ca/ergast/f1/',formatDate(new Date(), 'JJJJ'),'/1/results/'].join('')), { timeout: 10000, responseType: 'text' }, async (err, response) => {
         if ((getAttr(response.data, 'MRData.RaceTable.Races.0.season') != null) && (response.statusCode == 200)) {
           setState('0_userdata.0.Formel1.Rennergebnisse.Rennen_Jahr' /* Rennen_Jahr */, parseFloat(formatDate(new Date(), 'JJJJ')), true);
         }
       });
      });
      Blocker_api = false;
      on({ id: '0_userdata.0.Formel1.Rennergebnisse.Rennen_Nr' /* Rennen_Nr */, change: 'any' }, async (obj) => {
       let value = obj.state.val;
       let oldValue = obj.oldState.val;
       if (Blocker_api == false) {
         Blocker_api = true;
         httpGet((['https://api.jolpi.ca/ergast/f1/',getState('0_userdata.0.Formel1.Rennergebnisse.Rennen_Jahr').val,'/',(obj.state ? obj.state.val : ''),'/results/'].join('')), { timeout: 10000, responseType: 'text' }, async (err, response) => {
           if ((getAttr(response.data, 'MRData.RaceTable.Races.0.season') != null) && (response.statusCode == 200)) {
             setState('0_userdata.0.Formel1.Rennergebnisse.json' /* json */, response.data, true);
             if ((obj.state ? obj.state.val : '') > getState('0_userdata.0.Formel1.Rennergebnisse.Rennen_gefahren').val) {
               setState('0_userdata.0.Formel1.Rennergebnisse.Rennen_gefahren' /* Rennen_gefahren */, (obj.state ? obj.state.val : ''), true);
             }
             await wait(500);
             Blocker_api = false;
           } else {
             await wait(500);
             if (getState('0_userdata.0.Formel1.Rennergebnisse.Rennen_Nr').val > 1) {
               setState('0_userdata.0.Formel1.Rennergebnisse.Rennen_Nr' /* Rennen_Nr */, (getState('0_userdata.0.Formel1.Rennergebnisse.Rennen_Nr').val - 1), true);
             }
             Blocker_api = false;
           }
         });
       }
      });
      schedule("2,17,32,47 4-23 * * 0,6", async () => {
       httpGet((['https://api.jolpi.ca/ergast/f1/',getState('0_userdata.0.Formel1.Rennergebnisse.Rennen_Jahr').val,'/driverstandings/'].join('')), { timeout: 10000, responseType: 'text' }, async (err, response) => {
         if (response.statusCode == 200) {
           setState('0_userdata.0.Formel1.Rennergebnisse.Rennen_gefahren' /* Rennen_gefahren */, parseFloat(getAttr(response.data, 'MRData.StandingsTable.round')), true);
         }
       });
      });
      on({ id: '0_userdata.0.Formel1.Rennergebnisse.json' /* json */, change: 'any' }, async (obj) => {
       let value = obj.state.val;
       let oldValue = obj.oldState.val;
       X = 0;
       if (getState('0_userdata.0.Formel1.Rennergebnisse.Rennen_Nr').val == getState('0_userdata.0.Formel1.Rennergebnisse.Rennen_gefahren').val) {
         setState('0_userdata.0.Formel1.Rennergebnisse.Ueberschrift_VIS' /* Ueberschrift_VIS */, (['••• Rennen ',getState('0_userdata.0.Formel1.Rennergebnisse.Rennen_Nr').val,' von ',getState('0_userdata.0.Formel1.Kalender.Anzahl_Rennen_Aktuelles_Jahr').val,' • ',getAttr((obj.state ? obj.state.val : ''), 'MRData.RaceTable.Races.0.raceName'),' • ',formatDate(getDateObject(getAttr((obj.state ? obj.state.val : ''), 'MRData.RaceTable.Races.0.date')), 'T.M.JJ'),' •••'].join('')), true);
       } else {
         setState('0_userdata.0.Formel1.Rennergebnisse.Ueberschrift_VIS' /* Ueberschrift_VIS */, (['Rennen ',getState('0_userdata.0.Formel1.Rennergebnisse.Rennen_Nr').val,' von ',getState('0_userdata.0.Formel1.Kalender.Anzahl_Rennen_Aktuelles_Jahr').val,' • ',getAttr((obj.state ? obj.state.val : ''), 'MRData.RaceTable.Races.0.raceName'),' • ',formatDate(getDateObject(getAttr((obj.state ? obj.state.val : ''), 'MRData.RaceTable.Races.0.date')), 'T.M.JJ')].join('')), true);
       }
       while (!(getAttr((obj.state ? obj.state.val : ''), ('MRData.RaceTable.Races.0.Results.' + String(X))) == null)) {
         Anzahl_Fahrer = X + 1;
         X = (typeof X === 'number' ? X : 0) + 1;
       }
       X = 0;
       Rennen = [];
       while (!(getAttr((obj.state ? obj.state.val : ''), ('MRData.RaceTable.Races.0.Results.' + String(X))) == null)) {
         Position = getAttr((obj.state ? obj.state.val : ''), (['MRData.RaceTable.Races.0.Results.',X,'.position'].join('')));
         Aenderung = getAttr((obj.state ? obj.state.val : ''), (['MRData.RaceTable.Races.0.Results.',X,'.grid'].join(''))) - getAttr((obj.state ? obj.state.val : ''), (['MRData.RaceTable.Races.0.Results.',X,'.position'].join('')));
         if (getAttr((obj.state ? obj.state.val : ''), (['MRData.RaceTable.Races.0.Results.',X,'.grid'].join(''))) != 0) {
           Start = getAttr((obj.state ? obj.state.val : ''), (['MRData.RaceTable.Races.0.Results.',X,'.grid'].join('')));
         } else {
           Start = 'Box';
           Aenderung = Anzahl_Fahrer - getAttr((obj.state ? obj.state.val : ''), (['MRData.RaceTable.Races.0.Results.',X,'.position'].join('')));
         }
         if (getAttr((obj.state ? obj.state.val : ''), (['MRData.RaceTable.Races.0.Results.',X,'.status'].join(''))) == 'Finished') {
           Zeit = getAttr((obj.state ? obj.state.val : ''), (['MRData.RaceTable.Races.0.Results.',X,'.Time.time'].join('')));
         } else if (getAttr((obj.state ? obj.state.val : ''), (['MRData.RaceTable.Races.0.Results.',X,'.status'].join(''))) == '+1 Lap') {
           Zeit = '+1 Runde';
         } else if (getAttr((obj.state ? obj.state.val : ''), (['MRData.RaceTable.Races.0.Results.',X,'.status'].join(''))) == '+2 Laps') {
           Zeit = '+2 Runden';
         } else if (getAttr((obj.state ? obj.state.val : ''), (['MRData.RaceTable.Races.0.Results.',X,'.status'].join(''))) == '+3 Laps') {
           Zeit = '+3 Runden';
         } else if (getAttr((obj.state ? obj.state.val : ''), (['MRData.RaceTable.Races.0.Results.',X,'.status'].join(''))) == '+4 Laps') {
           Zeit = '+4 Runden';
         } else if (getAttr((obj.state ? obj.state.val : ''), (['MRData.RaceTable.Races.0.Results.',X,'.status'].join(''))) == '+5 Laps') {
           Zeit = '+5 Runden';
         } else if (getAttr((obj.state ? obj.state.val : ''), (['MRData.RaceTable.Races.0.Results.',X,'.status'].join(''))) == '+6 Laps') {
           Zeit = '+6 Runden';
         } else if (getAttr((obj.state ? obj.state.val : ''), (['MRData.RaceTable.Races.0.Results.',X,'.status'].join(''))) == '+7 Laps') {
           Zeit = '+7 Runden';
         } else if (getAttr((obj.state ? obj.state.val : ''), (['MRData.RaceTable.Races.0.Results.',X,'.status'].join(''))) == '+8 Laps') {
           Zeit = '+8 Runden';
         } else if (getAttr((obj.state ? obj.state.val : ''), (['MRData.RaceTable.Races.0.Results.',X,'.status'].join(''))) == '+9 Laps') {
           Zeit = '+9 Runden';
         } else {
           Zeit = ['<span style="color:',Farbe_fuer_Ausgefallen,';">Ausfall</span>'].join('');
           Position = '';
           Aenderung = 'Ausfall';
         }
         if ([getAttr((obj.state ? obj.state.val : ''), (['MRData.RaceTable.Races.0.Results.',X,'.Driver.givenName'].join(''))),' ',getAttr((obj.state ? obj.state.val : ''), (['MRData.RaceTable.Races.0.Results.',X,'.Driver.familyName'].join('')))].join('') == Fahrer) {
           spanINFahrer = ['<span style="color:',Farbe_fuer_Fahrer,';">'].join('');
           spanOUTFahrer = '</span>';
         } else {
           spanINFahrer = '';
           spanOUTFahrer = '';
         }
         if (getAttr((obj.state ? obj.state.val : ''), (['MRData.RaceTable.Races.0.Results.',X,'.Constructor.name'].join(''))) == Team) {
           spanINTeam = ['<span style="color:',Farbe_fuer_Team,';">'].join('');
           spanOUTTeam = '</span>';
         } else {
           spanINTeam = '';
           spanOUTTeam = '';
         }
         if (Aenderung == 'Ausfall') {
           Aenderung2 = '';
         } else if (Aenderung == 0) {
           Aenderung2 = '=';
         } else if (Aenderung > 0) {
           Aenderung2 = [Aenderung,'<span style="color:',Farbe_Pfeil_UP,';"> ↑</span>'].join('');
         } else if (Aenderung < 0) {
           Aenderung2 = [Aenderung,'<span style="color:',Farbe_Pfeil_Down,';"> ↓</span>'].join('');
         }
         if (getAttr((obj.state ? obj.state.val : ''), (['MRData.RaceTable.Races.0.Results.',X,'.FastestLap.rank'].join(''))) == 1) {
           spanINFastLap = ['<span style="color:',Farbe_Fast_Lap,';">'].join('');
           spanOUTFastLap = '</span>';
         } else {
           spanINFastLap = '';
           spanOUTFastLap = '';
         }
         if (getAttr((obj.state ? obj.state.val : ''), (['MRData.RaceTable.Races.0.Results.',X,'.points'].join(''))) != 0) {
           Punkte = getAttr((obj.state ? obj.state.val : ''), (['MRData.RaceTable.Races.0.Results.',X,'.points'].join('')));
         } else {
           Punkte = '';
         }
         VIS = { 'Position': Position, 'Change': Aenderung2, 'Fahrer': [spanINFahrer,getAttr((obj.state ? obj.state.val : ''), (['MRData.RaceTable.Races.0.Results.',X,'.Driver.givenName'].join(''))),' ',getAttr((obj.state ? obj.state.val : ''), (['MRData.RaceTable.Races.0.Results.',X,'.Driver.familyName'].join(''))),spanOUTFahrer].join(''), 'Team': [spanINTeam,getAttr((obj.state ? obj.state.val : ''), (['MRData.RaceTable.Races.0.Results.',X,'.Constructor.name'].join(''))),spanOUTTeam].join(''), 'Grid': Start, 'Runden': getAttr((obj.state ? obj.state.val : ''), (['MRData.RaceTable.Races.0.Results.',X,'.laps'].join(''))), 'Zeit': Zeit, 'Punkte': Punkte, 'Fast Lap': [spanINFastLap,getAttr((obj.state ? obj.state.val : ''), (['MRData.RaceTable.Races.0.Results.',X,'.FastestLap.Time.time'].join(''))),spanOUTFastLap].join('') };
         Rennen.push(VIS);
         X = (typeof X === 'number' ? X : 0) + 1;
       }
       setState('0_userdata.0.Formel1.Rennergebnisse.VIS_json' /* VIS_json */, JSON.stringify(Rennen), true);
      });
      

      Fahrerwertung

      // ################################################
      // Formel1 Fahrerwertung v1.01
      // by stenmic
      // ################################################
      
      var Fahrer, Farbe_fuer_Fahrer, Team, Farbe_fuer_Team, Farbe_Pfeil_UP, Farbe_Pfeil_Down, Quelle, X, Fahrerwertung, Y, Change, spanINFahrer, spanOUTFahrer, spanINTeam, VIS, spanOUTTeam;
      
      // ################################################
      Fahrer = 'Nico Hülkenberg';
      Farbe_fuer_Fahrer = '#3bb273';
      Team = 'Haas F1 Team';
      Farbe_fuer_Team = '#26b1e6';
      Farbe_Pfeil_UP = '#3bb273';
      Farbe_Pfeil_Down = '#e55a52';
      // ################################################
      
      on({ id: '0_userdata.0.Formel1.Rennergebnisse.Rennen_gefahren' /* Rennen_gefahren */, change: 'ne' }, async (obj) => {
       let value = obj.state.val;
       let oldValue = obj.oldState.val;
       setState('0_userdata.0.Formel1.Fahrerwertung.Jahr' /* Jahr */, (getState('0_userdata.0.Formel1.Fahrerwertung.Jahr').val + 1), true);
      });
      on({ id: '0_userdata.0.Formel1.Fahrerwertung.Jahr' /* Jahr */, change: 'ne' }, async (obj) => {
       let value = obj.state.val;
       let oldValue = obj.oldState.val;
       await wait(1000);
       httpGet((['https://api.jolpi.ca/ergast/f1/',(obj.state ? obj.state.val : ''),'/driverstandings/'].join('')), { timeout: 10000, responseType: 'text' }, async (err, response) => {
         if (response.statusCode == 200) {
           if (getAttr(response.data, 'MRData.StandingsTable.round') == null) {
             setState('0_userdata.0.Formel1.Fahrerwertung.Jahr' /* Jahr */, ((obj.state ? obj.state.val : '') - 1), true);
           }
         }
       });
      });
      on({ id: '0_userdata.0.Formel1.Fahrerwertung.Rennen_aktuell' /* Rennen_aktuell */, change: 'any' }, async (obj) => {
       let value = obj.state.val;
       let oldValue = obj.oldState.val;
       httpGet((['https://api.jolpi.ca/ergast/f1/',getState('0_userdata.0.Formel1.Fahrerwertung.Jahr').val,'/driverstandings/'].join('')), { timeout: 10000, responseType: 'text' }, async (err, response) => {
         if (response.statusCode == 200) {
           setState('0_userdata.0.Formel1.Fahrerwertung.json' /* json */, response.data, true);
           setState('0_userdata.0.Formel1.Fahrerwertung.Rennen_gefahren' /* Rennen_gefahren */, parseFloat(getAttr(response.data, 'MRData.StandingsTable.round')), true);
           setState('0_userdata.0.Formel1.Fahrerwertung.Rennen_Nr' /* Rennen_Nr */, parseFloat(getAttr(response.data, 'MRData.StandingsTable.round')), true);
         }
       });
      });
      on({ id: '0_userdata.0.Formel1.Fahrerwertung.Rennen_zurueck' /* Rennen_zurueck */, change: 'any' }, async (obj) => {
       let value = obj.state.val;
       let oldValue = obj.oldState.val;
       if (getState('0_userdata.0.Formel1.Fahrerwertung.Rennen_Nr').val > 1) {
         setState('0_userdata.0.Formel1.Fahrerwertung.Rennen_Nr' /* Rennen_Nr */, (getState('0_userdata.0.Formel1.Fahrerwertung.Rennen_Nr').val - 1), true);
       }
      });
      on({ id: '0_userdata.0.Formel1.Fahrerwertung.Rennen_vor' /* Rennen_vor */, change: 'any' }, async (obj) => {
       let value = obj.state.val;
       let oldValue = obj.oldState.val;
       setState('0_userdata.0.Formel1.Fahrerwertung.Rennen_Nr' /* Rennen_Nr */, (getState('0_userdata.0.Formel1.Fahrerwertung.Rennen_Nr').val + 1), true);
      });
      on({ id: '0_userdata.0.Formel1.Fahrerwertung.Rennen_Nr' /* Rennen_Nr */, change: 'ne' }, async (obj) => {
       let value = obj.state.val;
       let oldValue = obj.oldState.val;
       httpGet((['https://api.jolpi.ca/ergast/f1/',getState('0_userdata.0.Formel1.Fahrerwertung.Jahr').val,'/',(obj.state ? obj.state.val : ''),'/driverstandings/'].join('')), { timeout: 10000, responseType: 'text' }, async (err, response) => {
         if ((response.statusCode == 200) && (getAttr(response.data, 'MRData.total') != 0)) {
           setState('0_userdata.0.Formel1.Fahrerwertung.json' /* json */, response.data, true);
         } else {
           setState('0_userdata.0.Formel1.Fahrerwertung.Rennen_aktuell' /* Rennen_aktuell */, true, true);
         }
       });
      });
      on({ id: '0_userdata.0.Formel1.Fahrerwertung.json' /* json */, change: 'ne' }, async (obj) => {
       let value = obj.state.val;
       let oldValue = obj.oldState.val;
       if (getState('0_userdata.0.Formel1.Fahrerwertung.Rennen_Nr').val == 1) {
         httpGet((['https://api.jolpi.ca/ergast/f1/',getState('0_userdata.0.Formel1.Fahrerwertung.Jahr').val,'/',getState('0_userdata.0.Formel1.Fahrerwertung.Rennen_Nr').val,'/driverstandings/'].join('')), { timeout: 10000, responseType: 'text' }, async (err, response) => {
           if (response.statusCode == 200) {
             setState('0_userdata.0.Formel1.Fahrerwertung.json_letztes_Rennen' /* json_letztes_Rennen */, response.data, true);
           }
         });
       } else {
         httpGet((['https://api.jolpi.ca/ergast/f1/',getState('0_userdata.0.Formel1.Fahrerwertung.Jahr').val,'/',getState('0_userdata.0.Formel1.Fahrerwertung.Rennen_Nr').val - 1,'/driverstandings/'].join('')), { timeout: 10000, responseType: 'text' }, async (err, response) => {
           if (response.statusCode == 200) {
             setState('0_userdata.0.Formel1.Fahrerwertung.json_letztes_Rennen' /* json_letztes_Rennen */, response.data, true);
           }
         });
       }
      });
      on({ id: '0_userdata.0.Formel1.Fahrerwertung.json_letztes_Rennen' /* json_letztes_Rennen */, change: 'any' }, async (obj) => {
       let value = obj.state.val;
       let oldValue = obj.oldState.val;
       Quelle = getState('0_userdata.0.Formel1.Fahrerwertung.json').val;
       X = 0;
       Fahrerwertung = [];
       while (!(getAttr(Quelle, ('MRData.StandingsTable.StandingsLists.0.DriverStandings.' + String(X))) == null)) {
         Y = 0;
         while (!(getAttr(getState('0_userdata.0.Formel1.Fahrerwertung.json_letztes_Rennen').val, (['MRData.StandingsTable.StandingsLists.0.DriverStandings.',Y,'.Driver.driverId'].join(''))) == getAttr(Quelle, (['MRData.StandingsTable.StandingsLists.0.DriverStandings.',X,'.Driver.driverId'].join(''))))) {
           if (Y > 100) {
             break;
           } else {
             Y = (typeof Y === 'number' ? Y : 0) + 1;
           }
         }
         if (getAttr(getState('0_userdata.0.Formel1.Fahrerwertung.json_letztes_Rennen').val, (['MRData.StandingsTable.StandingsLists.0.DriverStandings.',Y,'.position'].join(''))) - getAttr(Quelle, (['MRData.StandingsTable.StandingsLists.0.DriverStandings.',X,'.position'].join(''))) == 0) {
           Change = '=';
         } else if (getAttr(getState('0_userdata.0.Formel1.Fahrerwertung.json_letztes_Rennen').val, (['MRData.StandingsTable.StandingsLists.0.DriverStandings.',Y,'.position'].join(''))) - getAttr(Quelle, (['MRData.StandingsTable.StandingsLists.0.DriverStandings.',X,'.position'].join(''))) > 0) {
           Change = [getAttr(getState('0_userdata.0.Formel1.Fahrerwertung.json_letztes_Rennen').val, (['MRData.StandingsTable.StandingsLists.0.DriverStandings.',Y,'.position'].join(''))) - getAttr(Quelle, (['MRData.StandingsTable.StandingsLists.0.DriverStandings.',X,'.position'].join(''))),'<span style="color:',Farbe_Pfeil_UP,';"> ↑</span>'].join('');
         } else {
           Change = [getAttr(getState('0_userdata.0.Formel1.Fahrerwertung.json_letztes_Rennen').val, (['MRData.StandingsTable.StandingsLists.0.DriverStandings.',Y,'.position'].join(''))) - getAttr(Quelle, (['MRData.StandingsTable.StandingsLists.0.DriverStandings.',X,'.position'].join(''))),'<span style="color:',Farbe_Pfeil_Down,';"> ↓</span>'].join('');
         }
         if ([getAttr(Quelle, (['MRData.StandingsTable.StandingsLists.0.DriverStandings.',X,'.Driver.givenName'].join(''))),' ',getAttr(Quelle, (['MRData.StandingsTable.StandingsLists.0.DriverStandings.',X,'.Driver.familyName'].join('')))].join('') == Fahrer) {
           spanINFahrer = ['<span style="color:',Farbe_fuer_Fahrer,';">'].join('');
           spanOUTFahrer = '</span>';
         } else {
           spanINFahrer = '';
           spanOUTFahrer = '';
         }
         if (getAttr(Quelle, (['MRData.StandingsTable.StandingsLists.0.DriverStandings.',X,'.Constructors.0.name'].join(''))) == Team) {
           spanINTeam = ['<span style="color:',Farbe_fuer_Team,';">'].join('');
           spanOUTTeam = '</span>';
         } else {
           spanINTeam = '';
           spanOUTTeam = '';
         }
         VIS = { 'Positon': getAttr(Quelle, (['MRData.StandingsTable.StandingsLists.0.DriverStandings.',X,'.position'].join(''))), 'Change': Change, 'Fahrer': [spanINFahrer,getAttr(Quelle, (['MRData.StandingsTable.StandingsLists.0.DriverStandings.',X,'.Driver.givenName'].join(''))),' ',getAttr(Quelle, (['MRData.StandingsTable.StandingsLists.0.DriverStandings.',X,'.Driver.familyName'].join(''))),' • ',getAttr(Quelle, (['MRData.StandingsTable.StandingsLists.0.DriverStandings.',X,'.Driver.nationality'].join(''))),spanOUTFahrer].join(''), 'Punkte': getAttr(Quelle, (['MRData.StandingsTable.StandingsLists.0.DriverStandings.',X,'.points'].join(''))), 'Siege': getAttr(Quelle, (['MRData.StandingsTable.StandingsLists.0.DriverStandings.',X,'.wins'].join(''))), 'Team': [spanINTeam,getAttr(Quelle, (['MRData.StandingsTable.StandingsLists.0.DriverStandings.',X,'.Constructors.0.name'].join(''))),spanOUTTeam].join('') };
         Fahrerwertung.push(VIS);
         X = (typeof X === 'number' ? X : 0) + 1;
       }
       setState('0_userdata.0.Formel1.Fahrerwertung.VIS_json' /* VIS_json */, JSON.stringify(Fahrerwertung), true);
       if (getState('0_userdata.0.Formel1.Fahrerwertung.Rennen_Nr').val == getState('0_userdata.0.Formel1.Fahrerwertung.Rennen_gefahren').val) {
         setState('0_userdata.0.Formel1.Fahrerwertung.Ueberschrift_VIS' /* Ueberschrift_VIS */, (['••• Fahrerwertung ',getState('0_userdata.0.Formel1.Fahrerwertung.Jahr').val,' nach ',getState('0_userdata.0.Formel1.Fahrerwertung.Rennen_Nr').val,' von ',getState('0_userdata.0.Formel1.Kalender.Anzahl_Rennen_Aktuelles_Jahr').val,' Rennen •••'].join('')), true);
       } else {
         setState('0_userdata.0.Formel1.Fahrerwertung.Ueberschrift_VIS' /* Ueberschrift_VIS */, (['Fahrerwertung ',getState('0_userdata.0.Formel1.Fahrerwertung.Jahr').val,' nach ',getState('0_userdata.0.Formel1.Fahrerwertung.Rennen_Nr').val,' von ',getState('0_userdata.0.Formel1.Kalender.Anzahl_Rennen_Aktuelles_Jahr').val,' Rennen'].join('')), true);
       }
      });
      
      

      Konstrukteur

      
      // ################################################
      // Formel1 Konstrukteur v1.01
      // by stenmic
      // ################################################
      
      var Team, Farbe_fuer_Team, Farbe_Pfeil_UP, Farbe_Pfeil_Down, Quelle, X, Fahrerwertung, Y, Change, spanINTeam, VIS, spanOUTTeam;
      
      // ################################################
      Team = 'Haas F1 Team';
      Farbe_fuer_Team = '#26b1e6';
      Farbe_Pfeil_UP = '#3bb273';
      Farbe_Pfeil_Down = '#e55a52';
      // ################################################
      
      on({ id: '0_userdata.0.Formel1.Rennergebnisse.Rennen_gefahren' /* Rennen_gefahren */, change: 'ne' }, async (obj) => {
       let value = obj.state.val;
       let oldValue = obj.oldState.val;
       setState('0_userdata.0.Formel1.Konstrukteur.Jahr' /* Jahr */, (getState('0_userdata.0.Formel1.Konstrukteur.Jahr').val + 1), true);
      });
      on({ id: '0_userdata.0.Formel1.Konstrukteur.Jahr' /* Jahr */, change: 'ne' }, async (obj) => {
       let value = obj.state.val;
       let oldValue = obj.oldState.val;
       await wait(1000);
       httpGet((['https://api.jolpi.ca/ergast/f1/',(obj.state ? obj.state.val : ''),'/constructorstandings/'].join('')), { timeout: 10000, responseType: 'text' }, async (err, response) => {
         if (response.statusCode == 200) {
           if (getAttr(response.data, 'MRData.StandingsTable.round') == null) {
             setState('0_userdata.0.Formel1.Konstrukteur.Jahr' /* Jahr */, ((obj.state ? obj.state.val : '') - 1), true);
           }
         }
       });
      });
      on({ id: '0_userdata.0.Formel1.Konstrukteur.Rennen_aktuell' /* Rennen_aktuell */, change: 'any' }, async (obj) => {
       let value = obj.state.val;
       let oldValue = obj.oldState.val;
       httpGet((['https://api.jolpi.ca/ergast/f1/',getState('0_userdata.0.Formel1.Konstrukteur.Jahr').val,'/constructorstandings/'].join('')), { timeout: 10000, responseType: 'text' }, async (err, response) => {
         if (response.statusCode == 200) {
           setState('0_userdata.0.Formel1.Konstrukteur.json' /* json */, response.data, true);
           setState('0_userdata.0.Formel1.Konstrukteur.Rennen_gefahren' /* Rennen_gefahren */, parseFloat(getAttr(response.data, 'MRData.StandingsTable.round')), true);
           setState('0_userdata.0.Formel1.Konstrukteur.Rennen_Nr' /* Rennen_Nr */, parseFloat(getAttr(response.data, 'MRData.StandingsTable.round')), true);
         }
       });
      });
      on({ id: '0_userdata.0.Formel1.Konstrukteur.Rennen_zurueck' /* Rennen_zurueck */, change: 'any' }, async (obj) => {
       let value = obj.state.val;
       let oldValue = obj.oldState.val;
       if (getState('0_userdata.0.Formel1.Konstrukteur.Rennen_Nr').val > 1) {
         setState('0_userdata.0.Formel1.Konstrukteur.Rennen_Nr' /* Rennen_Nr */, (getState('0_userdata.0.Formel1.Konstrukteur.Rennen_Nr').val - 1), true);
       }
      });
      on({ id: '0_userdata.0.Formel1.Konstrukteur.Rennen_vor' /* Rennen_vor */, change: 'any' }, async (obj) => {
       let value = obj.state.val;
       let oldValue = obj.oldState.val;
       setState('0_userdata.0.Formel1.Konstrukteur.Rennen_Nr' /* Rennen_Nr */, (getState('0_userdata.0.Formel1.Konstrukteur.Rennen_Nr').val + 1), true);
      });
      on({ id: '0_userdata.0.Formel1.Konstrukteur.Rennen_Nr' /* Rennen_Nr */, change: 'ne' }, async (obj) => {
       let value = obj.state.val;
       let oldValue = obj.oldState.val;
       httpGet((['https://api.jolpi.ca/ergast/f1/',getState('0_userdata.0.Formel1.Konstrukteur.Jahr').val,'/',(obj.state ? obj.state.val : ''),'/constructorstandings/'].join('')), { timeout: 10000, responseType: 'text' }, async (err, response) => {
         if ((response.statusCode == 200) && (getAttr(response.data, 'MRData.total') != 0)) {
           setState('0_userdata.0.Formel1.Konstrukteur.json' /* json */, response.data, true);
         } else {
           setState('0_userdata.0.Formel1.Konstrukteur.Rennen_aktuell' /* Rennen_aktuell */, true, true);
         }
       });
      });
      on({ id: '0_userdata.0.Formel1.Konstrukteur.json' /* json */, change: 'ne' }, async (obj) => {
       let value = obj.state.val;
       let oldValue = obj.oldState.val;
       if (getState('0_userdata.0.Formel1.Konstrukteur.Rennen_Nr').val == 1) {
         httpGet((['https://api.jolpi.ca/ergast/f1/',getState('0_userdata.0.Formel1.Konstrukteur.Jahr').val,'/',getState('0_userdata.0.Formel1.Konstrukteur.Rennen_Nr').val,'/constructorstandings/'].join('')), { timeout: 10000, responseType: 'text' }, async (err, response) => {
           if (response.statusCode == 200) {
             setState('0_userdata.0.Formel1.Konstrukteur.json_letztes_Rennen' /* json_letztes_Rennen */, response.data, true);
           }
         });
       } else {
         httpGet((['https://api.jolpi.ca/ergast/f1/',getState('0_userdata.0.Formel1.Konstrukteur.Jahr').val,'/',getState('0_userdata.0.Formel1.Konstrukteur.Rennen_Nr').val - 1,'/constructorstandings/'].join('')), { timeout: 10000, responseType: 'text' }, async (err, response) => {
           if (response.statusCode == 200) {
             setState('0_userdata.0.Formel1.Konstrukteur.json_letztes_Rennen' /* json_letztes_Rennen */, response.data, true);
           }
         });
       }
      });
      on({ id: '0_userdata.0.Formel1.Konstrukteur.json_letztes_Rennen' /* json_letztes_Rennen */, change: 'any' }, async (obj) => {
       let value = obj.state.val;
       let oldValue = obj.oldState.val;
       Quelle = getState('0_userdata.0.Formel1.Konstrukteur.json').val;
       X = 0;
       Fahrerwertung = [];
       while (!(getAttr(Quelle, ('MRData.StandingsTable.StandingsLists.0.ConstructorStandings.' + String(X))) == null)) {
         Y = 0;
         while (!(getAttr(getState('0_userdata.0.Formel1.Konstrukteur.json_letztes_Rennen').val, (['MRData.StandingsTable.StandingsLists.0.ConstructorStandings.',Y,'.Constructor.constructorId'].join(''))) == getAttr(Quelle, (['MRData.StandingsTable.StandingsLists.0.ConstructorStandings.',X,'.Constructor.constructorId'].join(''))))) {
           if (Y > 100) {
             break;
           } else {
             Y = (typeof Y === 'number' ? Y : 0) + 1;
           }
         }
         if (getAttr(getState('0_userdata.0.Formel1.Konstrukteur.json_letztes_Rennen').val, (['MRData.StandingsTable.StandingsLists.0.ConstructorStandings.',Y,'.position'].join(''))) - getAttr(Quelle, (['MRData.StandingsTable.StandingsLists.0.ConstructorStandings.',X,'.position'].join(''))) == 0) {
           Change = '=';
         } else if (getAttr(getState('0_userdata.0.Formel1.Konstrukteur.json_letztes_Rennen').val, (['MRData.StandingsTable.StandingsLists.0.ConstructorStandings.',Y,'.position'].join(''))) - getAttr(Quelle, (['MRData.StandingsTable.StandingsLists.0.ConstructorStandings.',X,'.position'].join(''))) > 0) {
           Change = [getAttr(getState('0_userdata.0.Formel1.Konstrukteur.json_letztes_Rennen').val, (['MRData.StandingsTable.StandingsLists.0.ConstructorStandings.',Y,'.position'].join(''))) - getAttr(Quelle, (['MRData.StandingsTable.StandingsLists.0.ConstructorStandings.',X,'.position'].join(''))),'<span style="color:',Farbe_Pfeil_UP,';"> ↑</span>'].join('');
         } else {
           Change = [getAttr(getState('0_userdata.0.Formel1.Konstrukteur.json_letztes_Rennen').val, (['MRData.StandingsTable.StandingsLists.0.ConstructorStandings.',Y,'.position'].join(''))) - getAttr(Quelle, (['MRData.StandingsTable.StandingsLists.0.ConstructorStandings.',X,'.position'].join(''))),'<span style="color:',Farbe_Pfeil_Down,';"> ↓</span>'].join('');
         }
         if (getAttr(Quelle, (['MRData.StandingsTable.StandingsLists.0.ConstructorStandings.',X,'.Constructor.name'].join(''))) == Team) {
           spanINTeam = ['<span style="color:',Farbe_fuer_Team,';">'].join('');
           spanOUTTeam = '</span>';
         } else {
           spanINTeam = '';
           spanOUTTeam = '';
         }
         VIS = { 'Positon': getAttr(Quelle, (['MRData.StandingsTable.StandingsLists.0.ConstructorStandings.',X,'.position'].join(''))), 'Change': Change, 'Team': [spanINTeam,getAttr(Quelle, (['MRData.StandingsTable.StandingsLists.0.ConstructorStandings.',X,'.Constructor.name'].join(''))),' • ',getAttr(Quelle, (['MRData.StandingsTable.StandingsLists.0.ConstructorStandings.',X,'.Constructor.nationality'].join(''))),spanOUTTeam].join(''), 'Punkte': getAttr(Quelle, (['MRData.StandingsTable.StandingsLists.0.ConstructorStandings.',X,'.points'].join(''))), 'Siege': getAttr(Quelle, (['MRData.StandingsTable.StandingsLists.0.ConstructorStandings.',X,'.wins'].join(''))) };
         Fahrerwertung.push(VIS);
         X = (typeof X === 'number' ? X : 0) + 1;
       }
       setState('0_userdata.0.Formel1.Konstrukteur.VIS_json' /* VIS_json */, JSON.stringify(Fahrerwertung), true);
       if (getState('0_userdata.0.Formel1.Konstrukteur.Rennen_Nr').val == getState('0_userdata.0.Formel1.Konstrukteur.Rennen_gefahren').val) {
         setState('0_userdata.0.Formel1.Konstrukteur.Ueberschrift_VIS' /* Ueberschrift_VIS */, (['••• Konstrukteurswertung ',getState('0_userdata.0.Formel1.Konstrukteur.Jahr').val,' nach ',getState('0_userdata.0.Formel1.Konstrukteur.Rennen_Nr').val,' von ',getState('0_userdata.0.Formel1.Kalender.Anzahl_Rennen_Aktuelles_Jahr').val,' Rennen •••'].join('')), true);
       } else {
         setState('0_userdata.0.Formel1.Konstrukteur.Ueberschrift_VIS' /* Ueberschrift_VIS */, (['Konstrukteurswertung ',getState('0_userdata.0.Formel1.Konstrukteur.Jahr').val,' nach ',getState('0_userdata.0.Formel1.Konstrukteur.Rennen_Nr').val,' von ',getState('0_userdata.0.Formel1.Kalender.Anzahl_Rennen_Aktuelles_Jahr').val,' Rennen'].join('')), true);
       }
      });
      

      So sollte es dann aussehen

      2024-11-16 11 45 12.jpg

      !!!Wichtig!!!
      für die Initialisierung muss man jetzt unter den Datenpunkten einmalig bei allen 4 Bereichen den "aktuell" Button ausführen.
      Am besten auch in dieser Reihenfolge:
      Kalender.Jahr_aktuell
      Rennergebnisse.Rennen_aktuell
      Fahrerwertung.Rennen_aktuell
      Konstrukteur.Rennen_aktuell

      Beispiel für den Kalender
      2024-11-16 11 50 29.jpg

      Danach können die vor, zurück und aktuell Button genutzt werden.

      Für die VIS sind jeweilige Datenpunkte für Überschriften und Tabellen vorhanden

      Ueberschrift_VIS (html widget mit binding)

      VIS_json

      Für die Darstellung der Json Tabelle (VIS_json) empfehle ich https://github.com/inventwo/ioBroker.vis-inventwo
      Geht aber glaube ich nur für VIS1

      2024-11-15 18 52 21.jpg

      das Standard widget geht aber auch.

      Würde mich freuen wenn einige von euch die Skripte testen und eventuelle Fehler melden würden.

      So sieht es bei mir am Ende aus:

      Info... die Strecken im Kalender sind mit wikipedia verlinkt.

      1.png

      2.png

      3.png

      4.png

      Eigentlich sollte alles fehlerfrei funktionieren aber eventuell muss ich nächste Saison nachbessern falls er zu Fehlermeldungen wegen dem Jahr kommt. Dass kann ich jetzt noch nicht wirklich alles prüfen.

      posted in JavaScript
      S
      stenmic
    • Dauerhafter Support für vis1 oder ein Sterben auf Raten?

      Frage an die Entwickler.
      ist eigentlich geplant vis1 dauerhaft zu Supporten oder wird es irgendwann nicht mehr gepflegt?
      ich hab da ein wenig Sorge weil ich ne Menge Zeit in meine neue vis1 investiert habe.
      vis2 sagt mir leider überhaupt nicht zu, die Performance ist gruselig.

      posted in Visualisierung
      S
      stenmic
    • Meine VIS mit 76 Seiten.

      Ich schimpf aktuell ja echt viel hier im Forum. Jedoch gibts nicht besseres wie ioBoker mit seiner Möglichkeit zur Visualisierung. Ich möchte euch hier mal einen Teil meiner Vis zeigen, sehr viel ist extrem auf mich angepasst, aber für die eine oder andere Inspiration vielleicht doch interesant. Genutzt wird VIS1, Material Design Widgets, justGage Widgets und inventwo Design Widgets. Bin gespannt auf eure Meinung

      Home... Die Wetterseiten sind noch (lange) nicht fertig.


      1-0.png

      1-1.png

      1-2.png

      1-3.png

      1-4.png

      1-5.png

      1-6.png

      1-7.png

      1-8.png

      1-9.png

      1-10.png

      Das Auto


      2-1.png

      2-2.png

      Meine Systeme


      4-1.png

      4-2.png

      4-3.png

      Strom/Gas


      5-4.png

      5-5.png

      5-1.png

      5-3.png

      Haushaltsgeräte


      6-1.png

      6-2.png

      Die Heizung


      7-1.png

      7-2.png

      7-3.png

      7-4.png

      Mein 3D-Drucker (Klipper)


      9-1.png

      9-2.png

      9-3.png

      9-4.png

      9-5.png

      9-6.png

      9-7.png

      9-8.png

      IMG_7767.PNG

      Die Aktien


      10-1.png

      10-2.png

      TV-Programm


      11-1.png

      11-2.png

      11-3.png

      Die Bundesliga


      12-1.png

      12-2.png

      posted in Visualisierung
      S
      stenmic
    • Liebherr Smart Device einbinden - so geht's

      Moin,
      wer Liebherr Smart Device Geräte hat, möchte diese eventuell in ioBroker einbinden.
      So kann man die Werte bekommen.

      Optionen in der Liebherr App aktivieren

      1. Es wird die Device-ID benötigt (unter Geräte)
      2. Betatest muss aktiviert werden (Den API-Key sofort kopieren und sichern, wird nur einmal angezeigt)


      optionen.PNG
      device-ID.PNG
      api-key.PNG

      Blockly Beispiel

      2025-03-30 08 43 50.jpg

      <xml xmlns="https://developers.google.com/blockly/xml">
       <block type="schedule" id="lM*WR|MH+q,F(eaI{G{h" x="113" y="88">
         <field name="SCHEDULE">*/10 * * * *</field>
         <statement name="STATEMENT">
           <block type="procedures_callcustomnoreturn" id="sXQ^Gl1J7RLMY0OF%D%s">
             <mutation name="Json"></mutation>
           </block>
         </statement>
         <next>
           <block type="on" id="%vmC.dk%d:MQ!R-u~^@P">
             <field name="OID">0_userdata.0.Gefrierschrank.Json</field>
             <field name="CONDITION">ne</field>
             <field name="ACK_CONDITION"></field>
             <statement name="STATEMENT">
               <block type="update" id="lQ8Q53[%rzM}gqO=z?HE">
                 <mutation xmlns="http://www.w3.org/1999/xhtml" delay_input="false"></mutation>
                 <field name="OID">0_userdata.0.Gefrierschrank.Temperaturen.Ist</field>
                 <field name="WITH_DELAY">FALSE</field>
                 <value name="VALUE">
                   <block type="get_attr" id="3XBnpq%|J},tZdSuC0KS">
                     <value name="PATH">
                       <shadow type="text" id="6yC%E@~Q%P[|-;CHDY@M">
                         <field name="TEXT">1.value</field>
                       </shadow>
                     </value>
                     <value name="OBJECT">
                       <shadow type="get_object" id="bxM,S0*#%P:Gkh:D~^T0">
                         <field name="OID">Object ID</field>
                       </shadow>
                       <block type="on_source" id="P^}^h8O!CKDxcJo,zzTb">
                         <field name="ATTR">state.val</field>
                       </block>
                     </value>
                   </block>
                 </value>
                 <next>
                   <block type="update" id="`edwP~(SKu]p{t#,A,H3">
                     <mutation xmlns="http://www.w3.org/1999/xhtml" delay_input="false"></mutation>
                     <field name="OID">0_userdata.0.Gefrierschrank.Temperaturen.Soll</field>
                     <field name="WITH_DELAY">FALSE</field>
                     <value name="VALUE">
                       <block type="get_attr" id="lZdy6QagoBkQkdSU^DH*">
                         <value name="PATH">
                           <shadow type="text" id="s]Jv{S,oT.WI=K_cu*sM">
                             <field name="TEXT">1.target</field>
                           </shadow>
                         </value>
                         <value name="OBJECT">
                           <shadow type="get_object" id="ClUZTfZRG25^-VA_*OqE">
                             <field name="OID">Object ID</field>
                           </shadow>
                           <block type="on_source" id="DO4`LaS)wQoguA+;,UX5">
                             <field name="ATTR">state.val</field>
                           </block>
                         </value>
                       </block>
                     </value>
                     <next>
                       <block type="controls_if" id="4q}VfNKT`-e~kuO5%,!]">
                         <mutation else="1"></mutation>
                         <value name="IF0">
                           <block type="logic_compare" id="Iu;b51.eB5,U`~_a0LYq">
                             <field name="OP">EQ</field>
                             <value name="A">
                               <block type="get_attr" id="FGjuoRUaRId0eAqkB@SX">
                                 <value name="PATH">
                                   <shadow type="text" id="inO/We_{nMEkzQme,-io">
                                     <field name="TEXT">0.value</field>
                                   </shadow>
                                 </value>
                                 <value name="OBJECT">
                                   <shadow type="get_object" id="~wYWNWIVZ(UZ$#X@E**b">
                                     <field name="OID">Object ID</field>
                                   </shadow>
                                   <block type="on_source" id="Y9+QAAVe|zdG*BArB?PY">
                                     <field name="ATTR">state.val</field>
                                   </block>
                                 </value>
                               </block>
                             </value>
                             <value name="B">
                               <block type="logic_boolean" id="5$.8K#9FF2.!5NJPj^!P">
                                 <field name="BOOL">TRUE</field>
                               </block>
                             </value>
                           </block>
                         </value>
                         <statement name="DO0">
                           <block type="update" id="WSt]_]@@[gn*xXw@ZBIW">
                             <mutation xmlns="http://www.w3.org/1999/xhtml" delay_input="false"></mutation>
                             <field name="OID">0_userdata.0.Gefrierschrank.Temperaturen.Superfrost</field>
                             <field name="WITH_DELAY">FALSE</field>
                             <value name="VALUE">
                               <block type="text" id="oB$BOlCGAVWvV_C^[N|(">
                                 <field name="TEXT">on</field>
                               </block>
                             </value>
                           </block>
                         </statement>
                         <statement name="ELSE">
                           <block type="update" id="#6Ze6}irp/U@3OtGejte">
                             <mutation xmlns="http://www.w3.org/1999/xhtml" delay_input="false"></mutation>
                             <field name="OID">0_userdata.0.Gefrierschrank.Temperaturen.Superfrost</field>
                             <field name="WITH_DELAY">FALSE</field>
                             <value name="VALUE">
                               <block type="text" id="je?/iEZINQJS+)p5uHb=">
                                 <field name="TEXT">off</field>
                               </block>
                             </value>
                           </block>
                         </statement>
                       </block>
                     </next>
                   </block>
                 </next>
               </block>
             </statement>
           </block>
         </next>
       </block>
       <block type="procedures_defcustomnoreturn" id="58E*=$3Hjml7hK,wSSKR" x="288" y="113">
         <mutation statements="false"></mutation>
         <field name="NAME">Json</field>
         <field name="SCRIPT">Y29uc3QgaHR0cCA9IHJlcXVpcmUoImh0dHBzIik7DQoNCmNvbnN0IG9wdGlvbnMgPSB7DQogICJtZXRob2QiOiAiR0VUIiwNCiAgImhvc3RuYW1lIjogImhvbWUtYXBpLnNtYXJ0ZGV2aWNlLmxpZWJoZXJyLmNvbSIsDQogICJwb3J0IjogbnVsbCwNCiAgInBhdGgiOiAiL3YxL2RldmljZXMvWFguWFhYLlhYWC5YL2NvbnRyb2xzIiwNCiAgImhlYWRlcnMiOiB7DQogICAgImFjY2VwdCI6ICIqLyoiLA0KICAgICJhcGkta2V5IjogIlhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWCINCiAgICAgICAgICAgICAgICANCiAgfQ0KfTsNCg0KY29uc3QgcmVxID0gaHR0cC5yZXF1ZXN0KG9wdGlvbnMsIGZ1bmN0aW9uIChyZXMpIHsNCiAgY29uc3QgY2h1bmtzID0gW107DQoNCiAgcmVzLm9uKCJkYXRhIiwgZnVuY3Rpb24gKGNodW5rKSB7DQogICAgY2h1bmtzLnB1c2goY2h1bmspOw0KICB9KTsNCg0KICByZXMub24oImVuZCIsIGZ1bmN0aW9uICgpIHsNCiAgICBjb25zdCBib2R5ID0gQnVmZmVyLmNvbmNhdChjaHVua3MpOw0KICAgIHNldFN0YXRlKCcwX3VzZXJkYXRhLjAuR2VmcmllcnNjaHJhbmsuSnNvbicsIChib2R5LnRvU3RyaW5nKCkpLCB0cnVlKTsNCiAgfSk7DQp9KTsNCg0KcmVxLmVuZCgpOw==</field>
         <comment pinned="false" h="80" w="160">Beschreibe diese Funktion …</comment>
       </block>
      </xml>
      

      Die Funktion muss angepasst werden

      1. Device-ID
      2. API-Key
      3. Speicherpfad für's json

      script.jpg

      const http = require("https");
      
      const options = {
       "method": "GET",
       "hostname": "home-api.smartdevice.liebherr.com",
       "port": null,
       "path": "/v1/devices/XX.XXX.XXX.X/controls",
       "headers": {
         "accept": "*/*",
         "api-key": "XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX"
                     
       }
      };
      
      const req = http.request(options, function (res) {
       const chunks = [];
      
       res.on("data", function (chunk) {
         chunks.push(chunk);
       });
      
       res.on("end", function () {
         const body = Buffer.concat(chunks);
         setState('0_userdata.0.Gefrierschrank.Json', (body.toString()), true);
       });
      });
      
      req.end();
      

      Die/Das Json sieht dann bei mir so aus

      json.jpg

      Das Blockly schreibt die Werte dann entsprechend

      objekte.jpg

      Mehr Optionen sind hier zu finden
      https://developer.liebherr.com/apis/smartdevice-homeapi/swagger-ui/
      Wobei Swagger bei mir nicht funktioniert hat.

      posted in Blockly
      S
      stenmic
    • Skript für Sonnenwenden, Tagundnachtgleiche und Jahreszeiten

      Ich konnte keine Fuktion in Blockly dafür finden, deshalb dieses Skript.
      Was kann es...

      • Datum der Sonnenwenden und Tagundnachtgleiche anzeigen
      • Tage bis zum nächsten Ereignis anzeigen
      • Astronomische Jahreszeiten anzeigen
      • Kalendarische Jahreszeiten anzeigen

      2024-11-20 17 35 20.jpg

      2024-11-20 17 36 07.jpg

      Alles nicht selbst erfunden sonder von hier (excel) übernommen.

      https://www.herber.de/forum/archiv/1104to1108/1105081_Formel_fuer_Jahreszeitenberechnung.html

      Der Pfad kann am Anfang gewählt werden.
      Das Skript initalisiert sich beim Start und dann jeden Tag um 0:0 und 30 Sekunden.

      // #########################################
      var PFAD = '0_userdata.0.Sonnenwenden';
      // #########################################
      
      if ( !existsState(''+PFAD+'.01_Fruehlings-Tagundnachtgleiche')) {
       createState(''+PFAD+'.01_Fruehlings-Tagundnachtgleiche','Datum',{name: '01_Fruehlings-Tagundnachtgleiche',role: 'value',type: 'string'});
       createState(''+PFAD+'.02_Sommersonnenwende','Datum',{name: '02_Sommersonnenwende',role: 'value',type: 'string'});
       createState(''+PFAD+'.03_Herbst-Tagundnachtgleiche','Datum',{name: '03_Herbst-Tagundnachtgleiche',role: 'value',type: 'string'});
       createState(''+PFAD+'.04_Wintersonnenwende','Datum',{name: '04_Wintersonnenwende',role: 'value',type: 'string'});
       createState(''+PFAD+'.Astronomische_Jahreszeiten','Datum',{name: 'Astronomische_Jahreszeiten',role: 'value',type: 'string'});
       createState(''+PFAD+'.Kalendarische_Jahreszeiten','Datum',{name: 'Kalendarische_Jahreszeiten',role: 'value',type: 'string'});
       createState(''+PFAD+'.naechstes_Ereignis','naechstes_Ereignis',{name: 'Sonnenwende',role: 'value',type: 'string'});
       await wait(2000);
      }
      
      // #########################################
      // Check um 0:0:30
      // #########################################
      schedule("30 0 0 * * *", async () => {
      await Berechnung();
      });
      
      await Berechnung();
      
      async function Berechnung() {
       var Jahr = parseFloat(formatDate(new Date(), 'JJJJ'));
       var HeuteNullUhr = Math.floor(((new Date().getTime()) + 7200000) / 86400000) * 86400000;
       var FruehlingsTagundnachtgleiche = Math.floor(((36605.319 + (Jahr - 2000) * 365.24 + 1 / 24) * 86400000 - 2209165245600) / 86400000) * 86400000 + 43200000;
       var Sommersonnenwende = Math.floor(((36605.319 + (Jahr - 2000) * 365.24 + 92.76 + 2 / 24 + Math.floor((Jahr - 2000) / 12) * 0.01) * 86400000 - 2209165245600) / 86400000) * 86400000 + 43200000;
       var HerbstTagundnachtgleiche = Math.floor(((36605.319 + (Jahr - 2000) * 365.24 + 186.41 + 2 / 24 + Math.floor((Jahr - 2000) / 12) * 0.02) * 86400000 - 2209165245600) / 86400000) * 86400000 + 43200000;
       var Wintersonnenwende = Math.floor(((36605.319 + (Jahr - 2000) * 365.24 + 276.26 + 1 / 24 + Math.floor((Jahr - 2000) / 12) * 0.02) * 86400000 - 2209165245600) / 86400000) * 86400000 + 43200000;
       var FruehlingsTagundnachtgleicheNextYear = Math.floor(((36605.319 + ((Jahr + 1) - 2000) * 365.24 + 1 / 24) * 86400000 - 2209165245600) / 86400000) * 86400000 + 43200000;
       if (getState(''+PFAD+'.01_Fruehlings-Tagundnachtgleiche').val != formatDate(getDateObject(FruehlingsTagundnachtgleiche), 'T.M.JJJJ')) {
         setState(''+PFAD+'.01_Fruehlings-Tagundnachtgleiche', formatDate(getDateObject(FruehlingsTagundnachtgleiche), 'T.M.JJJJ'), true);
       }
       if (getState(''+PFAD+'.02_Sommersonnenwende').val != formatDate(getDateObject(Sommersonnenwende), 'T.M.JJJJ')) {
         setState(''+PFAD+'.02_Sommersonnenwende', formatDate(getDateObject(Sommersonnenwende), 'T.M.JJJJ'), true);
       }
       if (getState(''+PFAD+'.03_Herbst-Tagundnachtgleiche').val != formatDate(getDateObject(HerbstTagundnachtgleiche), 'T.M.JJJJ')) {
         setState(''+PFAD+'.03_Herbst-Tagundnachtgleiche', formatDate(getDateObject(HerbstTagundnachtgleiche), 'T.M.JJJJ'), true);
       }
       if (getState(''+PFAD+'.04_Wintersonnenwende').val != formatDate(getDateObject(Wintersonnenwende), 'T.M.JJJJ')) {
         setState(''+PFAD+'.04_Wintersonnenwende', formatDate(getDateObject(Wintersonnenwende), 'T.M.JJJJ'), true);
       }
       if (Math.floor((FruehlingsTagundnachtgleiche - HeuteNullUhr) / 86400000) > 1) {
         setState(''+PFAD+'.naechstes_Ereignis', (['Die nächste Tag/Nacht Gleichheit ist in ',Math.floor((FruehlingsTagundnachtgleiche - HeuteNullUhr) / 86400000),' Tagen, am ',formatDate(getDateObject(FruehlingsTagundnachtgleiche), 'T.M.JJJJ')].join('')), true);
         if (getState(''+PFAD+'.Astronomische_Jahreszeiten').val != 'Winter') {
           setState(''+PFAD+'.Astronomische_Jahreszeiten', 'Winter', true);
         }
       } else if (Math.floor((FruehlingsTagundnachtgleiche - HeuteNullUhr) / 86400000) == 1) {
         setState(''+PFAD+'.naechstes_Ereignis', 'Die nächste Tag/Nacht Gleichheit ist Morgen', true);
       } else if (Math.floor((FruehlingsTagundnachtgleiche - HeuteNullUhr) / 86400000) == 0) {
         setState(''+PFAD+'.naechstes_Ereignis', 'Heute ist Tag/Nacht Gleichheit', true);
         setState(''+PFAD+'.Astronomische_Jahreszeiten', 'Heute ist Frühlingsanfang', true);
       } else if (Math.floor((Sommersonnenwende - HeuteNullUhr) / 86400000) > 1) {
         setState(''+PFAD+'.naechstes_Ereignis', (['Die nächste Sonnenwende ist in ',Math.floor((Sommersonnenwende - HeuteNullUhr) / 86400000),' Tagen, am ',formatDate(getDateObject(Sommersonnenwende), 'T.M.JJJJ')].join('')), true);
         if (getState(''+PFAD+'.Astronomische_Jahreszeiten').val != 'Frühling') {
           setState(''+PFAD+'.Astronomische_Jahreszeiten', 'Frühling', true);
         }
       } else if (Math.floor((Sommersonnenwende - HeuteNullUhr) / 86400000) == 1) {
         setState(''+PFAD+'.naechstes_Ereignis', 'Die nächste Sonnenwende ist Morgen', true);
       } else if (Math.floor((Sommersonnenwende - HeuteNullUhr) / 86400000) == 0) {
         setState(''+PFAD+'.naechstes_Ereignis', 'Heute ist Sonnenwende ', true);
         setState(''+PFAD+'.Astronomische_Jahreszeiten', 'Heute ist Sommeranfang', true);
       } else if (Math.floor((HerbstTagundnachtgleiche - HeuteNullUhr) / 86400000) > 1) {
         setState(''+PFAD+'.naechstes_Ereignis', (['Die nächste Tag/Nacht Gleichheit ist in ',Math.floor((HerbstTagundnachtgleiche - HeuteNullUhr) / 86400000),' Tagen, am ',formatDate(getDateObject(HerbstTagundnachtgleiche), 'T.M.JJJJ')].join('')), true);
         if (getState(''+PFAD+'.Astronomische_Jahreszeiten').val != 'Sommer') {
           setState(''+PFAD+'.Astronomische_Jahreszeiten', 'Sommer', true);
         }
       } else if (Math.floor((HerbstTagundnachtgleiche - HeuteNullUhr) / 86400000) == 1) {
         setState(''+PFAD+'.naechstes_Ereignis', 'Die nächste Tag/Nacht Gleichheit ist Morgen', true);
       } else if (Math.floor((HerbstTagundnachtgleiche - HeuteNullUhr) / 86400000) == 0) {
         setState(''+PFAD+'.naechstes_Ereignis', 'Heute ist Tag/Nacht Gleichheit', true);
         setState(''+PFAD+'.Astronomische_Jahreszeiten', 'Heute ist Herbstanfang', true);
       } else if (Math.floor((Wintersonnenwende - HeuteNullUhr) / 86400000) > 1) {
         setState(''+PFAD+'.naechstes_Ereignis', (['Die nächste Sonnenwende ist in ',Math.floor((Wintersonnenwende - HeuteNullUhr) / 86400000),' Tagen, am ',formatDate(getDateObject(Wintersonnenwende), 'T.M.JJJJ')].join('')), true);
         if (getState(''+PFAD+'.Astronomische_Jahreszeiten').val != 'Herbst') {
           setState(''+PFAD+'.Astronomische_Jahreszeiten', 'Herbst', true);
         }
       } else if (Math.floor((Wintersonnenwende - HeuteNullUhr) / 86400000) == 1) {
         setState(''+PFAD+'.naechstes_Ereignis', 'Die nächste Sonnenwende ist Morgen', true);
       } else if (Math.floor((Wintersonnenwende - HeuteNullUhr) / 86400000) == 0) {
         setState(''+PFAD+'.naechstes_Ereignis', 'Heute ist Sonnenwende ', true);
         setState(''+PFAD+'.Astronomische_Jahreszeiten', 'Heute ist Winteranfang', true);
       } else if (Math.floor((FruehlingsTagundnachtgleicheNextYear - HeuteNullUhr) / 86400000) > 1) {
         setState(''+PFAD+'.naechstes_Ereignis', (['Die nächste Tag/Nacht Gleichheit ist in ',Math.floor((FruehlingsTagundnachtgleicheNextYear - HeuteNullUhr) / 86400000),' Tagen, am ',formatDate(getDateObject(FruehlingsTagundnachtgleicheNextYear), 'T.M.JJJJ')].join('')), true);
         if (getState(''+PFAD+'.Astronomische_Jahreszeiten').val != 'Winter') {
           setState(''+PFAD+'.Astronomische_Jahreszeiten', 'Winter', true);
         }
       } else if (Math.floor((FruehlingsTagundnachtgleicheNextYear - HeuteNullUhr) / 86400000) == 1) {
         setState(''+PFAD+'.naechstes_Ereignis', 'Die nächste Tag/Nacht Gleichheit ist Morgen', true);
       } else if (Math.floor((FruehlingsTagundnachtgleicheNextYear - HeuteNullUhr) / 86400000) == 0) {
         setState(''+PFAD+'.naechstes_Ereignis', 'Heute ist Tag/Nacht Gleichheit', true);
       }
       if (3 <= parseFloat(formatDate(new Date(), 'M')) && parseFloat(formatDate(new Date(), 'M')) < 6) {
         if (getState(''+PFAD+'.Kalendarische_Jahreszeiten').val != 'Frühling') {
           setState(''+PFAD+'.Kalendarische_Jahreszeiten', 'Frühling', true);
         }
       } else if (6 <= parseFloat(formatDate(new Date(), 'M')) && parseFloat(formatDate(new Date(), 'M')) < 9) {
         if (getState(''+PFAD+'.Kalendarische_Jahreszeiten').val != 'Sommer') {
           setState(''+PFAD+'.Kalendarische_Jahreszeiten', 'Sommer', true);
         }
       } else if (9 <= parseFloat(formatDate(new Date(), 'M')) && parseFloat(formatDate(new Date(), 'M')) < 12) {
         if (getState(''+PFAD+'.Kalendarische_Jahreszeiten').val != 'Herbst') {
           setState(''+PFAD+'.Kalendarische_Jahreszeiten', 'Herbst', true);
         }
       } else {
         if (getState(''+PFAD+'.Kalendarische_Jahreszeiten').val != 'Winter') {
           setState(''+PFAD+'.Kalendarische_Jahreszeiten', 'Winter', true);
         }
       }
      }
      

      posted in JavaScript
      S
      stenmic
    • RE: E-INK Display OpenEPaperLink - Displayanzeige mit Batterie

      Ich bin mir nicht sicher, ob es hier schon eine Lösung für nen Json-String gibt.
      Hab beim Durchlesen jedenfalls keine gefunden.

      Hier ist meine Lösung.

      Als erstes muss "axios" im Javascript Adapter hinzugefügt werden:
      2024-08-03 07 08 27.jpg

      Der Tag muss auf "Json template" eingestellt werden:
      2024-08-03 07 07 34.jpg

      Und hier das Blockly, sollte selbsterklärend sein:

      2024-08-03 07 06 18.jpg

      Die Funktion:
      2024-08-03 07 06 27.jpg

      Blockly:


      <xml xmlns="https://developers.google.com/blockly/xml">
      <variables>
      <variable id="^bhgSAw+X+YJvf?RhU3">AP_IP</variable> <variable id="uc8fh+2kjeHGm-/vox=3">TAG_MAC</variable> <variable id="$Ig5a7mq0|-|sEkjT7ur">JS</variable> </variables> <block type="procedures_defcustomnoreturn" id="l{VWT5d2R8(RDtcq_L|-" x="163" y="-787"> <mutation statements="false"> <arg name="AP_IP" varid="^bhgSAw+X+YJvf?RhU3"></arg>
      <arg name="TAG_MAC" varid="uc8fh+2kjeHGm-/vox=3"></arg>
      <arg name="JS" varid="$Ig5a7mq0|-|sEkjT7ur"></arg>
      </mutation>
      <field name="NAME">OpenEPaperJson</field>
      <field name="SCRIPT">Y29uc3QgYXhpb3MgPSByZXF1aXJlKCdheGlvcycpOw0KDQpjb25zdCBvYmogPSB7DQogIG1hYzogVEFHX01BQywNCiAganNvbjogSlMsDQp9Ow0KDQpjb25zdCBkYXRhID0gT2JqZWN0LmtleXMob2JqKQ0KICAubWFwKChrZXkpID0+IGAke2tleX09JHtlbmNvZGVVUklDb21wb25lbnQob2JqW2tleV0pfWApDQogIC5qb2luKCcmJyk7DQoNCmNvbnN0IG9wdGlvbnMgPSB7DQogIG1ldGhvZDogJ1BPU1QnLA0KICBoZWFkZXJzOiB7ICdjb250ZW50LXR5cGUnOiAnYXBwbGljYXRpb24veC13d3ctZm9ybS11cmxlbmNvZGVkJyB9LA0KICB1cmw6ICdodHRwOi8vJytBUF9JUCsnL2pzb251cGxvYWQnLA0KICBkYXRhDQp9Ow0KDQphd2FpdCBheGlvcyhvcHRpb25zKTsNCi8vY29uc29sZS5sb2cob3B0aW9ucyk7</field>
      <comment pinned="false" h="80" w="160">Beschreibe diese Funktion …</comment>
      </block>
      <block type="procedures_callcustomnoreturn" id="ZR0:KP{+eKkQUre=m" x="163" y="-737"> <mutation name="OpenEPaperJson"> <arg name="AP_IP"></arg> <arg name="TAG_MAC"></arg> <arg name="JS"></arg> </mutation> <value name="ARG0"> <block type="text" id="8m.We}frb),Frmeu7S(?"> <field name="TEXT">192.168.178.xxx</field> </block> </value> <value name="ARG1"> <block type="text" id="yk4}TL@=?^fe$@Tct/B">
      <field name="TEXT">0000021F1D31xxxx</field>
      </block>
      </value>
      <value name="ARG2">
      <block type="text" id="Jq[@4;8ac*CU/g}jB82I">
      <field name="TEXT">[ {"text": [5,5,"Bahnschrift 20","fonts/bahnschrift20",1]}, {"box": [10,30,20,20,1]}, {"box": [35,30,20,20,2]}, {"triangle": [60,30,60,50,80,40,1]}, {"text": [5,80,"Plain text glasstown_nbp_tf","glasstown_nbp_tf",1]}, {"text": [5,95,"Plain text 7x14_tf","7x14_tf",2]}, {"text": [5,110,"Plain text t0_14b_tf","t0_14b_tf",1]}, {"text": [135,5,"30","fonts/bahnschrift30",2]}, {"text": [215,5,"70","fonts/bahnschrift70",1]}, {"text": [150,80,"50","fonts/calibrib50",2,0]}, {"text": [205,60,"80","fonts/calibrib80",2]}, {"text": [90,35,"calibrib30","fonts/calibrib30",1]}, {"line": [10,120,290,120,1]}, {"line": [10,115,290,115,2]} ]</field>
      </block>
      </value>
      </block>
      </xml>

      Hier noch die Erklärung wie der json String aussehen muss

      posted in Praktische Anwendungen (Showcase)
      S
      stenmic
    • RE: Test Adapter rpi2 2.x

      @laser sagte in Test Adapter rpi2 2.x:

      @garfonso Es ist doch super, daß Du Dich um den Adapter kümmerst.

      Das sehe ich auch so

      posted in Tester
      S
      stenmic
    • RE: Deutlich bessere Integration Home Assistant in ioBroker

      ich nutze einfach das Gute von Beiden im ioBroker

      posted in ioBroker Allgemein
      S
      stenmic
    • RE: Script für Formel 1 - Kalender, Ergebnisse und Wertungen

      Update...
      Die WM Stände sind jetzt auch fertig, ging schneller als gedacht.
      Wenn einer schon die ersten beide Skripte nutzt, bitte nochmal die Datenpunkte anlegen.

      posted in JavaScript
      S
      stenmic
    • RE: Test eCharts Adapter

      @bluefox
      Hi, zwei Fragen.
      Sobald ich bei echart das Grid einfärbe wird es gestrichelt dargestellt. Ist das normal?
      Schön wäre auch wenn man mehr Optionen aus Datenpunkten übernehmen könnte.
      z.B. Farben und Zeitbereiche. Dann könnte man mehr über die VIS steuern.
      Bei Farben meine ich, wenn der Wert für mich positiv ist möchte ich ne grüne Line, bei schlechten Werten eine Rote. Die Farbe steht in einem Datenpunkt, den ich je nach Situation flexibel anpasse.
      Oder vielleicht könnte man Bindings analog vis nutzen. Dann wäre der Adapterfür mich der Killer für Grafana.

      posted in Tester
      S
      stenmic

    Latest posts made by stenmic

    • RE: Test Adapter BMW/Mini v4.x.x

      @tippy88 bei mir ist es auch so

      posted in Tester
      S
      stenmic
    • RE: Test Adapter BMW/Mini v4.x.x

      @mclane da kann ich leider nicht helfen, bin in der Apple Welt unterwegs. Finde es jedoch sehr interessant.

      posted in Tester
      S
      stenmic
    • RE: Test Adapter BMW/Mini v4.x.x

      @mclane mach doch bitte dazu einen eigen Beitrag auf.
      Hier geht es ja um den Adapter. Ist sonst vielleicht verwirrend.

      posted in Tester
      S
      stenmic
    • RE: BETA-TEST Neuer Amazon Skill "iobroker.assistant"

      @denjo nein, ich schalte nur "Steckdosen" die ich als eigenen Datenpunkt angelegt habe und in Skripten weiter verarbeite.
      Also keine "echten" Geräte.

      posted in Cloud Dienste
      S
      stenmic
    • RE: BETA-TEST Neuer Amazon Skill "iobroker.assistant"

      @apollon77
      hab auf v3 umgestellt und alles läuft soweit.
      Ich nehme an, der Haken bei "Amazon Alexa Custom Skill" muss auch weiterhin gesetzt bleiben, oder?

      2025-10-18 06 36 00.jpg

      posted in Cloud Dienste
      S
      stenmic
    • RE: Test Adapter BMW/Mini v4.x.x

      @mike1429 sagte in Test Adapter BMW/Mini v4.x.x:

      @stenmic Also das mit den chargingBlocks ist noch nicht klar:

      1. Die charging history kommt bei mir nur wenn man den entsprechenden "Knopf" betätigt. Automatisch geht da nichts, ausser über ein Skript, aber wie oft? Mit welchem Trigger?
      2. Ein dataxx Ordner beinhaltet ggfls. mehrere chargingBlocks mit unterschiedlichem Datum, aber nur eine zusammenfassende Angabe der geladenen Energie. Man kann also nicht die KWs eines Ladevorgangs wissen.
        Ist dies über den Adapter lösbar?
        Wie macht ihr es?
        Danke!!

      Also...
      der Adapter arbeitet mit 2 Diensten von BMW.
      Einmal ist es MQTT, sobald sich Werte am Auto ändern aktualisieren sich diese automatisch im Ordner "stream". Dabei ist die Anzahl der Aktualisierungen pro Tag völlig egal.

      Dann gibt es die API Werte. Diese stehen im Ordner "api"
      Diese werden nur aktualisiert, wenn du den jeweiligen Button im "remote" Ordern triggerst.
      Das mit den Buttons ist gewollt, da du bei API in Summe nur 50 Abfragen pro Tag machen kannst.
      Du must dir jetzt überlegen, welche API Werte du wie oft am Tag aktualisieren möchtest und dir ein passendes Skript z.B. mit Blockly anlegen, welchen die Buttons triggert.

      Die kWh pro Ladegang stehen bei mir z.B. unter
      bmw.0.XXX.api.chargingHistory.data01.energyConsumedFromPowerGridKwh

      2025-10-15 17 59 39.jpg

      Die passen sogar ziemlich genau (ich messe über einen Shelly EM Gen3 meine Ladungen)

      Die kWh stehen für die letzten Ladegänge jeweils im dataxx Ordner.
      Mit den chargingBlocksxx hab ich mich noch nicht beschäftigt, aber ich vermute in Summe ergeben die "averagePowerGridKw" den "energyConsumedFromPowerGridKwh" Wert.

      posted in Tester
      S
      stenmic
    • RE: Test Adapter BMW/Mini v4.x.x

      @exmatador sagte in Test Adapter BMW/Mini v4.x.x:

      @stenmic
      Hallo, ich habe ein paar Fragen rund um die Positionserkennung, also Latitude und Longitude.
      Beide sind unter

      bmw.0.WBAxxx.stream.vehicle.cabin.infotainment.navigation.currentLocation.latitude.value
      bmw.0.WBAxxx.stream.vehicle.cabin.infotainment.navigation.currentLocation.longitude.value
      

      auch zu finden.
      Meine Fragen dazu:

      1. Wieso steht der Wert in einem Verzeichnis?
      2. Wieso gibt es unterhalb des Verzeichnisses die Values: c01 | c02 | c03 ? Die beiden ersten beinhalten den ganzzahligen Wert und die Nachkommastellen. Aktualisiert werden diese aber - so mein Gefühl - nur sporadisch.
      3. Die o.g. Werte Lat & Long werden so etwa alle 2 - 3 Minuten aktualisiert. Das ist bei einer Autofahrt doch ziemlich selten, da gehen Km ins Land. Und eigentlich ist MQTT doch für nahezu Echtzeit ausgelegt. Kann man den Zyklus irgendwie forcieren oder blockt BMW da?
      4. Kann oder besser darf man den remote.fetchViaAPI so oft wie man möchte auf "true" setzen oder geht das zu Lasten der Quotas?

      Vielen Dank
      Gruß ExMatador

      2-3 Minuten reichen doch völlig aus. Denk mal drüber nach was da sonst für Datenmenge für nix bei den vielen Autos zusammenkommt.

      posted in Tester
      S
      stenmic
    • RE: Test Adapter BMW/Mini v4.x.x

      @exmatador du hast 50 API abrufe am Tag….
      hält somit keine Stunde 👳‍♂️

      posted in Tester
      S
      stenmic
    • RE: Test Adapter BMW/Mini v4.x.x

      @mike1429
      schau mal hier rein
      bmw.0.XXX.api.chargingHistory.data01
      Der letzte ist immer im data01

      Wenn es die Struktur bei dir nicht gibt, hier mal draufdrücken
      bmw.0.XXX.remote.chargingHistory

      posted in Tester
      S
      stenmic
    • RE: Test Adapter BMW/Mini v4.x.x

      @tombox
      bei mir läuft der Adapter nun seit Tagen perfekt.
      Nur eine Fehlermeldung bekomme ich jede Nacht bei der Zwangstrennung der Fritzbox (DSL).
      Meinst du, dass könnten man noch rausfiltern?

      posted in Tester
      S
      stenmic
    Community
    Impressum | Datenschutz-Bestimmungen | Nutzungsbedingungen
    The ioBroker Community 2014-2023
    logo