Nosen
Published © CC BY-SA

SL Real Time Information 4

Arduino sketch written for NodeMCU to fetch information from Stockholm Lokaltrafiks API about departures from any given stop.

IntermediateShowcase (no instructions)888
SL Real Time Information 4

Things used in this project

Hardware components

NodeMCU ESP8266 Breakout Board
NodeMCU ESP8266 Breakout Board
×1

Software apps and online services

SL Realtidsinformation 4
SL Platsuppslag

Story

Read more

Schematics

Breadboard

Schematic of hookup onto the breadboard. The NodeMCU will accept any voltage up to 20 Volts.

Code

SL_Real_Time_Information_4.ino

Arduino
Just add API keys and your wifi credentials
/*
  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(",", "]"));
}

Credits

Nosen
0 projects • 0 followers

Comments