Hardware components | ||||||
| × | 1 | ||||
Software apps and online services | ||||||
| ||||||
|
This project was about interfacing a small RAM microcontroller with the massive REST interface of the SL API, to parse json documents orders of magnitude bigger than the RAM and to make that data easily accessible to the user.
I tried many approaches but settled upon the excellent ArduinoJson library.
The code is easy to remix and use in your own project.
Default output
/*
This sketch makes use of the SL Realtidsinformation 4 API
to fetch and present the json data in the serial monitor.
It's written to be easily remixable to fit your project.
Read about the APIs here:
https://www.trafiklab.se/api/sl-realtidsinformation-4
https://www.trafiklab.se/api/sl-platsuppslag
*/
#include <WiFiClient.h>
#include <ESP8266WiFi.h>
#include <ArduinoJson.h>
// Enter your WiFi credentials here:
const char* wifiName = "your-wifi";
const char* wifiPass = "your-pass";
// Enter your API key for SL Platsuppslag here (if you don't need SL Platsuppslag just set fetchStopInfo to false):
const char* PUAPIKey = "XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX";
// Enter your API key for SL Realtidsinformation 4 here:
const char* RTD4APIKey = "XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX";
// Enter site ID (e.g. 9001 for T-centralen, 9192 for Slussen):
const char* RTD4siteID = "9001";
// Enter time window (60 minutes is max):
const char* RTD4timeWindow = "60";
const bool fetchStopInfo = true;// Set to false if not using the SL Platsuppslag API.
const bool lookForMetros = true;
const bool lookForBuses = true;
const bool lookForTrains = true;
const bool lookForTrams = true;
const bool lookForShips = true;
const bool lookForStopPointDeviations = true;
WiFiClient client;
DynamicJsonDocument doc(16 * 1024);
void setup() {
Serial.begin(115200);
delay(10);
Serial.println();
Serial.print("Connecting to ");
Serial.println(wifiName);
WiFi.begin(wifiName, wifiPass);
while (WiFi.status() != WL_CONNECTED) {
delay(500);
Serial.print(".");
}
Serial.println();
Serial.println("WiFi connected.");
Serial.print("IP address: ");
Serial.println(WiFi.localIP()); //You can get IP address assigned to ESP
if (fetchStopInfo) {
stopInfoFetcher(PUAPIKey, RTD4siteID);
}
}
void loop() {
client.connect("api.sl.se", 80);
client.print("GET /api2/realtimedeparturesV4.json?key=");
client.print(RTD4APIKey);
client.print("&siteid=");
client.print(RTD4siteID);
client.print("&timewindow=");
client.print(RTD4timeWindow);
client.println(" HTTP/1.0");
client.println("Host: api.sl.se");
client.println("Connection: close");
client.println();
if (lookForMetros) {
findTransport("Metros");
}
if (lookForBuses) {
findTransport("Buses");
}
if (lookForTrains) {
findTransport("Trains");
}
if (lookForTrams) {
findTransport("Trams");
}
if (lookForShips) {
findTransport("Ships");
}
if (lookForStopPointDeviations) {
findStopPointDeviations();
}
client.stop();
delay(300000); //GET Data at every 5 minutes
}
void stopInfoFetcher(const char* APIkey, const char* siteID) {
client.connect("api.sl.se", 80);
client.print("GET /api2/typeahead.json?key=");
client.print(APIkey);
client.print("&searchstring=");
client.print(siteID);
client.print("&stationsonly=True&maxresults=1");
client.println(" HTTP/1.0");
client.println("Host: api.sl.se");
client.println("Connection: close");
client.println();
client.find("\"ResponseData\":[");
Serial.println();
Serial.println(F("Stop Point Info: "));
do {
// Parse the JSON object
deserializeJson(doc, client);
if (doc.isNull()) {
Serial.println("No stop info found.");
break;
}
Serial.print(F("Name: "));
Serial.println(doc["Name"].as<char*>());
Serial.print(F("SiteId: "));
Serial.println(doc["SiteId"].as<char*>());
Serial.print(F("Type: "));
Serial.println(doc["Type"].as<char*>());
Serial.print(F("X: "));
Serial.println(doc["X"].as<char*>());
Serial.print(F("Y: "));
Serial.println(doc["Y"].as<char*>());
Serial.print(F("Products: "));
Serial.println(doc["Products"].as<char*>());
}
while (client.findUntil(",", "]"));
client.stop();
}
void findTransport(char* type) {
Serial.println();
Serial.print(F("#### "));
Serial.print(type);
Serial.println(F(" ####"));
char* beginning = "\"";
char* ending = "\":[";
char searchTerm[20];
sprintf(searchTerm, "%s%s%s", beginning, type, ending);
client.find(searchTerm);
do {
// Parse the JSON object
deserializeJson(doc, client);
if (doc.isNull()) {
Serial.print("No ");
Serial.print(type);
Serial.println(" found.");
break;
}
Serial.println();
Serial.print(F("GroupOfLine: "));
Serial.println(doc["GroupOfLine"].as<char*>());
Serial.print(F("DisplayTime: "));
Serial.println(doc["DisplayTime"].as<char*>());
Serial.print(F("TransportMode: "));
Serial.println(doc["TransportMode"].as<char*>());
Serial.print(F("LineNumber: "));
Serial.println(doc["LineNumber"].as<char*>());
Serial.print(F("Destination: "));
Serial.println(doc["Destination"].as<char*>());
Serial.print(F("JourneyDirection: "));
Serial.println(doc["JourneyDirection"].as<int>());
Serial.print(F("StopAreaName: "));
Serial.println(doc["StopAreaName"].as<char*>());
Serial.print(F("StopAreaNumber: "));
Serial.println(doc["StopAreaNumber"].as<int>());
Serial.print(F("StopPointNumber: "));
Serial.println(doc["StopPointNumber"].as<int>());
Serial.print(F("StopPointDesignation: "));
Serial.println(doc["StopPointDesignation"].as<char*>());
Serial.print(F("TimeTabledDateTime: "));
Serial.println(doc["TimeTabledDateTime"].as<char*>());
Serial.print(F("ExpectedDateTime: "));
Serial.println(doc["ExpectedDateTime"].as<char*>());
Serial.print(F("JourneyNumber: "));
Serial.println(doc["JourneyNumber"].as<int>());
if (doc["Deviations"].isNull() == false) {
Serial.println(F("# Deviations #"));
}
for (int i = 0; i < doc["Deviations"].size(); i++) {
Serial.print(F("Text: "));
Serial.println(doc["Deviations"][i]["Text"].as<char*>());
Serial.print(F("Consequence: "));
Serial.println(doc["Deviations"][i]["Consequence"].as<char*>());
Serial.print(F("ImportanceLevel: "));
Serial.println(doc["Deviations"][i]["ImportanceLevel"].as<int>());
}
} while (client.findUntil(",", "]"));
}
void findStopPointDeviations() {
client.find("\"StopPointDeviations\":[");
Serial.println();
Serial.println(F("#### Stop Point Deviations ####"));
do {
// Parse the JSON object
deserializeJson(doc, client);
if (doc.isNull()) {
Serial.println("No stop point deviations found.");
break;
}
Serial.println(F("# StopInfo #"));
Serial.print(F("StopAreaNumber: "));
Serial.println(doc["StopInfo"]["StopAreaNumber"].as<int>());
Serial.print(F("StopAreaName: "));
Serial.println(doc["StopInfo"]["StopAreaName"].as<char*>());
Serial.print(F("TransportMode: "));
Serial.println(doc["StopInfo"]["TransportMode"].as<char*>());
Serial.print(F("GroupOfLine: "));
Serial.println(doc["StopInfo"]["GroupOfLine"].as<char*>());
Serial.println(F("# Deviation #"));
Serial.print(F("Text: "));
Serial.println(doc["Deviation"]["Text"].as<char*>());
Serial.print(F("Consequence: "));
Serial.println(doc["Deviation"]["Consequence"].as<char*>());
Serial.print(F("ImportanceLevel: "));
Serial.println(doc["Deviation"]["ImportanceLevel"].as<int>());
} while (client.findUntil(",", "]"));
}
Comments