Different results when pulling API data with MicroPython or Arduino IDE

heikki.hietala
Posts: 17
Joined: Tue Sep 04, 2018 6:47 am

Different results when pulling API data with MicroPython or Arduino IDE

Postby heikki.hietala » Sun Jun 02, 2024 5:47 am

Hi all,

I'm using an ESP32 to pull in XML flight data for Finnish airports from the Finnish Aviation Authority's API. I have managed to do it with both MicroPython and Arduino's IDE, but the data is clean only with MicroPython.

The data mass is 900,000 characters on the average, so it cannot be read at once. I read the stream and write it in a file called flights.xml, and then I parse that to get the next arriving or departing flights. This is an example of the data:
  1. <flights xmlns="http://www.finavia.fi/FlightsService.xsd" xmlns:xsd="http://www.w3.org/2001/XMLSchema">
  2. <dep>
  3. <header>
  4. <timestamp>2024-05-17T04:06:15Z</timestamp>
  5. <from>Finavia</from>
  6. <description>Departure flight data</description>
  7. </header>
  8. <body>
  9. <flight>
  10. <h_apt>HEL</h_apt>
  11. <fltnr>AY1103</fltnr>
  12. <sdt>2024-05-16T16:30:00Z</sdt>
  13. <sdate>20240516</sdate>
  14. <acreg>OHATF</acreg>
  15. <actype>AT7</actype>
  16. <mfltnr/>
  17. <cflight_1>QR6174</cflight_1>
  18. <cflight_2>JL6873</cflight_2>
  19. <cflight_3/>
  20. <cflight_4/>
  21. <cflight_5/>
  22. <cflight_6/>
  23. <route_1>VNO</route_1>
  24. <route_2/>
  25. <route_3/>
  26. <route_4/>
  27. <route_n_1>Vilnius</route_n_1>
  28. <route_n_2/>
  29. <route_n_3/>
  30. <route_n_4/>
  31. <route_n_fi_1>Vilna</route_n_fi_1>
  32. <route_n_fi_2/>
  33. <route_n_fi_3/>
  34. <route_n_fi_4/>
  35. <chkarea>200</chkarea>
  36. <chkdsk_1>211</chkdsk_1>
  37. <chkdsk_2>211</chkdsk_2>
  38. <calls_1>2024-05-16T16:13:30Z</calls_1>
  39. <calls_2/>
  40. <calls_3>2024-05-16T16:27:40Z</calls_3>
  41. <calls_4/>
  42. <park>6</park>
  43. <park_prv>8</park_prv>
  44. <gate>6</gate>
  45. <gate_prv>8</gate_prv>
  46. <prm>DEP</prm>
  47. <prt>Departed</prt>
  48. <prt_f>Lähtenyt</prt_f>
  49. <prt_s>Avgått</prt_s>
  50. <est_d>2024-05-16T16:40:00Z</est_d>
  51. <pest_d>2024-05-16T16:40:00Z</pest_d>
  52. <act_d>2024-05-16T16:42:00Z</act_d>
  53. <ablk_d>2024-05-16T16:38:00Z</ablk_d>
  54. <callsign>FIN9Q</callsign>
  55. </flight>
  56. </body>
  57. </dep>
  58. </flights>
The issue is that the C program introduces random errors into the XML, always between elements, and mostly the errors are of the type "ff9" or "ff0":

<gate>6</gate>
<gate_prv>8</gate_prv>
ff0
<prm>DEP</prm>

and so on. This is the function that gets the data in chunks of 1024 bytes (the chunk soze has no effect on the error):
  1. // Function to fetch flight data from API and store in SPIFFS
  2. void fetchFlightData() {
  3.   HTTPClient http;
  4.   http.begin(api_url);
  5.   http.addHeader("app_id", api_key);
  6.   http.addHeader("app_key", app_key);
  7.   int httpCode = http.GET();
  8.  
  9.   if (httpCode > 0) {
  10.     if (httpCode == HTTP_CODE_OK) {
  11.       WiFiClient* stream = http.getStreamPtr();
  12.       File file = SPIFFS.open("/flights.xml", FILE_WRITE);
  13.  
  14.       if (!file) {
  15.         Serial.println("Failed to open file for writing");
  16.         return;
  17.       }
  18.  
  19.       uint8_t buffer[1024];
  20.       int bytesRead;
  21.  
  22.       while (http.connected() && (bytesRead = stream->readBytes(buffer, sizeof(buffer))) > 0) {
  23.         file.write(buffer, bytesRead);
  24.       }
  25.  
  26.       file.close();
  27.       Serial.println("File written successfully");
  28.       cleanFileContents(); // Clean the file after writing
  29.     } else {
  30.       Serial.printf("HTTP GET request failed: %s\n", http.errorToString(httpCode).c_str());
  31.     }
  32.   } else {
  33.     Serial.printf("HTTP GET request failed: %s\n", http.errorToString(httpCode).c_str());
  34.   }
  35.  
  36.   http.end();
  37. }
And the relevant bit in Python:
  1. async def fetch_flight_data():
  2.     print("Getting data from API...")
  3.     headers = {
  4.         "Accept": "application/xml",
  5.         "app_id": API_KEY,
  6.         "app_key": APP_KEY
  7.     }
  8.     response = requests.get(API_URL, headers=headers)
  9.     if response.status_code == 200:
  10.         with open(RESPONSE_FILE, "wb") as file:
  11.             while True:
  12.                 chunk = response.raw.read(CHUNK_SIZE)
  13.                 if not chunk:
  14.                     break
  15.                 file.write(chunk)
  16.         print("Data written to file:", RESPONSE_FILE)
  17.     else:
  18.         print("Error fetching data:", response.status_code)
Any assistance would be of great help as I would rather code in C than in Python.

Who is online

Users browsing this forum: No registered users and 46 guests