2025. november 2., vasárnap

BKK Futár - ESP32


#include <WiFi.h>
#include <HTTPClient.h>
#include <ArduinoJson.h>
#include <time.h>

static const char* WIFI_SSID     = "YOUR_WIFI_SSID";
static const char* WIFI_PASSWORD = "YOUR_WIFI_PASSWORD";
static const char* BKK_API_KEY   = "YOUR_BKK_API_KEY";
static const char* LOCAL_TIMEZONE  = "CET-1CEST,M3.5.0/2,M10.5.0/3";
const char* stopId         = "F04166";
const int   minutesAfter = 30;

unsigned long lastApiCall = 0;
const long apiCallInterval = 60000;

void wifi_connect() {
  if (WiFi.status() == WL_CONNECTED) return;

  Serial.printf("Kapcsolódás a WiFihez (%s)...", WIFI_SSID);
  WiFi.mode(WIFI_STA);
  WiFi.disconnect();
  WiFi.setAutoReconnect(true);
  WiFi.begin(WIFI_SSID, WIFI_PASSWORD);

  unsigned long start = millis();
  while (WiFi.status() != WL_CONNECTED && millis() - start < 10000) {
    delay(250);
    Serial.print(".");
    yield();
  }

  if (WiFi.status() == WL_CONNECTED) {
    Serial.println(" SIKERES!");
    Serial.print("IP cím: ");
    Serial.println(WiFi.localIP());
  } else {
    Serial.println(" SIKERTELEN!");
  }
}

void wifi_disconnect() {
  if (WiFi.status() == WL_CONNECTED) WiFi.disconnect(false);
  WiFi.mode(WIFI_OFF);
  Serial.println("WiFi kapcsolat bontva!");
}

size_t formatLocalHHMM(long epochSec, char* buffer, size_t bufferSize) {
  time_t t = (time_t)epochSec;
  struct tm lt;
  localtime_r(&t, &lt);

  return snprintf(buffer, bufferSize, "%d:%02d", lt.tm_hour, lt.tm_min);
}


void fetchBKKData(const char* stopId);

void setup() {
  Serial.begin(115200);
  delay(500);
  Serial.println("BKK Menetrend Indítása...");

  wifi_connect();
 
  if (WiFi.status() != WL_CONNECTED) {
    Serial.println("Kritikus hiba: Wi-Fi kapcsolat nélkül nem folytatható.");
    while (true) {
      delay(1000);
    }
  }

  setenv("TZ", LOCAL_TIMEZONE, 1);
  tzset();

  fetchBKKData("F04165");
  fetchBKKData(stopId);
}

void loop() {
  if (millis() - lastApiCall > apiCallInterval) {
    lastApiCall = millis();
    Serial.printf("\n--- Frissítés ---\n");
    fetchBKKData(stopId);
  }
}

void parseBKKJson(const String& jsonString,const char* stopId) {
  DynamicJsonDocument doc(24576);
  DeserializationError error = deserializeJson(doc, jsonString);
  if (error) { Serial.print("JSON hiba: "); Serial.println(error.c_str()); return; }

  long long serverTimeMs = doc["currentTime"].as<long long>();
  long serverTimeSec = (long)(serverTimeMs / 1000LL);

  char timeBuffer[6];
  formatLocalHHMM(serverTimeSec, timeBuffer, sizeof(timeBuffer));
  Serial.print("Lekérdezés ideje: ");
  Serial.println(timeBuffer);

  JsonObject routes = doc["data"]["references"]["routes"];
  JsonObject trips  = doc["data"]["references"]["trips"];
  JsonArray stopTimes = doc["data"]["entry"]["stopTimes"];

  Serial.printf("Érkező járatok (Mesgye utca %s):\n",stopId);
  if (stopTimes.size() == 0) { Serial.println("Jelenleg nincsenek érkező járatok."); return; }

  for (JsonObject st : stopTimes) {
    const char* tripId    = st["tripId"];
    const char* routeId   = trips[tripId]["routeId"];
    const char* shortName = routes[routeId]["shortName"];
    const char* headsign  = st["stopHeadsign"];

    long predictedTimeSec = st["predictedDepartureTime"] | 0;
    if (predictedTimeSec == 0) predictedTimeSec = st["departureTime"] | 0;

    long diffSeconds = predictedTimeSec - serverTimeSec;

    long adj = (diffSeconds >= 0) ? (diffSeconds + 30) : (diffSeconds - 30);
    int minutes = (int)(adj / 60);

    char arrivalBuffer[6];
    formatLocalHHMM(predictedTimeSec, arrivalBuffer, sizeof(arrivalBuffer));

    int minutesShown = (minutes < 1) ? 0 : minutes;
    Serial.printf("%5s %2d' %4s %s\n",
      arrivalBuffer,
      minutesShown,
      shortName ? shortName : "?",
      headsign ? headsign : "?"
    );
  }

}

void fetchBKKData(const char* stopId) {
  if (WiFi.status() != WL_CONNECTED) { Serial.println("WiFi kapcsolat megszakadt."); return; }
 
  char urlBuffer[200];

  snprintf(urlBuffer, sizeof(urlBuffer),
    "https://futar.bkk.hu/api/query/v1/ws/otp/api/where/"
"arrivals-and-departures-for-stop.json?"
"key=%s&stopId=BKK_%s&minutesAfter=%d",
    BKK_API_KEY, stopId, minutesAfter);

  HTTPClient http;
  http.begin(urlBuffer);
  int httpCode = http.GET();
 
 
  if (httpCode > 0) {
    if (httpCode == HTTP_CODE_OK) parseBKKJson(http.getString(),stopId);
    else Serial.printf("Hiba a BKK API hívásakor. HTTP kód: %d\n", httpCode);
  } else {
    Serial.printf("HTTP GET hiba: %s\n", http.errorToString(httpCode).c_str());
  }
  http.end();
}

Nincsenek megjegyzések:

Megjegyzés küldése