Using PubSubClient and GET request
Posted: Fri Jul 13, 2018 2:00 am
Hi,
Self taught "hobbiest" here with lots to learn...
In short the code below polls various sensors, publishes their data to my MQTT server then displays the data on a Nextion display. In addition it also fetches a weather forecast, again to display.
The issue is that the MQTT part works, the forecast "GET" dosn't. Well if I'm lucky I get an initial one then nothing after that. The code with the MQTT part removed does work, so I think it is a network connection issue, with MQTT closing the connection and the "GET" code not reopeninging it....but I'm guessing.
I've searched the internet and tried changes but I'm going nowhere.
All advice, suggestions welcomed.
--
Roland
Everday is good day for learning
Self taught "hobbiest" here with lots to learn...
In short the code below polls various sensors, publishes their data to my MQTT server then displays the data on a Nextion display. In addition it also fetches a weather forecast, again to display.
The issue is that the MQTT part works, the forecast "GET" dosn't. Well if I'm lucky I get an initial one then nothing after that. The code with the MQTT part removed does work, so I think it is a network connection issue, with MQTT closing the connection and the "GET" code not reopeninging it....but I'm guessing.
I've searched the internet and tried changes but I'm going nowhere.
Code: Select all
// Inspired by ESP32 Weather Station Project
// http://educ8s.tv/esp32-weather-station
// Code from a number of sources
// This version was created by Roland Hill, July 2018
// Board = ESP8266_12mod LoLin NodeMcu V3
#define ARDUINOJSON_ENABLE_PROGMEM 0
/*-----( Import needed libraries )-----*/
#include <ArduinoJson.h>
#include <OneWire.h>
#include <DallasTemperature.h>
#include <DHT_U.h>
#include <DHT.h>
#include <Wire.h>
#include <ESP8266WiFi.h>
#include <Adafruit_Sensor.h>
#include <Adafruit_BME280.h>
#include <PubSubClient.h>
/*-----( Declare Constants and Pin Numbers )-----*/
//spare data pin is GPIO2,D4
#define DHTPIN 4 // GPI04,D2
#define DHTTYPE DHT22 // DHT22(AM2302)
#define ONE_WIRE_BUS 5 // GPIO5,D1
#define I2C_SDA 12 // GPIO12,D6
#define I2C_SCL 14 // GPIO14,D5
#define ALTITUDE 0 // Altitude in Papamoa, NZ
#define LED_PIN LED_BUILTIN
#define tho "sensor/dht22a/humidity"
#define tto "sensor/dht22a/temperature"
#define tt3 "sensor/28FF0E3E8C1603CA/temperature"
#define tpo "sensor/bme280/pressure"
const char* ssid = "redacted";
const char* password = "redacted";
String CityID = "2184975"; //Papamoa, NZ
String APIKEY = "redacted";
int weatherID = 0;
const char* servername = "api.openweathermap.org"; // remote server we will connect to
String result;
int iterations = 1800;
String weatherDescription = "";
String weatherLocation = "";
float temperature = 0;
float temp_out = 0;
float humidity = 0;
float pressure = 0;
/*-----( Declare objects )-----*/
//BME280
Adafruit_BME280 bme;
// DHT 22(AM2302)
DHT dht(DHTPIN, DHTTYPE);
// DS18B20 sensor
OneWire oneWire(ONE_WIRE_BUS); //oneWire instance to communicate with any OneWire devices
DallasTemperature sensors(&oneWire);// Pass address of our oneWire instance to Dallas Temperature.
DeviceAddress Probe03 = { 0x28, 0xFF, 0x0E, 0x3E, 0x8C, 0x16, 0x03, 0xCA };
// Initialize the Ethernet and MQTT client objects
WiFiClient espClient;
PubSubClient client(espClient);
void setup() {
Serial.begin(9600);
pinMode(LED_PIN, OUTPUT);
setup_wifi();
client.setServer("redacted", 1883);
// BME280
initSensor();
// DS18B20 sensor, resolution, 9 to 12 bits (lower is faster)
sensors.setResolution(Probe03, 10);
// DHT 22(AM2302)
dht.begin();
}
void loop() {
// Connect to MQTT
if (!client.connected())
{
reconnect();
} else {
client.loop();
}
delay(2000);
if (iterations == 1800) //We check for updated weather forecast once every hour
{
getWeatherData();
printWeatherIcon(weatherID);
iterations = 0;
}
getTemp_In();
sendTemp_InToNextion();
getTemp_Out();
sendTemp_OutToNextion();
getHumidity();
sendHumidityToNextion();
getPressure();
sendPressureToNextion();
iterations++;
blinkLED();
// Publish
client.publish(tho, String(humidity).c_str(), true);
delay(1000);
client.publish(tto, String(temp_out).c_str(), true);
delay(1000);
client.publish(tt3, String(temperature).c_str(), true);
delay(1000);
client.publish(tpo, String(pressure).c_str(), true);
delay(1000);
}
void setup_wifi() {
delay(10);
WiFi.hostname("hillnode_3");
// We start by connecting to a WiFi network
WiFi.begin(ssid, password);
while (WiFi.status() != WL_CONNECTED) {
delay(500);
Serial.print(".");
}
}
void reconnect() {
// Loop until we're reconnected
while (!client.connected()) {
// Attempt to connect
if (client.connect("ESP8266Client_3", "redacted", "redacted")) {
Serial.println("connected\n");
} else {
// Wait 5 seconds before retrying
delay(5000);
}
}
}
void initSensor() {
Wire.begin(I2C_SDA, I2C_SCL);
bool status = bme.begin(BME280_ADDRESS);
if (!status) {
Serial.println("Could not find a valid BME280 sensor, check wiring!");
while (1);
}
}
void blinkLED() {
digitalWrite(LED_PIN, HIGH);
delay(100);
digitalWrite(LED_PIN, LOW);
}
float getTemp_Out() {
temp_out = dht.readTemperature();
}
float getTemp_In() {
sensors.requestTemperatures();
temperature = sensors.getTempC(Probe03);
}
float getHumidity() {
humidity = dht.readHumidity();
}
float getPressure() {
pressure = bme.readPressure();
pressure = bme.seaLevelForAltitude(ALTITUDE, pressure);
pressure = pressure / 100.0F;
}
void getWeatherData() { //client function to send/receive GET request data.
String result = "";
WiFiClient client;
const int httpPort = 80;
if (!client.connect(servername, httpPort)) {
return;
}
// We now create a URI for the request
String url = "/data/2.5/forecast?id=" + CityID + "&units=metric&cnt=1&APPID=" + APIKEY;
// This will send the request to the server
client.print(String("GET ") + url + " HTTP/1.1\r\n" +
"Host: " + servername + "\r\n" +
"Connection: close\r\n\r\n");
unsigned long timeout = millis();
while (client.available() == 0) {
if (millis() - timeout > 5000) {
client.stop();
return;
}
}
// Read all the lines of the reply from server
while (client.available()) {
result = client.readStringUntil('\r');
}
result.replace('[', ' ');
result.replace(']', ' ');
char jsonArray [result.length() + 1];
result.toCharArray(jsonArray, sizeof(jsonArray));
jsonArray[result.length() + 1] = '\0';
StaticJsonBuffer<1024> json_buf;
JsonObject &root = json_buf.parseObject(jsonArray);
if (!root.success())
{
Serial.println("parseObject() failed");
}
String location = root["city"]["name"];
String temperature = root["list"]["main"]["temp"];
String weather = root["list"]["weather"]["main"];
String description = root["list"]["weather"]["description"];
String idString = root["list"]["weather"]["id"];
String timeS = root["list"]["dt_txt"];
weatherID = idString.toInt();
Serial.print("\nWeatherID: ");
Serial.print(weatherID);
endNextionCommand(); //We need that in order the nextion to recognise the first command after the serial print
}
void showConnectingIcon() {
Serial.println();
String command = "weatherIcon.pic=3";
Serial.print(command);
endNextionCommand();
}
void sendHumidityToNextion() {
String command = "humidity.txt=\"" + String(humidity, 1) + "\"";
Serial.print(command);
endNextionCommand();
}
void sendTemp_InToNextion() {
String command = "temperature.txt=\"" + String(temperature, 1) + "\"";
Serial.print(command);
endNextionCommand();
}
void sendTemp_OutToNextion() {
String command = "temp_out.txt=\"" + String(temp_out, 1) + "\"";
Serial.print(command);
endNextionCommand();
}
void sendPressureToNextion() {
String command = "pressure.txt=\"" + String(pressure, 1) + "\"";
Serial.print(command);
endNextionCommand();
}
void endNextionCommand() {
Serial.write(0xff);
Serial.write(0xff);
Serial.write(0xff);
}
void printWeatherIcon(int id) {
switch (id)
{
case 800: drawClearWeather(); break;
case 801: drawFewClouds(); break;
case 802: drawFewClouds(); break;
case 803: drawCloud(); break;
case 804: drawCloud(); break;
case 200: drawThunderstorm(); break;
case 201: drawThunderstorm(); break;
case 202: drawThunderstorm(); break;
case 210: drawThunderstorm(); break;
case 211: drawThunderstorm(); break;
case 212: drawThunderstorm(); break;
case 221: drawThunderstorm(); break;
case 230: drawThunderstorm(); break;
case 231: drawThunderstorm(); break;
case 232: drawThunderstorm(); break;
case 300: drawLightRain(); break;
case 301: drawLightRain(); break;
case 302: drawLightRain(); break;
case 310: drawLightRain(); break;
case 311: drawLightRain(); break;
case 312: drawLightRain(); break;
case 313: drawLightRain(); break;
case 314: drawLightRain(); break;
case 321: drawLightRain(); break;
case 500: drawLightRainWithSunOrMoon(); break;
case 501: drawLightRainWithSunOrMoon(); break;
case 502: drawLightRainWithSunOrMoon(); break;
case 503: drawLightRainWithSunOrMoon(); break;
case 504: drawLightRainWithSunOrMoon(); break;
case 511: drawLightRain(); break;
case 520: drawModerateRain(); break;
case 521: drawModerateRain(); break;
case 522: drawHeavyRain(); break;
case 531: drawHeavyRain(); break;
case 600: drawLightSnowfall(); break;
case 601: drawModerateSnowfall(); break;
case 602: drawHeavySnowfall(); break;
case 611: drawLightSnowfall(); break;
case 612: drawLightSnowfall(); break;
case 615: drawLightSnowfall(); break;
case 616: drawLightSnowfall(); break;
case 620: drawLightSnowfall(); break;
case 621: drawModerateSnowfall(); break;
case 622: drawHeavySnowfall(); break;
case 701: drawFog(); break;
case 711: drawFog(); break;
case 721: drawFog(); break;
case 731: drawFog(); break;
case 741: drawFog(); break;
case 751: drawFog(); break;
case 761: drawFog(); break;
case 762: drawFog(); break;
case 771: drawFog(); break;
case 781: drawFog(); break;
default: break;
}
}
void drawFog() {
String command = "weatherIcon.pic=13";
Serial.print(command);
endNextionCommand();
}
void drawHeavySnowfall() {
String command = "weatherIcon.pic=8";
Serial.print(command);
endNextionCommand();
}
void drawModerateSnowfall() {
String command = "weatherIcon.pic=8";
Serial.print(command);
endNextionCommand();
}
void drawLightSnowfall() {
String command = "weatherIcon.pic=11";
Serial.print(command);
endNextionCommand();
}
void drawHeavyRain() {
String command = "weatherIcon.pic=10";
Serial.print(command);
endNextionCommand();
}
void drawModerateRain() {
String command = "weatherIcon.pic=6";
Serial.print(command);
endNextionCommand();
}
void drawLightRain() {
String command = "weatherIcon.pic=6";
Serial.print(command);
endNextionCommand();
}
void drawLightRainWithSunOrMoon() {
String command = "weatherIcon.pic=7";
Serial.print(command);
endNextionCommand();
}
void drawThunderstorm() {
String command = "weatherIcon.pic=3";
Serial.print(command);
endNextionCommand();
}
void drawClearWeather() {
String command = "weatherIcon.pic=4";
Serial.print(command);
endNextionCommand();
}
void drawCloud() {
String command = "weatherIcon.pic=9";
Serial.print(command);
endNextionCommand();
}
void drawFewClouds() {
String command = "weatherIcon.pic=5";
Serial.print(command);
endNextionCommand();
}
All advice, suggestions welcomed.
--
Roland
Everday is good day for learning