Get your Favorite Stats Updated Constantly

Online Stats Checker w ESP32

Notice that this can apply to any ESP32 or ESP8266 with WiFi



Ever want to have a display update real time info from any website or game? 

You Can! Using a wifi and parsing library, it is really easy to setup your own IOT project to get whatever info you want.

Reference Code: https://github.com/AdaoH3/APIwTFT


What's recommended:

Processor: ESP32 or ESP8266 with WiFi compatibility (I am using an Adafruit Reverse TFT Feather S2)

Some sort of IDE: (I use Visual Studio Code with PIO Home but Arduino IDE works just fine)

API Testing Software: (I use Postman which is free and would recommend it.

Optional: Some sort of output such as a TFT display

    (VsCode for reference)


1. First install the needed libraries below:

ArduinoJSON    <- This is for parsing (sorting out) the response back from a website

Some Sort of Display Library <- Optional if you are using a display


2. Setup WiFi on your device

    a.  Include this library

#include <WiFiClientSecure.h>


    b.  Alter these to your Wifi Network (Hotspots on phone work)

// Enter your WiFi SSID and password

char ssid[] = "Hotspot1";    // your network SSID (name)

char pass[] = "NotYours"; 

    c. Begin Wifi connection in Setup

WiFi.begin(ssid, pass);

while (WiFi.status() != WL_CONNECTED) 

{

  delay(500);

  Serial.print(".");

}

This allows for wifi to initiate the connection and then prints dots to the serial monitor until connected.

    

    d. You should be connected. If you want to troubleshoot or verify your connection copy and paste this function and then call it after you connect in setup()

void printWifiStatus() {

  // Print the SSID of the network you're attached to:

  Serial.print("SSID: ");

  Serial.println(WiFi.SSID());

  // Print your board's IP address:

  IPAddress ip = WiFi.localIP();

  Serial.print("IP Address: ");

  Serial.println(ip);

  // Print the received signal strength:

  long rssi = WiFi.RSSI();

  Serial.print("Signal strength (RSSI):");

  Serial.print(rssi);

  Serial.println(" dBm");

}

3. Grab request from your website of choice

    a. Find out a website that you want to collect data from. Search up that website with API after the website name. For example searching up Quaver API leads me here:



Now you should see a bunch of requests, I would scroll through the documentation and figure out what info you want to take. 

    b. Take the Base URL (What comes before the GET request) and copy and paste it into postman under a new collection Get Request.

Please note this is not a Postman or API Tutorial, I am going to use it in the easiest way to explain which is not using the best standards. 


For example: "https://api.quavergame.com/v1" is my baseURL


    c. Then test out your get request for whatever information by pasting the other part in the link after.

For Example: "/users/full/:id" except I am replacing id with my game ID (obtained from the website) to get my information

"/users/full/609092" in my case:

You should get a response similar to this. Look to see if you got back the info you wanted.
(SAVE THIS FOR A LATER STEP)

    d. Update your actual Arduino code with the baseURL and the path:

BaseURL = https://api.quavergame.com/v1
Path = "/users/full/609092"

into

#define SERVER "api.quavergame.com"
#define PATH "/v1/users/609092/achievements"

Note: REMOVE THE "HTTPS://" FROM THE BASE URL

    e. Legit copy and paste this other code (Essentially starts a wifi client process to gather API data and saves it in the client object. If troubleshooting uncomment the return lines to understand what is going wrong.

WiFiClientSecure client;
client.setInsecure();

if (client.connect(SERVER, 443))
{
//Serial.println("Connected to server"); This is for Debugging
// Make an HTTP request:
client.println("GET " PATH " HTTP/1.1");
client.println("Host: " SERVER);
client.println("Connection: close");
client.println();
}
else
{
//return 2; // Connection failed
}

char status[32] = {0};
client.readBytesUntil('\r', status, sizeof(status));
if (strcmp(status, "HTTP/1.1 200 OK") != 0) {
Serial.print(F("Unexpected response: "));
Serial.println(status);
//return 3; // Unexpected HTTP response
}

//formats out the unnecessary info to be parsed by skipping 4 first lines
client.find("\r\n\r\n", 4);
client.println();

If you want to know more, use ChatGPT to go into depth about each process. Basically this just checks if it gets an OK server response and then formats the response in a way that can be parsed.

(First 4 lines is what gets filtered out of response) 

(This is by default sorted out on Postman, however WifiClient doesn't sort this out)

HTTP/1.1 200 OK

Content-Type: application/json

Date: [Date]

[Other Headers]


{"status":200,"achievements":[{"id":1,"steam_api_name":"BABY_STEPS", ... (rest of the JSON content)}]}


  After this you have officially gotten the request on your device. Now some filtering is just needed to be done. 


4. Use the Arduino JSON Assistant to help format a parsing response. 

https://arduinojson.org/v6/assistant/#/step1

    a. Select your settings:

Mode:

You should always probably use 

Deserialize or Deserialize and Filter 

(Filter needed if you get more info than you want from the web response and want to save space)


Input:

Just use Stream (Most memory efficient option)


    b. Setup

        1. Copy and paste your Postman or API response into the assistant's input box

        2. If any filters structure them like this (Change to your fit):












    c. Almost always select total maximum. If curious watch the youtube tutorial provided on the website. 

   d. Look at the outputted code and if it says StaticJsonDocument for creating objects, change it like I am: 

Original: 

// Stream& input;

StaticJsonDocument<48> filter;

filter["achievements"][0]["unlocked"] = true;

StaticJsonDocument<1536> doc;

DeserializationError error = deserializeJson(doc, input, DeserializationOption::Filter(filter));

if (error) {

Serial.print("deserializeJson() failed: ");

Serial.println(error.c_str());

return;

}

for (JsonObject achievement : doc["achievements"].as<JsonArray>()) {

bool achievement_unlocked = achievement["unlocked"]; // true, false, false, false, false, true, false, ...

}


 to:

 DynamicJsonDocument filter(48);

  filter["achievements"][0]["unlocked"] = true;

  DynamicJsonDocument doc(1536);

  DeserializationError error = deserializeJson(doc, client, DeserializationOption::Filter(filter));

  if (error) {

    Serial.print("deserializeJson() failed: ");

    Serial.println(error.c_str());

    return NULL; // JSON deserialization failed

  }

  for (JsonObject achievement : doc["achievements"].as<JsonArray>()) {

    bool achievement_unlocked = achievement["unlocked"];

  }

Replacing the StaticJsonDocument with DynamicJsonDocument saves a lot of space on the device.


 5. Final

 Finally paste that into your function after the get request from the WifiClient. It's up to you what you want to do with the output whether that be display information or to use them in calculations. Have fun!


My Code Reference: (Takes achievement data from a game, tallies it up and displays it):

https://github.com/AdaoH3/APIwTFT


My used references while making:

https://learn.adafruit.com/esp32-s2-reverse-tft-feather/built-in-tft TFT Display Control

https://learn.adafruit.com/esp32-s2-reverse-tft-feather/wifi-test Wifi Scan with JSON Parsing

https://arduinojson.org/ Arduino JSON Assistant

Brian Lough ArduinoJSON Tutorial                                                                    

https://wiki.quavergame.com/docs/api/users Quaver API




Comments