From 9766c7c23c1c462e1e9a52b26ecc7856253601c1 Mon Sep 17 00:00:00 2001
From: Brandon
Date: Sat, 4 May 2019 21:37:39 -0600
Subject: [PATCH 1/2] Updated files to implement speed & pressure
Implemented wind speed and barometric pressure display.
---
marquee/OpenWeatherMapClient.cpp | 700 ++++++++++++++++---------------
marquee/OpenWeatherMapClient.h | 175 ++++----
marquee/marquee.ino | 26 +-
3 files changed, 472 insertions(+), 429 deletions(-)
diff --git a/marquee/OpenWeatherMapClient.cpp b/marquee/OpenWeatherMapClient.cpp
index ab95b3e..9a9608b 100644
--- a/marquee/OpenWeatherMapClient.cpp
+++ b/marquee/OpenWeatherMapClient.cpp
@@ -1,341 +1,359 @@
-/** The MIT License (MIT)
-
-Copyright (c) 2018 David Payne
-
-Permission is hereby granted, free of charge, to any person obtaining a copy
-of this software and associated documentation files (the "Software"), to deal
-in the Software without restriction, including without limitation the rights
-to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
-copies of the Software, and to permit persons to whom the Software is
-furnished to do so, subject to the following conditions:
-
-The above copyright notice and this permission notice shall be included in all
-copies or substantial portions of the Software.
-
-THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
-IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
-FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
-AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
-LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
-OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
-SOFTWARE.
-*/
-
-#include "OpenWeatherMapClient.h"
-
-OpenWeatherMapClient::OpenWeatherMapClient(String ApiKey, int CityIDs[], int cityCount, boolean isMetric) {
- updateCityIdList(CityIDs, cityCount);
- myApiKey = ApiKey;
- setMetric(isMetric);
-}
-
-void OpenWeatherMapClient::updateWeatherApiKey(String ApiKey) {
- myApiKey = ApiKey;
-}
-
-void OpenWeatherMapClient::updateWeather() {
- WiFiClient weatherClient;
- String apiGetData = "GET /data/2.5/group?id=" + myCityIDs + "&units=" + units + "&cnt=1&APPID=" + myApiKey + " HTTP/1.1";
-
- Serial.println("Getting Weather Data");
- Serial.println(apiGetData);
- weathers[0].cached = false;
- weathers[0].error = "";
- if (weatherClient.connect(servername, 80)) { //starts client connection, checks for connection
- weatherClient.println(apiGetData);
- weatherClient.println("Host: " + String(servername));
- weatherClient.println("User-Agent: ArduinoWiFi/1.1");
- weatherClient.println("Connection: close");
- weatherClient.println();
- }
- else {
- Serial.println("connection for weather data failed"); //error message if no client connect
- Serial.println();
- weathers[0].error = "Connection for weather data failed";
- return;
- }
-
- while(weatherClient.connected() && !weatherClient.available()) delay(1); //waits for data
-
- Serial.println("Waiting for data");
-
- // Check HTTP status
- char status[32] = {0};
- weatherClient.readBytesUntil('\r', status, sizeof(status));
- Serial.println("Response Header: " + String(status));
- if (strcmp(status, "HTTP/1.1 200 OK") != 0) {
- Serial.print(F("Unexpected response: "));
- Serial.println(status);
- weathers[0].error = "Weather Data Error: " + String(status);
- return;
- }
-
- // Skip HTTP headers
- char endOfHeaders[] = "\r\n\r\n";
- if (!weatherClient.find(endOfHeaders)) {
- Serial.println(F("Invalid response"));
- return;
- }
-
- const size_t bufferSize = 710;
- DynamicJsonBuffer jsonBuffer(bufferSize);
-
- // Parse JSON object
- JsonObject& root = jsonBuffer.parseObject(weatherClient);
- if (!root.success()) {
- Serial.println(F("Weather Data Parsing failed!"));
- weathers[0].error = "Weather Data Parsing failed!";
- return;
- }
-
- weatherClient.stop(); //stop client
-
- if (root.measureLength() <= 150) {
- Serial.println("Error Does not look like we got the data. Size: " + String(root.measureLength()));
- weathers[0].cached = true;
- weathers[0].error = (const char*)root["message"];
- Serial.println("Error: " + weathers[0].error);
- return;
- }
- int count = root["cnt"];
-
- for (int inx = 0; inx < count; inx++) {
- weathers[inx].lat = (const char*)root["list"][inx]["coord"]["lat"];
- weathers[inx].lon = (const char*)root["list"][inx]["coord"]["lon"];
- weathers[inx].dt = (const char*)root["list"][inx]["dt"];
- weathers[inx].city = (const char*)root["list"][inx]["name"];
- weathers[inx].country = (const char*)root["list"][inx]["sys"]["country"];
- weathers[inx].temp = (const char*)root["list"][inx]["main"]["temp"];
- weathers[inx].humidity = (const char*)root["list"][inx]["main"]["humidity"];
- weathers[inx].condition = (const char*)root["list"][inx]["weather"][0]["main"];
- weathers[inx].wind = (const char*)root["list"][inx]["wind"]["speed"];
- weathers[inx].weatherId = (const char*)root["list"][inx]["weather"][0]["id"];
- weathers[inx].description = (const char*)root["list"][inx]["weather"][0]["description"];
- weathers[inx].icon = (const char*)root["list"][inx]["weather"][0]["icon"];
-
- if (units == "metric") {
- // convert to kph from m/s
- float f = (weathers[inx].wind.toFloat() * 3.6);
- weathers[inx].wind = String(f);
- }
-
- Serial.println("lat: " + weathers[inx].lat);
- Serial.println("lon: " + weathers[inx].lon);
- Serial.println("dt: " + weathers[inx].dt);
- Serial.println("city: " + weathers[inx].city);
- Serial.println("country: " + weathers[inx].country);
- Serial.println("temp: " + weathers[inx].temp);
- Serial.println("humidity: " + weathers[inx].humidity);
- Serial.println("condition: " + weathers[inx].condition);
- Serial.println("wind: " + weathers[inx].wind);
- Serial.println("weatherId: " + weathers[inx].weatherId);
- Serial.println("description: " + weathers[inx].description);
- Serial.println("icon: " + weathers[inx].icon);
- Serial.println();
-
- }
-}
-
-String OpenWeatherMapClient::roundValue(String value) {
- float f = value.toFloat();
- int rounded = (int)(f+0.5f);
- return String(rounded);
-}
-
-void OpenWeatherMapClient::updateCityIdList(int CityIDs[], int cityCount) {
- myCityIDs = "";
- for (int inx = 0; inx < cityCount; inx++) {
- if (CityIDs[inx] > 0) {
- if (myCityIDs != "") {
- myCityIDs = myCityIDs + ",";
- }
- myCityIDs = myCityIDs + String(CityIDs[inx]);
- }
- }
-}
-
-void OpenWeatherMapClient::setMetric(boolean isMetric) {
- if (isMetric) {
- units = "metric";
- } else {
- units = "imperial";
- }
-}
-
-String OpenWeatherMapClient::getLat(int index) {
- return weathers[index].lat;
-}
-
-String OpenWeatherMapClient::getLon(int index) {
- return weathers[index].lon;
-}
-
-String OpenWeatherMapClient::getDt(int index) {
- return weathers[index].dt;
-}
-
-String OpenWeatherMapClient::getCity(int index) {
- return weathers[index].city;
-}
-
-String OpenWeatherMapClient::getCountry(int index) {
- return weathers[index].country;
-}
-
-String OpenWeatherMapClient::getTemp(int index) {
- return weathers[index].temp;
-}
-
-String OpenWeatherMapClient::getTempRounded(int index) {
- return roundValue(getTemp(index));
-}
-
-String OpenWeatherMapClient::getHumidity(int index) {
- return weathers[index].humidity;
-}
-
-String OpenWeatherMapClient::getHumidityRounded(int index) {
- return roundValue(getHumidity(index));
-}
-
-String OpenWeatherMapClient::getCondition(int index) {
- return weathers[index].condition;
-}
-
-String OpenWeatherMapClient::getWind(int index) {
- return weathers[index].wind;
-}
-
-String OpenWeatherMapClient::getWindRounded(int index) {
- return roundValue(getWind(index));
-}
-
-String OpenWeatherMapClient::getWeatherId(int index) {
- return weathers[index].weatherId;
-}
-
-String OpenWeatherMapClient::getDescription(int index) {
- return weathers[index].description;
-}
-
-String OpenWeatherMapClient::getIcon(int index) {
- return weathers[index].icon;
-}
-
-boolean OpenWeatherMapClient::getCached() {
- return weathers[0].cached;
-}
-
-String OpenWeatherMapClient::getMyCityIDs() {
- return myCityIDs;
-}
-
-String OpenWeatherMapClient::getError() {
- return weathers[0].error;
-}
-
-String OpenWeatherMapClient::getWeekDay(int index, float offset) {
- String rtnValue = "";
- long epoc = weathers[index].dt.toInt();
- long day = 0;
- if (epoc != 0) {
- day = (((epoc + (3600 * (int)offset)) / 86400) + 4) % 7;
- switch (day) {
- case 0:
- rtnValue = "Sunday";
- break;
- case 1:
- rtnValue = "Monday";
- break;
- case 2:
- rtnValue = "Tuesday";
- break;
- case 3:
- rtnValue = "Wednesday";
- break;
- case 4:
- rtnValue = "Thursday";
- break;
- case 5:
- rtnValue = "Friday";
- break;
- case 6:
- rtnValue = "Saturday";
- break;
- default:
- break;
- }
- }
- return rtnValue;
-}
-
-String OpenWeatherMapClient::getWeatherIcon(int index)
-{
- int id = getWeatherId(index).toInt();
- String W = ")";
- switch(id)
- {
- case 800: W = "B"; break;
- case 801: W = "Y"; break;
- case 802: W = "H"; break;
- case 803: W = "H"; break;
- case 804: W = "Y"; break;
-
- case 200: W = "0"; break;
- case 201: W = "0"; break;
- case 202: W = "0"; break;
- case 210: W = "0"; break;
- case 211: W = "0"; break;
- case 212: W = "0"; break;
- case 221: W = "0"; break;
- case 230: W = "0"; break;
- case 231: W = "0"; break;
- case 232: W = "0"; break;
-
- case 300: W = "R"; break;
- case 301: W = "R"; break;
- case 302: W = "R"; break;
- case 310: W = "R"; break;
- case 311: W = "R"; break;
- case 312: W = "R"; break;
- case 313: W = "R"; break;
- case 314: W = "R"; break;
- case 321: W = "R"; break;
-
- case 500: W = "R"; break;
- case 501: W = "R"; break;
- case 502: W = "R"; break;
- case 503: W = "R"; break;
- case 504: W = "R"; break;
- case 511: W = "R"; break;
- case 520: W = "R"; break;
- case 521: W = "R"; break;
- case 522: W = "R"; break;
- case 531: W = "R"; break;
-
- case 600: W = "W"; break;
- case 601: W = "W"; break;
- case 602: W = "W"; break;
- case 611: W = "W"; break;
- case 612: W = "W"; break;
- case 615: W = "W"; break;
- case 616: W = "W"; break;
- case 620: W = "W"; break;
- case 621: W = "W"; break;
- case 622: W = "W"; break;
-
- case 701: W = "M"; break;
- case 711: W = "M"; break;
- case 721: W = "M"; break;
- case 731: W = "M"; break;
- case 741: W = "M"; break;
- case 751: W = "M"; break;
- case 761: W = "M"; break;
- case 762: W = "M"; break;
- case 771: W = "M"; break;
- case 781: W = "M"; break;
-
- default:break;
- }
- return W;
-}
+/** The MIT License (MIT)
+
+Copyright (c) 2018 David Payne
+
+Permission is hereby granted, free of charge, to any person obtaining a copy
+of this software and associated documentation files (the "Software"), to deal
+in the Software without restriction, including without limitation the rights
+to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+copies of the Software, and to permit persons to whom the Software is
+furnished to do so, subject to the following conditions:
+
+The above copyright notice and this permission notice shall be included in all
+copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+SOFTWARE.
+*/
+
+#include "OpenWeatherMapClient.h"
+
+OpenWeatherMapClient::OpenWeatherMapClient(String ApiKey, int CityIDs[], int cityCount, boolean isMetric) {
+ updateCityIdList(CityIDs, cityCount);
+ myApiKey = ApiKey;
+ setMetric(isMetric);
+}
+
+void OpenWeatherMapClient::updateWeatherApiKey(String ApiKey) {
+ myApiKey = ApiKey;
+}
+
+void OpenWeatherMapClient::updateWeather() {
+ WiFiClient weatherClient;
+ String apiGetData = "GET /data/2.5/group?id=" + myCityIDs + "&units=" + units + "&cnt=1&APPID=" + myApiKey + " HTTP/1.1";
+
+ Serial.println("Getting Weather Data");
+ Serial.println(apiGetData);
+ weathers[0].cached = false;
+ weathers[0].error = "";
+ if (weatherClient.connect(servername, 80)) { //starts client connection, checks for connection
+ weatherClient.println(apiGetData);
+ weatherClient.println("Host: " + String(servername));
+ weatherClient.println("User-Agent: ArduinoWiFi/1.1");
+ weatherClient.println("Connection: close");
+ weatherClient.println();
+ }
+ else {
+ Serial.println("connection for weather data failed"); //error message if no client connect
+ Serial.println();
+ weathers[0].error = "Connection for weather data failed";
+ return;
+ }
+
+ while(weatherClient.connected() && !weatherClient.available()) delay(1); //waits for data
+
+ Serial.println("Waiting for data");
+
+ // Check HTTP status
+ char status[32] = {0};
+ weatherClient.readBytesUntil('\r', status, sizeof(status));
+ Serial.println("Response Header: " + String(status));
+ if (strcmp(status, "HTTP/1.1 200 OK") != 0) {
+ Serial.print(F("Unexpected response: "));
+ Serial.println(status);
+ weathers[0].error = "Weather Data Error: " + String(status);
+ return;
+ }
+
+ // Skip HTTP headers
+ char endOfHeaders[] = "\r\n\r\n";
+ if (!weatherClient.find(endOfHeaders)) {
+ Serial.println(F("Invalid response"));
+ return;
+ }
+
+ const size_t bufferSize = 710;
+ DynamicJsonBuffer jsonBuffer(bufferSize);
+
+ // Parse JSON object
+ JsonObject& root = jsonBuffer.parseObject(weatherClient);
+ if (!root.success()) {
+ Serial.println(F("Weather Data Parsing failed!"));
+ weathers[0].error = "Weather Data Parsing failed!";
+ return;
+ }
+
+ weatherClient.stop(); //stop client
+
+ if (root.measureLength() <= 150) {
+ Serial.println("Error Does not look like we got the data. Size: " + String(root.measureLength()));
+ weathers[0].cached = true;
+ weathers[0].error = (const char*)root["message"];
+ Serial.println("Error: " + weathers[0].error);
+ return;
+ }
+ int count = root["cnt"];
+
+ for (int inx = 0; inx < count; inx++) {
+ weathers[inx].lat = (const char*)root["list"][inx]["coord"]["lat"];
+ weathers[inx].lon = (const char*)root["list"][inx]["coord"]["lon"];
+ weathers[inx].dt = (const char*)root["list"][inx]["dt"];
+ weathers[inx].city = (const char*)root["list"][inx]["name"];
+ weathers[inx].country = (const char*)root["list"][inx]["sys"]["country"];
+ weathers[inx].temp = (const char*)root["list"][inx]["main"]["temp"];
+ weathers[inx].humidity = (const char*)root["list"][inx]["main"]["humidity"];
+ weathers[inx].condition = (const char*)root["list"][inx]["weather"][0]["main"];
+ weathers[inx].wind = (const char*)root["list"][inx]["wind"]["speed"];
+ weathers[inx].weatherId = (const char*)root["list"][inx]["weather"][0]["id"];
+ weathers[inx].description = (const char*)root["list"][inx]["weather"][0]["description"];
+ weathers[inx].icon = (const char*)root["list"][inx]["weather"][0]["icon"];
+ weathers[inx].pressure = (const char*)root["list"][inx]["main"]["pressure"];
+ weathers[inx].direction = (const char*)root["list"][inx]["wind"]["deg"];
+
+ if (units == "metric") {
+ // convert to kph from m/s
+ float f = (weathers[inx].wind.toFloat() * 3.6);
+ weathers[inx].wind = String(f);
+ }
+
+ Serial.println("lat: " + weathers[inx].lat);
+ Serial.println("lon: " + weathers[inx].lon);
+ Serial.println("dt: " + weathers[inx].dt);
+ Serial.println("city: " + weathers[inx].city);
+ Serial.println("country: " + weathers[inx].country);
+ Serial.println("temp: " + weathers[inx].temp);
+ Serial.println("humidity: " + weathers[inx].humidity);
+ Serial.println("condition: " + weathers[inx].condition);
+ Serial.println("wind: " + weathers[inx].wind);
+ Serial.println("direction: " + weathers[inx].direction);
+ Serial.println("weatherId: " + weathers[inx].weatherId);
+ Serial.println("description: " + weathers[inx].description);
+ Serial.println("icon: " + weathers[inx].icon);
+ Serial.println();
+
+ }
+}
+
+String OpenWeatherMapClient::roundValue(String value) {
+ float f = value.toFloat();
+ int rounded = (int)(f+0.5f);
+ return String(rounded);
+}
+
+void OpenWeatherMapClient::updateCityIdList(int CityIDs[], int cityCount) {
+ myCityIDs = "";
+ for (int inx = 0; inx < cityCount; inx++) {
+ if (CityIDs[inx] > 0) {
+ if (myCityIDs != "") {
+ myCityIDs = myCityIDs + ",";
+ }
+ myCityIDs = myCityIDs + String(CityIDs[inx]);
+ }
+ }
+}
+
+void OpenWeatherMapClient::setMetric(boolean isMetric) {
+ if (isMetric) {
+ units = "metric";
+ } else {
+ units = "imperial";
+ }
+}
+
+String OpenWeatherMapClient::getLat(int index) {
+ return weathers[index].lat;
+}
+
+String OpenWeatherMapClient::getLon(int index) {
+ return weathers[index].lon;
+}
+
+String OpenWeatherMapClient::getDt(int index) {
+ return weathers[index].dt;
+}
+
+String OpenWeatherMapClient::getCity(int index) {
+ return weathers[index].city;
+}
+
+String OpenWeatherMapClient::getCountry(int index) {
+ return weathers[index].country;
+}
+
+String OpenWeatherMapClient::getTemp(int index) {
+ return weathers[index].temp;
+}
+
+String OpenWeatherMapClient::getTempRounded(int index) {
+ return roundValue(getTemp(index));
+}
+
+String OpenWeatherMapClient::getHumidity(int index) {
+ return weathers[index].humidity;
+}
+
+String OpenWeatherMapClient::getHumidityRounded(int index) {
+ return roundValue(getHumidity(index));
+}
+
+String OpenWeatherMapClient::getCondition(int index) {
+ return weathers[index].condition;
+}
+
+String OpenWeatherMapClient::getWind(int index) {
+ return weathers[index].wind;
+}
+
+String OpenWeatherMapClient::getDirection(int index)
+{
+ return weathers[index].direction;
+}
+
+String OpenWeatherMapClient::getDirectionRounded(int index)
+{
+ return roundValue(getDirection(index));
+}
+
+String OpenWeatherMapClient::getWindRounded(int index) {
+ return roundValue(getWind(index));
+}
+
+String OpenWeatherMapClient::getWeatherId(int index) {
+ return weathers[index].weatherId;
+}
+
+String OpenWeatherMapClient::getDescription(int index) {
+ return weathers[index].description;
+}
+
+String OpenWeatherMapClient::getPressure(int index)
+{
+ return weathers[index].pressure;
+}
+
+String OpenWeatherMapClient::getIcon(int index) {
+ return weathers[index].icon;
+}
+
+boolean OpenWeatherMapClient::getCached() {
+ return weathers[0].cached;
+}
+
+String OpenWeatherMapClient::getMyCityIDs() {
+ return myCityIDs;
+}
+
+String OpenWeatherMapClient::getError() {
+ return weathers[0].error;
+}
+
+String OpenWeatherMapClient::getWeekDay(int index, float offset) {
+ String rtnValue = "";
+ long epoc = weathers[index].dt.toInt();
+ long day = 0;
+ if (epoc != 0) {
+ day = (((epoc + (3600 * (int)offset)) / 86400) + 4) % 7;
+ switch (day) {
+ case 0:
+ rtnValue = "Sunday";
+ break;
+ case 1:
+ rtnValue = "Monday";
+ break;
+ case 2:
+ rtnValue = "Tuesday";
+ break;
+ case 3:
+ rtnValue = "Wednesday";
+ break;
+ case 4:
+ rtnValue = "Thursday";
+ break;
+ case 5:
+ rtnValue = "Friday";
+ break;
+ case 6:
+ rtnValue = "Saturday";
+ break;
+ default:
+ break;
+ }
+ }
+ return rtnValue;
+}
+
+String OpenWeatherMapClient::getWeatherIcon(int index)
+{
+ int id = getWeatherId(index).toInt();
+ String W = ")";
+ switch(id)
+ {
+ case 800: W = "B"; break;
+ case 801: W = "Y"; break;
+ case 802: W = "H"; break;
+ case 803: W = "H"; break;
+ case 804: W = "Y"; break;
+
+ case 200: W = "0"; break;
+ case 201: W = "0"; break;
+ case 202: W = "0"; break;
+ case 210: W = "0"; break;
+ case 211: W = "0"; break;
+ case 212: W = "0"; break;
+ case 221: W = "0"; break;
+ case 230: W = "0"; break;
+ case 231: W = "0"; break;
+ case 232: W = "0"; break;
+
+ case 300: W = "R"; break;
+ case 301: W = "R"; break;
+ case 302: W = "R"; break;
+ case 310: W = "R"; break;
+ case 311: W = "R"; break;
+ case 312: W = "R"; break;
+ case 313: W = "R"; break;
+ case 314: W = "R"; break;
+ case 321: W = "R"; break;
+
+ case 500: W = "R"; break;
+ case 501: W = "R"; break;
+ case 502: W = "R"; break;
+ case 503: W = "R"; break;
+ case 504: W = "R"; break;
+ case 511: W = "R"; break;
+ case 520: W = "R"; break;
+ case 521: W = "R"; break;
+ case 522: W = "R"; break;
+ case 531: W = "R"; break;
+
+ case 600: W = "W"; break;
+ case 601: W = "W"; break;
+ case 602: W = "W"; break;
+ case 611: W = "W"; break;
+ case 612: W = "W"; break;
+ case 615: W = "W"; break;
+ case 616: W = "W"; break;
+ case 620: W = "W"; break;
+ case 621: W = "W"; break;
+ case 622: W = "W"; break;
+
+ case 701: W = "M"; break;
+ case 711: W = "M"; break;
+ case 721: W = "M"; break;
+ case 731: W = "M"; break;
+ case 741: W = "M"; break;
+ case 751: W = "M"; break;
+ case 761: W = "M"; break;
+ case 762: W = "M"; break;
+ case 771: W = "M"; break;
+ case 781: W = "M"; break;
+
+ default:break;
+ }
+ return W;
+}
diff --git a/marquee/OpenWeatherMapClient.h b/marquee/OpenWeatherMapClient.h
index 594e3f9..2b34a97 100644
--- a/marquee/OpenWeatherMapClient.h
+++ b/marquee/OpenWeatherMapClient.h
@@ -1,85 +1,90 @@
-/** The MIT License (MIT)
-
-Copyright (c) 2018 David Payne
-
-Permission is hereby granted, free of charge, to any person obtaining a copy
-of this software and associated documentation files (the "Software"), to deal
-in the Software without restriction, including without limitation the rights
-to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
-copies of the Software, and to permit persons to whom the Software is
-furnished to do so, subject to the following conditions:
-
-The above copyright notice and this permission notice shall be included in all
-copies or substantial portions of the Software.
-
-THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
-IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
-FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
-AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
-LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
-OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
-SOFTWARE.
-*/
-
-#pragma once
-#include
-#include "libs/ArduinoJson/ArduinoJson.h"
-
-class OpenWeatherMapClient {
-
-private:
- String myCityIDs = "";
- String myApiKey = "";
- String units = "";
-
- const char* servername = "api.openweathermap.org"; // remote server we will connect to
-
- typedef struct {
- String lat;
- String lon;
- String dt;
- String city;
- String country;
- String temp;
- String humidity;
- String condition;
- String wind;
- String weatherId;
- String description;
- String icon;
- boolean cached;
- String error;
- } weather;
-
- weather weathers[5];
-
- String roundValue(String value);
-
-public:
- OpenWeatherMapClient(String ApiKey, int CityIDs[], int cityCount, boolean isMetric);
- void updateWeather();
- void updateWeatherApiKey(String ApiKey);
- void updateCityIdList(int CityIDs[], int cityCount);
- void setMetric(boolean isMetric);
-
- String getLat(int index);
- String getLon(int index);
- String getDt(int index);
- String getCity(int index);
- String getCountry(int index);
- String getTemp(int index);
- String getTempRounded(int index);
- String getHumidity(int index);
- String getHumidityRounded(int index);
- String getCondition(int index);
- String getWind(int index);
- String getWindRounded(int index);
- String getWeatherId(int index);
- String getDescription(int index);
- String getIcon(int index);
- boolean getCached();
- String getMyCityIDs();
- String getWeatherIcon(int index);
- String getError();
- String getWeekDay(int index, float offset);
-};
+/** The MIT License (MIT)
+
+Copyright (c) 2018 David Payne
+
+Permission is hereby granted, free of charge, to any person obtaining a copy
+of this software and associated documentation files (the "Software"), to deal
+in the Software without restriction, including without limitation the rights
+to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+copies of the Software, and to permit persons to whom the Software is
+furnished to do so, subject to the following conditions:
+
+The above copyright notice and this permission notice shall be included in all
+copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+SOFTWARE.
+*/
+
+#pragma once
+#include
+#include "libs/ArduinoJson/ArduinoJson.h"
+
+class OpenWeatherMapClient {
+
+private:
+ String myCityIDs = "";
+ String myApiKey = "";
+ String units = "";
+
+ const char* servername = "api.openweathermap.org"; // remote server we will connect to
+
+ typedef struct {
+ String lat;
+ String lon;
+ String dt;
+ String city;
+ String country;
+ String temp;
+ String humidity;
+ String condition;
+ String wind;
+ String weatherId;
+ String description;
+ String icon;
+ boolean cached;
+ String error;
+ String pressure;
+ String direction;
+ } weather;
+
+ weather weathers[5];
+
+ String roundValue(String value);
+
+public:
+ OpenWeatherMapClient(String ApiKey, int CityIDs[], int cityCount, boolean isMetric);
+ void updateWeather();
+ void updateWeatherApiKey(String ApiKey);
+ void updateCityIdList(int CityIDs[], int cityCount);
+ void setMetric(boolean isMetric);
+
+ String getLat(int index);
+ String getLon(int index);
+ String getDt(int index);
+ String getCity(int index);
+ String getCountry(int index);
+ String getTemp(int index);
+ String getTempRounded(int index);
+ String getHumidity(int index);
+ String getHumidityRounded(int index);
+ String getCondition(int index);
+ String getWind(int index);
+ String getWindRounded(int index);
+ String getDirection(int index);
+ String getDirectionRounded(int index);
+ String getPressure(int index);
+ String getWeatherId(int index);
+ String getDescription(int index);
+ String getIcon(int index);
+ boolean getCached();
+ String getMyCityIDs();
+ String getWeatherIcon(int index);
+ String getError();
+ String getWeekDay(int index, float offset);
+};
diff --git a/marquee/marquee.ino b/marquee/marquee.ino
index 8d70b0b..ec4828f 100644
--- a/marquee/marquee.ino
+++ b/marquee/marquee.ino
@@ -79,6 +79,8 @@ boolean SHOW_CITY = true;
boolean SHOW_CONDITION = true;
boolean SHOW_HUMIDITY = true;
boolean SHOW_WIND = true;
+boolean SHOW_WINDDIR = true;
+boolean SHOW_PRESSURE = true;
// OctoPrint Client
OctoPrintClient printerClient(OctoPrintApiKey, OctoPrintServer, OctoPrintPort, OctoAuthUser, OctoAuthPass);
@@ -121,6 +123,7 @@ static const char CHANGE_FORM1[] PROGMEM = "
"
" Display Humidity
"
" Display Wind
"
+ " Display Barometric Pressure
"
" Use 24 Hour Clock (military time)
";
static const char CHANGE_FORM2[] PROGMEM = " Show PM indicator (only 12h format)
"
@@ -392,9 +395,14 @@ void loop() {
msg += "Humidity:" + weatherClient.getHumidityRounded(0) + "% ";
}
if (SHOW_WIND) {
- msg += "Wind:" + weatherClient.getWindRounded(0) + getSpeedSymbol() + " ";
+ msg += "Wind:" + weatherClient.getDirectionRounded(0) + " deg/";
+ msg += weatherClient.getWindRounded(0) + " " + getSpeedSymbol() + " ";
+ }
+ //line to show barometric pressure
+ if (SHOW_PRESSURE)
+ {
+ msg += "Pressure:" + weatherClient.getPressure(0) + " mb ";
}
-
msg += marqueeMessage + " ";
if (NEWS_ENABLED) {
@@ -567,6 +575,7 @@ void handleLocations() {
SHOW_CONDITION = server.hasArg("showcondition");
SHOW_HUMIDITY = server.hasArg("showhumidity");
SHOW_WIND = server.hasArg("showwind");
+ SHOW_PRESSURE = server.hasArg("showpressure");
IS_METRIC = server.hasArg("metric");
marqueeMessage = decodeHtmlString(server.arg("marqueeMsg"));
timeDisplayTurnsOn = decodeHtmlString(server.arg("startTime"));
@@ -825,6 +834,11 @@ void handleConfigure() {
isWindChecked = "checked='checked'";
}
form.replace("%WIND_CHECKED%", isWindChecked);
+ String isPressureChecked = "";
+ if (SHOW_PRESSURE) {
+ isPressureChecked = "checked='checked'";
+ }
+ form.replace("%PRESSURE_CHECKED%", isPressureChecked);
String is24hourChecked = "";
if (IS_24HOUR) {
is24hourChecked = "checked='checked'";
@@ -1080,7 +1094,8 @@ void displayWeatherData() {
html += "";
html += "
";
html += weatherClient.getHumidity(0) + "% Humidity
";
- html += weatherClient.getWind(0) + "
" + getSpeedSymbol() + " Wind
";
+ html += weatherClient.getDirection(0) + " deg/" + weatherClient.getWind(0) + "
" + getSpeedSymbol() + " Wind
";
+ html += weatherClient.getPressure(0) + " Pressure
";
html += "
";
html += "";
html += weatherClient.getCondition(0) + " (" + weatherClient.getDescription(0) + ")
";
@@ -1319,6 +1334,7 @@ String writeCityIds() {
f.println("SHOW_CONDITION=" + String(SHOW_CONDITION));
f.println("SHOW_HUMIDITY=" + String(SHOW_HUMIDITY));
f.println("SHOW_WIND=" + String(SHOW_WIND));
+ f.println("SHOW_PRESSURE=" + String(SHOW_PRESSURE));
f.println("SHOW_DATE=" + String(SHOW_DATE));
f.println("USE_PIHOLE=" + String(USE_PIHOLE));
f.println("PiHoleServer=" + PiHoleServer);
@@ -1494,6 +1510,10 @@ void readCityIds() {
SHOW_WIND = line.substring(line.lastIndexOf("SHOW_WIND=") + 10).toInt();
Serial.println("SHOW_WIND=" + String(SHOW_WIND));
}
+ if (line.indexOf("SHOW_PRESSURE=") >= 0) {
+ SHOW_PRESSURE = line.substring(line.lastIndexOf("SHOW_PRESSURE=") + 14).toInt();
+ Serial.println("SHOW_PRESSURE=" + String(SHOW_PRESSURE));
+ }
if (line.indexOf("SHOW_DATE=") >= 0) {
SHOW_DATE = line.substring(line.lastIndexOf("SHOW_DATE=") + 10).toInt();
Serial.println("SHOW_DATE=" + String(SHOW_DATE));
From 7206dec37ad669283817fff525a74110b621cf12 Mon Sep 17 00:00:00 2001
From: Brandon
Date: Sun, 5 May 2019 19:57:49 -0600
Subject: [PATCH 2/2] add additional weather features
Support added for wind direction, barometric pressure, and daily high/low temperatures.
---
marquee/OpenWeatherMapClient.cpp | 18 ++++++++++
marquee/OpenWeatherMapClient.h | 4 +++
marquee/marquee.ino | 57 ++++++++++++++++++++++++++------
3 files changed, 68 insertions(+), 11 deletions(-)
diff --git a/marquee/OpenWeatherMapClient.cpp b/marquee/OpenWeatherMapClient.cpp
index 9a9608b..8d4e05b 100644
--- a/marquee/OpenWeatherMapClient.cpp
+++ b/marquee/OpenWeatherMapClient.cpp
@@ -114,6 +114,8 @@ void OpenWeatherMapClient::updateWeather() {
weathers[inx].icon = (const char*)root["list"][inx]["weather"][0]["icon"];
weathers[inx].pressure = (const char*)root["list"][inx]["main"]["pressure"];
weathers[inx].direction = (const char*)root["list"][inx]["wind"]["deg"];
+ weathers[inx].high = (const char*)root["list"][inx]["main"]["temp_max"];
+ weathers[inx].low = (const char*)root["list"][inx]["main"]["temp_min"];
if (units == "metric") {
// convert to kph from m/s
@@ -121,6 +123,12 @@ void OpenWeatherMapClient::updateWeather() {
weathers[inx].wind = String(f);
}
+ if (units != "metric")
+ {
+ float p = (weathers[inx].pressure.toFloat() * 0.0295301); //convert millibars to inches
+ weathers[inx].pressure = String(p);
+ }
+
Serial.println("lat: " + weathers[inx].lat);
Serial.println("lon: " + weathers[inx].lon);
Serial.println("dt: " + weathers[inx].dt);
@@ -236,6 +244,16 @@ String OpenWeatherMapClient::getPressure(int index)
return weathers[index].pressure;
}
+String OpenWeatherMapClient::getHigh(int index)
+{
+ return weathers[index].high;
+}
+
+String OpenWeatherMapClient::getLow(int index)
+{
+ return weathers[index].low;
+}
+
String OpenWeatherMapClient::getIcon(int index) {
return weathers[index].icon;
}
diff --git a/marquee/OpenWeatherMapClient.h b/marquee/OpenWeatherMapClient.h
index 2b34a97..636acd0 100644
--- a/marquee/OpenWeatherMapClient.h
+++ b/marquee/OpenWeatherMapClient.h
@@ -51,6 +51,8 @@ class OpenWeatherMapClient {
String error;
String pressure;
String direction;
+ String high;
+ String low;
} weather;
weather weathers[5];
@@ -79,6 +81,8 @@ class OpenWeatherMapClient {
String getDirection(int index);
String getDirectionRounded(int index);
String getPressure(int index);
+ String getHigh(int index);
+ String getLow(int index);
String getWeatherId(int index);
String getDescription(int index);
String getIcon(int index);
diff --git a/marquee/marquee.ino b/marquee/marquee.ino
index ec4828f..6f615d3 100644
--- a/marquee/marquee.ino
+++ b/marquee/marquee.ino
@@ -81,6 +81,7 @@ boolean SHOW_HUMIDITY = true;
boolean SHOW_WIND = true;
boolean SHOW_WINDDIR = true;
boolean SHOW_PRESSURE = true;
+boolean SHOW_HIGHLOW = true;
// OctoPrint Client
OctoPrintClient printerClient(OctoPrintApiKey, OctoPrintServer, OctoPrintPort, OctoAuthUser, OctoAuthPass);
@@ -124,6 +125,7 @@ static const char CHANGE_FORM1[] PROGMEM = "
"
"
Display Wind
"
"
Display Barometric Pressure
"
+ "
Display Daily High/Low Temperatures
"
"
Use 24 Hour Clock (military time)
";
static const char CHANGE_FORM2[] PROGMEM = "
Show PM indicator (only 12h format)
"
@@ -382,17 +384,17 @@ void loop() {
if (SHOW_DATE) {
msg += TimeDB.getDayName() + ", ";
- msg += TimeDB.getMonthName() + " " + day() + " ";
+ msg += TimeDB.getMonthName() + " " + day() + " ";
}
if (SHOW_CITY) {
- msg += weatherClient.getCity(0) + " ";
+ msg += weatherClient.getCity(0) + " ";
}
- msg += temperature + getTempSymbol() + " ";
+ msg += temperature + getTempSymbol() + " ";
if (SHOW_CONDITION) {
- msg += description + " ";
+ msg += description + " ";
}
if (SHOW_HUMIDITY) {
- msg += "Humidity:" + weatherClient.getHumidityRounded(0) + "% ";
+ msg += "Humidity:" + weatherClient.getHumidityRounded(0) + "% ";
}
if (SHOW_WIND) {
msg += "Wind:" + weatherClient.getDirectionRounded(0) + " deg/";
@@ -401,23 +403,29 @@ void loop() {
//line to show barometric pressure
if (SHOW_PRESSURE)
{
- msg += "Pressure:" + weatherClient.getPressure(0) + " mb ";
+ msg += "Pressure:" + weatherClient.getPressure(0) + getPressureSymbol() + " ";
}
- msg += marqueeMessage + " ";
+ //show high/low temperature
+ if (SHOW_HIGHLOW)
+ {
+ msg += "Daily High/Low Temperatures:" + weatherClient.getHigh(0) + "/" + weatherClient.getLow(0) + " " + getTempSymbol() + " ";
+ }
+ msg += marqueeMessage + " ";
+
if (NEWS_ENABLED) {
- msg += " " + NEWS_SOURCE + ": " + newsClient.getTitle(newsIndex) + " ";
+ msg += " " + NEWS_SOURCE + ": " + newsClient.getTitle(newsIndex) + " ";
newsIndex += 1;
if (newsIndex > 9) {
newsIndex = 0;
}
}
if (OCTOPRINT_ENABLED && printerClient.isPrinting()) {
- msg += " " + printerClient.getFileName() + " ";
- msg += "(" + printerClient.getProgressCompletion() + "%) ";
+ msg += " " + printerClient.getFileName() + " ";
+ msg += "(" + printerClient.getProgressCompletion() + "%) ";
}
if (BitcoinCurrencyCode != "NONE" && BitcoinCurrencyCode != "") {
- msg += " Bitcoin: " + bitcoinClient.getRate() + " " + bitcoinClient.getCode() + " ";
+ msg += " Bitcoin: " + bitcoinClient.getRate() + " " + bitcoinClient.getCode() + " ";
}
if (USE_PIHOLE) {
piholeClient.getPiHoleData(PiHoleServer, PiHolePort);
@@ -576,6 +584,7 @@ void handleLocations() {
SHOW_HUMIDITY = server.hasArg("showhumidity");
SHOW_WIND = server.hasArg("showwind");
SHOW_PRESSURE = server.hasArg("showpressure");
+ SHOW_HIGHLOW = server.hasArg("showhighlow");
IS_METRIC = server.hasArg("metric");
marqueeMessage = decodeHtmlString(server.arg("marqueeMsg"));
timeDisplayTurnsOn = decodeHtmlString(server.arg("startTime"));
@@ -839,6 +848,14 @@ void handleConfigure() {
isPressureChecked = "checked='checked'";
}
form.replace("%PRESSURE_CHECKED%", isPressureChecked);
+
+ String isHighlowChecked = "";
+ if (SHOW_HIGHLOW) {
+ isHighlowChecked = "checked='checked'";
+ }
+ form.replace("%HIGHLOW_CHECKED%", isHighlowChecked);
+
+
String is24hourChecked = "";
if (IS_24HOUR) {
is24hourChecked = "checked='checked'";
@@ -1100,6 +1117,7 @@ void displayWeatherData() {
html += "
";
html += weatherClient.getCondition(0) + " (" + weatherClient.getDescription(0) + ")
";
html += temperature + " " + getTempSymbol() + "
";
+ html += weatherClient.getHigh(0) + "/" + weatherClient.getLow(0) + " " + getTempSymbol() + "
";
html += time + "
";
html += " Map It!
";
html += "
";
@@ -1212,6 +1230,16 @@ String getSpeedSymbol() {
return rtnValue;
}
+String getPressureSymbol()
+{
+ String rtnValue = "";
+ if (IS_METRIC)
+ {
+ rtnValue = "mb";
+ }
+ return rtnValue;
+}
+
// converts the dBm to a range between 0 and 100%
int8_t getWifiQuality() {
int32_t dbm = WiFi.RSSI();
@@ -1335,6 +1363,7 @@ String writeCityIds() {
f.println("SHOW_HUMIDITY=" + String(SHOW_HUMIDITY));
f.println("SHOW_WIND=" + String(SHOW_WIND));
f.println("SHOW_PRESSURE=" + String(SHOW_PRESSURE));
+ f.println("SHOW_HIGHLOW=" + String(SHOW_HIGHLOW));
f.println("SHOW_DATE=" + String(SHOW_DATE));
f.println("USE_PIHOLE=" + String(USE_PIHOLE));
f.println("PiHoleServer=" + PiHoleServer);
@@ -1514,6 +1543,12 @@ void readCityIds() {
SHOW_PRESSURE = line.substring(line.lastIndexOf("SHOW_PRESSURE=") + 14).toInt();
Serial.println("SHOW_PRESSURE=" + String(SHOW_PRESSURE));
}
+
+ if (line.indexOf("SHOW_HIGHLOW=") >= 0) {
+ SHOW_HIGHLOW = line.substring(line.lastIndexOf("SHOW_HIGHLOW=") + 13).toInt();
+ Serial.println("SHOW_HIGHLOW=" + String(SHOW_HIGHLOW));
+ }
+
if (line.indexOf("SHOW_DATE=") >= 0) {
SHOW_DATE = line.substring(line.lastIndexOf("SHOW_DATE=") + 10).toInt();
Serial.println("SHOW_DATE=" + String(SHOW_DATE));