|
@@ -19,190 +19,33 @@ void drawWeatherPallete(int x, int y) {
|
|
|
int lineHeight = 44;
|
|
|
|
|
|
//Print current temperature and humd
|
|
|
- display.getTextBounds(String(currentTemp) + "C", 0, 0, &tbx, &tby, &tbw, &tbh);
|
|
|
- display.setCursor(display.width() - tbw - 10, y + tbh);
|
|
|
- display.print(String(currentTemp) + "C");
|
|
|
-
|
|
|
+ display.getTextBounds(String(currentTemp) + " C", 0, 0, &tbx, &tby, &tbw, &tbh);
|
|
|
+ int tempX = display.width() - tbw - 10;
|
|
|
+ display.setCursor(tempX, y + tbh);
|
|
|
+ display.print(String(currentTemp) + " C");
|
|
|
+ //Draw the degree sign as it is not supported in ASCII
|
|
|
+ display.getTextBounds(String(currentTemp), 0, 0, &tbx, &tby, &tbw, &tbh);
|
|
|
+ display.fillCircle(tempX + tbw + 10, y + 7, 6, textColor);
|
|
|
+ display.fillCircle(tempX + tbw + 10, y + 7, 3, GxEPD_WHITE);
|
|
|
+
|
|
|
y += tbh + 10;
|
|
|
+ display.setFont(&FreeSans18pt7b);
|
|
|
display.getTextBounds(String(currentHumd) + "%", 0, 0, &tbx, &tby, &tbw, &tbh);
|
|
|
display.setCursor(display.width() - tbw - 10, y + tbh);
|
|
|
display.print(String(currentHumd) + "%");
|
|
|
- y += tbh + 10;
|
|
|
- display.setFont(&FreeSans9pt7b);
|
|
|
- lineHeight = 18;
|
|
|
-
|
|
|
- if (renderForcast) {
|
|
|
- //Render the forcast for coming 5 days
|
|
|
- //if data grab failed, skip the render
|
|
|
- String forcast;
|
|
|
- for (int i = 0; i < 5; i++) {
|
|
|
- y += lineHeight;
|
|
|
- forcast = String(forcastTempMin[i]) + "-" + String(forcastTempMax[i]) + "C " + String(forcastRhMax[i]) + "%";
|
|
|
- display.getTextBounds(forcast, 0, 0, &tbx, &tby, &tbw, &tbh);
|
|
|
- display.setCursor(display.width() - tbw - 10, y);
|
|
|
- display.print(forcast);
|
|
|
- }
|
|
|
- }
|
|
|
-
|
|
|
}
|
|
|
|
|
|
-
|
|
|
-//Current weather info
|
|
|
-const char* rhurl = "https://data.weather.gov.hk/weatherAPI/opendata/weather.php?dataType=rhrread&lang=en";
|
|
|
-//Weather forcast info
|
|
|
-const char* wfurl = "https://data.weather.gov.hk/weatherAPI/opendata/weather.php?dataType=fnd&lang=en";
|
|
|
-
|
|
|
-/*
|
|
|
- Weather Forcast Loaders
|
|
|
-*/
|
|
|
-
|
|
|
-bool updateAndRenderForcastInfo() {
|
|
|
- Serial.println("Updating weather forcast info...");
|
|
|
- WiFiClientSecure httpsClient; // Use WiFiClientSecure for HTTPS
|
|
|
- httpsClient.setInsecure(); // Ignore SSL certificate verification (for simplicity)
|
|
|
-
|
|
|
- if (httpsClient.connect("data.weather.gov.hk", 443)) {
|
|
|
- Serial.println("Downloading forcast info");
|
|
|
- httpsClient.print(String("GET ") + wfurl + " HTTP/1.1\r\n" +
|
|
|
- "Host: data.weather.gov.hk\r\n" +
|
|
|
- "Connection: close\r\n\r\n");
|
|
|
-
|
|
|
- String response = "";
|
|
|
- //Skip through the headers
|
|
|
- while (httpsClient.connected()) {
|
|
|
- String line = httpsClient.readStringUntil('\n');
|
|
|
- if (line == "\r") {
|
|
|
- break;
|
|
|
- }
|
|
|
- }
|
|
|
-
|
|
|
- //Read the JSON body
|
|
|
- String line = "";
|
|
|
- while (httpsClient.available()) {
|
|
|
- line = httpsClient.readStringUntil('\n'); //Read Line by Line
|
|
|
- response += line;
|
|
|
- }
|
|
|
-
|
|
|
- //Trim the first unwannted byte and the last
|
|
|
- int startTrimPos = response.indexOf("{");
|
|
|
- int lastTrimPos = response.lastIndexOf("}");
|
|
|
- response = response.substring(startTrimPos, lastTrimPos + 1);
|
|
|
-
|
|
|
- //Serial.println(response);
|
|
|
- if (response.length() < 10){
|
|
|
- //TODO HANDLE ERROR
|
|
|
- return false;
|
|
|
- }
|
|
|
-
|
|
|
- // Build the filter
|
|
|
- StaticJsonDocument<1024> filter;
|
|
|
- for (int i = 0; i < 7; i++) {
|
|
|
- filter["weatherForecast"][i]["week"] = true;
|
|
|
- filter["weatherForecast"][i]["forecastMintemp"]["value"] = true;
|
|
|
- filter["weatherForecast"][i]["forecastMaxtemp"]["value"] = true;
|
|
|
- filter["weatherForecast"][i]["forecastMaxrh"]["value"] = true;
|
|
|
- filter["weatherForecast"][i]["ForecastIcon"] = true;
|
|
|
- }
|
|
|
-
|
|
|
- // Parse JSON data
|
|
|
- StaticJsonDocument<5120> jsonDoc;
|
|
|
- auto error = deserializeJson(jsonDoc, response, DeserializationOption::Filter(filter));
|
|
|
- if (error) {
|
|
|
- Serial.print(F("deserializeJson() failed with code "));
|
|
|
- Serial.println(error.c_str());
|
|
|
- return false;
|
|
|
- }
|
|
|
-
|
|
|
- //serializeJsonPretty(jsonDoc, Serial);
|
|
|
-
|
|
|
- //Render the weather forcast onto the HMI
|
|
|
- for (int i = 0; i < 7; i++) {
|
|
|
- //Get day of week
|
|
|
- String dow = jsonDoc["weatherForecast"][i]["week"];
|
|
|
- dow = dow.substring(0, 3);
|
|
|
-
|
|
|
- //Get min-max temp
|
|
|
- int minTemp = jsonDoc["weatherForecast"][i]["forecastMintemp"]["value"];
|
|
|
- int maxTemp = jsonDoc["weatherForecast"][i]["forecastMaxtemp"]["value"];
|
|
|
- int maxRh = jsonDoc["weatherForecast"][i]["forecastMaxrh"]["value"];
|
|
|
- //Get forcast icon
|
|
|
- int forcastIcon = jsonDoc["weatherForecast"][i]["ForecastIcon"];
|
|
|
- //TODO: Implement this
|
|
|
- //renderForcastField(String(i), dow, minTemp, maxTemp, maxRh, forcastIcon);
|
|
|
- forcastTempMin[i] = minTemp;
|
|
|
- forcastTempMax[i] = maxTemp;
|
|
|
- forcastRhMax[i] = maxRh;
|
|
|
- }
|
|
|
- }
|
|
|
- return true;
|
|
|
-}
|
|
|
-
|
|
|
-/*
|
|
|
- Current Weather Loaders
|
|
|
-*/
|
|
|
-
|
|
|
-void updateCurrentWeatherInfo() {
|
|
|
- WiFiClientSecure httpsClient; // Use WiFiClientSecure for HTTPS
|
|
|
- httpsClient.setInsecure(); // Ignore SSL certificate verification (for simplicity)
|
|
|
-
|
|
|
- if (httpsClient.connect("data.weather.gov.hk", 443)) {
|
|
|
- Serial.println("Downloading current weather info");
|
|
|
- httpsClient.print(String("GET ") + rhurl + " HTTP/1.1\r\n" +
|
|
|
- "Host: data.weather.gov.hk\r\n" +
|
|
|
- "Connection: close\r\n\r\n");
|
|
|
-
|
|
|
- String response = "";
|
|
|
- //Skip through the headers
|
|
|
- while (httpsClient.connected()) {
|
|
|
- String line = httpsClient.readStringUntil('\n');
|
|
|
- if (line == "\r") {
|
|
|
- break;
|
|
|
- }
|
|
|
- }
|
|
|
-
|
|
|
- //Read the JSON body
|
|
|
- String line;
|
|
|
- while (httpsClient.available()) {
|
|
|
- line = httpsClient.readStringUntil('\n'); //Read Line by Line
|
|
|
- response += line;
|
|
|
- }
|
|
|
-
|
|
|
-
|
|
|
- //Trim the first unwannted byte and the last
|
|
|
- int startTrimPos = response.indexOf("{");
|
|
|
- int lastTrimPos = response.lastIndexOf("}");
|
|
|
- response = response.substring(startTrimPos, lastTrimPos + 1);
|
|
|
-
|
|
|
- //Serial.println(response);
|
|
|
-
|
|
|
- // Build the filter
|
|
|
- StaticJsonDocument<1024> filter;
|
|
|
- filter["temperature"]["data"][0]["value"] = true;
|
|
|
- filter["humidity"]["data"][0]["value"] = true;
|
|
|
- filter["rainfall"]["data"][0]["max"] = true;
|
|
|
- filter["rainfall"]["data"][0]["main"] = true;
|
|
|
-
|
|
|
- // Parse JSON data
|
|
|
- StaticJsonDocument<4096> jsonDoc;
|
|
|
- auto error = deserializeJson(jsonDoc, response, DeserializationOption::Filter(filter));
|
|
|
- if (error) {
|
|
|
- Serial.print(F("deserializeJson() failed with code "));
|
|
|
- Serial.println(error.c_str());
|
|
|
- return;
|
|
|
- }
|
|
|
-
|
|
|
- // Access and return the temperature value
|
|
|
- currentTemp = jsonDoc["temperature"]["data"][19]["value"];
|
|
|
- currentHumd = jsonDoc["humidity"]["data"][0]["value"];
|
|
|
- currentRain = jsonDoc["rainfall"]["data"][16]["max"];
|
|
|
- currentIsRaining = String(jsonDoc["rainfall"]["data"][16]["main"]) == "TRUE";
|
|
|
-
|
|
|
- // Serial debug prints
|
|
|
- Serial.println(int(jsonDoc["temperature"]["data"][19]["value"]));
|
|
|
- Serial.println(int(jsonDoc["humidity"]["data"][0]["value"]));
|
|
|
- Serial.println(int(jsonDoc["rainfall"]["data"][16]["max"]));
|
|
|
- Serial.println(String(jsonDoc["rainfall"]["data"][16]["main"]));
|
|
|
- } else {
|
|
|
- Serial.println("Failed to connect to server");
|
|
|
+//Draw the sun or moon icon base on day / night time
|
|
|
+void drawSunMoon(int x, int y){
|
|
|
+ if (isNight()){
|
|
|
+ //Draw moon
|
|
|
+ display.fillCircle(x, y, 40, GxEPD_RED);
|
|
|
+ display.fillCircle(x - 30, y - 15, 38, GxEPD_WHITE);
|
|
|
+ }else{
|
|
|
+ //Draw sun
|
|
|
+ display.fillCircle(x, y, 40, GxEPD_RED);
|
|
|
+ //some clouds
|
|
|
+ display.fillCircle(x + 10, y + 28, 20, GxEPD_WHITE);
|
|
|
+ display.fillCircle(x + 40, y + 20, 30, GxEPD_WHITE);
|
|
|
}
|
|
|
}
|