Navigation

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

    NEWS

    • ioBroker@Smart Living Forum Solingen, 14.06. - Agenda added

    • ioBroker goes Matter ... Matter Adapter in Stable

    • Monatsrückblick - April 2025

    • Profile
    • Following 0
    • Followers 0
    • Topics 2
    • Posts 66
    • Best 14
    • Groups 1

    Sebastian IO

    @Sebastian IO

    Starter

    26
    Reputation
    63
    Profile views
    66
    Posts
    0
    Followers
    0
    Following
    Joined Last Online

    Sebastian IO Follow
    Starter

    Best posts made by Sebastian IO

    • RE: Test Coronavirus Statistics for ioBroker

      @dutchman wollte danke sagen für die tolle Aufbereitung der Daten.

      Hab mir dadurch ein generisches javascript für die ganzen Infos progammieren können.

      Läuft unter der jarvis vis, mit einem Filter für:
      Länder
      Top5
      Bundesländer
      Kreise und Städte

      Hier mal ein paar Screens:
      corona-1-city-states.png corona-2-states.png corona-3-countries.png corona-4-top5.png

      Danke nochmal und mach weiter so!

      posted in Tester
      Sebastian IO
      Sebastian IO
    • RE: Test Coronavirus Statistics for ioBroker

      Script zum Auslesen der corona statistik für jarvis visualisierung

      Mein Setup für jarvis zur Darstellung

      Für die Filter Statelist horizontal
      Für die Ausgabe customHtml
      Für das Aufbereiten des Designs in den Einstellungen Styles (pro)

      das Script wird im javascript adapter hinterlegt:

      const moment = require("moment");
      
      //Datumsformat
      moment.locale('de');
      let fRkiFaktor = 1.00443;
      
      /****** DATENPUNKTE MÜSSEN ERSTELLT WERDEN (Name Pfad frei konfigurierbar)  **********/
      /**role html, type string (Typ = Zeichenkette)  */
      let coronaHtmlDp = '0_userdata.0.vis.jarvis.coronahtml';
      
      // verwendet in function write_corona_stats() und für die Aktivierung der Eventlistener
      /**role switch, type boolean (Typ = Logikwert) */
      /**FILTER: setze den Wert auf false und der ausgewählte Datenpunkt wird nicht angezeigt */
      let filterDp = {
          'states': '0_userdata.0.vis.jarvis.corona.filter.bundeslaender',
          'cities': '0_userdata.0.vis.jarvis.corona.filter.cities',
          'countries': '0_userdata.0.vis.jarvis.corona.filter.countries',
          'top5': '0_userdata.0.vis.jarvis.corona.filter.top5stats',
      }
      /******ENDE DATENPUNKTE MÜSSEN ERSTELLT WERDEN **********/
      
      let countrySelector = '[id=coronavirus-statistics.0.*.population]';
      let oListCountry = $(countrySelector);
      
      let stateSelector = '[id=coronavirus-statistics.0.Germany.Bundesland.*.cases]';
      let oListState = $(stateSelector);
      
      let kreisSelector = '[id=coronavirus-statistics.0.Germany.Kreis.*.BL]';
      let oListKreis = $(kreisSelector);
      
      let stadtSelector = '[id=coronavirus-statistics.0.Germany.Stadt.*.BL]';
      let oListStadt = $(stadtSelector);
      
      //Mapper für Länder und Statistiken top5 und weltweit (nicht benötigte Datenpunkte können auskommentiert werden)
      let oSchemeCountry = {
          'updated': { 'title': 'zuletzt aktualisiert', 'format': 'datetime' },
          'population': { 'title': 'Einwohnerzahl', 'format': 'int' },
          'cases': { 'title': 'Fälle gesamt', 'format': 'int' },
          'active': { 'title': 'Aktuell infiziert', 'format': 'int' },
          'critical': { 'title': 'Im kritischen Zustand', 'format': 'int' },
          'recovered': { 'title': 'Genesene', 'format': 'int' },
          'tests': { 'title': 'Testungen', 'format': 'int' },
          'deaths': { 'title': 'Todesfälle', 'format': 'int' },
          'todayCases': { 'title': 'Heute neu infiziert', 'format': 'int' },
          'todayDeaths': { 'title': 'Heute Todesfälle', 'format': 'int' },
          'todayRecovered': { 'title': 'Heute Genesene', 'format': 'int' },
      };
      
      //Mapper für Bundesländer (nicht benötigte Datenpunkte können auskommentiert werden)
      let oSchemeState = {
          'updated': { 'title': 'zuletzt aktualisiert', 'format': 'datetime' },
          'cases': { 'title': ' COVID-19 Fälle gesamt', 'format': 'int' },
          'cases7_per_100k': { 'title': '7-Tage-Inzidenz', 'format': 'float' },
          'deaths': { 'title': 'COVID-19 Todesfälle', 'format': 'int' },
      
      };
      
      //Mapper für Stadt und Kreise (nicht benötigte Datenpunkte können auskommentiert werden)
      // hat ein title den Eintrag object wird der Name des Datenpunktes verwendet
      let oScheme = {
          'BL': { 'title': 'object', 'format': 'string' },
          'cases': { 'title': 'COVID-19 Fälle gesamt', 'format': 'int' },
          // 'cases_per_100k': { 'title': 'object', 'format': 'float' },
          // 'cases_per_population': { 'title': 'object', 'format': 'float' },
          // 'death_rate': { 'title': 'object', 'format': 'float' },
          'deaths': { 'title': 'COVID-19 Todesfälle', 'format': 'int' },
          'cases7_per_100k': { 'title': '7-Tage-Inzidenz', 'format': 'float' },
      };
      
      //Mapper für grafische Darstellung 7-Tages-Inzidenz verwendet in function calcGefahrInzidenz()
      let oScheme7Tg = {
          'ok': { 'title': 'Status ok', 'bgcolor': 'green', 'color': '#fff' },//wert 0 - 35
          'critical': { 'title': 'Status kritisch', 'bgcolor': 'orange', 'color': '#fff' }, //wert 35 - 50
          'high': { 'title': 'Status hoch', 'bgcolor': 'red', 'color': '#fff' }, // 50 - 100
          'veryhigh': { 'title': 'Status sehr hoch Notbremse aktiviert', 'bgcolor': 'darkred', 'color': '#fff' }// > 100
      };
      
      //Mapper für erlaubte Dinge 7-Tages-Inzidenz verwendet in function calcGefahrInzidenz()
      let oSchemeAllowed = {
          'ok': [// 0 - 35
              { 'title': 'Privat', 'descr': '3 Haushalte max. zehn Personen, Kinder bis 14 Jahre nicht mitgezählt' },
              { 'title': 'Geschäfte', 'descr': 'Einzelhandel mit kontrollierten Einlass' },
              { 'title': 'Freizeit', 'descr': 'Museen, Galerien, Zoos, Botanische Gärten, Gedenkstätten' },
              { 'title': 'Sport', 'descr': 'Außensport kontaktfrei (max. 10 Personen)' },
              { 'title': 'Gastronomie', 'descr': 'erst ab 22. März' },
          ],
          'critical': [ // 35 - 50
              { 'title': 'Privat', 'descr': 'Max 5 Personen aus zwei Haushalten, Kinder bis 14 Jahre nicht mitgezählt' },
              { 'title': 'Geschäfte', 'descr': 'Einzelhandel mit kontrollierten Einlass' },
              { 'title': 'Freizeit', 'descr': 'Museen, Galerien, Zoos, Botanische Gärten, Gedenkstätten' },
              { 'title': 'Sport', 'descr': 'Außensport kontaktfrei (max. 10 Personen)' },
              { 'title': 'Gastronomie', 'descr': 'erst ab 22. März' },
          ],
          'high': [ // 50 - 100
              { 'title': 'Privat', 'descr': 'Max 5 Personen aus zwei Haushalten, Kinder bis 14 Jahre nicht mitgezählt' },
              { 'title': 'Geschäfte', 'descr': 'Einzelhandel Click & Collect oder Click & Meet (40 Quadratmeter pro Person), Kontaktdatenerhebung' },
              { 'title': 'Freizeit', 'descr': 'Museen, Galerien, Zoos, Botanische Gärten, Gedenkstätten nur mit Terminbuchung' },
              { 'title': 'Sport', 'descr': 'Individualsport außen, max 5 Personen aus 2 Haushalten' },
              { 'title': 'Gastronomie', 'descr': 'erst ab 22. März' },
          ],
          'veryhigh': [ // > 100
              { 'title': 'Privat', 'descr': 'ein Haushalt und eine weitere Person, nächtliche Ausgangssperre' },
              { 'title': 'Geschäfte', 'descr': 'Einzelhandel geschlossen' },
              { 'title': 'Freizeit', 'descr': 'Museen, Galerien, Zoos, Botanische Gärten, Gedenkstätten geschlossen' },
              { 'title': 'Sport', 'descr': 'Individualsport nur allein' },
              { 'title': 'Gastronomie', 'descr': 'erst ab 22. März' },
              { 'title': 'Kindergärten und Kitas', 'descr': 'geschlossen, nur Notbetreuung' },
              { 'title': 'Schulen', 'descr': 'nur Distanzunterricht' },
          ],
      };
      
      //Mapper für Legende Landkreise und Städte
      let oSchemeLegende = {
          'city': [
              { 'title': 'Hinweis', 'descr': 'Zudem gilt die sogenannte Notbremse: Steigt die 7-Tage-Inzidenz pro 100.000 Einwohner an drei aufeinander folgenden Tagen in einem Landkreis oder einer kreisfreien Stadt über 100, treten die Regeln, die vor dem 8. März gegolten hatten, wieder in Kraft.' }
          ],
      };
      
      //Eventlistener for filter 
      for (const [key, dp] of Object.entries(filterDp)) {
          on({ id: dp }, write_corona_stats);
      };
      
      write_corona_stats();
      
      function write_corona_stats() {
          try {
      
              let sStateOut = '';
              let sOutSumGermany = '';
              //Liste ausgewählter Bundesländer
              var calcInzidenzSum = 0.00;
              if (oListState.length > 0) {
                  let bShowStates = getState(filterDp.states).val;
                  sStateOut = '<div class="co-container states">';
      
                  oListState.each((item, index) => {
                      let iStateID = item.replace('.cases', '');
                      if (bShowStates === true) {
                          let sStateName = iStateID.replace('coronavirus-statistics.0.Germany.Bundesland.', '');
                          sStateOut += '<div class="co-container"><div class="co-heading state">' + sStateName + '</div>';
                      }
                      for (const [key, dp] of Object.entries(oSchemeState)) {
                          if (bShowStates === true) {
                              sStateOut += builElements(key, dp, iStateID, false, '');
                          }
                          if (key === 'cases7_per_100k') {
                              calcInzidenzSum += parseFloat(getState(iStateID + '.' + key).val);
                          }
                      }//End for
                      if (bShowStates === true) {
                          sStateOut += '</div>';
                      }
                  });
      
                  if (oListState.length === 16) {
                      let calc7IndDe = (calcInzidenzSum / oListState.length * fRkiFaktor);
                      let fCalc7IndDe = calc7IndDe.toFixed(2);
                      let sCalc7IndDe = number_format(calc7IndDe, 2, ',', '.');
      
                      let oReturn = calcGefahrInzidenz(fCalc7IndDe, sCalc7IndDe, false);
                      let valc7IndDe = oReturn.val;
      
                      sOutSumGermany = '<div class="co-entry de-7-inz horizontal"><div class="co-descr">7-Tage-Inzidenz</div><div class="co-val">' + valc7IndDe + '</div></div>';
                  }
                  sStateOut += '</div>';
              }
      
              //Liste ausgewählter Länder
              let sCountryOut = '';
              if (oListCountry.length > 0) {
                  let bShowTop5 = getState(filterDp.top5).val;
                  let bCountries = getState(filterDp.countries).val;
                  //only countries
                  if (bCountries === true) {
                      sCountryOut = '<div class="co-container countries">';
                      oListCountry.each((item, index) => {
                          let iCountryID = item.replace('.population', '');
                          if ((iCountryID.indexOf("country_Top_5") === -1 && iCountryID.indexOf("global_totals") === -1)) {
                              let sCountryName = iCountryID.replace('coronavirus-statistics.0.', '');
                              let sFlag = '<img class="co-flag" src="' + getState(iCountryID + '.flag').val + '"> ';
                              let sCountryNameTrans = sFlag + sCountryName;
      
                              if (sCountryName === 'Germany') {
                                  sCountryNameTrans = sFlag + 'Deutschland';
                              }
                              sCountryOut += '<div class="co-container country"><div class="co-heading country">' + sCountryNameTrans + '</div>';
      
                              for (const [key, dp] of Object.entries(oSchemeCountry)) {
                                  sCountryOut += builElements(key, dp, iCountryID, false, 'horizontal');
                              }//End for
      
                              if (sCountryName === 'Germany') {
                                  sCountryOut += sOutSumGermany;
                              }
                              sCountryOut += '</div>';
                          }
                      });
                      sCountryOut += '</div>';
                  }
      
                  //only stats
                  if (bShowTop5 === true) {
                      sCountryOut += '<div class="co-container stats">';
                      oListCountry.each((item, index) => {
                          let iCountryID = item.replace('.population', '');
                          if (iCountryID.indexOf("country_Top_5") > -1 || iCountryID.indexOf("global_totals") > -1) {
                              let sCountryName = iCountryID.replace('coronavirus-statistics.0.', '');
                              let sFlag = '';
                              if (iCountryID.indexOf("global_totals") === -1) {
                                  sFlag = '<img class="co-flag" src="' + getState(iCountryID + '.flag').val + '"> ';
                              }
                              let sCountryNameTrans = sFlag + sCountryName;
      
                              if (sCountryName.indexOf("country_Top_5") > -1) {
                                  let obj = getObject(iCountryID);
                                  sCountryNameTrans = sFlag + obj.common.name;
                              } else if (sCountryName.indexOf("global_totals") > -1) {
                                  sCountryNameTrans = 'Weltweit gesamt';
                              }
                              sCountryOut += '<div class="co-container country"><div class="co-heading stats">' + sCountryNameTrans + '</div>';
      
                              for (const [key, dp] of Object.entries(oSchemeCountry)) {
                                  sCountryOut += builElements(key, dp, iCountryID, false, '');
                              }//End for
      
                              sCountryOut += '</div>';
                          }
                      });
                      sCountryOut += '</div>';
                  }
              }
      
              //Liste Landkreise
              let sCityCountiesOut = '';
              if (oListKreis.length > 0 && getState(filterDp.cities).val === true) {
      
                  oListKreis.each((item, index) => {
                      let iKreisID = item.replace('.BL', '');
                      let sKreisName = iKreisID.replace('coronavirus-statistics.0.Germany.Kreis.', '');
                      sCityCountiesOut += '<div class="co-container"><div class="co-heading county">' + 'Kreis ' + sKreisName + '</div>';
      
                      for (const [key, dp] of Object.entries(oScheme)) {
                          sCityCountiesOut += builElements(key, dp, iKreisID, true, '');
                      }//End for
      
                      sCityCountiesOut += '</div>';
                  });//end each
              }
      
              //Liste kreisfreie Städte
              if (oListStadt.length > 0 && getState(filterDp.cities).val === true) {
                  oListStadt.each((item, index) => {
                      let iStadtID = item.replace('.BL', '');
                      let sStadtName = iStadtID.replace('coronavirus-statistics.0.Germany.Stadt.', '');
                      sCityCountiesOut += '<div class="co-container"><div class="co-heading city">' + 'Stadt ' + sStadtName + '</div>';
      
                      for (const [key, dp] of Object.entries(oScheme)) {
                          sCityCountiesOut += builElements(key, dp, iStadtID, true, '');
                      }//End for
      
                      sCityCountiesOut += '</div>';
                  });//end each
              }
      
              if (sCityCountiesOut !== '') {
                  let sLegende = '<div class="co-legende">';
                  for (const [key, element] of Object.entries(oSchemeLegende.city)) {
                      sLegende += '<b>' + element.title + '</b>: ' + element.descr;
                  };
                  sLegende += '</div>';
                  sCityCountiesOut = '<div class="co-container cities-counties">' + sCityCountiesOut + sLegende + '</div>';
              }
      
              var sHtml = '<div class="co-overview">';
              sHtml += sCountryOut + sStateOut + sCityCountiesOut;
      
              setState(coronaHtmlDp, sHtml);
      
          } catch (err) {
              console.error('[CoronaStatus] error: ' + err.message + ', stack: ' + err.stack);
          }
      }
      
      function builElements(key, dp, dpId, bAllow, cssClass) {
          let descr = '';
          let val = '';
          let sList = '';
          let sOut = '';
      
          if (dp.title === 'object') {
              let obj = getObject(dpId + '.' + key);
              descr = obj.common.name;
          } else {
              descr = dp.title
          }
      
          if (dp.format === 'string') {
              val = getState(dpId + '.' + key).val;
          } else if (dp.format === 'datetime') {
              let valDate = getState(dpId + '.' + key).val;
              val = moment(valDate).format('DD.MM.YYYY HH:mm');
          } else if (dp.format === 'int') {
              val = getState(dpId + '.' + key).val;
              val = number_format(val, 0, '', '.');
          } else if (dp.format === 'float') {
              let fVal = parseFloat(getState(dpId + '.' + key).val).toFixed(2);
              val = number_format(fVal, 2, ',', '.');
              if (key === 'cases7_per_100k') {
                  let oReturn = calcGefahrInzidenz(fVal, val, bAllow);
                  val = oReturn.val;
                  sList = (oReturn.list !== '') ? '<div class="co-allowed-list">' + oReturn.list + '</div>' : '';
              }
          }
      
          sOut = '<div class="co-entry co-dp-' + key + ' ' + cssClass + '"><div class="co-descr">' + descr + '</div><div class="co-val">' + val + '</div></div>';
      
          if (sList !== '') {
              sOut += sList;
          }
      
          return sOut;
      }
      
      function calcGefahrInzidenz(fVal, sVal, isAllowed) {
          let iVal = parseInt(fVal);
          let val = '';
          let sListAllowed = '';
      
          if (iVal < 35) {
              val = '<span class="badge" title="' + oScheme7Tg.ok.title + '" style="background-color:' + oScheme7Tg.ok.bgcolor + ';color:' + oScheme7Tg.ok.color + ';">' + sVal + '</span>';
              if (isAllowed === true) {
                  sListAllowed = '<ul class="co-list">';
                  for (const [key, element] of Object.entries(oSchemeAllowed.ok)) {
                      sListAllowed += '<li><b>' + element.title + '</b>: ' + element.descr + '</li>';
                  };
                  sListAllowed += '</ul>';
              }
          } else if (iVal >= 35 && iVal < 50) {
              val = '<span class="badge" title="' + oScheme7Tg.critical.title + '" style="background-color:' + oScheme7Tg.critical.bgcolor + ';color:' + oScheme7Tg.critical.color + ';">' + sVal + '</span>';
              if (isAllowed === true) {
                  sListAllowed = '<ul class="co-list">';
                  for (const [key, element] of Object.entries(oSchemeAllowed.critical)) {
                      sListAllowed += '<li><b>' + element.title + '</b>: ' + element.descr + '</li>';
                  };
                  sListAllowed += '</ul>';
              }
          } else if (iVal >= 50 && iVal < 100) {
              val = '<span class="badge" title="' + oScheme7Tg.high.title + '" style="background-color:' + oScheme7Tg.high.bgcolor + ';color:' + oScheme7Tg.high.color + ';">' + sVal + '</span>';
              if (isAllowed === true) {
                  sListAllowed = '<ul class="co-list">';
                  for (const [key, element] of Object.entries(oSchemeAllowed.high)) {
                      sListAllowed += '<li><b>' + element.title + '</b>: ' + element.descr + '</li>';
                  };
                  sListAllowed += '</ul>';
              }
          } else if (iVal >= 100) {
              val = '<span class="badge" title="' + oScheme7Tg.veryhigh.title + '" style="background-color:' + oScheme7Tg.veryhigh.bgcolor + ';color:' + oScheme7Tg.veryhigh.color + ';">' + sVal + '</span>';
              if (isAllowed === true) {
                  sListAllowed = '<ul class="co-list">';
                  for (const [key, element] of Object.entries(oSchemeAllowed.veryhigh)) {
                      sListAllowed += '<li><b>' + element.title + '</b>: ' + element.descr + '</li>';
                  };
                  sListAllowed += '</ul>';
              }
          }
          let oReturn = { 'val': val, 'list': sListAllowed };
      
          return oReturn;
      }
      
      //taken from https://gist.github.com/VassilisPallas/d73632e9de4794b7dd10b7408f7948e8/bf17eccef8521b4e5869bdc6a5b09a771356fbff
      function number_format(intFloatNumber, decimals, dec_point, thousands_point) {
      
          if (intFloatNumber == null || !isFinite(intFloatNumber)) {
              throw new TypeError("number is not valid");
          }
      
          if (!decimals) {
              let len = intFloatNumber.toString().split('.').length;
              decimals = len > 1 ? len : 0;
          }
      
          dec_point = (!dec_point) ? '.' : dec_point;
          thousands_point = (!thousands_point) ? '.' : thousands_point;
      
          intFloatNumber = parseFloat(intFloatNumber).toFixed(decimals);
          intFloatNumber = intFloatNumber.replace(".", dec_point);
      
          var splitNum = intFloatNumber.split(dec_point);
          splitNum[0] = splitNum[0].replace(/\B(?=(\d{3})+(?!\d))/g, thousands_point);
          intFloatNumber = splitNum.join(dec_point);
      
          return intFloatNumber;
      }
      
      

      Das erforderliche Css für das Design:

      /*corona*/
      .co-overview{
      position: relative;
      width: 100% ;
      display: inline-block;
      box-sizing:border-box;
      }
      
      .co-container{
      position: relative;
      width: calc(25% - 20px);
      display: inline-block;
      box-sizing:border-box;
      margin:10px;
      vertical-align:text-top;
      background-color:#f4f4f4;
      border-radius:8px;
      
      }
      
      .co-container.stats,
      .co-container.cities-counties,
      .co-container.countries,
      .co-container.states{
      width: 100%;
      background-color:#fff;
      margin:0;
      padding:0;
      }
      
      .co-container.stats .co-container{
      width:calc(33.333% - 20px);
      margin:10px;
      }
      
      .co-container.stats .co-container,
      .co-container.countries .co-container,
      .co-container.cities-counties .co-container,
      .co-container.states .co-container{
      box-shadow: 0px 2px 1px -1px rgba(0,0,0,0.2),0px 1px 1px 0px rgba(0,0,0,0.14),0px 1px 3px 0px rgba(0,0,0,0.12);
      background-color:#fff;
      }
      
      
      .co-container.country{
      width: calc(100% - 20px);
      }
      .co-legende{
      width: calc(100% - 20px);
      padding: 10px;
      background: #FFCCBC;
      position: relative;
      margin-left: 10px;
      box-sizing: border-box;
      border-radius:8px;
      box-shadow: 0px 2px 1px -1px rgba(0,0,0,0.2),0px 1px 1px 0px rgba(0,0,0,0.14),0px 1px 3px 0px rgba(0,0,0,0.12);
      margin-bottom: 10px;
      margin-top:10px;
      }
      
      .co-heading{
      position: relative;
      width: 100%;
      display: inline-block;
      font-weight:bold;
      padding: 0 5px;
      box-sizing: border-box;
      }
      
      .co-heading.stats,
      .co-heading.country,
      .co-heading.county,
      .co-heading.city,
      .co-heading.state{
      background: #2196F3;
      font-size: 14px;
      line-height: 35px;
      color: #fff;
      font-weight: normal;
      border-top-left-radius: 8px;
      border-top-right-radius: 8px;
      }
      
      .co-heading.stats{
      background:#F57C00;
      }
      .co-heading.country{
      background:#880E4F;
      }
      
      .co-heading.county,
      .co-heading.city{
      background: #00796B;
      }
      
      img.co-flag{
      height:15px;
      width:auto;
      }
      .co-entry{
      position: relative;
      width: 100%;
      display: inline-block;
      padding: 0 10px;
      box-sizing:border-box;
      }
      
      
      .co-entry .badge{
      font-size:12px;
      padding: 0px 4px;
      border-radius: 4px;
      }
      .co-descr{
      position: relative;
      width: 60%;
      display: inline-block;
      overflow: hidden;
      text-overflow: ellipsis;
      white-space: nowrap;
      }
      .co-val{
      position: relative;
      width: 40%;
      display: inline-block;
      overflow: hidden;
      text-overflow: ellipsis;
      white-space: nowrap;
      text-align:right;
      }
      
      .co-container.states .co-entry.co-dp-updated,
      .co-container.stats .co-entry.co-dp-updated{
      font-size:11px;
      }
      .co-container.countries .co-entry.co-dp-updated.horizontal{
      font-size:14px;
      }
      
      .co-entry.horizontal{
      width: calc(16.6666% - 20px);
      margin: 17px 10px;
      background:#fff;
      border-radius:8px;
      padding:0;
      box-shadow: 0px 2px 1px -1px rgba(0,0,0,0.2),0px 1px 1px 0px rgba(0,0,0,0.14),0px 1px 3px 0px rgba(0,0,0,0.12);
      }
      
      .co-entry.horizontal .co-descr,
      .co-entry.horizontal .co-val{
      width:100%;
      text-align:center;
      }
      .co-entry.horizontal .co-val{
      font-weight:bold;
      }
      .co-entry.horizontal .co-descr{
      background: #880E4F;
      font-size: 14px;
      line-height: 35px;
      color: #fff;
      font-weight: normal;
      border-top-left-radius: 8px;
      border-top-right-radius: 8px;
      }
      
      .co-allowed-list{
      position: relative;
      width: 100%;
      display: inline-block;
      padding: 10px;
      background-color: #EAEAB9;
      border-bottom-left-radius: 8px;
      box-sizing: border-box;
      margin-top: 10px;
      border-bottom-right-radius: 8px;
      }
      .co-list{
      margin:0;
      padding:0;
      list-style:none;
      position:relative;
      width:100%;
      display:inline-block;
      }
      
      .co-list li{
      position:relative;
      width:100%;
      font-size:14px;
      line-height:18px;
      marign-bottom:4px;
      }
      
      /*corona*/
      @media (max-width: 768px) {
      .co-container.stats .co-container {
          width: calc(50% - 20px);
      }
      .co-container{
      width: calc(50% - 20px);
      }
      }
      @media (max-width: 536px) {
      
      .co-container{
      width: calc(100% - 20px);
      }
      
      .co-container.stats .co-container {
          width: calc(100% - 20px);
      }
      .co-entry.horizontal {
          width: calc(50% - 20px);
      }
      }
      
      

      Have fun!

      posted in Tester
      Sebastian IO
      Sebastian IO
    • [Projekt] Integr. Cubinote - Alexa Sprache drucken - Listen

      "Alexa, drucke Einkaufsliste"
      "Alexa, drucke Aufgabenliste" ...

      ... genau diese beiden Sprachbefehle haben mir gefehlt für einen schnellen Ausdruck in Notizgröße für obengenannte Listen!
      Ich bin fündig geworden bei Cubinote, einem noch sehr jungen Produkt. Es ist ein kleiner Thermopapier Drucker für die Hosentasche mit eigener App zum Drucken von Notizen und auch Bildern im 1Bit monochrom Format! Also eine Spielerei für TechnikNerds!

      Der große Vorteil, dieser Drucker bietet eine WepApi an, mit dieser kann man dann verschiedene Befehle absetzen und der kleine Drucker führt diese aus.
      Das Projekt war geboren ...

      Was wurde gemacht:
      Es wurden Datenpunkte für die wichtigsten Daten wie (url,appid,accesskey,deviceid etc) angelegt, weitere Datenpunkte für die verschiedenen States zum Abfragen, Smartobjekte angelegt über iot zum Erstellen von Routinen mit Alexa, in meinem Fall drucken.
      Noch ein paar Javascripte programmiert für die einzelnen Abfragen, wie Binding, Status und Drucken. Alles mit einander verknüpft, getestet und aktiviert.

      Ich habe ein kurzes Video mit meinem Smartphone aufgenommen, leider ist der Ton sehr leise. Wer Interesse hat, kann sich das 1-minütige Video auf YT ansehen (Ton muss leider sehr laut gestellt werden, sorry):
      Cubinote Integration Video YT

      Viel Spass.

      Für Ideen und Anregungen bin ich natürlich offen!

      PS: Ich will mir eventuell dann auch andere Datenpunkte, wie Systeminformationen etc auch per Sprache zum Druck ausgeben lassen.

      posted in Praktische Anwendungen (Showcase)
      Sebastian IO
      Sebastian IO
    • RE: jarvis v2.2.0 - just another remarkable vis

      Dann auch mal meine ersten Versuche mit jarvis!
      Eigene Modifikationen für
      Tankerkönig mit customHtml (eigene Scripte in javascript Adapter)
      Newsfeed reader RSS2.0 customHtml (eigene Scripte in javascript Adapter)
      Abfallkalender mit ical customHtml (eigene Scripte in javascript Adapter)
      Drucker Api Integration für Thermopapierdrucker von Cubinote (eigene Scripte in javascript Adapter)
      2021-03-06-17_54_55-Langhaus-1980.jpg

      Macht Spass, wenn man mal durch das Konzept durchgestiegen ist!

      posted in Tester
      Sebastian IO
      Sebastian IO
    • RE: Test Coronavirus Statistics for ioBroker

      @ash2k Ich bin ja froh, dass wir dir weiterhelfen konnten. #communitygedanke

      posted in Tester
      Sebastian IO
      Sebastian IO
    • RE: Test/Support für Adapter rssfeed und vis-2-widgets-rssfeed

      @OliverIO guten morgen,

      hab es nun anders über das Script als Vorlage hier: https://forum.iobroker.net/topic/6072/gelöst-newsfeed-in-iobroker-vis-darstellen/43 gelöst. Hab es so angepasst, dass man per Script x-viele Feeds integrieren kann und habe moment.js für vernünftige Datumsformatierung verwendet und auch Bilder sind in der Anzeige möglich.
      Kommt wirklich nice, mit dem fade effekt von jquery.

      Dazu habe ich unter Scripts folgendes angepasst und integriert.

      Grundscript:
      Js:

      $("#slideshow > div:gt(0)").hide();
      
      setInterval(function() {
        $('#slideshow > div:first')
          .fadeOut(1000)
          .next()
          .fadeIn(1000)
          .end()
          .appendTo('#slideshow');
      }, 3000);
      

      Css:

      #slideshow {
        margin: 80px auto;
        position: relative;
        width: 240px;
        height: 240px;
        padding: 10px;
        box-shadow: 0 0 20px rgba(0, 0, 0, 0.4);
      }
      
      #slideshow > div {
        position: absolute;
        top: 10px;
        left: 10px;
        right: 10px;
        bottom: 10px;
      }
      

      html:

      <div id="slideshow">
         <div>
          feed 1
         </div>
         <div>
           feed 2
         </div>
         <div>
           feed 3
         </div>
      </div>
      

      Da ich selber Webentwickler bin, war das nicht wirklich die große Herausforderung.
      Vielleicht kannst Du ja was mit den Snippets anfangen.
      Ich bin mit dem Ergebnis für V 0.0.1b sehr zufrieden. Kann natürlich noch einiges verbessert und optimiert werden, aber für einen Schnellschuss ist es ok.

      posted in Tester
      Sebastian IO
      Sebastian IO
    • RE: [Vorstellung] neue Visualisierung :: minuVis

      @svallant ich hätte noch Feature Request liebschau:

      1. Könnte man den HtmlOutput auch in den CompactMode mit integrieren?
        Da ja nicht direkt html eingebunden werden kann, plane ich einen Datenpunkt, der mir die SystemInfo Iobroker per Javascript htmlformatiert in den Datenpunkt schreibt, das gleiche würde ich auch für meine echo devices machen wollen.

      2. Könnte man bei Fillern und CompactMode Start auch Werte aus Datenpunkten hinterlegen anstatt nur eines normalen Strings? (eventl. nach {} im value per regex suchen)

      Ansonsten sehr gute Arbeit und Responsive ohne einen großen Overhead. Danke macht weiter so!

      posted in Visualisierung
      Sebastian IO
      Sebastian IO
    • RE: [Projekt] Integr. Cubinote - Alexa Sprache drucken - Listen

      @agria4800 guten morgen,

      ich poste meine Scripte die ich verwende, ich arbeite auch mit alexa als sprachausgabe, sprich du musst dann ein Gerät hinterlegen, dort wird dann die Sprachausgabe erfolgen.

      Ich poste dir auch ein Script mit createState, dort werden alle wichtigen Datenpunkte angelegt, diese brauchst du nur einmal ausführen zum anlegen, danach kannst du das Script wieder ausschalten.

      Script createStatesCubinote (dementsprechend deine Zugangsdaten hinterlegen, bevor das Script ausgeführt wird):

      
      createState('0_userdata.0.cubinote.apiurl','http://api.cubinote.com/home/',{name:'Api url for requests',type:"string",role:"value"});
      createState('0_userdata.0.cubinote.appid','YOUR APP ID',{name:'AppID',type:"string",role:"value"});
      createState('0_userdata.0.cubinote.accesskey','YOUR ACCESSTOKEN',{name:'Access Key',type:"string",role:"value"});
      createState('0_userdata.0.cubinote.deviceid','YOUR DEVICEID',{name:'Id of cubinote printer',type:"string",role:"value"});
      createState('0_userdata.0.cubinote.bindid','YOUR BINDID',{name:'Id of cubinote Binding id',type:"string",role:"value"});
      createState('0_userdata.0.cubinote.userid','YOUR USERID',{name:'Username account',type:"string",role:"value"});
      
      createState('0_userdata.0.cubinote.actionStates.print_shoppinglist_state',false,{name:'Shopping List state',type:"boolean",role:"switch"});
      createState('0_userdata.0.cubinote.actionStates.print_todolist_state',false,{name:'Todo List state',type:"boolean",role:"switch"});
      createState('0_userdata.0.cubinote.actionStates.read_cubinotestatus_state',false,{name:'Cubinote Status state',type:"boolean",role:"switch"});
      createState('0_userdata.0.cubinote.actionStates.write_binding_state',false,{name:'Write binding state',type:"boolean",role:"button"});
      createState('0_userdata.0.cubinote.actionStates.check_binding_state',false,{name:'Check binding state',type:"boolean",role:"switch"});
      

      write & check binding state script:

      Bei echodevice deinen Echo hinterlegen, nun kannst du mit den Datenpunkten
      0_userdata.0.cubinote.actionStates.write_binding_state (einmal auf true setzen) deine binding id bekommen, diese wird dann in den definierten Datenpunkt geschrieben.

      0_userdata.0.cubinote.actionStates.check_binding_state (einmal auf true setzen) hier bekommst du dann eine Sprachausgabe ob die Verbindung erfolgreich war. Beide Datenpunkte brauchst du nur einmal ausführen, letztlich brauchen wir ja nur die bindid.

      const moment = require('moment');
      var aApiSettings = {
          //Echo fuer Sprachausgabe
          'echodevice': 'YOUR ECHO DEVICE',
          'url': getState("0_userdata.0.cubinote.apiurl").val,
          'action': {
              'print': 'printpaper',
              'devicestatus': 'getdeviceinfo',
              'printstatus': 'getprintstat',
              'requestbind': 'requestbind',
              'requestbindstatus': 'getbindrequeststatus',
              'verifybind': 'verifybind',
          },
          'appid': '?appID=' + getState("0_userdata.0.cubinote.appid").val,
          'accesskey': '&ak=' + getState("0_userdata.0.cubinote.accesskey").val,
          'deviceid': '&deviceID=' + getState("0_userdata.0.cubinote.deviceid").val,
          'bindid': '&bindID=' + getState("0_userdata.0.cubinote.bindid").val,
          'userid': '&useridentifying=' + getState("0_userdata.0.cubinote.userid").val,
          'liststates': {
              '0_userdata.0.cubinote.actionStates.print_shoppinglist_state': 'alexa2.0.Lists.SHOPPING_LIST.json',
              '0_userdata.0.cubinote.actionStates.print_todolist_state': 'alexa2.0.Lists.TO_DO.json'
          }
      }
      //check binding state
      on({ id: '0_userdata.0.cubinote.actionStates.check_binding_state', val: true }, function (obj) {
          var value = obj.state.val;
          var oldValue = obj.oldState.val;
          moment.locale('de');         // de
          var TimeStamp = moment().format('YYYY-MM-DD hh:mm:ss');
          var sTimestamp = '&timestamp=' + TimeStamp;
          var apiUrl = aApiSettings.url + aApiSettings.action.requestbindstatus + aApiSettings.appid + aApiSettings.accesskey + sTimestamp + aApiSettings.deviceid + aApiSettings.bindid;
          const request = require('request');
          request({ 'uri': apiUrl }, function (error, response, json) {
              if (!error && response.statusCode === 200) {
                  var aReturn = JSON.parse(json);
                  if (aReturn.showapi_res_code == 1) {
                      //Alexa Sprachausgabe
                      setState(aApiSettings.echodevice + ".Commands.speak", '50; Verbindungsstatus erfolgreich');
      
                  }
                  if (aReturn.showapi_res_code != 1) {
                      //Alexa Sprachausgabe
                      setState(aApiSettings.echodevice + ".Commands.speak", '50; Verbindungsstatus nicht erfolgreich');
      
                  }
              }
          });
          //reset check binding state after 2 seconds
          setStateDelayed('0_userdata.0.cubinote.actionStates.check_binding_state', false, 2000, false);
      
      });
      
      on({ id: '0_userdata.0.cubinote.actionStates.write_binding_state', val: true }, function (obj) {
          var value = obj.state.val;
          var oldValue = obj.oldState.val;
          moment.locale('de');         // de
          var TimeStamp = moment().format('YYYY-MM-DD hh:mm:ss');
          var sTimestamp = '&timestamp=' + TimeStamp;
          var apiUrl = aApiSettings.url + aApiSettings.action.requestbind + aApiSettings.appid + aApiSettings.accesskey + sTimestamp + aApiSettings.deviceid + aApiSettings.userid;
          //console.log(apiUrl);
          const request = require('request');
          request({ 'uri': apiUrl }, function (error, response, json) {
              if (!error && response.statusCode === 200) {
                  var aReturn = JSON.parse(json);
                  //{"showapi_res_code":1,"showapi_res_error":"ok","showapi_devicetype":301,"showapi_bindid":807712}
                  if (aReturn.showapi_res_code == 1) {
                      setState("0_userdata.0.cubinote.bindid", aReturn.showapi_bindid);
                      setState(aApiSettings.echodevice + ".Commands.speak", '50; Verbindung erfolgreich');
                      var verificationUrl = aApiSettings.url + aApiSettings.action.verifybind + aApiSettings.appid + aApiSettings.accesskey + sTimestamp + aApiSettings.deviceid;
                      verificationUrl += '&bindID=' + aReturn.showapi_bindid + '&verifyCode=CODE&enablePush=0';
                      //console.log(verificationUrl);
                  }
      
              }
          });
      });
      

      Script für Cubinote Status abfragen:
      0_userdata.0.cubinote.actionStates.read_cubinotestatus_state (einmal auf true setzen) hier wird der Status des Cubinotes abgefragt und eine Sprachausgabe erzeugt. (0-out of paper and overtemperature; 1-overtemperature; 2-out of paper; 3-normal)

      const moment = require('moment');
      var aApiSettings = {
          //Echo Gerät für Sprachausgabe
          'echodevice': 'YOUR ALEXA ECHO DEVICE',
          'url': getState("0_userdata.0.cubinote.apiurl").val,
          'action': {
              'print': 'printpaper',
              'devicestatus': 'getdeviceinfo',
              'printstatus': 'getprintstat',
              'requestbind': 'requestbind',
              'requestbindstatus': 'getbindrequeststatus'
          },
          'appid': '?appID=' + getState("0_userdata.0.cubinote.appid").val,
          'accesskey': '&ak=' + getState("0_userdata.0.cubinote.accesskey").val,
          'deviceid': '&deviceID=' + getState("0_userdata.0.cubinote.deviceid").val,
          'bindid': '&bindID=' + getState("0_userdata.0.cubinote.bindid").val,
          'userid': '&useridentifying' + getState("0_userdata.0.cubinote.userid").val,
          'liststates': {
              '0_userdata.0.cubinote.actionStates.print_shoppinglist_state': 'alexa2.0.Lists.SHOPPING_LIST.json',
              '0_userdata.0.cubinote.actionStates.print_todolist_state': 'alexa2.0.Lists.TO_DO.json'
          }
      }
      
      //check cubinote state
      on({ id: '0_userdata.0.cubinote.actionStates.read_cubinotestatus_state', val: true }, function (obj) {
          var value = obj.state.val;
          var oldValue = obj.oldState.val;
      
         var outputDevice = aApiSettings.echodevice;
          
          moment.locale('de');         // de
          var TimeStamp = moment().format('YYYY-MM-DD hh:mm:ss');
          var sTimestamp = '&timestamp=' + TimeStamp;
          var apiUrl = aApiSettings.url + aApiSettings.action.devicestatus + aApiSettings.appid + aApiSettings.accesskey + sTimestamp + aApiSettings.deviceid + aApiSettings.bindid;
      
          const request = require('request');
          request({ 'uri': apiUrl }, function (error, response, json) {
              if (!error && response.statusCode === 200) {
                  //{"showapi_res_code":1,"showapi_res_error":"ok","showapi_devicetype":601,"showapi_state":1,"showapi_isOnline":1 }
                 var aReturn = JSON.parse(json);
                 //console.log(aReturn);
                  if (aReturn.showapi_res_code == 1) {
                      // console.log(aReturn);
                      if (aReturn.showapi_isOnline == 1) {
                          //0-out of paper and overtemperature; 1-overtemperature; 2-out of paper; 3-normal
                          var msg = '';
                          if (aReturn.showapi_state == 1) {
                              msg = ' und überhitzt.';
                          }
                          if (aReturn.showapi_state == 2) {
                              msg = ' und hat kein Papier mehr.';
                          }
                          if (aReturn.showapi_state == 3) {
                              msg = ' und der Status ist normal.';
                          }
                          setState(outputDevice + ".Commands.speak", '50; Cubinot ist online'+msg);
                      }
                      if (aReturn.showapi_isOnline == 0) {
                          setState(outputDevice + ".Commands.speak", '50; Cubinot ist offline');
                      }
                  }
              }
          });
      
      
          setStateDelayed('0_userdata.0.cubinote.actionStates.read_cubinotestatus_state', false, 2000, false);
      });
      
      

      Hier nun das Script für Ausdruck der alexa shopping liste und todo liste:
      0_userdata.0.cubinote.actionStates.print_shoppinglist_state (Wert auf true setzen) druckt die Alexa Einkaufsliste
      0_userdata.0.cubinote.actionStates.print_todolist_state (Wert auf true setzen) druckt die Alexa Todoliste

      
      const moment = require('moment');
      const fs = require('fs');
      
      var aApiSettings = {
          //Echo Gerät für Sprachausgabe
          'echodevice': 'YOUR ECHO DEVICE',
          'url': getState("0_userdata.0.cubinote.apiurl").val,
          'action': {
              'print': 'printpaper',
              'devicestatus': 'getdeviceinfo',
              'printstatus': 'getprintstat',
              'requestbind': 'requestbind',
              'requestbindstatus': 'getbindrequeststatus'     
          },
          'appid': '?appID=' + getState("0_userdata.0.cubinote.appid").val,
          'accesskey': '&ak=' + getState("0_userdata.0.cubinote.accesskey").val,
          'deviceid': '&deviceID=' + getState("0_userdata.0.cubinote.deviceid").val,
          'bindid': '&bindID=' + getState("0_userdata.0.cubinote.bindid").val,
          'userid': '&useridentifying' + getState("0_userdata.0.cubinote.userid").val,
          'liststates': {
              '0_userdata.0.cubinote.actionStates.print_shoppinglist_state': 'alexa2.0.Lists.SHOPPING_LIST.json',
              '0_userdata.0.cubinote.actionStates.print_todolist_state': 'alexa2.0.Lists.TO_DO.json'
          }
      }
      
      /**Print States */
      for (const [state, list] of Object.entries(aApiSettings.liststates)) {
      
          on({ id: state, val: true }, function (obj) {
              var value = obj.state.val;
              var oldValue = obj.oldState.val;
      
              moment.locale('de');         // de
              var TimeStamp = moment().format('YYYY-MM-DD hh:mm:ss');
              var sTimestamp = '&timestamp=' + TimeStamp;
              var apiUrl = aApiSettings.url + aApiSettings.action.print + aApiSettings.appid + aApiSettings.accesskey + sTimestamp + aApiSettings.deviceid + aApiSettings.bindid;
              apiUrl += '&printcontent=T:';
      
      
              var aLists = JSON.parse(getState(list).val);
              var printList = '';
              var TimeStampList = moment().format('DD.MM.YYYY HH:mm');
              if(list == 'alexa2.0.Lists.SHOPPING_LIST.json'){
                  printList = 'Einkaufsliste '+TimeStampList+'\n\r';
                  printList += '================================\n\n\r';
              }
              if(list == 'alexa2.0.Lists.TO_DO.json'){
                  printList = 'TODO Liste '+TimeStampList+'\n\r';
                  printList += '================================\n\n\r';
              }
               printList += aLists.map(function (val) {
                  var item = val.value
                  item = item[0].toUpperCase() + item.substring(1);
                  return (val.completed ? '[X] ' : '[ ] ') + item;
              }).join('\n\n\r');
             
            //es sind keine Umlaute zulässig somit müssen diese ersetzt werden
              printList = printList.replace(/Ä/g, 'Ae');
              printList = printList.replace(/ä/g, 'ae');
              printList = printList.replace(/Ö/g, 'Oe');
              printList = printList.replace(/ö/g, 'oe');
              printList = printList.replace(/Ü/g, 'Ue');
              printList = printList.replace(/ü/g, 'ue');
              printList = printList.replace(/ß/g, 'ss');
      
              var base64 = new Buffer(printList).toString('base64');
      
              apiUrl += base64;
            
              //console.log(apiUrl);
              const request = require('request');
              request({ 'uri': apiUrl}, function (error, response, json) {
                  if (!error && response.statusCode === 200) {
      
                      var aReturn = JSON.parse(json);
                      //{"showapi_res_code":1,"showapi_res_error":"ok","result":2,"printcontentid":52476}
                      if (aReturn.result == 2) {
                          var statusUrl = aApiSettings.url + aApiSettings.action.printstatus + aApiSettings.appid + aApiSettings.accesskey + sTimestamp;
                          statusUrl += '&printcontentid=' + aReturn.printcontentid;
      
                          request({ 'uri': statusUrl }, function (err, resp, jsonStatus) {
                              //{"showapi_res_code":1,"showapi_res_error":"ok","printflag":1,"printcontentid":52476}
                              var outputDevice = aApiSettings.echodevice;
                              
                              setState(outputDevice + ".Commands.speak", '50; Drucken Liste erfolgreich');
          
                          });
      
                      }
      
                  }
              });
      
              setStateDelayed(state, false, 2000, false);
          });
      }
      
      

      Die actionstates wurden alle als switch definiert die sich nach 2 Sekunden wieder automatisch auf false setzen, ich habe diese so gewählt, da man dann in den Alexa Routinen einfacher Sprachbefehle definieren kann. Sprich jeder action state wurde so angelegt dass man mit alexa routinen einfach und schnell sprachbefehle erzeugen kann im Zusammenspiel mit iot.

      iot-cubinote.png

      Ich denke nun hast du alles dass du auch weiter damit experementieren kannst.
      Ich wünsche Dir viel Spaß.

      posted in Praktische Anwendungen (Showcase)
      Sebastian IO
      Sebastian IO
    • RE: jarvis v2.2.0 - just another remarkable vis

      Auslesen von Mitgliedern einer Alexa Musikgruppe und Abspeicherung in einen eigenen Datenpunkt zur Verwendung in jarvis

      // ID der Alexa Musikgruppe
      var idOfAlexaMusicGroup = 'YOUR ALEXA DEVICE ID OF MUSICGROUP';
      
      // Eigener definierter Datenpunkt als bsp 0_userdata.0.alexa.musicgroup.wohnzimmer.member
      //typ zeichenkette
      var idUserDataMember = 'YOUR DATAPOINT';
      
      /*NOTHING to change*/
      var membersMusicGroup = getState(idOfAlexaMusicGroup+".Info.multiroomMembers").val;
      var aMembers = membersMusicGroup.split(',');
      var iLengthMembers = aMembers.length;
      var sMembers = '';
      
      for(var i = 0; i < iLengthMembers; i++){
          if(sMembers === ''){
          sMembers += getState('alexa2.0.Echo-Devices.'+aMembers[i]+'.Info.name').val;
          }else{
              sMembers += ', '+getState('alexa2.0.Echo-Devices.'+aMembers[i]+'.Info.name').val;
          }
      }
      setState(idUserDataMember,sMembers);
      

      screen-member-musicgroup.png
      Kleines Script zum Samstagsausklang 🙂 !

      posted in Tester
      Sebastian IO
      Sebastian IO
    • RE: Test Coronavirus Statistics for ioBroker

      @sigi234 du musst nun deine Farben noch in den Einstellungen Css pro anpassen, ich verwende ja das helle Design und da ist die StandardFarbe schwarz:

      Diese Anweisung suchen:

      .co-overview{
      position: relative;
      width: 100% ;
      display: inline-block;
      box-sizing:border-box;
      color:#000;
      }
      
      posted in Tester
      Sebastian IO
      Sebastian IO

    Latest posts made by Sebastian IO

    • RE: Test Coronavirus Statistics for ioBroker

      @markus-2 korrekt!

      posted in Tester
      Sebastian IO
      Sebastian IO
    • RE: [Projekt] Integr. Cubinote - Alexa Sprache drucken - Listen

      @legoracer70 moin ich kann dir da leider auch nicht so richtig weiterhelfen, mein glück war dass ich noch ein altes smartphone hatte und damit mich mit dem cubinote im 2,4Ghz WLAN verbinden konnte. Der Rest wie man einen Reset macht, müsste ja irgendwo in der Beschreibung/Handbuch stehen. Aber ich kann mich auch erinnern dass es nicht so einfach war den cubinote mit ins wlan zubringen. Evtl. mal im Router schauen ob der Cubinote auftaucht, aber wie gesagt, das kann an vielem liegen.

      Sorry!

      posted in Praktische Anwendungen (Showcase)
      Sebastian IO
      Sebastian IO
    • RE: [Projekt] Integr. Cubinote - Alexa Sprache drucken - Listen

      @mcchickents Hast du alle scripte eingebunden? als bsp für die alexa listen nochmal:
      Wird ein Fehler im javascript Protokoll ausgeworfen?

      const moment = require('moment');
      const fs = require('fs');
       
      var aApiSettings = {
          //Echo Gerät für Sprachausgabe
          'echodevice': 'YOUR ECHO DEVICE',
          'url': getState("0_userdata.0.cubinote.apiurl").val,
          'action': {
      
              'print': 'printpaper',
              'devicestatus': 'getdeviceinfo',
              'printstatus': 'getprintstat',
              'requestbind': 'requestbind',
              'requestbindstatus': 'getbindrequeststatus'     
          },
      
          'appid': '?appID=' + getState("0_userdata.0.cubinote.appid").val,
          'accesskey': '&ak=' + getState("0_userdata.0.cubinote.accesskey").val,
          'deviceid': '&deviceID=' + getState("0_userdata.0.cubinote.deviceid").val,
          'bindid': '&bindID=' + getState("0_userdata.0.cubinote.bindid").val,
          'userid': '&useridentifying' + getState("0_userdata.0.cubinote.userid").val,
          'liststates': {
              '0_userdata.0.cubinote.actionStates.print_shoppinglist_state': 'alexa2.0.Lists.SHOPPING_LIST.json',
              '0_userdata.0.cubinote.actionStates.print_todolist_state': 'alexa2.0.Lists.TO_DO.json'
          }
      }
      
       
      
      /**Print States */
      
      for (const [state, list] of Object.entries(aApiSettings.liststates)) {
      
          on({ id: state, val: true }, function (obj) {
              var value = obj.state.val;
              var oldValue = obj.oldState.val;
              moment.locale('de');         // de
      
              var TimeStamp = moment().format('YYYY-MM-DD hh:mm:ss');
              var sTimestamp = '&timestamp=' + TimeStamp;
      
              var apiUrl = aApiSettings.url + aApiSettings.action.print + aApiSettings.appid + aApiSettings.accesskey + sTimestamp + aApiSettings.deviceid + aApiSettings.bindid;
      
              apiUrl += '&printcontent=T:';
      
              var aLists = JSON.parse(getState(list).val);
              var printList = '';
              var TimeStampList = moment().format('DD.MM.YYYY HH:mm');
      
              if(list == 'alexa2.0.Lists.SHOPPING_LIST.json'){
                  printList = 'Einkaufsliste '+TimeStampList+'\n\r';
                  printList += '================================\n\n\r';
              }
      
              if(list == 'alexa2.0.Lists.TO_DO.json'){
                  printList = 'TODO Liste '+TimeStampList+'\n\r';
                  printList += '================================\n\n\r';
              }
      
               printList += aLists.map(function (val) {
                  var item = val.value
                  item = item[0].toUpperCase() + item.substring(1);
                  return (val.completed ? '[X] ' : '[ ] ') + item;
              }).join('\n\n\r');
          
      
            //es sind keine Umlaute zulässig somit müssen diese ersetzt werden
      
              printList = printList.replace(/Ä/g, 'Ae');
              printList = printList.replace(/ä/g, 'ae');
              printList = printList.replace(/Ö/g, 'Oe');
              printList = printList.replace(/ö/g, 'oe');
              printList = printList.replace(/Ü/g, 'Ue');
              printList = printList.replace(/ü/g, 'ue');
              printList = printList.replace(/ß/g, 'ss');
       
              var base64 = new Buffer(printList).toString('base64');
              apiUrl += base64;
      
              //console.log(apiUrl);
      
              const request = require('request');
              request({ 'uri': apiUrl}, function (error, response, json) {
                  if (!error && response.statusCode === 200) {
                      var aReturn = JSON.parse(json);
                      //{"showapi_res_code":1,"showapi_res_error":"ok","result":2,"printcontentid":52476}
      
                      if (aReturn.result == 2) {
                          var statusUrl = aApiSettings.url + aApiSettings.action.printstatus + aApiSettings.appid + aApiSettings.accesskey + sTimestamp;
      
                          statusUrl += '&printcontentid=' + aReturn.printcontentid;
      
                          request({ 'uri': statusUrl }, function (err, resp, jsonStatus) {
                              //{"showapi_res_code":1,"showapi_res_error":"ok","printflag":1,"printcontentid":52476}
                              var outputDevice = aApiSettings.echodevice;
                              setState(outputDevice + ".Commands.speak", '50; Drucken Liste erfolgreich');    
                          }); 
      
                      } 
      
                  }
      
              }); 
              setStateDelayed(state, false, 2000, false);
          });
      }
       
      
      
      posted in Praktische Anwendungen (Showcase)
      Sebastian IO
      Sebastian IO
    • RE: [Projekt] Integr. Cubinote - Alexa Sprache drucken - Listen

      @mcchickents und im javascript protokoll steht auch nichts? eventuell den javascript adapter neustarten! Werden die obengenannten actionStates wieder automatisch auf false gesetzt? Es kann prinzipiell nur eine Kleinigkeit sein!

      posted in Praktische Anwendungen (Showcase)
      Sebastian IO
      Sebastian IO
    • RE: [Projekt] Integr. Cubinote - Alexa Sprache drucken - Listen

      @mcchickents druckt cubinote deine Shoppingliste oder deine Todoliste aus? sprich über:
      0_userdata.0.cubinote.actionStates.print_shoppinglist_state auf true oder
      0_userdata.0.cubinote.actionStates.print_todolist_state auf true ?

      posted in Praktische Anwendungen (Showcase)
      Sebastian IO
      Sebastian IO
    • RE: [Projekt] Integr. Cubinote - Alexa Sprache drucken - Listen

      @mcchickents ich habe das jetzt auch mal direkt in der url eingegeben und als rückgabe im Browser bekomme ich als json format folgende Ausgabe:

      showapi_res_code	1
      showapi_res_error	"ok"
      showapi_devicetype	602
      showapi_bindid	807927
      

      Und der Drucker printet:
      App name: iobroker-cubinote
      Developer: sebastian_io
      Verification-Code: .....

      Bei dir müsste also dein App Name, Developer etc drin stehen und wenn du das über iobroker machst und den Datenpunkt 0_userdata.0.cubinote.actionStates.check_binding_state auf true setzt, dann sollte eine Sprachausgabe über deine ausgewählte alexa kommen, aber ohne Ausdruck!

      posted in Praktische Anwendungen (Showcase)
      Sebastian IO
      Sebastian IO
    • RE: [Projekt] Integr. Cubinote - Alexa Sprache drucken - Listen

      @mcchickents ich glaube es liegt an deiner userid, das wording ist verwirrend aber da muss der username eingetragen sein!

      Den Usernamen findest du in deiner app im Profil, direkt unter deinem Bild!

      posted in Praktische Anwendungen (Showcase)
      Sebastian IO
      Sebastian IO
    • RE: [Projekt] Integr. Cubinote - Alexa Sprache drucken - Listen

      @mcchickents hast du alle scripte von mir eingebunden? Sind alle Datenpunkte vorhanden? Kannst du den Status des cubinotes abfragen oder drucken?

      Deine appid darf max 3 oder 4-stellig sein, deine deviceid sollte aus buchstaben und zahlen bestehen und ungefähr 16 Zeichen lang sein und deine userid sollte dein Benutzername sein!

      posted in Praktische Anwendungen (Showcase)
      Sebastian IO
      Sebastian IO
    • RE: [Projekt] Integr. Cubinote - Alexa Sprache drucken - Listen

      @agria4800 danke für den coolen Tip,
      hab es jetzt für mich angepasst sodass es mit dem DP 0_userdata.0.cubinote.Notizen.notizenText zusammenarbeitet,
      hier ist ja auch schon das parsing für umlaute integriert und setzt den Text automatisch zurück!

      on({id: "alexa2.0.History.answerText", change: "ne"}, async function (obj) {
      
      
       if (getState("alexa2.0.History.summary").val.indexOf('sprich mir nach') !== -1 && getState("alexa2.0.History.answerText").val.indexOf('Wenn ich etwas nachsprechen') === -1 ) {
      
          setStateDelayed('0_userdata.0.cubinote.Notizen.notizenText', getState("alexa2.0.History.answerText").val, 1000, false);
         }
      
      });
      
      posted in Praktische Anwendungen (Showcase)
      Sebastian IO
      Sebastian IO
    • RE: [Projekt] Integr. Cubinote - Alexa Sprache drucken - Listen

      @mcchickents kann es sein dass du die normale installation für den cubinote noch nicht gemacht hast, soviel ich mich erinnere musste doch dieser Verification Code bei der Erstinstallation angegeben werden, sprich Aufnahme ins Wlan und in die Handy App?

      posted in Praktische Anwendungen (Showcase)
      Sebastian IO
      Sebastian IO
    Community
    Impressum | Datenschutz-Bestimmungen | Nutzungsbedingungen
    The ioBroker Community 2014-2023
    logo