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

weather: Add function for converting to units #2015

Merged
merged 3 commits into from
Nov 4, 2024
Merged

weather: Add function for converting to units #2015

merged 3 commits into from
Nov 4, 2024

Conversation

FintasticMan
Copy link
Member

Handles rounding correctly.

Copy link

github-actions bot commented Feb 12, 2024

Build size and comparison to main:

Section Size Difference
text 374576B 48B
data 948B 0B
bss 63504B 16B

@minacode
Copy link
Contributor

You could use structs of one int to make the types really safe.

@JF002
Copy link
Collaborator

JF002 commented Feb 15, 2024

I'm ok with the current state. I however thought about another option.

SimpleWeatherService would define a Temperature type : PineTime::Controllers::SimpleWeatherService::Temperature. It's the internal representation of a temperature in the SompleWeatherService expressed in "°C * 100"

struct Temperature {
  int16_t temperature;
}

Somewhere under DisplayApp, we would define another Temperature type : Pinetime::Applications::Temperature. It represent the temperature for the UI side of InfiniTime as an std::variant (TODO : check that the overhead of std::variant is negligible)

struct TemperatureCelsius {
  int16_t temperature;
}

struct TemperatureFahrenheit {
  int16_t temperature;
}

using Temperature = std::variant<TemperatureCelsius, TemperatureFahrenheit temperature

Then, also under DisplayApp, we define a function that converts from SimpleWeatherService Temperature to "display" temperature :

Pinetime::Applications::Temperature Convert(PineTime::Controllers::SimpleWeatherService::Temperature, Controllers::Settings::WeatherFormat format);

This way, all the "temperature" types are strongly typed and it's impossible to implicitly convert from one to another. Also SimpleWeatherService does not have any code related to the UI anymore.

@NeroBurner NeroBurner added the maintenance Background work label Oct 1, 2024
There is now a Temperature struct in the weather service, which holds
the internal representation. There is also a temperature struct in the
Applications namespace, which holds the temperature in either Celsius or
Fahrenheit.
Copy link
Member Author

@FintasticMan FintasticMan left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@JF002 I've just refactored this a bit, what do you think? I wasn't able to use std::variant, as it is very strict about knowing which variant to use at compile-time. That meant that we needed 2 completely separate code paths for Celsius and Fahrenheit.

@@ -61,13 +61,42 @@ namespace Pinetime {
Unknown = 255
};

class Temperature {
public:
explicit Temperature(int16_t raw = 0) : raw {raw} {
Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'm not a big fan of having the default value be 0 here, but otherwise the compiler complains about there being no default value for the array of Days in the Forecast.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think it would be conceptually better (maybe not memory-wise) to make the days array of type:
std::array<std::optional<Day>, nbOfDays>. Then you would not need to construct Days without values.

Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Would defining Temperature in Kelvin internally and converting to DisplayTemperature in °C or °F depending on the user setting for displaying be helpful?
Sorry, I'm not into object based programming that much...

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I don't think that is the problem here. The internal representation is never shown directly and can therefore be whatever. The problem is, that right now we need a temperature value in a place where no value should be.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think std::optional does make sense, I'm going to see how implementing it like that looks.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think this works quite well, what do you think?

@NeroBurner NeroBurner added this to the 1.15.0 milestone Oct 2, 2024
@minacode
Copy link
Contributor

minacode commented Oct 2, 2024

I like the current approach with the raw value and the two representations! :)

Also only iterate over the number of days actually in use, rather than
MaxNbForecastDays.
int16_t minTemp = optCurrentForecast->days[i].minTemperature;
lv_table_set_cell_type(forecast, 2, i, TemperatureStyle(maxTemp));
lv_table_set_cell_type(forecast, 3, i, TemperatureStyle(minTemp));
for (int i = 0; i < optCurrentForecast->nbDays; i++) {
Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It should be correct to use nbDays rather than MaxNbForecastDays here, but we should test it before merging.

Copy link
Collaborator

@JF002 JF002 left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LGTM!

@JF002 JF002 merged commit f7c87a7 into main Nov 4, 2024
6 of 7 checks passed
@FintasticMan FintasticMan deleted the temp_to_units branch November 4, 2024 20:27
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
maintenance Background work
Projects
None yet
Development

Successfully merging this pull request may close these issues.

6 participants