Weatherstation/Weather Station March 2023

From Federal Burro of Information
Jump to navigationJump to search

Features / improvements

  1. MDNS for discovery of web service.
  2. Moved Secrets to include file.
  3. removed serial requirement, so it can run "headless"
  4. moved from esp12 hardware to esp32 hardware. - note less elegant web code, not handler based.
#include <Wire.h>
#include <SPI.h>
#include <Adafruit_Sensor.h>
#include "Adafruit_BME680.h"
#include <WiFi.h>
#include <ESPmDNS.h>

#include "wifi_secrets.h"

#define HOSTNAME "weatherstation3"

char ssid[]     = SECRET_SSID;
char password[] = SECRET_PASS;


#define SEALEVELPRESSURE_HPA (1013.25)
#define I2C_SDA 0
#define I2C_SCL 1

WiFiServer server(80);

// Variable to store the HTTP request
String header;

Adafruit_BME680 bme;
unsigned long currentTime;
unsigned long previousTime;
const long timeoutTime = 2000;

void handleMetrics( WiFiClient client) {
  // digitalWrite(LED_BUILTIN, HIGH);
  Serial.print("request: metrics");

  // delay(1000);                       // wait for a second
  Serial.print("bme.performReading()");
  if (! bme.performReading()) {
    Serial.println("Failed to perform reading.");
    // server.send(200, "text/plain", "Failed to perform reading.");
    return;
  }
  Serial.println("Reading done, sending....");
  // # HELP temperature Temperature in Celcius"
  // # TYPE temperature guage")
  String message = "temperature{instance=\"";
  message += HOSTNAME;
  message += "\"} ";
  message += bme.temperature;
  message += "\n";
  
  // Serial.println("# HELP barometric_pressure in hectopascals (hPa)"
  // Serial.println("# TYPE barometric_pressure guage")
  message += "barometric_pressure{instance=\"";
  message += HOSTNAME;
  message += "\"} ";
  message += (bme.pressure / 100.0);
  message += "\n";

  // Serial.println("# HELP humidity relative humidity percent (%)"
  // Serial.println("# TYPE humidity guage")
  message += "humidity{instance=\"";
  message += HOSTNAME;
  message += "\"} ";
  message += bme.humidity;
  message += "\n";

  // Serial.println("# HELP gas_resistance Gas Resistance in  KOhms"
  // Serial.println("# TYPE gas_resistance guage")
  message += "gas_resistance{instance=\"";
  message += HOSTNAME;
  message += "\"} ";
  message += (bme.gas_resistance / 1000.0);
  message += "\n";

  // Serial.println("# HELP approximate_altitude in meters KOhms"
  // Serial.println("# TYPE approximate_altitude guage")
  message += "approximate_altitude{instance=\"";
  message += HOSTNAME;
  message += "\"} ";
  message += bme.readAltitude(SEALEVELPRESSURE_HPA);
  // message += "\n";
  Serial.println(message);
  client.print(message);
  // server.send(200, "text/plain", message);
}

void handleNotFound() {
  Serial.println("handleNotFound: not found");
  // server.send(404, "text/plain", "Not found");
}

// the setup function runs once when you press reset or power the board
void setup() {
  Wire.setPins(I2C_SDA, I2C_SCL);
  // initialize digital pin LED_BUILTIN as an output.
  pinMode(LED_BUILTIN, OUTPUT);
  digitalWrite(LED_BUILTIN, LOW);
  Serial.begin(9600);
  // while (!Serial);
  
  Serial.println(F("begin wifi"));
  WiFi.mode(WIFI_STA);
  WiFi.begin(ssid, password);
  Serial.println(F("wifi begined, wait for connected"));
  while (WiFi.status() != WL_CONNECTED) {
    delay(500);
    Serial.print(".");
  }
  Serial.println(F("connected"));
  
  Serial.println("");
  Serial.print("Connected to ");
  Serial.println(ssid);
  Serial.print("IP address: ");
  Serial.println(WiFi.localIP());

  if (!MDNS.begin(HOSTNAME)) {
    Serial.println("Error setting up MDNS responder!");
    while(1){
      delay(1000);
    }
  }

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

  Serial.println("setting over sampling");
  bme.setTemperatureOversampling(BME680_OS_8X);
  bme.setHumidityOversampling(BME680_OS_2X);
  bme.setPressureOversampling(BME680_OS_4X);
  bme.setIIRFilterSize(BME680_FILTER_SIZE_3);
  bme.setGasHeater(320, 150);
  Serial.println("set over sampling");

  Serial.println("web server begin");
  server.begin();
  Serial.println("HTTP server started");
  MDNS.addService("http", "tcp", 80);
}

void loop() {
  WiFiClient client = server.available();

  if (client) {                             // If a new client connects,
    currentTime = millis();
    previousTime = currentTime;
    Serial.println("C");          // print a message out in the serial port
    String currentLine = "";                // make a String to hold incoming data from the client
    while (client.connected() && currentTime - previousTime <= timeoutTime) {  // loop while the client's connected
      currentTime = millis();
      if (client.available()) {             // if there's bytes to read from the client,
        char c = client.read();             // read a byte, then
        // Serial.write(c);                    // print it out the serial monitor
        header += c;
        if (c == '\n') {                    // if the byte is a newline character
          // if the current line is blank, you got two newline characters in a row.
          // that's the end of the client HTTP request, so send a response:
          if (currentLine.length() == 0) {
            // HTTP headers always start with a response code (e.g. HTTP/1.1 200 OK)
            // and a content-type so the client knows what's coming, then a blank line:
            client.println("HTTP/1.1 200 OK");
            client.println("Content-type:text/html");
            client.println("Connection: close");
            client.println();
            
            if (header.indexOf("GET /metrics") >= 0) {
              handleMetrics(client);
              //stuff
            } else {
              Serial.println("UNRECOGNIZED CALL");
            }
            
            // client.println("<p>GPIO 27 - State " + output27State + "</p>");
            break;
          } else { // if you got a newline, then clear currentLine
            currentLine = "";
          }
        } else if (c != '\r') {  // if you got anything else but a carriage return character,
          currentLine += c;      // add it to the end of the currentLine
        }
    }
  }
  // Clear the header variable
  header = "";
  // Close the connection
  client.stop();
  Serial.println("Client disconnected.");
  Serial.println("");
  }
}
/*
  Serial.println("loop start");
  delay(1000);                       // wait for a second
  digitalWrite(LED_BUILTIN, HIGH);   // turn the LED on (HIGH is the voltage level)
  digitalWrite(LED_BUILTIN, LOW);    // turn the LED off by making the voltage LOW
*/

  //server.handleClient();
  // MDNS.update();