Weiter zum Inhalt
  • Home
  • Aktuell
  • 0 Ungelesen 0
  • Kategorien
  • Unreplied
  • Beliebt
  • GitHub
  • Docu
  • Hilfe
Skins
  • Hell
  • Brite
  • Cerulean
  • Cosmo
  • Flatly
  • Journal
  • Litera
  • Lumen
  • Lux
  • Materia
  • Minty
  • Morph
  • Pulse
  • Sandstone
  • Simplex
  • Sketchy
  • Spacelab
  • United
  • Yeti
  • Zephyr
  • Dunkel
  • Cyborg
  • Darkly
  • Quartz
  • Slate
  • Solar
  • Superhero
  • Vapor

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

Community Forum

donate donate
  1. ioBroker Community Home
  2. Deutsch
  3. Visualisierung
  4. Handball Spielplan per Javascript Widget

NEWS

  • Der neue Monatsrückblick für September 2026 ist online!
    BluefoxB
    Bluefox
    8
    1
    300

  • Neu im Blog: Was die neue Website alles kann
    BluefoxB
    Bluefox
    7
    1
    255

  • Node.js 24 ist jetzt offiziell empfohlen!
    apollon77A
    apollon77
    9
    1
    524

Handball Spielplan per Javascript Widget

Geplant Angeheftet Gesperrt Verschoben Visualisierung
9 Beiträge 4 Kommentatoren 245 Aufrufe 4 Beobachtet
  • Älteste zuerst
  • Neuste zuerst
  • Meiste Stimmen
Antworten
  • In einem neuen Thema antworten
Anmelden zum Antworten
Dieses Thema wurde gelöscht. Nur Nutzer mit entsprechenden Rechten können es sehen.
  • D
    D
    Dominic151617
    schrieb am zuletzt editiert von
    #1

    Hallo zusammen,

    ich versuche grad den Handball Spielplan von meinem Sohn in unsere Lovelace Visualisierung einzubinden. Grundsätzlich ist das bei Handball.net auch vorgesehen. Man kann (wenn man es verstehen würde😉) ein Widget in eine Webseite einbinden Beispiel Anleitung.
    Anleitung:

    1. Füge den Code zum Laden des Widget-Javascripts in die Seite ein. Dieser Code lädt asynchron im Hintergrund, ohne die restliche Seite zu blockieren. Er muss nur einmal pro Seite eingefügt werden, auch wenn mehrere Widgets angezeigt werden.
    <script>
    (function(e,t,n,r,i,s,o){e[i]=e[i]||function(){(e[i].q=e[i].q||[]).push(arguments)}, e[i].l=1*new Date;s=t.createElement(n),o=t.getElementsByTagName(n)[0];s.async=1; s.src=r;o.parentNode.insertBefore(s,o)})(window,document,"script", 'https://www.handball.net/widgets/embed/v1.js',"_hb");
    </script>
    
    1. Füge den HTML-Container in Deiner Seite dort ein, wo das Widget erscheinen soll.
    <div id='handball-spielplan'></div>
    
    1. Füge den Code zum Einbetten Deines Widgets in die Seite ein.
    <script>
          _hb({
          widget: 'spielplan',
          teamId: 'handball4all.schleswig-holstein.1397781',
          container: 'handball-spielplan'
        })
        </script>
    


    Dummerweise habe ich mal so gar keine Ahnung von Webseiten. Die Vorschläge der Chatbots laufen darauf hinaus, die Elemente zusammen in eine HTML Datei zu packen, diese unter vis abzulegen und das als i-Frame oder Markdown einzubinden. Ich habe auch noch mal versucht, den kombinerten HTML Code als String unter Alias abzulegen und diesen für Lovelace "freizugeben". Leider alles ohne Erfolg. Hat jemand ne idee?
    HTML Datei:

    <!DOCTYPE html>
    <html>
      <head>
        <meta charset="UTF-8" />
        <script>
          (function(e,t,n,r,i,s,o){
            e[i]=e[i]||function(){(e[i].q=e[i].q||[]).push(arguments)},
            e[i].l=1*new Date;
            s=t.createElement(n),o=t.getElementsByTagName(n)[0];
            s.async=1; s.src=r;
            o.parentNode.insertBefore(s,o)
          })(window,document,"script",
          "https://www.handball.net/widgets/embed/v1.js","_hb");
        </script>
      </head>
    
      <body>
        <div id="handball-spielplan"></div>
    
        <script>
          _hb({
            widget: "spielplan",
            teamId: "handball4all.schleswig-holstein.1397781",
            container: "handball-spielplan"
          });
        </script>
      </body>
    </html>
    

    1 Antwort Letzte Antwort
    0
    • T
      T
      Tschulte
      schrieb am zuletzt editiert von
      #2

      dieser weg klappt wohl nicht mehr, was aber mittlerweile geht Daten über https://www.handball.net/api
      /new/search
      /api/new/team/*
      /api/new/match/*
      /api/new/competition/*
      /api/new/club/*
      /api/new/standings/*
      /api/new/results/*
      /api/new/calendar/*

      OliverIOO 1 Antwort Letzte Antwort
      0
      • T Tschulte

        dieser weg klappt wohl nicht mehr, was aber mittlerweile geht Daten über https://www.handball.net/api
        /new/search
        /api/new/team/*
        /api/new/match/*
        /api/new/competition/*
        /api/new/club/*
        /api/new/standings/*
        /api/new/results/*
        /api/new/calendar/*

        OliverIOO
        OliverIOO
        OliverIO
        schrieb am zuletzt editiert von
        #3

        @Tschulte

        so wie es aussieht stehen die widgets nach dem neu launch der seite nicht zur verfügung. auch zugriff auf die api gibt es nur auf Nachfrage
        https://www.handball.net/news/10827/das-neue-handball-net-funktionen-spieldaten-und-aktuelle-einschrankungen

        Meine Adapter und Widgets
        TVProgram, SqueezeboxRPC, OpenLiga, RSSFeed, MyTime,, pi-hole2, vis-json-template, skiinfo, vis-mapwidgets, vis-2-widgets-rssfeed
        Links im Profil

        1 Antwort Letzte Antwort
        0
        • T
          T
          Tschulte
          schrieb am zuletzt editiert von Tschulte
          #4

          ich frage mich, welche api sie zugriff gewähren würden, denn die daten sind ja alle einsehbar über zum Beispiel
          https://www.handball.net/api/new/teams/clubs/******* Ich habe sie mal angeschrieben und danach gefragt :)

          OliverIOO 1 Antwort Letzte Antwort
          0
          • T Tschulte

            ich frage mich, welche api sie zugriff gewähren würden, denn die daten sind ja alle einsehbar über zum Beispiel
            https://www.handball.net/api/new/teams/clubs/******* Ich habe sie mal angeschrieben und danach gefragt :)

            OliverIOO
            OliverIOO
            OliverIO
            schrieb am zuletzt editiert von OliverIO
            #5

            @Tschulte

            Im link haben die geschrieben, das die Daten von handball360 kommen. Das ist wohl die Platform vom Dhb, der schreibt in faq das der Zugriff nur auf Nachfrage gewährt wird.

            Hat man da kostenlosen Zugriff wenn man sich anmeldet?
            Dann könnte ich mal schauen.

            Meine Adapter und Widgets
            TVProgram, SqueezeboxRPC, OpenLiga, RSSFeed, MyTime,, pi-hole2, vis-json-template, skiinfo, vis-mapwidgets, vis-2-widgets-rssfeed
            Links im Profil

            B 1 Antwort Letzte Antwort
            0
            • T
              T
              Tschulte
              schrieb am zuletzt editiert von
              #6

              man muss sich nicht anmelden. Schau mal im browser F12 über https://www.handball.net/club/1p6o5xs Abfrage geht dann nach https://www.handball.net/api/new/teams?federation_id=161&club_id=1p6o5xs&per_page=8&page=1&has_roster=1&season_id=2627

              1 Antwort Letzte Antwort
              0
              • OliverIOO OliverIO

                @Tschulte

                Im link haben die geschrieben, das die Daten von handball360 kommen. Das ist wohl die Platform vom Dhb, der schreibt in faq das der Zugriff nur auf Nachfrage gewährt wird.

                Hat man da kostenlosen Zugriff wenn man sich anmeldet?
                Dann könnte ich mal schauen.

                B
                B
                bommel_030
                schrieb am zuletzt editiert von
                #7

                @OliverIO
                Afaik, braucht man sich nicht anmelden.
                Das Problem wird sein, dass nicht alle Verbände mit Hanball360 arbeiten. Der Brandenburger Verband wird da erst nächste Saison (so Gott will...) dabei sein.
                Ich sehe auch im eingeloggten Zustand nicht mehr

                1 Antwort Letzte Antwort
                0
                • OliverIOO
                  OliverIOO
                  OliverIO
                  schrieb am zuletzt editiert von
                  #8

                  so hier das ergebnis. Ich habe mal den Verein 1.FC Köln genommen, da dort mehr Daten waren

                  1. Im javascript Adapter folgendes Skript erstellen

                  /*
                  * ============================================================
                  * KONFIGURATION
                  * ============================================================
                  */
                  
                  /*
                  * handball.net Vereins-ID
                  *
                  * Beispiel:
                  * https://www.handball.net/club/1rz94gz
                  */
                  const clubId = '1rz94gz';
                  
                  /*
                  * Anzahl der Tage ab heute
                  */
                  const days = 30;
                  
                  /*
                  * Anzahl Spiele pro API-Seite
                  */
                  const perPage = 50;
                  
                  /*
                  * Ziel-Datenpunkt für das fertige HTML
                  */
                  const stateId = '0_userdata.0.handball.clubScheduleHtml';
                  
                  /*
                  * Täglicher Abruf als Cron-Schedule
                  *
                  * 0 3 * * * = täglich um 03:00 Uhr
                  */
                  const cronSchedule = '0 3 * * *';
                  
                  /*
                  * Farbschema:
                  *
                  * 'dark'
                  * 'light'
                  */
                  const theme = 'dark';
                  
                  /*
                  * Akzentfarbe
                  */
                  const accentColor = '#ff5a00';
                  
                  /*
                  * Vereins- und Mannschaftslogos anzeigen
                  */
                  const showLogos = true;
                  
                  /*
                  * Spielhalle anzeigen
                  */
                  const showVenue = true;
                  
                  /*
                  * Wettbewerb / Liga anzeigen
                  */
                  const showCompetition = true;
                  
                  /*
                  * Verband anzeigen
                  */
                  const showFederation = true;
                  
                  /*
                  * Zeitpunkt der letzten Aktualisierung anzeigen
                  */
                  const showLastUpdate = true;
                  
                  
                  /*
                  * ============================================================
                  * AB HIER KEINE KONFIGURATION MEHR ERFORDERLICH
                  * ============================================================
                  */
                  
                  
                  /*
                  * Datenpunkt anlegen
                  */
                  createState(
                     stateId,
                     '',
                     {
                         name: 'handball.net Vereinsspielplan HTML',
                         type: 'string',
                         role: 'html',
                         read: true,
                         write: false
                     }
                  );
                  
                  
                  /*
                  * ============================================================
                  * HILFSFUNKTIONEN
                  * ============================================================
                  */
                  
                  function pad(value)
                  {
                     return String(value).padStart(
                         2,
                         '0'
                     );
                  }
                  
                  
                  function formatApiDate(date)
                  {
                     return date.getFullYear() +
                         '-' +
                         pad(
                             date.getMonth() + 1
                         ) +
                         '-' +
                         pad(
                             date.getDate()
                         );
                  }
                  
                  
                  function getDateRange()
                  {
                     const from = new Date();
                  
                     from.setHours(
                         0,
                         0,
                         0,
                         0
                     );
                  
                     const to = new Date(from);
                  
                     to.setDate(
                         to.getDate() + days
                     );
                  
                     const result = {};
                  
                     result.from =
                         formatApiDate(from);
                  
                     result.to =
                         formatApiDate(to);
                  
                     return result;
                  }
                  
                  
                  function formatGameDate(value)
                  {
                     const date =
                         new Date(value);
                  
                     if (Number.isNaN(date.getTime()))
                     {
                         return '';
                     }
                  
                     return date.toLocaleDateString(
                         'de-DE',
                         {
                             weekday: 'long',
                             day: '2-digit',
                             month: '2-digit',
                             year: 'numeric'
                         }
                     );
                  }
                  
                  
                  function formatGameTime(value)
                  {
                     const date =
                         new Date(value);
                  
                     if (Number.isNaN(date.getTime()))
                     {
                         return '';
                     }
                  
                     return date.toLocaleTimeString(
                         'de-DE',
                         {
                             hour: '2-digit',
                             minute: '2-digit'
                         }
                     );
                  }
                  
                  
                  function getDateKey(value)
                  {
                     const date =
                         new Date(value);
                  
                     if (Number.isNaN(date.getTime()))
                     {
                         return '';
                     }
                  
                     return formatApiDate(date);
                  }
                  
                  
                  function escapeHtml(value)
                  {
                     if (
                         value === null ||
                         value === undefined
                     )
                     {
                         return '';
                     }
                  
                     return String(value)
                         .replaceAll('&', '&amp;')
                         .replaceAll('<', '&lt;')
                         .replaceAll('>', '&gt;')
                         .replaceAll('"', '&quot;')
                         .replaceAll("'", '&#039;');
                  }
                  
                  
                  function getApiUrl(page)
                  {
                     const range =
                         getDateRange();
                  
                     let url =
                         'https://www.handball.net/api/new/matches';
                  
                     url +=
                         '?club_id=' +
                         encodeURIComponent(clubId);
                  
                     url +=
                         '&per_page=' +
                         encodeURIComponent(
                             String(perPage)
                         );
                  
                     url +=
                         '&page=' +
                         encodeURIComponent(
                             String(page)
                         );
                  
                     url +=
                         '&date_from=' +
                         encodeURIComponent(
                             range.from
                         );
                  
                     url +=
                         '&date_to=' +
                         encodeURIComponent(
                             range.to
                         );
                  
                     return url;
                  }
                  
                  
                  function getClubUrl()
                  {
                     return 'https://www.handball.net/club/' +
                         encodeURIComponent(clubId);
                  }
                  
                  
                  function getMatchUrl(match)
                  {
                     /*
                      * Die API liefert keine explizite öffentliche Match-URL.
                      * Deshalb wird derzeit auf die Vereinsseite verlinkt.
                      *
                      * Sobald das Match-URL-Schema feststeht, muss nur diese
                      * Funktion angepasst werden.
                      */
                  
                     if (!match)
                     {
                         return getClubUrl();
                     }
                  
                     return getClubUrl();
                  }
                  
                  
                  function isOwnTeam(team)
                  {
                     if (!team)
                     {
                         return false;
                     }
                  
                     if (!team.club)
                     {
                         return false;
                     }
                  
                     return team.club.id === clubId;
                  }
                  
                  
                  function getClubFromMatches(matches)
                  {
                     for (const match of matches)
                     {
                         if (
                             match.local &&
                             match.local.club &&
                             match.local.club.id === clubId
                         )
                         {
                             return match.local.club;
                         }
                  
                         if (
                             match.visitor &&
                             match.visitor.club &&
                             match.visitor.club.id === clubId
                         )
                         {
                             return match.visitor.club;
                         }
                     }
                  
                     return null;
                  }
                  
                  
                  function hasVisibleResult(match)
                  {
                     if (!match)
                     {
                         return false;
                     }
                  
                     if (!match.result)
                     {
                         return false;
                     }
                  
                     if (
                         match.result.local === null ||
                         match.result.local === undefined
                     )
                     {
                         return false;
                     }
                  
                     if (
                         match.result.visitor === null ||
                         match.result.visitor === undefined
                     )
                     {
                         return false;
                     }
                  
                     if (!match.status)
                     {
                         return false;
                     }
                  
                     if (match.status.is_live === true)
                     {
                         return true;
                     }
                  
                     if (match.status.is_finished === true)
                     {
                         return true;
                     }
                  
                     return false;
                  }
                  
                  
                  /*
                  * ============================================================
                  * API-ABRUF
                  * ============================================================
                  */
                  
                  async function fetchPage(page)
                  {
                     const url =
                         getApiUrl(page);
                  
                     log(
                         'handball.net API: ' + url,
                         'debug'
                     );
                  
                     const response =
                         await httpGetAsync(url);
                  
                     if (!response)
                     {
                         throw new Error(
                             'Keine Antwort von handball.net'
                         );
                     }
                  
                     if (response.statusCode !== 200)
                     {
                         throw new Error(
                             'HTTP ' +
                             response.statusCode
                         );
                     }
                  
                     let json;
                  
                     try
                     {
                         json =
                             JSON.parse(
                                 response.data
                             );
                     }
                     catch (error)
                     {
                         throw new Error(
                             'Ungültige JSON-Antwort von handball.net: ' +
                             error.message
                         );
                     }
                  
                     if (!json)
                     {
                         throw new Error(
                             'Leere Antwort von handball.net'
                         );
                     }
                  
                     if (json.success !== true)
                     {
                         throw new Error(
                             'handball.net meldet success != true'
                         );
                     }
                  
                     if (!Array.isArray(json.data))
                     {
                         throw new Error(
                             'handball.net liefert kein data-Array'
                         );
                     }
                  
                     return json;
                  }
                  
                  
                  function httpGetAsync(url)
                  {
                     return new Promise(
                         function (resolve, reject)
                         {
                             const options =
                             {
                                 method: 'GET',
                                 headers:
                                 {
                                     'Accept': 'application/json, text/plain, */*',
                                     'Accept-Language': 'de-DE,de;q=0.9,en;q=0.8',
                                     'Referer': 'https://www.handball.net/',
                                     'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 Chrome/154.0.0.0 Safari/537.36'
                                 }
                             };
                  
                             httpGet(
                                 url,
                                 options,
                                 function (error, response)
                                 {
                                     if (error)
                                     {
                                         reject(error);
                  
                                         return;
                                     }
                  
                                     resolve(response);
                                 }
                             );
                         }
                     );
                  }
                  
                  
                  async function fetchAllMatches()
                  {
                     const firstPage =
                         await fetchPage(1);
                  
                     let matches =
                         firstPage.data.slice();
                  
                     let lastPage = 1;
                  
                     if (
                         firstPage.pagination &&
                         Number(
                             firstPage.pagination.last_page
                         ) > 1
                     )
                     {
                         lastPage =
                             Number(
                                 firstPage.pagination.last_page
                             );
                     }
                  
                     log(
                         'handball.net: ' +
                         matches.length +
                         ' Spiele auf Seite 1, ' +
                         lastPage +
                         ' Seite(n) insgesamt',
                         'debug'
                     );
                  
                     let page = 2;
                  
                     while (page <= lastPage)
                     {
                         const pageData =
                             await fetchPage(page);
                  
                         matches =
                             matches.concat(
                                 pageData.data
                             );
                  
                         page++;
                     }
                  
                     /*
                      * Doppelte Spiele anhand der Match-ID entfernen
                      */
                     const result = [];
                  
                     const ids =
                         new Set();
                  
                     for (const match of matches)
                     {
                         if (!match)
                         {
                             continue;
                         }
                  
                         if (
                             match.id === null ||
                             match.id === undefined
                         )
                         {
                             result.push(match);
                  
                             continue;
                         }
                  
                         const id =
                             String(match.id);
                  
                         if (ids.has(id))
                         {
                             continue;
                         }
                  
                         ids.add(id);
                  
                         result.push(match);
                     }
                  
                     /*
                      * Chronologisch sortieren
                      */
                     result.sort(
                         function (a, b)
                         {
                             const timeA =
                                 new Date(a.date).getTime();
                  
                             const timeB =
                                 new Date(b.date).getTime();
                  
                             return timeA - timeB;
                         }
                     );
                  
                     return result;
                  }
                  
                  
                  /*
                  * ============================================================
                  * CSS ERZEUGEN
                  * ============================================================
                  */
                  
                  function createCss()
                  {
                     let background = '#151515';
                     let card = '#222222';
                     let cardHover = '#292929';
                     let text = '#f5f5f5';
                     let muted = '#aaaaaa';
                     let border = '#3a3a3a';
                     let soft = '#303030';
                  
                     if (theme === 'light')
                     {
                         background = '#f3f3f3';
                         card = '#ffffff';
                         cardHover = '#fafafa';
                         text = '#181818';
                         muted = '#707070';
                         border = '#dddddd';
                         soft = '#eeeeee';
                     }
                  
                     let css = '';
                  
                     css += '<style>\n';
                  
                     css += '.hb-schedule\n';
                     css += '{\n';
                     css += 'width:100%;\n';
                     css += 'box-sizing:border-box;\n';
                     css += 'padding:14px;\n';
                     css += 'background:' + background + ';\n';
                     css += 'color:' + text + ';\n';
                     css += 'font-family:Arial,Helvetica,sans-serif;\n';
                     css += '}\n';
                  
                     css += '.hb-schedule *\n';
                     css += '{\n';
                     css += 'box-sizing:border-box;\n';
                     css += '}\n';
                  
                     css += '.hb-header\n';
                     css += '{\n';
                     css += 'margin-bottom:15px;\n';
                     css += 'background:' + card + ';\n';
                     css += 'border:1px solid ' + border + ';\n';
                     css += 'border-radius:8px;\n';
                     css += 'overflow:hidden;\n';
                     css += '}\n';
                  
                     css += '.hb-header-accent\n';
                     css += '{\n';
                     css += 'height:5px;\n';
                     css += 'background:' + accentColor + ';\n';
                     css += '}\n';
                  
                     css += '.hb-header-content\n';
                     css += '{\n';
                     css += 'display:flex;\n';
                     css += 'align-items:center;\n';
                     css += 'justify-content:space-between;\n';
                     css += 'gap:12px;\n';
                     css += 'padding:14px 16px;\n';
                     css += '}\n';
                  
                     css += '.hb-club\n';
                     css += '{\n';
                     css += 'display:flex;\n';
                     css += 'align-items:center;\n';
                     css += 'gap:12px;\n';
                     css += 'min-width:0;\n';
                     css += '}\n';
                  
                     css += '.hb-club-logo\n';
                     css += '{\n';
                     css += 'width:52px;\n';
                     css += 'height:52px;\n';
                     css += 'object-fit:contain;\n';
                     css += 'flex:0 0 52px;\n';
                     css += '}\n';
                  
                     css += '.hb-title\n';
                     css += '{\n';
                     css += 'font-size:20px;\n';
                     css += 'font-weight:800;\n';
                     css += 'line-height:1.15;\n';
                     css += 'text-transform:uppercase;\n';
                     css += '}\n';
                  
                     css += '.hb-club-name\n';
                     css += '{\n';
                     css += 'margin-top:4px;\n';
                     css += 'color:' + accentColor + ';\n';
                     css += 'font-size:14px;\n';
                     css += 'font-weight:700;\n';
                     css += '}\n';
                  
                     css += '.hb-range\n';
                     css += '{\n';
                     css += 'flex:0 0 auto;\n';
                     css += 'padding:6px 9px;\n';
                     css += 'background:' + soft + ';\n';
                     css += 'color:' + muted + ';\n';
                     css += 'border-radius:4px;\n';
                     css += 'font-size:11px;\n';
                     css += 'font-weight:700;\n';
                     css += 'white-space:nowrap;\n';
                     css += '}\n';
                  
                     css += '.hb-date\n';
                     css += '{\n';
                     css += 'margin:17px 3px 7px 3px;\n';
                     css += 'color:' + muted + ';\n';
                     css += 'font-size:11px;\n';
                     css += 'font-weight:800;\n';
                     css += 'text-transform:uppercase;\n';
                     css += 'letter-spacing:0.5px;\n';
                     css += '}\n';
                  
                     css += '.hb-game\n';
                     css += '{\n';
                     css += 'display:block;\n';
                     css += 'margin-bottom:8px;\n';
                     css += 'padding:12px 14px;\n';
                     css += 'background:' + card + ';\n';
                     css += 'color:' + text + ';\n';
                     css += 'border:1px solid ' + border + ';\n';
                     css += 'border-left:4px solid ' + accentColor + ';\n';
                     css += 'border-radius:6px;\n';
                     css += 'text-decoration:none;\n';
                     css += '}\n';
                  
                     css += '.hb-game:hover\n';
                     css += '{\n';
                     css += 'background:' + cardHover + ';\n';
                     css += '}\n';
                  
                     css += '.hb-game-live\n';
                     css += '{\n';
                     css += 'border-left-color:#1abc9c;\n';
                     css += '}\n';
                  
                     css += '.hb-game-top\n';
                     css += '{\n';
                     css += 'display:flex;\n';
                     css += 'align-items:center;\n';
                     css += 'justify-content:space-between;\n';
                     css += 'gap:10px;\n';
                     css += 'margin-bottom:10px;\n';
                     css += '}\n';
                  
                     css += '.hb-competition\n';
                     css += '{\n';
                     css += 'min-width:0;\n';
                     css += 'overflow:hidden;\n';
                     css += 'color:' + muted + ';\n';
                     css += 'font-size:11px;\n';
                     css += 'font-weight:700;\n';
                     css += 'white-space:nowrap;\n';
                     css += 'text-overflow:ellipsis;\n';
                     css += '}\n';
                  
                     css += '.hb-live\n';
                     css += '{\n';
                     css += 'padding:3px 6px;\n';
                     css += 'background:#1abc9c;\n';
                     css += 'color:#ffffff;\n';
                     css += 'border-radius:3px;\n';
                     css += 'font-size:9px;\n';
                     css += 'font-weight:800;\n';
                     css += '}\n';
                  
                     css += '.hb-teams\n';
                     css += '{\n';
                     css += 'display:grid;\n';
                     css += 'grid-template-columns:minmax(0,1fr) 72px minmax(0,1fr);\n';
                     css += 'align-items:center;\n';
                     css += 'gap:10px;\n';
                     css += '}\n';
                  
                     css += '.hb-team\n';
                     css += '{\n';
                     css += 'display:flex;\n';
                     css += 'align-items:center;\n';
                     css += 'min-width:0;\n';
                     css += 'gap:8px;\n';
                     css += 'font-size:13px;\n';
                     css += 'font-weight:700;\n';
                     css += '}\n';
                  
                     css += '.hb-home\n';
                     css += '{\n';
                     css += 'justify-content:flex-end;\n';
                     css += 'text-align:right;\n';
                     css += '}\n';
                  
                     css += '.hb-away\n';
                     css += '{\n';
                     css += 'justify-content:flex-start;\n';
                     css += 'text-align:left;\n';
                     css += '}\n';
                  
                     css += '.hb-team-name\n';
                     css += '{\n';
                     css += 'min-width:0;\n';
                     css += 'overflow:hidden;\n';
                     css += 'white-space:nowrap;\n';
                     css += 'text-overflow:ellipsis;\n';
                     css += '}\n';
                  
                     css += '.hb-own-team\n';
                     css += '{\n';
                     css += 'color:' + accentColor + ';\n';
                     css += 'font-weight:800;\n';
                     css += '}\n';
                  
                     css += '.hb-team-logo\n';
                     css += '{\n';
                     css += 'width:32px;\n';
                     css += 'height:32px;\n';
                     css += 'object-fit:contain;\n';
                     css += 'flex:0 0 32px;\n';
                     css += '}\n';
                  
                     css += '.hb-center\n';
                     css += '{\n';
                     css += 'text-align:center;\n';
                     css += '}\n';
                  
                     css += '.hb-time\n';
                     css += '{\n';
                     css += 'color:' + accentColor + ';\n';
                     css += 'font-size:15px;\n';
                     css += 'font-weight:800;\n';
                     css += 'white-space:nowrap;\n';
                     css += '}\n';
                  
                     css += '.hb-score\n';
                     css += '{\n';
                     css += 'padding:5px 6px;\n';
                     css += 'background:' + soft + ';\n';
                     css += 'border-radius:4px;\n';
                     css += 'font-size:18px;\n';
                     css += 'font-weight:800;\n';
                     css += 'white-space:nowrap;\n';
                     css += '}\n';
                  
                     css += '.hb-meta\n';
                     css += '{\n';
                     css += 'display:flex;\n';
                     css += 'justify-content:space-between;\n';
                     css += 'gap:10px;\n';
                     css += 'margin-top:10px;\n';
                     css += 'padding-top:8px;\n';
                     css += 'border-top:1px solid ' + border + ';\n';
                     css += 'color:' + muted + ';\n';
                     css += 'font-size:10px;\n';
                     css += '}\n';
                  
                     css += '.hb-footer\n';
                     css += '{\n';
                     css += 'display:flex;\n';
                     css += 'justify-content:space-between;\n';
                     css += 'gap:10px;\n';
                     css += 'margin-top:12px;\n';
                     css += 'color:' + muted + ';\n';
                     css += 'font-size:9px;\n';
                     css += '}\n';
                  
                     css += '.hb-footer a\n';
                     css += '{\n';
                     css += 'color:' + accentColor + ';\n';
                     css += 'text-decoration:none;\n';
                     css += 'font-weight:700;\n';
                     css += '}\n';
                  
                     css += '.hb-empty\n';
                     css += '{\n';
                     css += 'padding:25px;\n';
                     css += 'background:' + card + ';\n';
                     css += 'border:1px solid ' + border + ';\n';
                     css += 'border-radius:6px;\n';
                     css += 'color:' + muted + ';\n';
                     css += 'text-align:center;\n';
                     css += '}\n';
                  
                     css += '</style>\n';
                  
                     return css;
                  }
                  
                  
                  /*
                  * ============================================================
                  * HTML-BAUSTEINE
                  * ============================================================
                  */
                  
                  function createLogo(
                     url,
                     alt,
                     className
                  )
                  {
                     if (!showLogos)
                     {
                         return '';
                     }
                  
                     if (!url)
                     {
                         return '';
                     }
                  
                     let html = '';
                  
                     html +=
                         '<img class="' +
                         escapeHtml(className) +
                         '" ';
                  
                     html +=
                         'src="' +
                         escapeHtml(url) +
                         '" ';
                  
                     html +=
                         'alt="' +
                         escapeHtml(alt) +
                         '" ';
                  
                     html +=
                         'loading="lazy">';
                  
                     return html;
                  }
                  
                  
                  function createTeam(
                     team,
                     side
                  )
                  {
                     if (!team)
                     {
                         return '';
                     }
                  
                     const own =
                         isOwnTeam(team);
                  
                     let className =
                         'hb-team ';
                  
                     if (side === 'home')
                     {
                         className +=
                             'hb-home';
                     }
                     else
                     {
                         className +=
                             'hb-away';
                     }
                  
                     if (own)
                     {
                         className +=
                             ' hb-own-team';
                     }
                  
                     let logoUrl = '';
                  
                     if (
                         team.club &&
                         team.club.logo
                     )
                     {
                         logoUrl =
                             team.club.logo;
                     }
                  
                     const logo =
                         createLogo(
                             logoUrl,
                             team.name || '',
                             'hb-team-logo'
                         );
                  
                     let html = '';
                  
                     html +=
                         '<div class="' +
                         className +
                         '">';
                  
                     if (side === 'away')
                     {
                         html += logo;
                     }
                  
                     html +=
                         '<span class="hb-team-name">' +
                         escapeHtml(
                             team.name || ''
                         ) +
                         '</span>';
                  
                     if (side === 'home')
                     {
                         html += logo;
                     }
                  
                     html += '</div>';
                  
                     return html;
                  }
                  
                  
                  function createCenter(match)
                  {
                     let html = '';
                  
                     if (hasVisibleResult(match))
                     {
                         html +=
                             '<div class="hb-score">';
                  
                         html +=
                             escapeHtml(
                                 match.result.local
                             );
                  
                         html += ' : ';
                  
                         html +=
                             escapeHtml(
                                 match.result.visitor
                             );
                  
                         html += '</div>';
                  
                         return html;
                     }
                  
                     html +=
                         '<div class="hb-time">';
                  
                     html +=
                         escapeHtml(
                             formatGameTime(
                                 match.date
                             )
                         );
                  
                     html += '</div>';
                  
                     return html;
                  }
                  
                  
                  function getVenue(match)
                  {
                     if (!showVenue)
                     {
                         return '';
                     }
                  
                     if (!match.field)
                     {
                         return '';
                     }
                  
                     if (
                         match.field.installation &&
                         match.field.installation.name
                     )
                     {
                         return match.field.installation.name;
                     }
                  
                     if (match.field.name)
                     {
                         return match.field.name;
                     }
                  
                     return '';
                  }
                  
                  
                  function getFederation(match)
                  {
                     if (!showFederation)
                     {
                         return '';
                     }
                  
                     if (!match.phase)
                     {
                         return '';
                     }
                  
                     if (!match.phase.federation)
                     {
                         return '';
                     }
                  
                     if (!match.phase.federation.name)
                     {
                         return '';
                     }
                  
                     return match.phase.federation.name;
                  }
                  
                  
                  function createGame(match)
                  {
                     let gameClass =
                         'hb-game';
                  
                     if (
                         match.status &&
                         match.status.is_live === true
                     )
                     {
                         gameClass +=
                             ' hb-game-live';
                     }
                  
                     let html = '';
                  
                     html +=
                         '<a class="' +
                         gameClass +
                         '" ';
                  
                     html +=
                         'href="' +
                         escapeHtml(
                             getMatchUrl(match)
                         ) +
                         '" ';
                  
                     html +=
                         'target="_blank" ';
                  
                     html +=
                         'rel="noopener noreferrer">';
                  
                     html +=
                         '<div class="hb-game-top">';
                  
                     if (
                         showCompetition &&
                         match.phase &&
                         match.phase.name
                     )
                     {
                         html +=
                             '<div class="hb-competition">' +
                             escapeHtml(
                                 match.phase.name
                             ) +
                             '</div>';
                     }
                     else
                     {
                         html +=
                             '<div></div>';
                     }
                  
                     if (
                         match.status &&
                         match.status.is_live === true
                     )
                     {
                         html +=
                             '<div class="hb-live">LIVE</div>';
                     }
                  
                     html += '</div>';
                  
                     html +=
                         '<div class="hb-teams">';
                  
                     html +=
                         createTeam(
                             match.local,
                             'home'
                         );
                  
                     html +=
                         '<div class="hb-center">';
                  
                     html +=
                         createCenter(match);
                  
                     html += '</div>';
                  
                     html +=
                         createTeam(
                             match.visitor,
                             'away'
                         );
                  
                     html += '</div>';
                  
                     const venue =
                         getVenue(match);
                  
                     const federation =
                         getFederation(match);
                  
                     if (venue || federation)
                     {
                         html +=
                             '<div class="hb-meta">';
                  
                         html += '<span>';
                  
                         if (venue)
                         {
                             html +=
                                 '⌖ ' +
                                 escapeHtml(venue);
                         }
                  
                         html += '</span>';
                  
                         html += '<span>';
                  
                         if (federation)
                         {
                             html +=
                                 escapeHtml(federation);
                         }
                  
                         html += '</span>';
                  
                         html += '</div>';
                     }
                  
                     html += '</a>';
                  
                     return html;
                  }
                  
                  
                  /*
                  * ============================================================
                  * GESAMTES HTML ERZEUGEN
                  * ============================================================
                  */
                  
                  function createHtml(matches)
                  {
                     const club =
                         getClubFromMatches(matches);
                  
                     let clubName =
                         clubId;
                  
                     let clubLogo = '';
                  
                     if (club)
                     {
                         if (club.name)
                         {
                             clubName =
                                 club.name;
                         }
                  
                         if (club.logo)
                         {
                             clubLogo =
                                 club.logo;
                         }
                     }
                  
                     let html = '';
                  
                     html +=
                         createCss();
                  
                     html +=
                         '<div class="hb-schedule">';
                  
                     /*
                      * Header
                      */
                     html +=
                         '<div class="hb-header">';
                  
                     html +=
                         '<div class="hb-header-accent"></div>';
                  
                     html +=
                         '<div class="hb-header-content">';
                  
                     html +=
                         '<div class="hb-club">';
                  
                     html +=
                         createLogo(
                             clubLogo,
                             clubName,
                             'hb-club-logo'
                         );
                  
                     html += '<div>';
                  
                     html +=
                         '<div class="hb-title">' +
                         'Vereinsspielplan' +
                         '</div>';
                  
                     html +=
                         '<div class="hb-club-name">' +
                         escapeHtml(clubName) +
                         '</div>';
                  
                     html += '</div>';
                  
                     html += '</div>';
                  
                     html +=
                         '<div class="hb-range">' +
                         escapeHtml(days) +
                         ' Tage' +
                         '</div>';
                  
                     html += '</div>';
                  
                     html += '</div>';
                  
                  
                     /*
                      * Spiele
                      */
                     if (matches.length === 0)
                     {
                         html +=
                             '<div class="hb-empty">' +
                             'Keine Spiele im gewählten Zeitraum gefunden.' +
                             '</div>';
                     }
                     else
                     {
                         let previousDate = '';
                  
                         for (const match of matches)
                         {
                             if (!match)
                             {
                                 continue;
                             }
                  
                             if (!match.date)
                             {
                                 continue;
                             }
                  
                             const currentDate =
                                 getDateKey(match.date);
                  
                             if (currentDate !== previousDate)
                             {
                                 html +=
                                     '<div class="hb-date">' +
                                     escapeHtml(
                                         formatGameDate(
                                             match.date
                                         )
                                     ) +
                                     '</div>';
                  
                                 previousDate =
                                     currentDate;
                             }
                  
                             html +=
                                 createGame(match);
                         }
                     }
                  
                  
                     /*
                      * Footer
                      */
                     html +=
                         '<div class="hb-footer">';
                  
                     if (showLastUpdate)
                     {
                         const now =
                             new Date();
                  
                         html +=
                             '<span>' +
                             'Aktualisiert: ' +
                             escapeHtml(
                                 now.toLocaleString(
                                     'de-DE'
                                 )
                             ) +
                             '</span>';
                     }
                     else
                     {
                         html += '<span></span>';
                     }
                  
                     html +=
                         '<a href="' +
                         escapeHtml(
                             getClubUrl()
                         ) +
                         '" ';
                  
                     html +=
                         'target="_blank" ';
                  
                     html +=
                         'rel="noopener noreferrer">';
                  
                     html +=
                         'handball.net ↗';
                  
                     html += '</a>';
                  
                     html += '</div>';
                  
                     html += '</div>';
                  
                     return html;
                  }
                  
                  
                  /*
                  * ============================================================
                  * AKTUALISIERUNG
                  * ============================================================
                  */
                  
                  async function updateSchedule()
                  {
                     try
                     {
                         const range =
                             getDateRange();
                  
                         log(
                             'Lade handball.net Spielplan für ' +
                             clubId +
                             ' von ' +
                             range.from +
                             ' bis ' +
                             range.to,
                             'info'
                         );
                  
                         const matches =
                             await fetchAllMatches();
                  
                         const html =
                             createHtml(matches);
                  
                         await setStateAsync(
                             stateId,
                             html,
                             true
                         );
                  
                         log(
                             'handball.net Spielplan aktualisiert: ' +
                             matches.length +
                             ' Spiel(e)',
                             'info'
                         );
                     }
                     catch (error)
                     {
                         let message =
                             String(error);
                  
                         if (
                             error &&
                             error.message
                         )
                         {
                             message =
                                 error.message;
                         }
                  
                         log(
                             'Fehler beim Abruf von handball.net: ' +
                             message,
                             'error'
                         );
                     }
                  }
                  
                  
                  /*
                  * ============================================================
                  * SCHEDULER
                  * ============================================================
                  */
                  
                  /*
                  * Täglicher Abruf
                  */
                  schedule(
                     cronSchedule,
                     function ()
                     {
                         updateSchedule();
                     }
                  );
                  
                  
                  /*
                  * Zusätzlich direkt beim Start des Skripts abrufen
                  */
                  updateSchedule();
                  

                  Am Anfang des Skripts können diverse Konfigurationen vorgenommen werden.
                  Die KlubID kann wie folgt ermittelt werden
                  Auf handball.net seinen Klub suchen und anzeigen.
                  In der Adresszeile des Browsers ist dann die KlubID 1rz94gz ersichtlich

                  https://www.handball.net/club/1rz94gz
                  

                  Auch der gewünschte DatenpunktID in den das html gespeichert wird
                  ob man hell/dunkel haben will
                  oder Hauptfarbe (accentcolor)
                  und ein paar Dinge mehr
                  können angepasst werden.

                  Der Abruf sollte nicht öfters als einmal am Tag erfolgen.
                  Vorkonfiguriert ist 3 Uhr nachts
                  handball.net hat Einstellungen (CORS), das der direkte Abruf aus dem browser nicht möglich ist.

                  Danach dann in vis/vis2 ein entsprechend großes basic HTML widget anlegen
                  und im html feld dann den Datenpunkt wie folgt notieren

                  {0_userdata.0.handball.clubScheduleHtml}
                  

                  sowie im css feld overflow-y

                  scroll
                  

                  eintragen

                  image.jpeg

                  Im runtime mode sieht das dann so aus

                  image.jpeg

                  Mit Klick auf das widget kommt man direkt auf die Vereinsseite

                  Meine Adapter und Widgets
                  TVProgram, SqueezeboxRPC, OpenLiga, RSSFeed, MyTime,, pi-hole2, vis-json-template, skiinfo, vis-mapwidgets, vis-2-widgets-rssfeed
                  Links im Profil

                  1 Antwort Letzte Antwort
                  0
                  • T
                    T
                    Tschulte
                    schrieb am zuletzt editiert von
                    #9

                    Sehr schick

                    1 Antwort Letzte Antwort
                    0

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

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

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

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


                    Support us

                    ioBroker
                    Community Adapters
                    Donate

                    504

                    Online

                    33.1k

                    Benutzende

                    84.0k

                    Themen

                    1.4m

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

                    • Du hast noch kein Konto? Registrieren

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