0

A few years back I wrote a program that pulled bus time data from the NYC MTA's "bus time" API and posted it on a wifi-connected OLED on my wall. All was well for a few years, but they changed the format and the code broke. Old bus time display.

https://www.hackster.io/futurebird/esp8266-lcd-ce41fc

Today I got around to updating the code and the hardware as well. The new version is much sleeker:

enter image description here

But, not one to be easily satisfied I decided I would do the code "right" this time. Last time I pulled the XML file from the MTA and use a string search to find the bits that I needed. The XML looks like this:

<ExpectedArrivalTime>2018T14:13:46.August 12</ExpectedArrivalTime>

So I did this:

while(client.available()){
String line = client.readStringUntil('\n');
delay(60);

//pull and print the "expected arrival times" from XML
//This is just a text search, not fancy.

if ( client.findUntil("ExpectedArrivalTime>","") ) {
client.findUntil("T","");
String nextBus = client.readStringUntil('.');
lcd.clear();
lcd.setCursor(0, 0);
lcd.print("Next 2 Bx1 buses:");
lcd.setCursor(0, 1);
lcd.print(nextBus);

client.findUntil("/ExpectedArrivalTime>","");
client.findUntil("ExpectedArrivalTime>","");
client.findUntil("T","");
String nextBus2 = client.readStringUntil('.');
lcd.setCursor(0, 2);
lcd.print(nextBus2);
 delay(3000); }
 }

To isolate the time. It always felt like a kludge. I decided to pull up the JSON verson of the page and do it "correctly" using a JSON parsing library. I loaded up ArduinoJson and soon discovered that I would need code that looks like this to parse the JSON since the MTA's formatting has a lot of extra stuff in it.

DynamicJsonBuffer jsonBuffer(bufferSize);
  JsonObject& root = jsonBuffer.parseObject(http.getString());

JsonObject& Siri_ServiceDelivery = root["Siri"]["ServiceDelivery"];
const char* Siri_ServiceDelivery_ResponseTimestamp = 
 Siri_ServiceDelivery["ResponseTimestamp"]; // "2018-08-12T00:09:36.888-04:00"

 JsonObject& Siri_ServiceDelivery_StopMonitoringDelivery0 = Siri_ServiceDelivery["StopMonitoringDelivery"][0];

You get the idea. There are about 20 lines of this and none of them can be removed because the time that I want to display is so deeply nested.

So, I guess I'm just wondering if there is a better way. Both of these methods "work" just fine, but I want this to be elegant.

Is there any way that I could make the JSON file less complex? Am I overlooking a more direct and simple parsing method?

Thanks!

  • 1
    the google API may provide simpler data .... developers.google.com/transit/gtfs-realtime – jsotola Aug 12 '18 at 18:22
  • 2
    for these type of apps, i like to "proxy" the complex remote API with a nodejs or php script that fetches the remote, cleans it up on a real computer with tons of RAM, built-in libs, etc, and then makes that available locally. This makes the heavy lifting a lot easier, and you can feed the ESP a clean response with just the data you need separated out onto lines or whatever's easy to consume. – dandavis Aug 12 '18 at 20:13
  • 1
    I've resigned to using the verbose JSON code it works fine and complies small. I just wanted it to be more elegant and less application specific. – futurebird Aug 17 '18 at 12:29

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Browse other questions tagged or ask your own question.