Tankerkönig Preise in Home-Assistant darstellen

Bislang gibt es noch keine Komponente für Tankerkönig im Home-Assistant. Wie man die Schnittstelle dennoch einbinden kann zeige ich hier.

Tankerkönig API-Key anfordern

Als erstes benötigen wir einen API-Key von Tankerkönig. Den bekommen wir indem wir auf hierhin gehen und dort in der Navigation auf API-KEY klicken. Anschließend füllen wir das Formular aus und schicken es ab. Haben wir das erledigt können wir mit dem API-Key nun die Schnittstelle von Tankerkönig verwenden um die Preise für E5, E10 und Diesel für beliebige Tankstellen zu erfahren.

Tankestellen finden

Um die Preise für eine oder mehrere Tankstelle zu finden benötigen wir die ID der jeweiligen Tankstelle. Dazu gehen wir hierhin und suchen in der Karte unseren Standort. Mit einem Doppelklick wird der Umkreis gesetzt und alle Tankstellen erscheinen als kleine Fähnchen in der Karte. Klicken wir auf ein Fähnchen wird die Tankstelle ausgewählt und landet in der Box am rechten Seitenrand. Haben wir alle Tankstellen ausgewählt die wir abrufen möchten klicken wir auf Tankstellen übernehmen. Nun erscheint eine Liste im JSON-Format. Was für uns aktuell nur wichtig ist sind die IDs, da wir die für den nächsten Schritt benötigen.

Preise abrufen

Für das Abrufen der Preise über die Schnittstelle müssen wir einen neuen Sensor erstellen. Das machen wir in der configuration.yaml unserer Home-Assistant Installation. Dort fügen wir folgenden Eintrag hinzu:

sensor:
  # ...
  - platform: rest
    name: Fuel
    scan_interval: 600
    resource: https://creativecommons.tankerkoenig.de/json/prices.php?apikey=API_KEY&ids=IDS_DER_TANKSTELLEN
    value_template: '{ value_json.prices.[] }'
    json_attributes:
      - prices
  # ...

API_KEY ersetzen wir mit seinem API-Key von Tankerkönig und IDS_DER_TANKSTELLEN ersetzen wir durch eine kommagetrennte Liste der IDs aus dem letzten Punkt. Also wenn wir folgende IDs haben:

  • 11571341-3296-4f16-a363-28b8c188872c
  • 7c3371e7-db66-4803-a979-5ca385ad106c
  • 86eb55f4-5535-44fa-a2b4-6b88260c17c4

würde die URL wie folgt aussehen

https://creativecommons.tankerkoenig.de/json/prices.php?apikey=API_KEY&ids=11571341-3296-4f16-a363-28b8c188872c,7c3371e7-db66-4803-a979-5ca385ad106c,86eb55f4-5535-44fa-a2b4-6b88260c17c4

Der erste Schritt wäre damit geschafft. Die Daten werden abgerufen und als Sensor im Home-Assistant zur Verfügung gestellt.

Darstellung

Es gibt mehrere Wege die Preise darzustellen. Entweder wir erstellen einen weiteren Sensor pro Preis, z.B.:

sensor:
  # ...
  - platform: template
    sensors:
      gasstation_1_e5:
        friendly_name: 'Tankstelle 1 (E5)'
        unit_of_measurement: '€'
        value_template: '{{ states.sensor.fuel.attributes["prices"]["11571341-3296-4f16-a363-28b8c188872c"]["e5"]}}'
      gasstation_1_e10:
        friendly_name: 'Tankstelle 1 (E10)'
        unit_of_measurement: '€'
        value_template: '{{ states.sensor.fuel.attributes["prices"]["11571341-3296-4f16-a363-28b8c188872c"]["e10"]}}'

oder (was ich bevorzuge) wir erstellen eine State card für alle Preise.

State card erstellen

In eurem Konfigurationsordner von Home-Assistant (dort wo sich die configuration.yaml befindet) gehen wir in den Ordner www. Falls noch keiner existiert legen wir den an. Anschließend gehen wir in den Unterordner custom_ui. Auch hier: wenn dieser nicht existiert, legen wir den an. In diesem Ordner erstellen wir eine Datei mit dem Namen: state-card-gasstation.html und folgendem Inhalt:

<script>
{
  const _NAME = 'Gasstation';
  const _URL = 'https://www.panbachi.de';
  const _VERSION = '20180608';

  if(!window.CUSTOM_UI_LIST) window.CUSTOM_UI_LIST = [];
    window.CUSTOM_UI_LIST.push({
      name: _NAME,
      url: _URL,
      version: _VERSION
    });
  }
</script>
<dom-module id='state-card-gasstation'>
  <template>
    <style>
td { text-align: center; }
td.street { font-weight: bold; }
td.gasstation img { vertical-align: middle; }
ha-label-badge { font-size: 85%; }
    </style>

    <table width="100%">
      <template is='dom-repeat' items='[[prices(hass, config.fuel)]]' as='price'>
        <tr>
          <td class="logo"><img height="40" width="40" src="/local/gasstation_logos/[[brand(config.entities, price.id)]].png"></td>
          <td class="street">[[street(config.entities, price.id)]]</td>
          <template is="dom-if" if="[[config.e5]]"><td><ha-label-badge value='[[price.e5]]€' label='E5'></ha-label-badge></td></template>
          <template is="dom-if" if="[[config.e10]]"><td><ha-label-badge value='[[price.e10]]€' label='E10'></ha-label-badge></td></template>
          <template is="dom-if" if="[[config.diesel]]"><td><ha-label-badge value='[[price.diesel]]€' label='Diesel'></ha-label-badge></td></template>
        </tr>
      </template>
    </table>
  </template>
</dom-module>

<script>
class StateCardGasstation extends Polymer.Element {
  static get is() { return 'state-card-gasstation'; }

  static get properties() {
    return {
      hass: Object,
      inDialog: {
        type: Boolean,
        value: false
      },
      stateObj: Object,
      config: {
        type: Object,
        computed: 'computeConfig(stateObj)',
      },
    }
  }

  computeConfig(stateObj) {
    if (stateObj && stateObj.attributes && stateObj.attributes.config && stateObj.attributes.config.entities && Array.isArray(stateObj.attributes.config.entities)) {
      return stateObj.attributes.config;
    } else {
      return { entities: [], fuel: {}, e5: true, e10: true, diesel: true };
    }
  }

  prices(hass, fuel) {
    let prices = hass.states[fuel].attributes.prices;
    let arr = [];

    for(let i in prices) {
      arr.push({
        id: i,
        e5: prices[i].e5,
        e10: prices[i].e10,
        diesel: prices[i].diesel
      });
    }

    return arr;
  }

  street(entities, id) {
    for(let i in entities) {
      if(entities[i].entity == id) {
        return entities[i].street;
      }
    }
  }

  brand(entities, id) {
    for(let i in entities) {
      if(entities[i].entity == id) {
        return entities[i].brand.toLowerCase();
      }
    }
  }

  _toStr(obj) {
    return JSON.stringify(obj, null, 2);
  }
}

customElements.define(StateCardGasstation.is, StateCardGasstation);
</script>

Das wäre geschafft…

Logos herunterladen

Als nächstes benötigen wir Logos von den Tankstellen. Diese bekommen wir über die Google-Bildersuche. Dort z.B. nach “Aral filetype:png” suchen. Da können wir uns dann ein Bild (ambesten mit transparentem Hintergrund) aussuchen und herunterladen. Die Bilder legen wir dann in dem Ordner www/gasstation_logos ab (Ordner müssen wir vorher noch anlegen). Beim Namen ist wichtig, dass dieser komplett kleingeschrieben ist. Also nicht “Aral.png” oder “ARAL.png” sondern “aral.png“. Warum das so ist erfahren wir später.

State card registrieren

Um die State card zu registrieren öffnen wir wieder unsere configuration.yaml. Die Konfiguration ergänzen wir um folgende Einträge:

# Enables the frontend
frontend:
  extra_html_url:
    # ...
    - /local/custom_ui/state-card-gasstation.html
  extra_html_url_es5:
    # ...
    - /local/custom_ui/state-card-gasstation.html

Script anlegen

In diesem Schritt legen wir ein Script an. Das dient nur dazu, dass wir ein Element haben, welches wir anzeigen können. Dazu öffnen wir die Datei scripts.yaml und tragen folgendes ein:

gasstation:
  sequence:

State card konfigurieren

In der Datei customize.yaml tragen wir nun folgendes ein:

script.gasstation:
  custom_ui_state_card: state-card-gasstation
  friendly_name: 'Tankstellen'
  config:
    fuel: sensor.fuel
    e5: true
    e10: true
    diesel: true
    entities:
      - entity: '11571341-3296-4f16-a363-28b8c188872c'
        street: 'Kölner Straße'
        brand: ARAL
      - entity: '7c3371e7-db66-4803-a979-5ca385ad106c'
        street: 'Dießemer Bruch'
        brand: SHELL
      - entity: '86eb55f4-5535-44fa-a2b4-6b88260c17c4'
        street: 'Kölner Straße'
        brand: SHELL

Hier müssen wir darauf achten, dass brand genauso heißt wie das passende Logo im Ordner www/gasstation_logos (wobei hier Groß- und Kleinschreibung egal ist, da der brand in Kleinbuchstaben umgewandelt wird um an das passende Logo zu kommen). Wenn wir z.B. nur E10 angezeigt bekommen möchten, können wir die Punkte “e5: true” und “diesel: true” weglassen.

Anzeigen lassen

Jetzt sind wir soweit, dass wir die die Tankstellen-Preise anzeigen lassen können. Dafür öffnen wir die groups.yaml und erstellen folgenden Eintrag (natürlich an eure konfigurierten Views angepasst):

default_view:
  view: yes
  name: Home
  entities:
    - group.gasstations

gasstations:
  name: Tankstellen
  entities:
    - script.gasstation

Fertig

Jetzt müssen wir nur noch Home-Assistant neustarten und sind fertig. Die Tankstellen-Preise werden uns im Frontend dargestellt.

Ich hoffe, dass euch der Beitrag helfen konnte. Die Lösung ist nicht perfekt und eher quick & dirty, aber für meine Zwecke reicht es =). Wenn ihr fragen oder Anregungen habt, lasst mir einen Kommentar da.

Schreibe einen Kommentar

Deine E-Mail-Adresse wird nicht veröffentlicht. Erforderliche Felder sind mit * markiert.