Newbie help <please> Arduino Server URL parsing parameters

Hello all
I'm building a weather station and I'm totally new to both Arduino and C++ programming so please bare with me and try and help.
I believe my problem is quite simple.
The weather station uses a server that if you access it via 192.168.10.45:8081 responds with an html output page giving you temperature, windspeed, wind direction etc. So far so good, and that really works great.
What I need is to be able to also get json output for these values, so I'm assuming that passing a url type parameter (or flag or switch if you prefer) would do the trick, thus 192.168.10.45:8081/?json or 192.168.10.45:8081/json or whatever it needs to work...

So here's the html output

  // listen for incoming clients
  EthernetClient client = server.available();
  if (client) {
    // an http request ends with a blank line
    boolean currentLineIsBlank = true;
    while (client.connected()) {
      if (client.available()) {
        char c = client.read();
        Serial.write(c);
        // if you've gotten to the end of the line (received a newline
        // character) and the line is blank, the http request has ended,
        // so you can send a reply
        if (c == '\n' && currentLineIsBlank) {
          // send a standard http response header
          digitalWrite(TX_Pin, HIGH);
          client.println("HTTP/1.1 200 OK");
          client.println("Content-Type: text/html");
          client.println("Connection: close"); // connection closed completion of response
          client.println("Refresh: 10"); // refresh the page automatically every 10 sec
          client.println();
          client.println("<!DOCTYPE HTML>");
          client.print("<HTML><HEAD><TITLE>RadioActive Weather Server</TITLE></HEAD>");
          client.println("<font color='red'><h2>RadioActive Weather Server</font></h2>");
          client.print("Agios Merkouris, Sifnos @ 36.987832, 24.719809<br><br>");
          client.println("<html><body>");
          digitalWrite(TX_Pin, HIGH); // Turn the TX LED on
          client.print("<span style=\"font-size: 26px\";>Outside Temperature now ");
          client.print(sensors.getTempCByIndex(1));
          client.println("C<br>");
          client.print("<br> Inside Temperature now ");
          client.print(sensors.getTempCByIndex(0));
          client.println("C<br>");
          client.print("<br> Wind Speed now ");
          client.print(WindSpeed);
          client.println(" mph || ");
          client.println(getKnots(WindSpeed));
          client.println(" Knots || ");
          client.println(getWindStrength(WindSpeed));
          client.println(" Beauforts<br>");
          getWindDirection();
// Only update the display if change greater than 5 degrees.
          if(abs(CalDirection - LastValue) > 5) {
            LastValue = CalDirection;
          }
          client.print("<br> Direction now ");
          client.print(CalDirection);
          client.print(direction(CalDirection));
          client.println("<br>");
          client.print("<br> Humidity now ");
          client.print(bme.getHumidity());
          client.println("%<br>");
          client.print("<br> Pressure now ");
          client.print(bme.getPressure_MB());
          client.println("mb%<br>");
          client.println("<font color='blue'>");
          client.print("<br> Outside Min Temperature was ");
          client.print(OutminTemp);
          client.println("C<br>");
          client.print("<br> Outside Max Temperature was ");
          client.print(OutmaxTemp);
          client.println("C<br>");
          client.println("<font color='green'>");
          client.print("<br> Inside Min Temperature was ");
          client.print(InminTemp);
          client.println("C<br>");
          client.print("<br> Inside Max Temperature was ");
          client.print(InmaxTemp);
          client.println("C");
          client.println("</font></body></html>");
          digitalWrite(TX_Pin, LOW); // Turn the TX LED off
          break;
        }
        if (c == '\n') {
          // you're starting a new line
          currentLineIsBlank = true;
        } else if (c != '\r') {
          // you've gotten a character on the current line
          currentLineIsBlank = false;
        }
      }
    }
  }

  // give the web browser time to receive the data
  delay(1);
  // close the connection:
  client.stop();
}

and here's the json output

  // listen for incoming clients
  EthernetClient client = server.available();
  if (client) {
    // an http request ends with a blank line
    boolean currentLineIsBlank = true;
    while (client.connected()) {
      if (client.available()) {
        char c = client.read();
        Serial.write(c);
        // if you've gotten to the end of the line (received a newline
        // character) and the line is blank, the http request has ended,
        // so you can send a reply
        if (c == '\n' && currentLineIsBlank) {
          // send a standard http response header
          digitalWrite(TX_Pin, HIGH); // Turn the TX LED on
          client.println("HTTP/1.1 200 OK");
          client.println("Content-Type: application/json");
          client.println("Connection: close"); // connection closed completion of response
          client.println("Refresh: 10"); // refresh the page automatically every 10 sec
          client.println();
          client.println("{");

          // TODO: determine if GPS be read from device ?

          client.println("    \"location\": {");
          client.println("        \"city\": \"Agios Merkouris, Sifnos\",");
          client.println("        \"country\": \"gr\",");
          client.println("        \"latitude\": \"36.987832\",");
          client.println("        \"longitude\": \"24.719809\"");
          client.println("    },");

          // [Temperature]
          client.println("    \"temperature\": {");

          // Celsius
          client.print("        \"current\": \"");
          client.print(sensors.getTempCByIndex(1));
          client.println("\"");
          client.println("    },");

          // [Wind conditions]
          getWindDirection();
          client.println("    \"wind\": {");

          client.print("        \"direction\": \"");
          client.print(direction(calDirection));
          client.println("\",");

          client.print("        \"direction-degrees\": \"");
          client.print(calDirection);
          client.println("\",");

          // KPH
          client.print("        \"current-speed\": \"");
          client.print(windSpeed);
          client.println("\",");

          // TODO: GUST SPEED
          // KPH
          client.print("        \"current-gust\": \"");
          client.print(0);
          client.println("\"");

          client.println("    },");


          // [Other data]
          client.println("    \"other\": {");

          client.print("        \"humidity\": \"");
          client.print(bme.getHumidity());
          client.println("\",");

          client.print("        \"pressure\": \"");
          client.print(bme.getPressure_MB());
          client.println("\"");
          client.println("    }");

          client.println("}");

          digitalWrite(TX_Pin, LOW); // Turn the TX LED off
          break;
        }
        if (c == '\n') {
          // you're starting a new line
          currentLineIsBlank = true;
        } else if (c != '\r') {
          // you've gotten a character on the current line
          currentLineIsBlank = false;
        }
      }
    }
  }

  // give the web browser time to receive the data
  delay(1);
  // close the connection:
  client.stop();
}

How can I pass and then read the url parameter and if json, then only output the json output and if not then output the html?
Thank you for listening :slight_smile:

Hi, I assume you are using an Arduino with an Ethernet card

this part of the code

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

listens to what's coming from the browsers, prints it to the Serial monitor but does not record it. It's just thrown away. You need to record the URL into a buffer of some sort and then parse the URL.

Hi @tpapas!

You could try having a look at this example code from this post.

Key commands are readString and readString.indexOf.

You could search for your keywords in the query string and then direct your program to deliver JSON or HTTP content accordingly.

Let us know how you get on :smiley:

Richard


//zoomkat 10-6-13
//simple button GET with iframe code
//open serial monitor to see what the arduino receives
//use the ' instead of " in html ilnes 
//address will look like http://192.168.1.102:84/ when submited
//for use with W5100 based ethernet shields

#include <SPI.h>
#include <Ethernet.h>

byte mac[] = { 0xDE, 0xAD, 0xBE, 0xEF, 0xFE, 0xED }; //ethernet shield mac address
byte ip[] = { 192, 168, 1, 102 }; // arduino IP in lan
byte gateway[] = { 192, 168, 1, 1 }; // internet access via router
byte subnet[] = { 255, 255, 255, 0 }; //subnet mask
EthernetServer server(84); //server port

String readString; 

//////////////////////

void setup(){

  pinMode(4, OUTPUT); //pin selected to control
  //start Ethernet
  Ethernet.begin(mac, ip, gateway, gateway, subnet);
  server.begin();

  //enable serial data print 
  Serial.begin(9600); 
  Serial.println("servertest1"); // so I can keep track of what is loaded
}

void loop(){
  // Create a client connection
  EthernetClient client = server.available();
  if (client) {
    while (client.connected()) {
      if (client.available()) {
        char c = client.read();

        //read char by char HTTP request
        if (readString.length() < 100) {

          //store characters to string 
          readString += c; 
          //Serial.print(c);
        } 

        //if HTTP request has ended
        if (c == '\n') {

          ///////////////
          Serial.println(readString); //print to serial monitor for debuging 

          //now output HTML data header
             if(readString.indexOf('?') >=0) { //don't send new page
               client.println("HTTP/1.1 204 Zoomkat");
               client.println();
               client.println();  
             }
             else {
          client.println("HTTP/1.1 200 OK"); //send new page
          client.println("Content-Type: text/html");
          client.println();

          client.println("<HTML>");
          client.println("<HEAD>");
          client.println("<TITLE>Arduino GET test page</TITLE>");
          client.println("</HEAD>");
          client.println("<BODY>");

          client.println("<H1>Zoomkat's simple Arduino button</H1>");
          
          client.println("<a href='/?on1' target='inlineframe'>ON</a>"); 
          client.println("<a href='/?off' target='inlineframe'>OFF</a>"); 

          client.println("<IFRAME name=inlineframe style='display:none'>");          
          client.println("</IFRAME>");

          client.println("</BODY>");
          client.println("</HTML>");
             }

          delay(1);
          //stopping client
          client.stop();

          ///////////////////// control arduino pin
          if(readString.indexOf("on1") >0)//checks for on
          {
            digitalWrite(4, HIGH);    // set pin 4 high
            Serial.println("Led On");
          }
          if(readString.indexOf("off") >0)//checks for off
          {
            digitalWrite(4, LOW);    // set pin 4 low
            Serial.println("Led Off");
          }
          //clearing string for next read
          readString="";

        }
      }
    }
  }
}

to be on the safe side, adding a

readString.reserve(50); // whatever size you think your largest URL will be

in the setup would help minimise dynamic memory allocation as the buffer grows.

Of course, the if (readString.length() < 100) { might come and bite you if the URL is longer than that.

Thank you so much for this valuable input...
I still don't understand a few things though.

  1. If I need json output would I be passing : 192.168.10.45:8081/json
  2. If above is correct, then how could I state that if "/json" then execute the json part and if not then do the html part?

in the proposed code from @R11K , you test for some special keywords in the URL in this way

if(readString.indexOf("HELLO") >=0) { // look for HELLO in the String and returns the index of the 'H' or -1 if not found
  // URL contained HELLO
}
else 
...

so it would be just a matter of test for "/json" for example or just "json"

Ok, I tried to do it but it gives an error... Maybe I did something wrong or maybe it's missing a "}" somewhere... I 'm not sure!
Here's what I did:

  // listen for incoming clients
  EthernetClient client = server.available();
  if (client) {

    if(readString.indexOf("json") >=0) { // look for json in the String and returns the index of the 'j' or -1 if not found
       // URL contained json
      boolean currentLineIsBlank = true;
      while (client.connected()) {
      if (client.available()) {
        char c = client.read();
        Serial.write(c);
        // if you've gotten to the end of the line (received a newline
        // character) and the line is blank, the http request has ended,
        // so you can send a reply
        if (c == '\n' && currentLineIsBlank) {
          // send a standard http response header
          digitalWrite(TX_Pin, HIGH); // Turn the TX LED on
          client.println("HTTP/1.1 200 OK");
          client.println("Content-Type: application/json");
          client.println("Connection: close"); // connection closed completion of response
          client.println("Refresh: 10"); // refresh the page automatically every 10 sec
          client.println();
          client.println("{");
          // [Temperature]
          client.println("    \"temperature\": {");
          // Celsius
          client.print("        \"current\": \"");
          client.print(sensors.getTempCByIndex(1));
          client.println("\"");
          client.println("    },");
          // [Wind conditions]
          getWindDirection();
          client.println("    \"wind\": {");
          client.print("        \"direction\": \"");
          client.print(direction(calDirection));
          client.println("\",");
          client.print("        \"direction-degrees\": \"");
          client.print(calDirection);
          client.println("\",");
          // KPH
          client.print("        \"current-speed\": \"");
          client.print(windSpeed);
          client.println("\",");
          // TODO: GUST SPEED
          // KPH
          client.print("        \"current-gust\": \"");
          client.print(0);
          client.println("\"");
          client.println("    },");
          // [Other data]
          client.println("    \"other\": {");
          client.print("        \"humidity\": \"");
          client.print(bme.getHumidity());
          client.println("\",");
          client.print("        \"pressure\": \"");
          client.print(bme.getPressure_MB());
          client.println("\"");
          client.println("    }");
          client.println("}");
          digitalWrite(TX_Pin, LOW); // Turn the TX LED off
          break;
          }
            if (c == '\n') {
             // you're starting a new line
             currentLineIsBlank = true;
           } else if (c != '\r') {
             // you've gotten a character on the current line
             currentLineIsBlank = false;
           }
         }
        }
      }
  // give the web browser time to receive the data
  delay(1);
  // close the connection:
  client.stop();
     }
    }
else 
    // an http request ends with a blank line
    boolean currentLineIsBlank = true;
    while (client.connected()) {
      if (client.available()) {
        char c = client.read();
        Serial.write(c);
        // if you've gotten to the end of the line (received a newline
        // character) and the line is blank, the http request has ended,
        // so you can send a reply
        if (c == '\n' && currentLineIsBlank) {
          // send a standard http response header
          digitalWrite(TX_Pin, HIGH);
          client.println("HTTP/1.1 200 OK");
          client.println("Content-Type: text/html");
          client.println("Connection: close"); // connection closed completion of response
          client.println("Refresh: 10"); // refresh the page automatically every 10 sec
          client.println();
          client.println("<!DOCTYPE HTML>");
          client.print("<HTML><HEAD><TITLE>RadioActive Weather Server</TITLE></HEAD>");
          client.println("<font color='red'><h2>RadioActive Weather Server</font></h2>");
          client.print("Agios Merkouris, Sifnos @ 36.987832, 24.719809<br><br>");
          client.println("<html><body>");
          digitalWrite(TX_Pin, HIGH); // Turn the TX LED on
          client.print("<span style=\"font-size: 26px\";>Outside Temperature now ");
          client.print(sensors.getTempCByIndex(1));
          client.println("C<br>");
          client.print("<br> Inside Temperature now ");
          client.print(sensors.getTempCByIndex(0));
          client.println("C<br>");
          client.print("<br> Wind Speed now ");
          client.print(WindSpeed);
          client.println(" mph || ");
          client.println(getKnots(WindSpeed));
          client.println(" Knots || ");
          client.println(getWindStrength(WindSpeed));
          client.println(" Beauforts<br>");
          getWindDirection();
// Only update the display if change greater than 5 degrees.
          if(abs(CalDirection - LastValue) > 5) {
            LastValue = CalDirection;
          }
          client.print("<br> Direction now ");
          client.print(CalDirection);
          client.print(direction(CalDirection));
          client.println("<br>");
          client.print("<br> Humidity now ");
          client.print(bme.getHumidity());
          client.println("%<br>");
          client.print("<br> Pressure now ");
          client.print(bme.getPressure_MB());
          client.println("mb%<br>");
          client.println("<font color='blue'>");
          client.print("<br> Outside Min Temperature was ");
          client.print(OutminTemp);
          client.println("C<br>");
          client.print("<br> Outside Max Temperature was ");
          client.print(OutmaxTemp);
          client.println("C<br>");
          client.println("<font color='green'>");
          client.print("<br> Inside Min Temperature was ");
          client.print(InminTemp);
          client.println("C<br>");
          client.print("<br> Inside Max Temperature was ");
          client.print(InmaxTemp);
          client.println("C");
          client.println("</font></body></html>");
          digitalWrite(TX_Pin, LOW); // Turn the TX LED off
          break;
          }
            if (c == '\n') {
              // you're starting a new line
              currentLineIsBlank = true;
            } else if (c != '\r') {
              // you've gotten a character on the current line
              currentLineIsBlank = false;
            }
          }
        }
      }

      // give the web browser time to receive the data
      delay(1);
      // close the connection:
      client.stop();
    }
 }

A compiler error?

The specific error message should help you to locate the problem.

Maybe paste it here if it’s perplexing you.

Thank you... Yes a compiler error
This is what it says:

Arduino: 1.8.13 (Windows 7), Board: "Arduino Mega or Mega 2560, ATmega2560 (Mega 2560)"
C:\Users\Riris\Dropbox\Arduino\Arduino\WeatherStation_with_email_MEGA_plus_Watchdog\WeatherStation_with_email_MEGA_plus_Watchdog.ino: In function 'void setup()':

WeatherStation_with_email_MEGA_plus_Watchdog:126:26: error: 'isr_timer' was not declared in this scope

Timer1.attachInterrupt(isr_timer);

                      ^~~~~~~~~

WeatherStation_with_email_MEGA_plus_Watchdog:254:1: error: expected unqualified-id before 'else'

else

^~~~

WeatherStation_with_email_MEGA_plus_Watchdog:257:5: error: expected unqualified-id before 'while'

 while (client.connected()) {

 ^~~~~

WeatherStation_with_email_MEGA_plus_Watchdog:333:7: error: expected declaration before '}' token

   }

   ^

exit status 1

'isr_timer' was not declared in this scope

And here's the code again, a little more of it this time:

 // listen for incoming clients
  EthernetClient client = server.available();
  if (client) {

    if(readString.indexOf("json") >=0) { // look for json in the String and returns the index of the 'j' or -1 if not found
       // URL contained json
      boolean currentLineIsBlank = true;
      while (client.connected()) {
      if (client.available()) {
        char c = client.read();
        Serial.write(c);
        // if you've gotten to the end of the line (received a newline
        // character) and the line is blank, the http request has ended,
        // so you can send a reply
        if (c == '\n' && currentLineIsBlank) {
          // send a standard http response header
          digitalWrite(TX_Pin, HIGH); // Turn the TX LED on
          client.println("HTTP/1.1 200 OK");
          client.println("Content-Type: application/json");
          client.println("Connection: close"); // connection closed completion of response
          client.println("Refresh: 10"); // refresh the page automatically every 10 sec
          client.println();
          client.println("{");
          // [Temperature]
          client.println("    \"temperature\": {");
          // Celsius
          client.print("        \"current\": \"");
          client.print(sensors.getTempCByIndex(1));
          client.println("\"");
          client.println("    },");
          // [Wind conditions]
          getWindDirection();
          client.println("    \"wind\": {");
          client.print("        \"direction\": \"");
          client.print(direction(calDirection));
          client.println("\",");
          client.print("        \"direction-degrees\": \"");
          client.print(calDirection);
          client.println("\",");
          // KPH
          client.print("        \"current-speed\": \"");
          client.print(windSpeed);
          client.println("\",");
          // TODO: GUST SPEED
          // KPH
          client.print("        \"current-gust\": \"");
          client.print(0);
          client.println("\"");
          client.println("    },");
          // [Other data]
          client.println("    \"other\": {");
          client.print("        \"humidity\": \"");
          client.print(bme.getHumidity());
          client.println("\",");
          client.print("        \"pressure\": \"");
          client.print(bme.getPressure_MB());
          client.println("\"");
          client.println("    }");
          client.println("}");
          digitalWrite(TX_Pin, LOW); // Turn the TX LED off
          break;
          }
            if (c == '\n') {
             // you're starting a new line
             currentLineIsBlank = true;
           } else if (c != '\r') {
             // you've gotten a character on the current line
             currentLineIsBlank = false;
           }
         }
        }
      }
  // give the web browser time to receive the data
  delay(1);
  // close the connection:
  client.stop();
     }
    }
else 
    // an http request ends with a blank line
    boolean currentLineIsBlank = true;
    while (client.connected()) {
      if (client.available()) {
        char c = client.read();
        Serial.write(c);
        // if you've gotten to the end of the line (received a newline
        // character) and the line is blank, the http request has ended,
        // so you can send a reply
        if (c == '\n' && currentLineIsBlank) {
          // send a standard http response header
          digitalWrite(TX_Pin, HIGH);
          client.println("HTTP/1.1 200 OK");
          client.println("Content-Type: text/html");
          client.println("Connection: close"); // connection closed completion of response
          client.println("Refresh: 10"); // refresh the page automatically every 10 sec
          client.println();
          client.println("<!DOCTYPE HTML>");
          client.print("<HTML><HEAD><TITLE>RadioActive Weather Server</TITLE></HEAD>");
          client.println("<font color='red'><h2>RadioActive Weather Server</font></h2>");
          client.print("Agios Merkouris, Sifnos @ 36.987832, 24.719809<br><br>");
          client.println("<html><body>");
          digitalWrite(TX_Pin, HIGH); // Turn the TX LED on
          client.print("<span style=\"font-size: 26px\";>Outside Temperature now ");
          client.print(sensors.getTempCByIndex(1));
          client.println("C<br>");
          client.print("<br> Inside Temperature now ");
          client.print(sensors.getTempCByIndex(0));
          client.println("C<br>");
          client.print("<br> Wind Speed now ");
          client.print(WindSpeed);
          client.println(" mph || ");
          client.println(getKnots(WindSpeed));
          client.println(" Knots || ");
          client.println(getWindStrength(WindSpeed));
          client.println(" Beauforts<br>");
          getWindDirection();
// Only update the display if change greater than 5 degrees.
          if(abs(CalDirection - LastValue) > 5) {
            LastValue = CalDirection;
          }
          client.print("<br> Direction now ");
          client.print(CalDirection);
          client.print(direction(CalDirection));
          client.println("<br>");
          client.print("<br> Humidity now ");
          client.print(bme.getHumidity());
          client.println("%<br>");
          client.print("<br> Pressure now ");
          client.print(bme.getPressure_MB());
          client.println("mb%<br>");
          client.println("<font color='blue'>");
          client.print("<br> Outside Min Temperature was ");
          client.print(OutminTemp);
          client.println("C<br>");
          client.print("<br> Outside Max Temperature was ");
          client.print(OutmaxTemp);
          client.println("C<br>");
          client.println("<font color='green'>");
          client.print("<br> Inside Min Temperature was ");
          client.print(InminTemp);
          client.println("C<br>");
          client.print("<br> Inside Max Temperature was ");
          client.print(InmaxTemp);
          client.println("C");
          client.println("</font></body></html>");
          digitalWrite(TX_Pin, LOW); // Turn the TX LED off
          break;
          }
            if (c == '\n') {
              // you're starting a new line
              currentLineIsBlank = true;
            } else if (c != '\r') {
              // you've gotten a character on the current line
              currentLineIsBlank = false;
            }
          }
        }
      }

      // give the web browser time to receive the data
      delay(1);
      // close the connection:
      client.stop();
    }
 }

// Interrupt handler routine for timer interrupt
void isr_timer() {

  TimerCount++;
  if (TimerCount == 6) {
//  IsSampleRequired = true;
//            if(IsSampleRequired) {
// convert to mp/h using the formula V=P(2.25/T)
// V = P(2.25/2.5) = P * 0.9
  WindSpeed = Rotations * 0.9;
        Rotations = 0; // Reset count for next sample
//      IsSampleRequired = false;
  TimerCount = 0;
  }
}

post the full code

Of course, I just didn't want to bother you with the whole thing...
I'm pretty sure it's missing "}" somewhere inthere but I can't find it :slight_smile:
Here's the whole code:

#include <SPI.h>
#include <Ethernet.h>
#include <OneWire.h>
#include <DallasTemperature.h>
#include "TimerOne.h"
#include <math.h>
#include "cactus_io_BME280_I2C.h"
#include <EMailSender.h>
#include <Watchdog.h>
#define TX_Pin 8 // used to indicate web data tx
// Data wire is plugged into digital pin 9 on the Arduino
#define ONE_WIRE_BUS 9
#define WindSensor_Pin (2) // digital pin for wind speed sensor
#define WindVane_Pin (A2) // analog pin for wind direction sensor
#define VaneOffset 0 // define the offset for caclulating wind direction
#define WEB_SERVER_PORT 8081 // use 8081 as the port for our server
#define EMAIL_SEND_DEBOUNCE 15*60*1000 // 15 minutes till next email send
#define TEMPERATURE_LEVEL_ALERT 39 // 39 degrees for email warning

volatile bool IsSampleRequired; // this is set true every 2.5s. Get wind speed
volatile unsigned int TimerCount; // used to count ticks for 2.5sec timer count
volatile unsigned long Rotations; // cup rotation counter for wind speed calcs
volatile unsigned long ContactBounceTime; // timer to avoid contact bounce in wind speed sensor
float WindSpeed; // speed miles per hour

int VaneValue; // raw analog value from wind vane
int Direction; // translated 0 - 360 wind direction
int CalDirection; // calibrated direction after offset applied
int LastValue; // last recorded direction value
int deviceCount = 0; // how many DS18B20 we keep on the OneWire
float OutminTemp; // keep track of minimum recorded Outside temp
float OutmaxTemp; // keep track of maximum recorded Outside temp
float InminTemp; // keep track of minimum recorded Inside temp
float InmaxTemp; // keep track of maximum recorded Inside temp

// Setup a oneWire instance to communicate with any OneWire device
OneWire oneWire(ONE_WIRE_BUS);
// Pass oneWire reference to DallasTemperature library
DallasTemperature sensors(&oneWire);

BME280_I2C bme; // I2C using address 0x77

// Here we setup the web server. We are using a static ip address and a mac address
byte mac[] = { 0xDE, 0xAD, 0xBE, 0xEF, 0xFE, 0xED };
IPAddress ip(192, 168, 10, 45);
IPAddress myDns(192, 168, 10, 1);
IPAddress gateway(192, 168, 10, 1);
IPAddress subnet(255, 255, 255, 0);
EthernetServer server(WEB_SERVER_PORT); // create a server listing on the given IPAddress port WEB_SERVER_PORT
EMailSender emailSend("apikey", "some api key in here", "email00@email.gr", "smtp.sendgrid.net", 25);

String readString; 

Watchdog watchdog;

void isr_rotation();
void sendEmail();

void setup() {
  Serial.begin(9600);
  while (!Serial) {
    ; // wait for serial port to connect. Needed for native USB port only
  }
  // setup anemometer values
  LastValue = 0;
  Rotations = 0;
  // setup timer values
  TimerCount = 0;
  {
    sensors.begin(); // Start up the library
    // locate devices on the bus
    // Serial.print("Locating devices...");
    // Serial.print("Found ");
    // deviceCount = sensors.getDeviceCount();
    // Serial.print(deviceCount, DEC);
    // Serial.println(" devices.");
    // Serial.println("");
    sensors.requestTemperatures();
    InminTemp = sensors.getTempCByIndex(0);
    InmaxTemp = sensors.getTempCByIndex(0);
    OutminTemp = sensors.getTempCByIndex(1);
    OutmaxTemp = sensors.getTempCByIndex(1);
  }

  // disable the SD card by switching pin 4 High
  pinMode(4, OUTPUT);
  digitalWrite(4, HIGH);
  pinMode(53, OUTPUT);
  pinMode(10, OUTPUT);
  digitalWrite(10, HIGH);
  Serial.println(F("Pin start!"));

  // start the Ethernet connection and server

  Ethernet.begin(mac, ip, myDns, gateway, subnet);
  // In case we want to work using DHCP, we uncomment the code below and comment the line right above!
  //    if (Ethernet.begin(mac) == 0) {
  //      Serial.println(F("Failed to configure Ethernet using DHCP"));
  //      if (Ethernet.hardwareStatus() == EthernetNoHardware) {
  //        Serial.println(F("Ethernet shield was not found.  Sorry, can't run without hardware. :("));
  //      } else if (Ethernet.linkStatus() == LinkOFF) {
  //        Serial.println(F("Ethernet cable is not connected."));
  //      }
  //      // no point in carrying on, so do nothing forevermore:
  //      while (true) {
  //        delay(1);
  //      }
  //    }

  Serial.println(F("Begin Execution!"));

  server.begin();

  if (!bme.begin()) {
    Serial.println(F("Could not find BME280 sensor, check wiring!"));
    while (1);
  }

  pinMode(TX_Pin, OUTPUT);
  pinMode(WindSensor_Pin, INPUT);
  attachInterrupt(digitalPinToInterrupt(WindSensor_Pin), isr_rotation, FALLING);

  // setup the timer for 0.5 second

  Timer1.initialize(500000);
  Timer1.attachInterrupt(isr_timer);

  sei(); // Enable Interrupts

  Serial.print(F("IP: "));
  Serial.println(Ethernet.localIP());
  Serial.print(F("Web Server: http://"));
  Serial.print(Ethernet.localIP());
  Serial.print(F(":"));
  Serial.print(WEB_SERVER_PORT);

  watchdog.enable(Watchdog::TIMEOUT_2S);
}

bool emailSended = false;
unsigned long timeElapsed = millis()-EMAIL_SEND_DEBOUNCE;

void loop() {

  watchdog.reset();
  // Send command to all the sensors for temperature conversion
  sensors.requestTemperatures();
  bme.readSensor();

  // update min and max temp values for Outside and Inside Temperatures
  if (sensors.getTempCByIndex(1) < OutminTemp) {
    OutminTemp = sensors.getTempCByIndex(1);
  }
  if (sensors.getTempCByIndex(1) > OutmaxTemp) {
    OutmaxTemp = sensors.getTempCByIndex(1);
  }
  if (sensors.getTempCByIndex(0) < InminTemp) {
    InminTemp = sensors.getTempCByIndex(0);
  }
  if (sensors.getTempCByIndex(0) > InmaxTemp) {
    InmaxTemp = sensors.getTempCByIndex(0);
  }

  // Check if value > TEMPERATURE_LEVEL_ALERT and check if you already send this email
  if (sensors.getTempCByIndex(0) > TEMPERATURE_LEVEL_ALERT && emailSended == false){
    emailSended = true;
    // check if you had already send an email in the last 15 minutes
    if (timeElapsed+EMAIL_SEND_DEBOUNCE < millis()){
      timeElapsed = millis();
      sendEmail();
    }
  }else if (sensors.getTempCByIndex(0) < TEMPERATURE_LEVEL_ALERT && emailSended == true){
    // The value return ok and so if you are going over TEMPERATURE_LEVEL_ALERT again new notification was sended
    emailSended = false;
  }
  // listen for incoming clients
  EthernetClient client = server.available();
  if (client) {

    if(readString.indexOf("json") >=0) { // look for json in the String and returns the index of the 'j' or -1 if not found
       // URL contained json
      boolean currentLineIsBlank = true;
      while (client.connected()) {
      if (client.available()) {
        char c = client.read();
        Serial.write(c);
        // if you've gotten to the end of the line (received a newline
        // character) and the line is blank, the http request has ended,
        // so you can send a reply
        if (c == '\n' && currentLineIsBlank) {
          // send a standard http response header
          digitalWrite(TX_Pin, HIGH); // Turn the TX LED on
          client.println("HTTP/1.1 200 OK");
          client.println("Content-Type: application/json");
          client.println("Connection: close"); // connection closed completion of response
          client.println("Refresh: 10"); // refresh the page automatically every 10 sec
          client.println();
          client.println("{");
          // [Temperature]
          client.println("    \"temperature\": {");
          // Celsius
          client.print("        \"current\": \"");
          client.print(sensors.getTempCByIndex(1));
          client.println("\"");
          client.println("    },");
          // [Wind conditions]
          getWindDirection();
          client.println("    \"wind\": {");
          client.print("        \"direction\": \"");
          client.print(direction(CalDirection));
          client.println("\",");
          client.print("        \"direction-degrees\": \"");
          client.print(CalDirection);
          client.println("\",");
          // KPH
          client.print("        \"current-speed\": \"");
          client.print(WindSpeed);
          client.println("\",");
          // TODO: GUST SPEED
          // KPH
          client.print("        \"current-gust\": \"");
          client.print(0);
          client.println("\"");
          client.println("    },");
          // [Other data]
          client.println("    \"other\": {");
          client.print("        \"humidity\": \"");
          client.print(bme.getHumidity());
          client.println("\",");
          client.print("        \"pressure\": \"");
          client.print(bme.getPressure_MB());
          client.println("\"");
          client.println("    }");
          client.println("}");
          digitalWrite(TX_Pin, LOW); // Turn the TX LED off
          break;
          }
            if (c == '\n') {
             // you're starting a new line
             currentLineIsBlank = true;
           } else if (c != '\r') {
             // you've gotten a character on the current line
             currentLineIsBlank = false;
           }
         }
        }
      }
  // give the web browser time to receive the data
  delay(1);
  // close the connection:
  client.stop();
     }
    }
else 
    // an http request ends with a blank line
    boolean currentLineIsBlank = true;
    while (client.connected()) {
      if (client.available()) {
        char c = client.read();
        Serial.write(c);
        // if you've gotten to the end of the line (received a newline
        // character) and the line is blank, the http request has ended,
        // so you can send a reply
        if (c == '\n' && currentLineIsBlank) {
          // send a standard http response header
          digitalWrite(TX_Pin, HIGH);
          client.println("HTTP/1.1 200 OK");
          client.println("Content-Type: text/html");
          client.println("Connection: close"); // connection closed completion of response
          client.println("Refresh: 10"); // refresh the page automatically every 10 sec
          client.println();
          client.println("<!DOCTYPE HTML>");
          client.print("<HTML><HEAD><TITLE>RadioActive Weather Server</TITLE></HEAD>");
          client.println("<font color='red'><h2>RadioActive Weather Server</font></h2>");
          client.print("Agios Merkouris, Sifnos @ 36.987832, 24.719809<br><br>");
          client.println("<html><body>");
          digitalWrite(TX_Pin, HIGH); // Turn the TX LED on
          client.print("<span style=\"font-size: 26px\";>Outside Temperature now ");
          client.print(sensors.getTempCByIndex(1));
          client.println("C<br>");
          client.print("<br> Inside Temperature now ");
          client.print(sensors.getTempCByIndex(0));
          client.println("C<br>");
          client.print("<br> Wind Speed now ");
          client.print(WindSpeed);
          client.println(" mph || ");
          client.println(getKnots(WindSpeed));
          client.println(" Knots || ");
          client.println(getWindStrength(WindSpeed));
          client.println(" Beauforts<br>");
          getWindDirection();
// Only update the display if change greater than 5 degrees.
          if(abs(CalDirection - LastValue) > 5) {
            LastValue = CalDirection;
          }
          client.print("<br> Direction now ");
          client.print(CalDirection);
          client.print(direction(CalDirection));
          client.println("<br>");
          client.print("<br> Humidity now ");
          client.print(bme.getHumidity());
          client.println("%<br>");
          client.print("<br> Pressure now ");
          client.print(bme.getPressure_MB());
          client.println("mb%<br>");
          client.println("<font color='blue'>");
          client.print("<br> Outside Min Temperature was ");
          client.print(OutminTemp);
          client.println("C<br>");
          client.print("<br> Outside Max Temperature was ");
          client.print(OutmaxTemp);
          client.println("C<br>");
          client.println("<font color='green'>");
          client.print("<br> Inside Min Temperature was ");
          client.print(InminTemp);
          client.println("C<br>");
          client.print("<br> Inside Max Temperature was ");
          client.print(InmaxTemp);
          client.println("C");
          client.println("</font></body></html>");
          digitalWrite(TX_Pin, LOW); // Turn the TX LED off
          break;
          }
            if (c == '\n') {
              // you're starting a new line
              currentLineIsBlank = true;
            } else if (c != '\r') {
              // you've gotten a character on the current line
              currentLineIsBlank = false;
            }
          }
        }
      }

      // give the web browser time to receive the data
      delay(1);
      // close the connection:
      client.stop();
    }
 }

// Interrupt handler routine for timer interrupt
void isr_timer() {

  TimerCount++;
  if (TimerCount == 6) {
//  IsSampleRequired = true;
//            if(IsSampleRequired) {
// convert to mp/h using the formula V=P(2.25/T)
// V = P(2.25/2.5) = P * 0.9
  WindSpeed = Rotations * 0.9;
        Rotations = 0; // Reset count for next sample
//      IsSampleRequired = false;
  TimerCount = 0;
  }
}

// Interrupt handler routine to increment the rotation count for wind speed
void isr_rotation() {
  if ((millis() - ContactBounceTime) > 15) { // debounce the switch contact
    Rotations++;
    ContactBounceTime = millis();
  }
}

// Convert MPH to Knots
float getKnots(float speed) {
return speed * 0.868976;
}


// Get Wind Direction
void getWindDirection() {
  VaneValue = analogRead(WindVane_Pin);
  Direction = map(VaneValue, 0, 1023, 0, 360);
  CalDirection = Direction + VaneOffset;
  if (CalDirection > 360)
    CalDirection = CalDirection - 360;
  if (CalDirection < 0)
    CalDirection = CalDirection + 360;
}


const char* direction(int CalDirection){
  if ((CalDirection) < 23) {
    return " North";
  }
  if ((CalDirection > 22) && (CalDirection < 68)) {
    return " NorthEast";
  }
  if ((CalDirection > 67) && (CalDirection < 113)) {
    return " East";
  }
  if ((CalDirection > 112) && (CalDirection < 158)) {
    return " SouthEast";
  }
  if ((CalDirection > 157) && (CalDirection < 203)) {
    return " South";
  }
  if ((CalDirection > 202) && (CalDirection < 247)) {
    return " SouthWest";
  }
  if ((CalDirection > 246) && (CalDirection < 292)) {
    return " West";
  }
  if ((CalDirection > 291) && (CalDirection < 337)) {
    return " NorthWest";
  }
  if ((CalDirection > 336) && (CalDirection <= 360)) {
    return " North";
  }
  return "No data!";
}


// converts wind speed to wind strength in Beaufort Scale
const char* getWindStrength(float speed) {

if(speed < 1)
  return "0";
else if(speed >= 1 && speed < 3)
  return "1";
else if(speed >= 3 && speed < 7)
  return "2";
else if(speed >= 7 && speed < 12)
  return "3";
else if(speed >= 12 && speed < 18)
  return "4";
else if(speed >= 18 && speed < 24)
  return "5";
else if(speed >= 24 && speed < 31)
  return "6";
else if(speed >= 31 && speed < 38)
  return "7";
else if(speed >= 38 && speed < 46)
  return "8";
else if(speed >= 46 && speed < 54)
  return "9";
else if(speed >= 54 && speed < 63)
  return "10";
else if(speed >= 63 && speed < 72)
  return "11";
else if(speed >= 72)
  return "12";  
else
  return "RUN!";
}


void sendEmail(){

  EMailSender::EMailMessage message;
  message.subject = "test Weather Server";
  getWindDirection();
  message.message = ("blah blah blah");

  //const char* emailToSend = "email1@email0.gr";
  //EMailSender::Response resp = emailSend.send(emailToSend, message);

  const char* arrayOfEmail[] = {"email1@email.gr", "email2@email.gr", "email3@email.gr", "email4@email.gr"};
  EMailSender::Response resp = emailSend.send(arrayOfEmail, 4, message);
  Serial.println(F("Sending status: "));
  Serial.println(resp.status);
  Serial.println(resp.code);
  Serial.println(resp.desc);
}

if you indented the code in the IDE by pressing ctrlT on a PC or cmdT on a Mac, you would be amazed at how it makes finding bugs easier :wink:

line 253 you are closing your loop function but you think you are in an if-else statement... by placing your cursor next to the curly bracket, the tooltip shows what you are closing (so here the loop)

I'd start there

It's not that bracket, I took it out and the error continues...
It's giving: exit status 1
'isr_timer' was not declared in this scope
and stops on line 126 where it calls this Timer1.attachInterrupt(isr_timer);

Well it’s not just taking it out, it’s refactoring your if else so that the brackets match. The error is likely before, may be you did not have the bracket for the if (since I see you don’t have any for the else…)

Your test should look like this:

if (condition) {

} else {

}

C++ is not like Python, indenting the code does not define the blocks. You need pairs of {}

I did a search on the code below, which contains the guilty culprit, I open 13 "{" and close 17 "}"
Although it's now supposedly properly indented with Ctrl-T, I still can't follow it...
Can you?

  if (client) {

    if (readString.indexOf("json") >= 0) { // look for json in the String and returns the index of the 'j' or -1 if not found
      // URL contained json
      boolean currentLineIsBlank = true;
      while (client.connected()) {
        if (client.available()) {
          char c = client.read();
          Serial.write(c);
          // if you've gotten to the end of the line (received a newline
          // character) and the line is blank, the http request has ended,
          // so you can send a reply
          if (c == '\n' && currentLineIsBlank) {
            // send a standard http response header
            digitalWrite(TX_Pin, HIGH); // Turn the TX LED on
            client.println("HTTP/1.1 200 OK");
            client.println("Content-Type: application/json");
            client.println("Connection: close"); // connection closed completion of response
            client.println("Refresh: 10"); // refresh the page automatically every 10 sec
            client.println();
            client.println("{");
            // [Temperature]
            client.println("    \"temperature\": {");
            // Celsius
            client.print("        \"current\": \"");
            client.print(sensors.getTempCByIndex(1));
            client.println("\"");
            client.println("    },");
            // [Wind conditions]
            getWindDirection();
            client.println("    \"wind\": {");
            client.print("        \"direction\": \"");
            client.print(direction(CalDirection));
            client.println("\",");
            client.print("        \"direction-degrees\": \"");
            client.print(CalDirection);
            client.println("\",");
            // KPH
            client.print("        \"current-speed\": \"");
            client.print(WindSpeed);
            client.println("\",");
            // TODO: GUST SPEED
            // KPH
            client.print("        \"current-gust\": \"");
            client.print(0);
            client.println("\"");
            client.println("    },");
            // [Other data]
            client.println("    \"other\": {");
            client.print("        \"humidity\": \"");
            client.print(bme.getHumidity());
            client.println("\",");
            client.print("        \"pressure\": \"");
            client.print(bme.getPressure_MB());
            client.println("\"");
            client.println("    }");
            client.println("}");
            digitalWrite(TX_Pin, LOW); // Turn the TX LED off
            break;
          }
          if (c == '\n') {
            // you're starting a new line
            currentLineIsBlank = true;
          } else if (c != '\r') {
            // you've gotten a character on the current line
            currentLineIsBlank = false;
          }
        }
      }
    }
    // give the web browser time to receive the data
    delay(1);
    // close the connection:
    client.stop();
  }
}
else
  // an http request ends with a blank line
  boolean currentLineIsBlank = true;
while (client.connected()) {
  if (client.available()) {
    char c = client.read();
    Serial.write(c);
    // if you've gotten to the end of the line (received a newline
    // character) and the line is blank, the http request has ended,
    // so you can send a reply
    if (c == '\n' && currentLineIsBlank) {
      // send a standard http response header
      digitalWrite(TX_Pin, HIGH);
      client.println("HTTP/1.1 200 OK");
      client.println("Content-Type: text/html");
      client.println("Connection: close"); // connection closed completion of response
      client.println("Refresh: 10"); // refresh the page automatically every 10 sec
      client.println();
      client.println("<!DOCTYPE HTML>");
      client.print("<HTML><HEAD><TITLE>RadioActive Weather Server</TITLE></HEAD>");
      client.println("<font color='red'><h2>RadioActive Weather Server</font></h2>");
      client.print("Agios Merkouris, Sifnos @ 36.987832, 24.719809<br><br>");
      client.println("<html><body>");
      digitalWrite(TX_Pin, HIGH); // Turn the TX LED on
      client.print("<span style=\"font-size: 26px\";>Outside Temperature now ");
      client.print(sensors.getTempCByIndex(1));
      client.println("C<br>");
      client.print("<br> Inside Temperature now ");
      client.print(sensors.getTempCByIndex(0));
      client.println("C<br>");
      client.print("<br> Wind Speed now ");
      client.print(WindSpeed);
      client.println(" mph || ");
      client.println(getKnots(WindSpeed));
      client.println(" Knots || ");
      client.println(getWindStrength(WindSpeed));
      client.println(" Beauforts<br>");
      getWindDirection();
      // Only update the display if change greater than 5 degrees.
      if (abs(CalDirection - LastValue) > 5) {
        LastValue = CalDirection;
      }
      client.print("<br> Direction now ");
      client.print(CalDirection);
      client.print(direction(CalDirection));
      client.println("<br>");
      client.print("<br> Humidity now ");
      client.print(bme.getHumidity());
      client.println("%<br>");
      client.print("<br> Pressure now ");
      client.print(bme.getPressure_MB());
      client.println("mb%<br>");
      client.println("<font color='blue'>");
      client.print("<br> Outside Min Temperature was ");
      client.print(OutminTemp);
      client.println("C<br>");
      client.print("<br> Outside Max Temperature was ");
      client.print(OutmaxTemp);
      client.println("C<br>");
      client.println("<font color='green'>");
      client.print("<br> Inside Min Temperature was ");
      client.print(InminTemp);
      client.println("C<br>");
      client.print("<br> Inside Max Temperature was ");
      client.print(InmaxTemp);
      client.println("C");
      client.println("</font></body></html>");
      digitalWrite(TX_Pin, LOW); // Turn the TX LED off
      break;
    }
    if (c == '\n') {
      // you're starting a new line
      currentLineIsBlank = true;
    } else if (c != '\r') {
      // you've gotten a character on the current line
      currentLineIsBlank = false;
    }
  }
}
}

// give the web browser time to receive the data
delay(1);
// close the connection:
client.stop();
}
}

If you indented the code then that looks suspicious.

I’m on my mobile so can’t do much

Your loop function is huge and complex, which is why you can't easily see the bracket mismatch.

I suggest that you refactor loop and take some of the massive sections that are just loads of client.print statements and put them in their own functions.

Once loop has been reduced to thirty lines or so, it'll be trivial to see what's wrong with it.

Finally fixed the loop and yes indeed the problem was brackets all over the place!
So, now that it compiled, I see that the (readString.indexOf("json") >= 0) always returns -1 no matter what I tried, so it doesn't go into that part of the code to output the json formatted output, only html.
Any ideas why?

Print readString to the console once received to find out exactly what it contains)

Ok, I'm sending 192.168.10.45:8081/json
Readstring is what I'm printing out, and this is what's getting printed in my serial monitor:

Readstring : GET /json HTTP/1.1
Host: 192.168.10.45:8081
Connection: keep-alive
Cache-Control: max-age=0
Upgrade-Insecure-Requests: 1
User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/91.0.4472.77 Safari/537.36
Accept: text/html,application/xhtml+xml,application/xml;q=0.9,image/avif,image/webp,image/apng,/;q=0.8,application/signed-exchange;v=b3;q=0.9
Sec-GPC: 1
Referer: http://192.168.10.45:8081/json
Accept-Encoding: gzip, deflate
Accept-Language: en-US,en;q=0.9

Readstring : GET /favicon.ico HTTP/1.1
Host: 192.168.10.45:8081
Connection: keep-alive
User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/91.0.4472.77 Safari/537.36
Accept: image/avif,image/webp,image/apng,image/svg+xml,image/,/*;q=0.8
Sec-GPC: 1
Referer: http://192.168.10.45:8081/json
Accept-Encoding: gzip, deflate
Accept-Language: en-US,en;q=0.9

So what do you make of it?!