mirror of
https://github.com/skoelle/wt32sc01-dashboard.git
synced 2026-09-17 17:30:25 +00:00
Phase 0/2: API layer kept 1:1, only secrets.h include path fixed
http_client/weather_api/calendar_api/departures_api are hardware- independent (HTTP GET + ArduinoJson parsing, same endpoints, same JSON). Kept verbatim per PLAN.md migration strategy; only changed #include "../../include/secrets.h" -> #include <secrets.h> to match the PlatformIO include/ layout (no functional change).
This commit is contained in:
@@ -0,0 +1,27 @@
|
||||
#include "calendar_api.h"
|
||||
#include "http_client.h"
|
||||
#include <secrets.h>
|
||||
#include <ArduinoJson.h>
|
||||
|
||||
CalendarData fetchCalendar() {
|
||||
CalendarData data;
|
||||
ApiResult res = httpGet(CALENDAR_API_URL);
|
||||
if (!res.success) { data.valid = false; return data; }
|
||||
|
||||
DynamicJsonDocument doc(8192);
|
||||
if (deserializeJson(doc, res.body)) { data.valid = false; return data; }
|
||||
|
||||
JsonArray events = doc["events"];
|
||||
for (JsonObject e : events) {
|
||||
CalendarEvent ev;
|
||||
ev.id = e["id"] | 0;
|
||||
ev.summary = e["summary"] | "";
|
||||
ev.startAt = e["start_at"] | "";
|
||||
ev.endAt = e["end_at"] | "";
|
||||
ev.allDay = e["all_day"] | false;
|
||||
ev.status = e["status"] | "";
|
||||
data.events.push_back(ev);
|
||||
}
|
||||
data.valid = true;
|
||||
return data;
|
||||
}
|
||||
@@ -0,0 +1,19 @@
|
||||
#pragma once
|
||||
#include <Arduino.h>
|
||||
#include <vector>
|
||||
|
||||
struct CalendarEvent {
|
||||
long id = 0;
|
||||
String summary;
|
||||
String startAt;
|
||||
String endAt;
|
||||
bool allDay = false;
|
||||
String status;
|
||||
};
|
||||
|
||||
struct CalendarData {
|
||||
bool valid = false;
|
||||
std::vector<CalendarEvent> events;
|
||||
};
|
||||
|
||||
CalendarData fetchCalendar();
|
||||
@@ -0,0 +1,30 @@
|
||||
#include "departures_api.h"
|
||||
#include "http_client.h"
|
||||
#include <secrets.h>
|
||||
#include <ArduinoJson.h>
|
||||
|
||||
DeparturesData fetchDepartures() {
|
||||
DeparturesData data;
|
||||
ApiResult res = httpGet(DEPARTURES_API_URL);
|
||||
if (!res.success) { data.valid = false; return data; }
|
||||
|
||||
DynamicJsonDocument doc(16384);
|
||||
if (deserializeJson(doc, res.body)) { data.valid = false; return data; }
|
||||
|
||||
JsonArray departures = doc["departures"];
|
||||
for (JsonObject d : departures) {
|
||||
Departure dep;
|
||||
dep.station = d["station"] | "";
|
||||
dep.type = d["type"] | "";
|
||||
dep.icon = d["icon"] | "";
|
||||
dep.line = d["line"] | "";
|
||||
dep.destination = d["destination"] | "";
|
||||
dep.timeEpoch = d["time_epoch"] | 0;
|
||||
dep.timeStr = d["time_str"] | "";
|
||||
dep.delayMin = d["delay_min"] | 0;
|
||||
dep.cancelled = d["cancelled"] | false;
|
||||
data.departures.push_back(dep);
|
||||
}
|
||||
data.valid = true;
|
||||
return data;
|
||||
}
|
||||
@@ -0,0 +1,22 @@
|
||||
#pragma once
|
||||
#include <Arduino.h>
|
||||
#include <vector>
|
||||
|
||||
struct Departure {
|
||||
String station;
|
||||
String type;
|
||||
String icon;
|
||||
String line;
|
||||
String destination;
|
||||
long timeEpoch = 0;
|
||||
String timeStr;
|
||||
int delayMin = 0;
|
||||
bool cancelled = false;
|
||||
};
|
||||
|
||||
struct DeparturesData {
|
||||
bool valid = false;
|
||||
std::vector<Departure> departures;
|
||||
};
|
||||
|
||||
DeparturesData fetchDepartures();
|
||||
@@ -0,0 +1,25 @@
|
||||
#include "http_client.h"
|
||||
#include <HTTPClient.h>
|
||||
#include <WiFi.h>
|
||||
|
||||
ApiResult httpGet(const String &url, uint32_t timeoutMs) {
|
||||
ApiResult result;
|
||||
if (WiFi.status() != WL_CONNECTED) {
|
||||
result.success = false;
|
||||
result.httpCode = -1;
|
||||
return result;
|
||||
}
|
||||
HTTPClient http;
|
||||
http.setTimeout(timeoutMs);
|
||||
http.begin(url);
|
||||
int code = http.GET();
|
||||
result.httpCode = code;
|
||||
if (code == HTTP_CODE_OK) {
|
||||
result.body = http.getString();
|
||||
result.success = true;
|
||||
} else {
|
||||
result.success = false;
|
||||
}
|
||||
http.end();
|
||||
return result;
|
||||
}
|
||||
@@ -0,0 +1,10 @@
|
||||
#pragma once
|
||||
#include <Arduino.h>
|
||||
|
||||
struct ApiResult {
|
||||
bool success = false;
|
||||
String body;
|
||||
int httpCode = -1;
|
||||
};
|
||||
|
||||
ApiResult httpGet(const String &url, uint32_t timeoutMs = 5000);
|
||||
@@ -0,0 +1,44 @@
|
||||
#include "weather_api.h"
|
||||
#include "http_client.h"
|
||||
#include <secrets.h>
|
||||
#include <ArduinoJson.h>
|
||||
|
||||
WeatherData fetchWeather() {
|
||||
WeatherData data;
|
||||
ApiResult res = httpGet(WEATHER_API_URL);
|
||||
if (!res.success) { data.valid = false; return data; }
|
||||
|
||||
DynamicJsonDocument doc(8192);
|
||||
if (deserializeJson(doc, res.body)) { data.valid = false; return data; }
|
||||
|
||||
JsonObject current = doc["current"];
|
||||
data.current.temperature = current["temperature"] | 0;
|
||||
data.current.symbol = current["symbol"] | "";
|
||||
data.current.description = current["description"] | "";
|
||||
|
||||
JsonArray forecast = doc["forecast"];
|
||||
for (JsonObject entry : forecast) {
|
||||
ForecastEntry fe;
|
||||
fe.time = entry["time"] | "";
|
||||
fe.temperature = entry["temperature"] | 0;
|
||||
fe.symbol = entry["symbol"] | "";
|
||||
fe.description = entry["description"] | "";
|
||||
JsonObject precip = entry["precipitation"];
|
||||
fe.precipitationProbability = precip["probability"] | 0.0f;
|
||||
fe.precipitationType = precip["type"] | "";
|
||||
data.forecast.push_back(fe);
|
||||
}
|
||||
data.valid = true;
|
||||
return data;
|
||||
}
|
||||
|
||||
bool willRainSoon(const WeatherData &data, int hours) {
|
||||
if (!data.valid) return false;
|
||||
int checked = 0;
|
||||
for (const auto &entry : data.forecast) {
|
||||
if (checked >= hours) break;
|
||||
if (entry.precipitationType == "rain" && entry.precipitationProbability > 0.0f) return true;
|
||||
checked++;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
@@ -0,0 +1,27 @@
|
||||
#pragma once
|
||||
#include <Arduino.h>
|
||||
#include <vector>
|
||||
|
||||
struct WeatherCurrent {
|
||||
int temperature = 0;
|
||||
String symbol;
|
||||
String description;
|
||||
};
|
||||
|
||||
struct ForecastEntry {
|
||||
String time;
|
||||
int temperature = 0;
|
||||
String symbol;
|
||||
String description;
|
||||
float precipitationProbability = 0.0f;
|
||||
String precipitationType;
|
||||
};
|
||||
|
||||
struct WeatherData {
|
||||
bool valid = false;
|
||||
WeatherCurrent current;
|
||||
std::vector<ForecastEntry> forecast;
|
||||
};
|
||||
|
||||
WeatherData fetchWeather();
|
||||
bool willRainSoon(const WeatherData &data, int hours = 8);
|
||||
Reference in New Issue
Block a user