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

extend weather block to show sunset and sunrise #2028

Open
wants to merge 28 commits into
base: master
Choose a base branch
from

Conversation

sMailund
Copy link

@sMailund sMailund commented Mar 27, 2024

ref #715
image

Opted to include into existing weather block instead of creating standalone block.
Implemented for both OpenWeatherMap and MetNo providers

src/blocks/weather/open_weather_map.rs Outdated Show resolved Hide resolved
src/blocks/weather.rs Outdated Show resolved Hide resolved
src/blocks/weather/open_weather_map.rs Outdated Show resolved Hide resolved
@@ -160,8 +178,8 @@ impl WeatherProvider for Service<'_> {
.error("No location given")?;

let querystr: HashMap<&str, String> = map! {
"lat" => lat,
"lon" => lon,
"lat" => &lat,
Copy link
Collaborator

Choose a reason for hiding this comment

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

https://api.met.no/weatherapi/sunrise/3.0/documentation

  • offset (optional), timezone offset, on the format +HH:MM or -HH:MM
    Timezone offset
    The optional offset parameter is the difference between local time and UTC, as defined in ISO 8601. This is used mainly for returning timestamps in local time, but is also used in some instances to calculate the correct date period. If omitted, all times will be given in UTC.

Presently timezones for the offset parameter range from -12:00 to +15:00, although this may change in the future. For GMT, only +00:00 is allowed. You can see a list of all current timezones on https://en.wikipedia.org/wiki/List_of_UTC_time_offsets.

Copy link
Author

Choose a reason for hiding this comment

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

I am not sure if this is necessary. After some testing, it seems like the status bar correctly renders the time in the correct timezone out of the box. It makes more sense for me to receive the sunset and sunrise times in GMT when it will be adjusted to the correct timezone when displayed anyways. What do you think, is it OK as it is?

image

image

(sorry late reply, been very busy lately)

Copy link
Collaborator

Choose a reason for hiding this comment

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

No worries. It looks like when the date is omitted I am getting the sunrise/sunset for tomorrow instead of today. You're right that it doesn't seem to matter if the offset is included.

The example I was using is https://api.met.no/weatherapi/sunrise/3.0/sun?lat=40.43&lon=-74.01&date=2024-05-13 (on 2024-05-13) I see the times for 2024-05-14. I think that the default date is the date in GMT

src/blocks/weather.rs Outdated Show resolved Hide resolved
@@ -283,11 +301,51 @@ impl WeatherProvider for Service<'_> {
})
};

let (sunset, sunrise) = match need_sunrise_and_sunset {
Copy link
Collaborator

Choose a reason for hiding this comment

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

I'd make this a if/else

@@ -283,11 +301,51 @@ impl WeatherProvider for Service<'_> {
})
};

let (sunset, sunrise) = match need_sunrise_and_sunset {
true => {
let current_date = chrono::Local::now().format("%Y-%m-%d").to_string();
Copy link
Collaborator

Choose a reason for hiding this comment

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

I think this needs to be the current_date for the location of the sunset/sunrise, not the current location.

BTW, I'm going to reach out to the met.no about this quirk.

Copy link
Author

@sMailund sMailund Jun 4, 2024

Choose a reason for hiding this comment

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

I'm guessing using the default value provided by met.no is probably the best bet instead of trying to set it myself as I did previously:
image
ref b1959a2

Copy link
Collaborator

Choose a reason for hiding this comment

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

On Mon, Jun 3, 2024 at 9:20 AM @met.no via RT <@met.no> wrote:

Well, the intended usage is to specify the date using the so named
parameter. If missing, the API will get the day from localtime on the
server, but since that is set to UTC the date will sometimes be different
than in other timezones.

We might look into converting localtime into the timezone specified. I'll
put it on the ToDo list.

Regards,

Geir
API developer

On 23/05/2024 03:21, Bryan via RT wrote:

Ticket URL: https://ticket.met.no/rt/Ticket/Display.html?id=147037

Geir,
Thanks for your reply!
I did initially think that the offset was required based on the documentation,
but even with the offset (and no date specified) I see tomorrow's
sunrise/sunset time.
https://api.met.no/weatherapi/sunrise/3.0/sun?lat=40.43&lon=-74.01&offset=-04:00
(hit at 2024-05-22 21:17 UTC-4) returns:

{
    "copyright": "MET Norway",
    "licenseURL": "https://api.met.no/license_data.html",
    "type": "Feature",
    "geometry": {
        "type": "Point",
        "coordinates": [
            -74,
            40.4
        ]
    },
    "when": {
        "interval": [
            "2024-05-23T04:52:00Z",
            "2024-05-24T04:56:00Z"
        ]
    },
    "properties": {
        "body": "Sun",
        "sunrise": {
            "time": "2024-05-23T05:32-04:00",
            "azimuth": 61.53
        },
        "sunset": {
            "time": "2024-05-23T20:13-04:00",
            "azimuth": 298.63
        },
        "solarnoon": {
            "time": "2024-05-23T12:52-04:00",
            "disc_centre_elevation": 70.36,
            "visible": true
        },
        "solarmidnight": {
            "time": "2024-05-23T00:52-04:00",
            "disc_centre_elevation": -28.93,
            "visible": false
        }
    }
}

On Wed, May 22, 2024 at 9:27 AM @met.no via RT <@met.no]> wrote:

Hello,

the intended usage is that you send the current time zone offset in the URL:

https://api.met.no/weatherapi/sunrise/3.0/sun?lat=59.933333&lon=10.716667&offset=-04:00

This way you will get timestamps in local time, and the start and end of the
date will be calculated correctly (e.g. "2024-05-21T23:13:00Z" to
"2024-05-22T23:17:00Z" UTC).

Without the offset parameter we have no way of knowing the correct time
zone, and by implication won't know when the calendar day starts and ends.
Instead the API will use the longitude to calculate the midday point (when
the sun crosses the meridian) and use the +/- 12 hour interval as the
"date". Also, timestamps will be returned as UTC.

All this is documented here:
https://docs.api.met.no/doc/sunrise/celestial.html
Hope this helps,

Geir
API developer

On 20/05/2024 04:01, Bryan via RT wrote:

Hello, I have a question regarding the default date that is used for the
sunrise api.
When I hit
https://api.met.no/weatherapi/sunrise/3.0/sun?lat=59.933333&lon=10.716667 at
23:00 UTC (19:00 NY local/(UTC-4) on 2024-05-18) I got back:

{
    "copyright": "MET Norway",
    "licenseURL": "  https://api.met.no/license_data.html  ",
    "type": "Feature",
    "geometry": {
        "type": "Point",
        "coordinates": [
            10.7,
            59.9
        ]
    },
    "when": {
        "interval": [
            "2024-05-17T23:13:00Z",
            "2024-05-18T23:17:00Z"
        ]
    },
    "properties": {
        "body": "Sun",
        "sunrise": {
            "time": "2024-05-18T02:32+00:00",
            "azimuth": 45.97
        },
        "sunset": {
            "time": "2024-05-18T19:56+00:00",
            "azimuth": 314.46
        },
        "solarnoon": {
            "time": "2024-05-18T11:13+00:00",
            "disc_centre_elevation": 49.81,
            "visible": true
        },
        "solarmidnight": {
            "time": "2024-05-17T23:13+00:00",
            "disc_centre_elevation": -10.5,
            "visible": false
        }
    }
}

However, after midnight UTC (20:05 NY local/(UTC-4) on 2024-05-18) I see the sunset times for the following day:

{
    "copyright": "MET Norway",
    "licenseURL": "  https://api.met.no/license_data.html  ",
    "type": "Feature",
    "geometry": {
        "type": "Point",
        "coordinates": [
            10.7,
            59.9
        ]
    },
    "when": {
        "interval": [
            "2024-05-18T23:13:00Z",
            "2024-05-19T23:17:00Z"
        ]
    },
    "properties": {
        "body": "Sun",
        "sunrise": {
            "time": "2024-05-19T02:30+00:00",
            "azimuth": 45.41
        },
        "sunset": {
            "time": "2024-05-19T19:58+00:00",
            "azimuth": 315.01
        },
        "solarnoon": {
            "time": "2024-05-19T11:13+00:00",
            "disc_centre_elevation": 50.03,
            "visible": true
        },
        "solarmidnight": {
            "time": "2024-05-18T23:13+00:00",
            "disc_centre_elevation": -10.28,
            "visible": false
        }
    }
}

Is this the intended behavior, to use the current date in UTC, instead of the local current date when no date is specified?

Thanks in advance!
//Bryan

@bim9262
Copy link
Collaborator

bim9262 commented Sep 6, 2024

I did a little POC to get the date based on the lat/long so that we can pass that to metno.

Add tz-search as a dependency

use chrono::Utc;
use chrono_tz::Tz;

fn main() {
    let (lat, long) = (30., -97.);
    let tz: Tz = tz_search::lookup(lat, long).unwrap().parse().unwrap();
    let date = Utc::now().with_timezone(&tz).format("%Y-%m-%d");
    println!("{}", date);
}

Obviously we'd want to swap out those unwraps for error("")?s

Comment on lines +311 to +320
let sun_data: SunResponse = REQWEST_CLIENT
.get(SUN_URL)
.query(&sun_query_string)
.header(reqwest::header::CONTENT_TYPE, "application/json")
.send()
.await
.error("Forecast request failed")?
.json()
.await
.error("Forecast request failed")?;
Copy link
Collaborator

Choose a reason for hiding this comment

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

I wonder how far off the results are to what we can compute ourselves (https://docs.rs/sunrise/)

Copy link
Collaborator

Choose a reason for hiding this comment

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

https://api.met.no/weatherapi/sunrise/3.0/sun?lat=40.43&lon=-74.01&date=2024-09-07

{
  "copyright": "MET Norway",
  "licenseURL": "https://api.met.no/license_data.html",
  "type": "Feature",
  "geometry": {
    "type": "Point",
    "coordinates": [-74, 40.4]
  },
  "when": {
    "interval": [
      "2024-09-07T04:53:00Z",
      "2024-09-08T04:56:00Z"
    ]
  },
  "properties": {
    "body": "Sun",
    "sunrise": {
      "time": "2024-09-07T10:29+00:00",
      "azimuth": 81.67
    },
    "sunset": {
      "time": "2024-09-07T23:17+00:00",
      "azimuth": 278.07
    },
    "solarnoon": {
      "time": "2024-09-07T16:53+00:00",
      "disc_centre_elevation": 55.29,
      "visible": true
    },
    "solarmidnight": {
      "time": "2024-09-07T04:53+00:00",
      "disc_centre_elevation": -43.72,
      "visible": false
    }
  }
}
use chrono::{Datelike, TimeZone, Utc};
use chrono_tz::Tz;
use sunrise::sunrise_sunset;

fn main() {
    let (lat, long) = (40.43, -74.01);
    let tz: Tz = tz_search::lookup(lat, long).unwrap().parse().unwrap();
    let date = Utc::now().with_timezone(&tz);
    let (sunrise, sunset) = sunrise_sunset(lat, long, date.year(), date.month(), date.day());
    println!(
        "{}\n{}\n{}\n{}",
        date.format("%Y-%m-%d"),
        tz,
        Utc.timestamp_opt(sunrise, 0).unwrap(),
        Utc.timestamp_opt(sunset, 0).unwrap()
    );
}
2024-09-07
America/New_York
2024-09-07 10:29:42 UTC
2024-09-07 23:18:23 UTC

The results are quite close (for the one random lat/long that I tested)!

Copy link
Collaborator

Choose a reason for hiding this comment

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

So we can save an API call and it is simpler? Nice

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

Successfully merging this pull request may close these issues.

3 participants