angesichts der hohen Spritpreise habe ich mal etwas zusammengebastelt, folgendes kann den Spritpreis einer bestimmten Tankstelle abfragen und auf einem SSD1306 Display anzeigen.
Kann natürlich nach belieben mit Funktionen erweitert werden. Ich selbst werde für mich noch eine Funktion schreiben, welche eine LED unter einem bestimmten Preis bunt blinken lässt.
Könnte eventuell dem ein oder anderem helfen, der Probleme beim Abfragen einer https / ssl API hat oder eben speziell zum Thema Tankstellenabfrage. Hierzu habe ich nämlich nichts im Netz gefunden und möchte es deswegen gerne mit der Allgemeinheit teilen.
#include <WiFi.h>
#include <HTTPClient.h>
#include <Arduino_JSON.h>
#include <Wire.h>
#include <SPI.h>
#include <Adafruit_GFX.h>
#include <Adafruit_SSD1306.h>
#define SCREEN_WIDTH 128 // OLED display width, in pixels
#define SCREEN_HEIGHT 64 // OLED display height, in pixels
// Declaration for an SSD1306 display connected to I2C (SDA, SCL pins)
Adafruit_SSD1306 display(SCREEN_WIDTH, SCREEN_HEIGHT, &Wire, -1);
const char* ssid = "Deine SSID";
const char* password = "WLAN Passwort";
// Dein Tankerkoenig ApiKey und die abzufragende TankstellenID
String TankerkoenigApiKey = "Dein eigener ApiKey";
String TankstellenID = "ID der Tankstelle";
// RootCA von Tankerkoenig
const char* root_ca = \
"-----BEGIN CERTIFICATE-----\n" \
"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\n" \
"-----END CERTIFICATE-----\n";
// Abfragetimer, laut Nutzungsbedingungen darf die API alle 5 Minuten abgefragt werden
unsigned long lastTime = 0;
// 5 Minuten (300000)
unsigned long timerDelay = 300000;
// Um die ersten 5 Minuten zu überspringen
bool skiptimer = true;
String jsonBuffer;
void setup() {
Serial.begin(115200);
WiFi.begin(ssid, password);
Serial.println("Connecting");
while (WiFi.status() != WL_CONNECTED) {
delay(500);
Serial.print(".");
}
Serial.println("");
Serial.print("Connected to WiFi network with IP Address: ");
Serial.println(WiFi.localIP());
Serial.println("Timer auf 5 Minuten gesetzt (timerDelay variable)");
if (!display.begin(SSD1306_SWITCHCAPVCC, 0x3C)) { // Address 0x3D for 128x64
Serial.println(F("SSD1306 allocation failed"));
for (;;);
}
delay(2000);
display.clearDisplay();
display.setTextSize(1);
display.setTextColor(WHITE);
display.setCursor(0, 10);
// Display static text
display.println("Hallo! :)");
display.display();
delay(2000);
display.clearDisplay();
display.setCursor(0, 10);
}
void loop() {
// Send an HTTP GET request
if ((millis() - lastTime) > timerDelay || skiptimer == true) {
// Check WiFi connection status
if (WiFi.status() == WL_CONNECTED) {
String serverPath = "https://creativecommons.tankerkoenig.de/json/detail.php?id=" + TankstellenID + "&apikey=" + TankerkoenigApiKey;
jsonBuffer = httpGETRequest(serverPath.c_str());
Serial.println(jsonBuffer);
JSONVar myObject = JSON.parse(jsonBuffer);
// JSON.typeof(jsonVar) can be used to get the type of the var
if (JSON.typeof(myObject) == "undefined") {
Serial.println("Parsing input failed!");
return;
}
Serial.print("JSON object = ");
Serial.println(myObject);
Serial.print("Super E10: ");
Serial.println(myObject["station"]["e10"]);
bool isOpen = myObject["station"]["isOpen"];
if (isOpen == true) {
display.clearDisplay();
display.setCursor(0, 10);
display.setTextSize(1);
display.println("Benzinpreis Super E10");
display.println();
display.setTextSize(4);
display.println(myObject["station"]["e10"]);
display.display();
} else {
display.clearDisplay();
display.display();
}
}
else {
Serial.println("WiFi Disconnected");
display.clearDisplay();
display.setCursor(0, 10);
display.setTextSize(1);
display.println("WiFi Disconnected");
display.display();
}
skiptimer = false;
lastTime = millis();
}
}
String httpGETRequest(const char* serverName) {
WiFiClient client;
HTTPClient http;
// Your Domain name with URL path or IP address with path
http.begin(serverName, root_ca);
// Send HTTP POST request
int httpResponseCode = http.GET();
String payload = "{}";
if (httpResponseCode > 0) {
Serial.print("HTTP Response code: ");
Serial.println(httpResponseCode);
payload = http.getString();
}
else {
Serial.print("Error code: ");
Serial.println(httpResponseCode);
display.clearDisplay();
display.setCursor(0, 10);
display.setTextSize(1);
display.print("HTTP Error: ");
display.println(httpResponseCode);
display.display();
}
// Free resources
http.end();
return payload;
}
Oh,schön.
Kann das ja mal dem örtlichen Oldtimerclub empfehlen.
Ich bin hier auf die Sonne angewiesen, für die Preisgünstige Fortbewegung, seit die Stadtwerke zum 1. Juli 2021 ihre "Tankstellen" auf kostenpflichtig umgestellt haben.
Ein "Balkonkraftwerk" erleichtert den Einstieg und ist schnell mal auf's Garagendach geschraubt.
Bei Kaufland, Lidl und Co. ist man hier noch gar nicht so weit.
In den Landkreisen nördlich und südlich ist es schon eine Weile möglich sich kostenfrei beim Discounter an zustöpseln.
Gerade mal gegoogelt, die ist ja echt sehr schön. Schade, dass ich keinen 3D-Drucker habe, sonst hätte ich mir auch eine mit echten Sprit Preisen gebastelt.
Wegen des Schattens des Nachbarhauses ist das nicht so sinnvoll,
wenn schon, dann direkt aufs Dach, da habe ich auch eine Menge mehr Fläche.
Bei meinem niedrigen Kilometerbedarf kann ich problemlos aus der Schuko-Dose laden.
Bin ja auch noch recht neu dabei, aber absolut begeistert,
ich werde keinen Verbrenner mehr kaufen
Ja, finde ich auch.
Die haben die ja nun schon 13 Jahre - da war von Markttransparenzstelle und sowas wie Tankerkönig-API noch nix zu sehen; deshalb ein direkter Deal mit Jet.
Hast Du ein STL-File oder eine Konstruktion für so einen "Preismast"?
Vielleicht könnte mein Drucker einen davon herstellen
Ich habe festgestellt, dass die ArduinoJSON Bibliothek besser und populärer als die Arduino_JSON ist und sie deshalb ersetzt. Außerdem habe ich FastLED hinzugefügt und eine WS2812 LED angeschlossen, welche unter einem bestimmten Preis bunt leuchtet.
(Die bereits eingetragene Tankstelle ist eine Demo-Tankstelle, diese ist geschlossen und das Display wird nichts anzeigen außer die if-Anfrage die auf isOpen prüft wird angepasst. Im Seriellen Monitor ist der Preis aber zu sehen.)
#include "FastLED.h"
#include <WiFi.h>
#include <HTTPClient.h>
#include <ArduinoJson.h>
#include <Wire.h>
#include <SPI.h>
#include <Adafruit_GFX.h>
#include <Adafruit_SSD1306.h>
#define SCREEN_WIDTH 128 // OLED display width, in pixels
#define SCREEN_HEIGHT 64 // OLED display height, in pixels
// Declaration for an SSD1306 display connected to I2C (SDA, SCL pins)
Adafruit_SSD1306 display(SCREEN_WIDTH, SCREEN_HEIGHT, &Wire, -1);
// Anzahl der LEDs für die FastLED Lib festlegen
#define ANZAHL_LEDS 60 // Weil an 60er LED-Stripe angeschlossen
#define LED_PIN 15
CRGB leds[ANZAHL_LEDS];
const char* ssid = "WLAN Name";
const char* password = "WLAN Passwort";
// Dein Tankerkoenig ApiKey und die abzufragende TankstellenID
String TankerkoenigApiKey = "API Key bitte selbst besorgen";
String TankstellenID = "24a381e3-0d72-416d-bfd8-b2f65f6e5802";
// Ist der Preis gleich dieser Variable oder darunter soll die LED bunt blinken
float preisalarm = 1.609;
// RootCA von Tankerkoenig
const char* root_ca = \
"-----BEGIN CERTIFICATE-----\n" \
"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\n" \
"-----END CERTIFICATE-----\n";
// Abfragetimer, laut Nutzungsbedingungen darf die API alle 5 Minuten abgefragt werden
unsigned long lastTime = 0;
// 5 Minuten (300000)
unsigned long timerDelay = 300000;
// Um die ersten 5 Minuten zu überspringen
bool skiptimer = true;
// Aktiviert LED im loop
bool ledalarm = false;
String jsonBuffer;
void setup() {
Serial.begin(115200);
// Initialize the Neopixels and Brightness
FastLED.addLeds<NEOPIXEL, LED_PIN>(leds, ANZAHL_LEDS);
FastLED.setBrightness(25); // Helligkeit
WiFi.begin(ssid, password);
Serial.println("Connecting");
while (WiFi.status() != WL_CONNECTED) {
delay(500);
Serial.print(".");
}
Serial.println("");
Serial.print("Connected to WiFi network with IP Address: ");
Serial.println(WiFi.localIP());
Serial.println("Timer auf 5 Minuten gesetzt (timerDelay variable)");
if (!display.begin(SSD1306_SWITCHCAPVCC, 0x3C)) { // Address 0x3D for 128x64
Serial.println(F("SSD1306 allocation failed"));
for (;;);
}
delay(2000);
display.clearDisplay();
display.setTextSize(1);
display.setTextColor(WHITE);
display.setCursor(0, 10);
// Display static text
display.println("Hallo! :)");
display.display();
delay(2000);
display.clearDisplay();
display.setCursor(0, 10);
}
void loop() {
// Send an HTTP GET request
if ((millis() - lastTime) > timerDelay || skiptimer == true) {
// Check WiFi connection status
if (WiFi.status() == WL_CONNECTED) {
String serverPath = "https://creativecommons.tankerkoenig.de/json/detail.php?id=" + TankstellenID + "&apikey=" + TankerkoenigApiKey;
jsonBuffer = httpGETRequest(serverPath.c_str());
Serial.println(jsonBuffer);
StaticJsonDocument<1024> doc;
DeserializationError error = deserializeJson(doc, jsonBuffer);
if (error) {
Serial.print(F("deserializeJson() failed: "));
Serial.println(error.f_str());
return;
}
JsonObject station = doc["station"];
float station_e10 = station["e10"];
Serial.print("Super E10: ");
Serial.println(station_e10, 3);
bool station_isOpen = station["isOpen"];
if (station_isOpen == true) {
display.clearDisplay();
display.setCursor(0, 10);
display.setTextSize(1);
display.println("Benzinpreis Super E10");
display.println();
display.setTextSize(4);
display.println(station_e10, 3);
display.display();
if (station_e10 <= preisalarm) {
Serial.println("Preisalarm hat zugeschlagen");
ledalarm = true;
} else {
Serial.println("Preisalarm hat nicht zugeschlagen");
ledalarm = false;
}
} else {
display.clearDisplay();
display.display();
ledalarm = false;
}
}
else {
Serial.println("WiFi Disconnected");
display.clearDisplay();
display.setCursor(0, 10);
display.setTextSize(1);
display.println("WiFi Disconnected");
display.display();
}
skiptimer = false;
lastTime = millis();
}
colorled();
}
String httpGETRequest(const char* serverName) {
WiFiClient client;
HTTPClient http;
// Your Domain name with URL path or IP address with path
http.begin(serverName, root_ca);
// Send HTTP POST request
int httpResponseCode = http.GET();
String payload = "{}";
if (httpResponseCode > 0) {
Serial.print("HTTP Response code: ");
Serial.println(httpResponseCode);
payload = http.getString();
}
else {
Serial.print("Error code: ");
Serial.println(httpResponseCode);
display.clearDisplay();
display.setCursor(0, 10);
display.setTextSize(1);
display.print("HTTP Error: ");
display.println(httpResponseCode);
display.display();
}
// Free resources
http.end();
return payload;
}
void colorled() {
if (ledalarm == true) {
uint8_t NUM_LEDS = 1;
uint8_t thisSpeed = 10;
uint8_t deltaHue = 10;
uint8_t thisHue = beat8(thisSpeed, 255);
fill_rainbow(leds, NUM_LEDS, thisHue, deltaHue);
FastLED.show();
} else {
leds[0] = CRGB::Black;
FastLED.show();
}
}
Ich denke schon, nur könnte die WiFi und HTTPClient Bibliothek anders benannt sein. Wäre super wenn es jemand testen könnte.
Danke für den Hinweis, die gehört selbstverständlich nicht in den Sketch. Hatte mal etwas mit dem Sensor rumprobiert und ihn vergessen rauszulöschen. Ich passe es eben an.
Prima, wenn die Version mit dem ESP32 bei mir funktioniert, werde ich es mit dem ESP8266-01 testen. Das ist für mich mal wieder etwas, wenn auch eine kleine Herausforderung.
Ich werde berichten.
Kann ich bestätigen - eine um Display und NeoPixel erleichterte Minimalversion mit Ausgabe auf die serielle Schnittstelle tut bei mir auch.
Jetzt mal sehen, wie ich das aufbaue (Idee: Wie ein Wecker - Knopf drücken zum händischen Abfragen, Pieper bei Preisalarm und nachts darf das Ding schlafen).