Arduino Uno Wifi Rev2 needs to display API

Hi everyone,
Looking for some help to realize my small project.
I have an Arduino Uno Wifi Rev2. I can connect it to my home Wifi. It get's an IP from my DHCP.
There is another device on same network that has an API.
I want my Arduino to get that API data and display it on my Serial Monitor.
The API is on "192.168.68.104/api/v1/data" and putting this in a browser it results in something like this:
"{"smr_version":50,"active_power_w":559,"active_power_l1_w":314,"active_power_l2_w":81,"active_power_l3_w":164}"
And that's what I need in a string to display.

Been trying some days now to find something workable (I'm not an educated programmer, so have to try and error with what I find on the net...)
Thanks!

image

My code up till now

#include <SPI.h>
#include <WiFiNINA.h>


char ssid[] = "XXXXXXXX";        // your network SSID (name)
char pass[] = "XXXXXXXX";    // your network password (use for WPA, or use as key for WEP)
int status = WL_IDLE_STATUS;     // the WiFi radio's status



void setup() {
  //Initialize serial and wait for port to open:
  Serial.begin(9600);
  while (!Serial) {
    ; // wait for serial port to connect. Needed for native USB port only
  }

  // check for the WiFi module:
  if (WiFi.status() == WL_NO_MODULE) {
    Serial.println("Communication with WiFi module failed!");
    // don't continue
    while (true);
  }

  String fv = WiFi.firmwareVersion();
  if (fv < WIFI_FIRMWARE_LATEST_VERSION) {
    Serial.println("Please upgrade the firmware");
  }

  // attempt to connect to WiFi network:
  while (status != WL_CONNECTED) {
    Serial.print("Attempting to connect to WPA SSID: ");
    Serial.println(ssid);
    // Connect to WPA/WPA2 network:
    status = WiFi.begin(ssid, pass);

    // wait 10 seconds for connection:
    delay(10000);
  }

  // you're connected now, so print out the data:
  Serial.print("You're connected to the network");
  printCurrentNet();
  printWifiData();

}

void loop() {
  

}

void printWifiData() {
  // print your board's IP address:
  IPAddress ip = WiFi.localIP();
  Serial.print("IP Address: ");
  Serial.println(ip);
  Serial.println(ip);

  // print your MAC address:
  byte mac[6];
  WiFi.macAddress(mac);
  Serial.print("MAC address: ");
  printMacAddress(mac);
}

void printCurrentNet() {
  // print the SSID of the network you're attached to:
  Serial.print("SSID: ");
  Serial.println(WiFi.SSID());

  // print the MAC address of the router you're attached to:
  byte bssid[6];
  WiFi.BSSID(bssid);
  Serial.print("BSSID: ");
  printMacAddress(bssid);

  // print the received signal strength:
  long rssi = WiFi.RSSI();
  Serial.print("signal strength (RSSI):");
  Serial.println(rssi);

  // print the encryption type:
  byte encryption = WiFi.encryptionType();
  Serial.print("Encryption Type:");
  Serial.println(encryption, HEX);
  Serial.println();
}

void printMacAddress(byte mac[]) {
  for (int i = 5; i >= 0; i--) {
    if (mac[i] < 16) {
      Serial.print("0");
    }
    Serial.print(mac[i], HEX);
    if (i > 0) {
      Serial.print(":");
    }
  }
  Serial.println();
}

The WiFiWebClient example of the WiFiNINA library shows you how to do that.

Thanks for your reply 'pylon', appreciated!
But... I tried this out and the only thing I got in the SerialMonitor was: "connected"
Then the HTTP Get request goes out, but how do I capture/see the API reply in my SerialMonitor?
(I'm a 70+y old trying to do modern stuff, enjoying it, but learning new stuff is getting hard :slight_smile:

This is the part of the example that displays the response on Serial Monitor:

void loop() {
  // if there are incoming bytes available
  // from the server, read them and print them:
  while (client.available()) {
    char c = client.read();
    Serial.write(c);
  }

If you want to get the data repeatedly, use the WiFiWebClientRepeating example.

1 Like

Do you have an manual for the API you want to use? Some APIs need some header fields to have specific values. We cannot know what these requirements are.

If you tried that code why don't you post that code? In the posted code you don't even try to access the API.

1 Like

Thanks guys, this helped me in the right direction.
I've got the values that i need out of the API.

This is the subroutine that reads my data and prints it:

Citaat

void MeasureNow()
{
    if (client.connect(server, 80)) {
      Serial.print("connected --- ");
    }
      // Make a HTTP request:
      Serial.print("Sending HTTP request --- ");
      lcd.setCursor(0,1);
      lcd.print("HTTPrequest sent");
      client.println("GET /api/v1/data  HTTP/1.1");
      client.println();
  
// if there are incoming bytes available
// from the server, read them and print them:
Serial.println("Receiving --- "); 
delay(1000); 

  while (client.available()) {
    char c = client.read();
    Serial.write(c);   

// Skip HTTP headers
  char endOfHeaders[] = "\r\n\r\n";
  if (!client.find(endOfHeaders)) {
    Serial.println(F("Invalid response"));
    client.stop();
    return;
  }
 //Deserialization 
StaticJsonDocument<16> filter;
filter["active_power_w"] = true;

StaticJsonDocument<64> doc;

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

if (error) {
  Serial.print(F("deserializeJson() failed: "));
  Serial.println(error.f_str());
  return;
}
int active_power_w = doc["active_power_w"]; // -1808
Serial.println();
Serial.print("SolarPower NOW = ");
Serial.println(active_power_w);
lcd.clear();
lcd.setCursor(0,0);
lcd.print("Available Power");
lcd.setCursor(0,1);
lcd.print(active_power_w);
}
}

You should probably add some code to tell you if the connection fails:

void MeasureNow()
{
    if (client.connect(server, 80)) {
      Serial.print("connected --- ");
    }
    else
    {
      Serial.println("Connection failed.");
      return; // Nothing more we can do.
    }
1 Like

This topic was automatically closed 180 days after the last reply. New replies are no longer allowed.