Polestar-API zu MQTT im Container (openWB-V1-Anbindung möglich)

Hallo zusammen,

ich habe heute mal versucht, den Docker container zum laufen zu bekommen.
Aber leider bekomme ich folegende Fehlermeldung:

Ich weiß nicht weiter und bitte um Unterstützung

Danke! Peter

client.connect (MQTT BROKER, MQTT_PORT, MQTT KEEPALIVE INTERVAL)

Hier liegt der Hase im Pfeffer:

Hast du die richtige Adresse für Deinen MQTT-Broker gesetzt?

der port war falsch. Jetzt bekomme ich Daten. Vielen Dank! :kissing_heart:
@Landmatrose : Jetzt die Frage an Dich: Wie lädt man die Daten aus dem Container in IO Broker? :grin:

1 „Gefällt mir“

Die Frage verstehe ich jetzt nicht wirklich. Du hast doch einen MQTT-Broker inkl. Port gerade konfiguriert. Wenn du einen beliebigen Broker verwendest, dann darfst du das nochmal tun…

Im IOBroker wird der MQTT-Broker einfach als Adapter installiert:

Die Werte des Containers/der API erscheinen dann als Objekte unterhalb der mqtt-Instanz und dem von dir vergebenen Namen des BASE_TOPIC (bei mir „MeinPolestar2“)

So ganz schlau werde ich daraus noch nicht.
Ich hatte in IOB kein MQTT installiert und trotzdem hat der Container Daten ausgegeben.
Nach der Installation von MQTT auf dem IOB werden die Daten auch dort angezeigt, aber sie werden nicht aktualisiert… :cry:
Aber morgen ist auch noch ein Tag.

Hat mir keine Ruhe gelassen. MQTT auf dem IOB weggeschmissen und neu installiert. Jetzt gehts! :star_struck:
Gute Nacht allerseits!

2 „Gefällt mir“

Empfehlung an alle:

Den Wert POLESTAR_CYCLE habe ich jetzt im Default auf 270 (Sekunden) reduziert.

Die API gibt nämlich eine Ablaufzeit expires_in vom 300 (Sekunden) zurück.

Mit der reduzierten Zeit für den nächsten Abruf, muss nur noch jedes 2. Mal das Token erneuert werden und ist damit etwas freundlicher für die Server-Last bei Polestar. Läppert sich… :blush:

kann man das Logging deaktivieren? mein Docker Container schreibt jeden Event/Abruf brav raus?

Vielleicht kann mir einer der Foristi helfen.
Ich möchte gerne die vorgegebene sperrige Antwort der API in der IOB Vis gegen einen eigenen/gefälligeren Text austauschen.

Ich vermute, dass das über ein JS Binding gemacht wird. Aber ich bekomme es nicht hin. Hat jemand einen Vorschlag/Lösung für mich? Danke und LG Peter

Mit VIS kenne ich mich nicht aus - wobei ich denke das hier auch Textänderungen vorgenommen werden können.

Aber eine Möglichkeit ist sicher über ein Skript bei Änderung der API ein eigenes Objekt mit dem Wunschtext zu beschreiben und dies darzustellen.

Leute bin ich denn ein Kiosk?
Oder bin ich etwa 'ne Bank?
Oder seh’ ich aus wie ein Hotel?
Oder wie ein Kassenschrank?
Leute bin ich denn ein Kiosk?
Oder bin ich etwa 'ne Bank?
Oder seh’ ich aus wie ein Hotel?
Oder wie ein Kassenschrank?

@CONSULitAS :arrow_right: chatgpt.com wie kann man in docker-compose.yml logging deaktivieren :arrow_right: polestar.fans

********************************

Um das Logging in der docker-compose.yml-Datei zu deaktivieren, kannst du die logging-Option auf eine bestimmte Weise konfigurieren. Dabei wird das Logging entweder vollständig deaktiviert oder auf ein Minimum reduziert.

Option 1: Logging vollständig deaktivieren

Du kannst none als Treiber für das Logging angeben. Dies deaktiviert das Logging für den entsprechenden Container.

version: '3'
services:
  app:
    image: your-image-name
    logging:
      driver: "none"

Erklärung

  • logging:: Definiert die Logging-Einstellungen.
  • driver: "none": Dies deaktiviert das Logging vollständig, sodass keine Logs gespeichert oder angezeigt werden.

Option 2: Logging auf ein Minimum reduzieren

Falls du das Logging nicht vollständig deaktivieren, aber minimieren möchtest, kannst du den json-file-Treiber verwenden und die Protokolleinschränkungen anpassen.

version: '3'
services:
  app:
    image: your-image-name
    logging:
      driver: "json-file"
      options:
        max-size: "1m"  # Maximale Log-Größe (z. B. 1 MB)
        max-file: "1"   # Nur eine Datei behalten

Erklärung

  • driver: "json-file": Docker verwendet diesen Treiber standardmäßig.
  • max-size: "1m": Begrenzung der Protokolldateigröße auf 1 MB.
  • max-file: "1": Es wird nur eine Protokolldatei beibehalten.

Wann welche Option verwenden?

Option Verwendung
Option 1 Wenn du die Logs vollständig deaktivieren möchtest (nichts wird protokolliert).
Option 2 Wenn du die Logs minimieren, aber nicht vollständig deaktivieren möchtest.

Mit der ersten Option werden keine Logs mehr generiert. Das kann hilfreich sein, wenn du die Ressourcen des Hosts schonen möchtest oder das Protokollieren überflüssig ist.

********************************

Ich nehme die Anregung aber auf und ergänze das Beispiel für die docker-compose.yml um

    logging:
      driver: "json-file"
      options:
        max-size: "1m"  # maximum log size 1 MiB
        max-file: "3"   # keep only 3 logfiles

@0802 Ich habe ja auch keine Ahnung von IOB, aber frage mal einen Freund:

@CONSULitAS :arrow_right: chatgpt.com hier Deine Frage samt Bild... :arrow_right: polestar.fans

Um die sperrige Antwort der API in ioBroker Vis gegen einen gefälligeren Text auszutauschen, kannst du JavaScript innerhalb eines Skripts verwenden, das den Originalwert der API abfängt, umwandelt und als neuen Wert weitergibt. Hier ist eine Schritt-für-Schritt-Anleitung:


1. JS Adapter in ioBroker konfigurieren

Falls du den JavaScript-Adapter noch nicht eingerichtet hast:

  • Installiere den JavaScript-Adapter in ioBroker.
  • Erstelle ein neues Skript (im Skript-Editor).

2. Beispielcode für das Binding

Hier ist ein Beispielcode, der die sperrigen API-Werte in einen benutzerfreundlicheren Text umwandelt. Dies setzt voraus, dass der Datenpunkt in ioBroker bereits vorhanden ist.

// === Konfiguration ===
// Datenpunkte anpassen: Hier trägst du die Original-Datenpunkte der API ein
const originalWBStatus = '0_userdata.0.api.WBStatus';  // Datenpunkt für WB Status
const originalChargeStatus = '0_userdata.0.api.LadungStatus';  // Ladestatus-Datenpunkt

// Ziel-Datenpunkte: Hierhin werden die benutzerfreundlichen Texte geschrieben
const customWBStatus = '0_userdata.0.vis.CustomWBStatus';
const customChargeStatus = '0_userdata.0.vis.CustomChargeStatus';

// === Umwandlungstabellen ===
// Mapping für WB Status
const wbStatusMap = {
    "CHARGER_CONNECTION_STATUS_DISCONNECTED": "Nicht verbunden",
    "CHARGER_CONNECTION_STATUS_CONNECTED": "Verbunden",
    "CHARGER_CONNECTION_STATUS_CHARGING": "Lädt"
};

// Mapping für Ladestatus
const chargeStatusMap = {
    "CHARGING_STATUS_IDLE": "Ladung pausiert",
    "CHARGING_STATUS_ACTIVE": "Lädt aktiv",
    "CHARGING_STATUS_COMPLETE": "Ladung abgeschlossen"
};

// === Skript-Logik ===
// WB Status überwachen und umwandeln
on({id: originalWBStatus, change: "any"}, function (obj) {
    const value = obj.state.val;
    const friendlyText = wbStatusMap[value] || "Unbekannt";
    setState(customWBStatus, friendlyText, true);
});

// Ladestatus überwachen und umwandeln
on({id: originalChargeStatus, change: "any"}, function (obj) {
    const value = obj.state.val;
    const friendlyText = chargeStatusMap[value] || "Unbekannt";
    setState(customChargeStatus, friendlyText, true);
});

// Ziel-Datenpunkte initialisieren, falls nicht vorhanden
if (!existsState(customWBStatus)) createState(customWBStatus, "Unbekannt");
if (!existsState(customChargeStatus)) createState(customChargeStatus, "Unbekannt");

3. Anpassungen vornehmen

  1. Datenpunkte:
    • Passe die Pfade (0_userdata.0.api.WBStatus) an deine eigenen API-Datenpunkte an.
  2. Mapping:
    • Erweitere die Tabellen wbStatusMap und chargeStatusMap, falls neue API-Werte hinzukommen.
  3. Custom-Datenpunkte:
    • Die neuen Datenpunkte (0_userdata.0.vis.CustomWBStatus) werden in VIS verwendet.

4. Datenpunkte in VIS einbinden

  • Binde die neuen benutzerfreundlichen Datenpunkte in VIS ein:
    • Beispiel: 0_userdata.0.vis.CustomWBStatus für „WB Status“
    • Beispiel: 0_userdata.0.vis.CustomChargeStatus für „Ladestatus“

5. VIS Darstellung

In VIS kannst du dann z.B. ein Text-Widget oder ein HTML-Widget verwenden, um die „freundlichen“ Werte anzuzeigen.


Ergebnis

Der sperrige API-Text wie "CHARGER_CONNECTION_STATUS_DISCONNECTED" wird zu „Nicht verbunden“ umgewandelt, und "CHARGING_STATUS_IDLE" wird zu „Ladung pausiert“.

hat soweit funktioniert. Vielen Dank an den „Freund“! :wink:

1 „Gefällt mir“

Ach ja, vielleicht kannst Du das noch gebrauchen:

CHARGING_CONNECTION_STATUS_DICT = {
    "CHARGER_CONNECTION_STATUS_CONNECTED": "Connected",
    "CHARGER_CONNECTION_STATUS_DISCONNECTED": "Disconnected",
    "CHARGER_CONNECTION_STATUS_FAULT": "Fault",
    "CHARGER_CONNECTION_STATUS_UNSPECIFIED": "Unspecified"
}

CHARGING_STATUS_DICT = {
    "CHARGING_STATUS_DONE": "Done",
    "CHARGING_STATUS_IDLE": "Idle",
    "CHARGING_STATUS_CHARGING": "Charging",
    "CHARGING_STATUS_FAULT": "Fault",
    "CHARGING_STATUS_UNSPECIFIED": "Unspecified",
    "CHARGING_STATUS_SCHEDULED": "Scheduled",
    "CHARGING_STATUS_DISCHARGING": "Discharging",
    "CHARGING_STATUS_ERROR": "Error",
    "CHARGING_STATUS_SMART_CHARGING": "Smart Charging",
}

Quelle:

ich muss das wirklich auf dem Raspberry installieren…

Danke für die Info, dachte es gibt eine ENV Variable für die Logging Tiefe…

Für Profis vermutlich trivial, ich aber habe dumm aus der Wäsche geschaut:
beim Update des JS-Adapters des IOB - der Container muss danach unbedingt neu gestartet werden. Wenn nicht, es gibt keinerlei Fehlermeldung, aber es kommen keine neuen Daten mehr an.

Das ist eher ein Bug.

Ich habe eine neue Version gebaut, die robuster auf einen nicht erreichbaren Broker reagiert:

Ist sicher noch nicht perfekt, aber deutlich besser. Es gibt recht ausführliche Meldungen über die Versuche zur Wiederverbindung.

Nach 20 Versuchen startet der Container automatisch neu.

Superschnelles Update​:+1:
In der IOB log-Datei stand sinngemäß etwas von neuem Schlüssel zur Kommunikation Container → MQTT nach dem Neustart.
Ich suche morgen früh 'mal den Eintrag heraus.

Edit: war kein Schlüssel, aber ein Geheimnis → hier der Log-Eintrag beim Wiederverbinden

Vielleicht hilft es dabei die API noch robuster zu machen…

Hallo zusammen,

bei mir läuft es jetzt seit ein paar Tagen nicht mehr … beim Starten des Containers gibt er unter anderem folgendes aus:

Eingekürzt:
> olestar2mqtt  | get_token(), no refresh token available
> polestar2mqtt  |  get_path_token()
> polestar2mqtt  | Error  : HTTPSConnectionPool(host='polestarid.eu.polestar.com', port=443): Max retries exceeded with url: /as/authorization.oauth2?response_type= ... : Failed to establish a new connection: [Errno 111] Connection refused'))
> polestar2mqtt  | in line: 700
> polestar2mqtt  | type   : ConnectionError

Ist da der Polestar Server down? Weil …
Max retries exceeded with url: /as/authorization.oauth2

Weihnachtliche Grüße

Komisch, läuft hier sauber:

 ⠿ Container polestar2mqtt  Started                                                                                                                                                                                                               0.3s
Polestar_2_MQTT.py startet
==========================
    MQTT (Unknown): attempt 1 to reconnect... (waiting 1 seconds)
    MQTT (Unknown): Reconnected successfully after 1.01 seconds!
ensure_valid_token()
    MQTT connected with result code 'Success': polestar2/container/connected=online
get_token(), no refresh token available
 get_path_token()
  code_verifier  = 7941_90VMrXn3fZUFUA82RSvFvxC4keTm0ooV...
  code_challenge = QGWyy4rkp0FbKuCH7Bc0a-ggZvkOmZERyebQ73...
  cookies        = PF=w4HZtRZACBX6mxyJ...; Path=/; Expires=Thu, 26-Dec-2024 15:36:28 GMT; Max-Age=3600; Secure; HttpOnly; SameSite=None
  cookie         = PF=w4HZtRZACBX6mxyJ....
  path_token     = 3CkkoK...
 perform_login()
  max_age    = 15780000
  uid        = NONE
  code       = nSlUqhVGd7VqXT7ZJ58LYXyTOljVduAm...-
 get_api_token()
  access_token  = eyJhbGciOiJSUzI1NiIsImtpZCI6Im1OeVJnZm1...
  refresh_token = baF3rsOTAcpIfHHowuylsPPsnhniBZDv7VUD...
  expires_in    = 299 (seconds)
  expiry_time   = 2024-12-26 15:41:28 CET+0100
get_car_data()
{
    "vin": "LPSVSEDEEML023...",

Hast Du mal den Container neu gestartet?

Bitte mal den kompletten Output. Token kannst Du natürlich abschneiden. Am besten hier ein Issue öffnen, dann spammen wir den Chat nicht voll: