Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Adjust code to display high/low temps in forecast? #196

Open
jurassic73 opened this issue May 27, 2021 · 26 comments
Open

Adjust code to display high/low temps in forecast? #196

jurassic73 opened this issue May 27, 2021 · 26 comments

Comments

@jurassic73
Copy link

jurassic73 commented May 27, 2021

Missing feature

High/Low temperature display in forecast?

Justification

I currently see what looks like the low temperature displayed only in the forecast view. Curious if this can be adjusted to display both the high and low temperatures in the forecast view? If I configure the following, I see tempMin twice which is the same value returned for temp:

String temp = String(forecasts[dayIndex].tempMin, 0) + ("/") + String(forecasts[dayIndex].tempMax, 0) + (IS_METRIC ? "°C" : "°F");

I just need to know what to change to pull the tempMin and tempMax through from the API call

Workarounds

None

@NeTgHoStKiLlEr
Copy link

I have the same Issue. It appears to be showing forecast data for night-time only, even the weather icons are in night-mode; showing moons instead of suns. Been working at this to try and finish before Fathers Day...!

IMG_20210613_101942
IMG_20210613_102008

As you can see, the Current Weather data is fine, but it then decides to show only night-time data for the forecast.

@marcelstoer
Copy link
Member

The min / max is actually "broken" (our opinion) in the OWM API, see #172.

@NeTgHoStKiLlEr
Copy link

NeTgHoStKiLlEr commented Jun 13, 2021

Should I open another Issue topic for my slightly different issue? I just don't understand why its showing moon icons during the day. I wouldn't even care if it showed the projected forecast for only one hour of the next three days, just that it needs to show daytime temps; it gets HOT here. That shouldn't have anything to do with the temp_min or temp_max confusion.. correct?

I'm guessing somewhere in this function, having something to do with the ObservationTimeStamp or DayIndex values is where the issue lies?

void drawForecastDetails(OLEDDisplay *display, int x, int y, int dayIndex) {
  time_t observationTimestamp = forecasts[dayIndex].observationTime;
  struct tm* timeInfo;
  timeInfo = localtime(&observationTimestamp);
  display->setTextAlignment(TEXT_ALIGN_CENTER);
  display->setFont(ArialMT_Plain_10);
  display->drawString(x + 20, y, WDAY_NAMES[timeInfo->tm_wday]);

  display->setFont(Meteocons_Plain_21);
  display->drawString(x + 20, y + 12, forecasts[dayIndex].iconMeteoCon);
  String temp = String(forecasts[dayIndex].temp, 0) + (IS_METRIC ? "°C" : "°F");
  display->setFont(ArialMT_Plain_10);
  display->drawString(x + 20, y + 34, temp);
  display->setTextAlignment(TEXT_ALIGN_LEFT);
}

I don't need the high/low for the current day, just need the 3 day forecast to show daytime temps instead of night. Ty!

EDIT: I suspect the original code was meant to get the current time of day, and show either Day or Night forecast data based on if its morning or afternoon time. This is the part that I can't find how it works to correct it.

@marcelstoer
Copy link
Member

Looks like I misinterpreted the issue at first.

@marcelstoer marcelstoer reopened this Jun 13, 2021
@NeTgHoStKiLlEr
Copy link

Well, the OP wanted additional functionality to display both night and day high/low temps at the same time. I just added onto this issue because I thought he realized it wasn't only supposed to show the low/night time temps during the day. I don't think he does, now. Hence me wondering if I should create a NEW topic! :)

@stale stale bot added the stale label Apr 17, 2022
@ThingPulse ThingPulse deleted a comment from stale bot Apr 17, 2022
@stale stale bot removed the stale label Apr 17, 2022
@KevinGroninga
Copy link

I too am having the same issue with the forecast temps appearing to be the low temps for each of the three days. Living in Phoenix Arizona, our concern is more with high temps for a given day (as you could imagine.) There was a previous request to display both Min and Max. I agree that would be ideal.

I did a little research and debugging on my own and took a look at the data being returned by the API from OpenWeatherMap. Very, very odd. It appears that for forecast data, it's sending data in 3 hour increments. So you're actually getting 8 different data sets for a given data. It also appears that in my case with the timezone offset that it's using the temp data from the 12:00 hour (middle of the day), but yet those temps appear to be the absolute lowest. So appears there's some sort of time offset issue as well.

Having said that, would it make any sense to look at all 8 data elements within a given forecast day and do some comparisons and then capture the highest temp_max value as well as the lowest temp_min value and use those to display?

Really would like to have this working...

Perhaps instead of having just one page with all three of the forecast days, we could fit more info for each day by having a separate page for each?

@KevinGroninga
Copy link

KevinGroninga commented May 10, 2022

Oh, just another thing I saw in the OpenWeatherMapForecast.cpp file. This 'could' potentially be part of the issue. Since I'm not an Arduino code developer, I'm not 100% certain. But in the following code, is there any accounting for the 'TZ' offset that was defined in the WeatherStationDemo sketch?

 if (allowedHoursCount > 0) {
      time_t time = data[currentForecast].observationTime;
      struct tm* timeInfo;
      **timeInfo = gmtime(&time);
      uint8_t currentHour = timeInfo->tm_hour;**
      for (uint8_t i = 0; i < allowedHoursCount; i++) {
        if (currentHour == allowedHours[i]) {
          isCurrentForecastAllowed = true;
          return;
        }
      }

@marcelstoer
Copy link
Member

is there any accounting for the 'TZ' offset

I wondered as well the other day. gmtime returns UTC.

@KevinGroninga
Copy link

Well, this has been disappointing. Went to some effort to put this together and even designed a 3D printed enclosure for it, the charge controller and small 3.7v battery. Now come to find out, the forecast info is basically useless. Hmmmm...

@marcelstoer
Copy link
Member

Maybe there's both a conceptual and a coding problem (not sure, haven't been around this code for a while).

With https://github.com/ThingPulse/esp8266-weather-station/blob/master/examples/OpenWeatherMapForecastDemo/OpenWeatherMapForecastDemo.ino#L101-L102

  uint8_t allowedHours[] = {0,12};
  client.setAllowedHours(allowedHours, 2);

you're basically limiting the forecasts to midnight and noon. I guess this assumes that min temp is around midnight and high temp around noon. For many places this is likely not true.
The coding problem then maybe is that 0/12 doesn't consider the timezone.

@KevinGroninga
Copy link

Well, I'm wondering if making an overriding OpenWeatherForecast.cpp would be an option. I looked at the return data and oddly the lowest 'temp' value in a given day (8 data sets) was at the 12:00 timeframe. If you know Arizona, you know that isn't true. Seems like it should read all 8 of the timeframes in a given forecast day and save the highest temp_max and the lowest temp_min. In any case, it seems there's an issue with the TZ offset as well. Typically for AZ the highest temp will be at about 15:00. If we look at the OpenWeatherMap web site and how they show the high/low for the forecast days, you'd think it would be possible to show the same info. So someone could look at the site and compare to the ESP01 and see the same results. Then they'd know for sure their app key and location code are correct. I could be wrong, but I think people would consider that a 'win' if the two compared. But long story short, there's something really off about that section of code that is currently capturing the tempMax.
FYI, I'm definitely not an Arduino developer. I'm
Actually an old school COBOL and RPG developer. So I can often deduce things by looking at the code.

Quote: I can't describe porn, but I know it when I see it!

@marcelstoer
Copy link
Member

marcelstoer commented Aug 15, 2022

I looked into this again today. It's complicated I'm afraid and I don't see a satisfactory solution. Below is a kind-of note to self so I don't have to start from scratch next time I arrive here again.

  • The OWM API in question is the "hourly forecast" API: https://openweathermap.org/api/hourly-forecast#JSON
  • It provides 96 3h forecasts i.e. roughly for the next 4 days (starting around now).
  • It does not include the daily min/max temperatures.
  • The forecast hours are fixed: 00:00, 03:00, 06:00 and so on.
  • Forecast time is Unix/UTC/GMT! Examples:
  • As a consequence, if you want the forecast for Zurich or Phoenix at midnight local time you are out of luck. Zurich is UTC/GMT +2h (+1 in winter due to DST) while Phoenix is UTC/GMT -7h - 1/2/7 are not multiples of 3. However, if the location configured in this library is in a timezone that is a multiple of 3h ahead or behind UTC one could compensate this by picking next/previous forecasts.
  • The forecast demo intends to get the forecast at midnight and noon by saying
    uint8_t allowedHours[] = {0,12};
    client.setAllowedHours(allowedHours, 2);
    For the reasons stated above this fails and I get the forecast at 2am and 2pm instead for Zurich (UTC +2).
  • The code in this library could actually inspect all forecasts (something it currently doesn't) and derive the daily local min/max temperature. OWM provides the min/max for each 3h segment.

@KevinGroninga
Copy link

KevinGroninga commented Aug 15, 2022 via email

@tjlanctx
Copy link

I know I am late here, but hoping to shed some light.
For the time offset, In your .ino that you are implementing, there is a line #define TZ. I have mine set to -7 (utc -7 hours for Mountain Time Zone.
Extra code could be added for DST.
For adding minimum and maximum to the forcast straight from the OpenWeathermap.org site, use tempMin and tempMax in the drawForcastDetails section. Currently uses only temp. You will have to duplicate the section that prints the temp variable and modify the xy coordinates to make room.
The code below is from WeatherStationDemo.ino.

void drawForecastDetails(OLEDDisplay display, int x, int y, int dayIndex) {
Serial.println("in drawForecastDetails");
time_t observationTimestamp = forecasts[dayIndex].observationTime;
struct tm
timeInfo;
timeInfo = localtime(&observationTimestamp);
display->setTextAlignment(TEXT_ALIGN_CENTER);

//Display forcast weekday names at top tlj
display->setFont(ArialMT_Plain_10);
display->drawString(x + 20, y, WDAY_NAMES[timeInfo->tm_wday]);

//Draw weather Icons tlj
display->setFont(Meteocons_Plain_21);
display->drawString(x + 20, y + 16, forecasts[dayIndex].iconMeteoCon);

//Display low temps at bottom of screen tlj
String tempMin = String(forecasts[dayIndex].tempMin, 0) + (IS_METRIC ? "°C" : "°F");
display->setFont(ArialMT_Plain_10);
display->drawString(x + 20, y + 34, tempMin);

//display max temps above icon tlj
String tempMax = String(forecasts[dayIndex].tempMax, 0) + (IS_METRIC ? "°C" : "°F");
display->setFont(ArialMT_Plain_10);
display->drawString(x + 20, y + 10, tempMax);

I am not getting the correct temps and I am also getting the half moon icon on the forecast section. I am debugging libraries and think the problem may be in OpenWeatherMapForecast lib, but not certain of that.

As a reminder, the code provided is FREE and DEMO. Some of the declarations are outdated, and some would say that certain standards are not followed. The programmer provided this code to us free of charge to use and modify however we want so we do not have to re-invent the wheel every time we do a project. They state up front there is no guarantee how and if it will work. For those that are disappointed, go pay a programmer or buy what you want, then you should expect it to work.

Thank you to @squix78, ThingPulse and others who have contributed to the code. I look forward to seeing any other solutions others may have.

@marcelstoer
Copy link
Member

marcelstoer commented Oct 20, 2023

FWIW For our new kit I addressed these issues in the sample application.

@tjlanctx
Copy link

Thank you very much @marcelstoer for the fast response! I had not looked at the code for the new kit with touch screen. I should have read your solution above (#172). And your work is much appreciated here. I am a retired programmer and unfortunately I have some cognitive disability issues making some of this far more difficult than it should be.

@b-boy-brown
Copy link

@tjlanctx - apologies to reply on a very stale issue, but did you every have any luck debugging the OpenWeatherMapForecast lib? I too am getting incorrect temps/ half moon icon on the forecast section, and I am racking my brain trying to solve it. Any help is appreciated! 🙏

@KevinGroninga
Copy link

No, have never gotten a resolution for this issue. Sorry. If anyone else has, sure would like to see/have access to the updated code.

@b-boy-brown
Copy link

b-boy-brown commented Jul 4, 2024

Thank you so much for a quick reply! So for what it's worth, I did just discover a workaround. Under the updateData function, for some reason uint8_t allowedHours[] = {12}; is not recognized, and this causes the fallback of midnight temps. If you change this to 15 or 18 (which are the subsequent OWM data pulls) it seems to work.

void updateData(OLEDDisplay *display) {
  drawProgress(display, 10, "Updating time...");
  drawProgress(display, 30, "Updating weather...");
  currentWeatherClient.setMetric(IS_METRIC);
  currentWeatherClient.setLanguage(OPEN_WEATHER_MAP_LANGUAGE);
  currentWeatherClient.updateCurrentById(&currentWeather, OPEN_WEATHER_MAP_APP_ID, OPEN_WEATHER_MAP_LOCATION_ID);
  drawProgress(display, 50, "Updating forecasts...");
  forecastClient.setMetric(IS_METRIC);
  forecastClient.setLanguage(OPEN_WEATHER_MAP_LANGUAGE);
  uint8_t allowedHours[] = {12}; // <-- Change this to 15 or 18
  forecastClient.setAllowedHours(allowedHours, sizeof(allowedHours));
  forecastClient.updateForecastsById(forecasts, OPEN_WEATHER_MAP_APP_ID, OPEN_WEATHER_MAP_LOCATION_ID, MAX_FORECASTS);

  readyForWeatherUpdate = false;
  drawProgress(display, 100, "Done...");
  delay(1000);
}

Not a permanent fix, but based on what others were looking for, I'm guessing this hits the mark. Hopefully this helps others out there! Only time will tell what issues DST causes... :/

PXL_20240704_213439991

@KevinGroninga
Copy link

Cool! I'll give this a try and see if it resolves the issues with the daily high temp. 3:00pm (15) would be our high temps here in Phx, so if it works, a good solution!

@KevinGroninga
Copy link

Hmm, I still appear to be getting what would be midnight temps. That change doesn't seem to work for me... Or perhaps I have the wrong base code now...

@KevinGroninga
Copy link

Okay, I figured this out. In order for me to get the high temps for the day and because of my UTC offset, I actually had to change that value to {0}! My UTC offset is -7, I'm in Phoenix. So I tried all of the possible values (0, 3, 6, 9, 12, 15, 18, 21), and the temps for '0' were the highest. So here's the way I think it works (and I could be wrong... In order to get the noon temp, I would add 12+7, which is 19. The closest to that would be 18. Which I think is then the 11:00am forecasted temp. Here in Phx, the high for the day is usually about 4-5pm. So that would be 17+7, which is 24. There is no 24, it's actually 0. 21 would give me the 2:00pm temp.

Sort of making sense now?

@b-boy-brown
Copy link

b-boy-brown commented Jul 5, 2024

You are 100% correct!

Looks like OWM provides the hourly responses with UTC timestamps (as per the documentation). So if you leave the base code untouched, e.g. uint8_t allowedHours[] = {12};, that actually grabs forecast results for 12:00PM UTC only, which for someone like me in California, is actually 5am PST (hence the low temps and moons!). This is embarrassingly obvious now we have figured this out!

I've settled on uint8_t allowedHours[] = {21};, as this is fetches the hottest part of the day for me too.

Glad we got there in the end! Thanks for all of your help and Happy 4th!

@marcelstoer
Copy link
Member

@KevinGroninga AFAIU what you said is pretty much in line with what I explained previously at #196 (comment), right? Also, unless someone is willing to contribute a PR with a fix (blue-print at #196 (comment)) we have to live with the shortcomings of the current implementation. Hence, I'm tempted to close this issue.

@tjlanctx
Copy link

tjlanctx commented Aug 24, 2024 via email

@AlexeyMal
Copy link

Dear All,
up to now I have used an OpenWeatherMapOneCallAPI to get the daily min/max temperature values. But now OpenWeatherMap discontinued the free OneCallAPI 2.5 and require a (payed) subscription to OneCallAPI3.0 with a credit card. So I have decided to change the provider and reprogrammed my weather station (originated from this repo) to use a new, free and flexible open-meteo API: https://open-meteo.com/en/docs .
Please use my code and enjoy:
https://github.com/AlexeyMal/esp8266-weather-station
Best regards, Alexey

Dear Marcel,
if you would like to add/change the API to open-meteo.com in your library, feel free to take OpenMeteoOneCall.h and OpenMeteoOneCall.cpp from my repository. The data structure is kept same to OpenWeatherMapOneCall.h/.cpp in your repository. But only the required fields are parced so far.
Best regards, Alexey

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

7 participants