Skip to content

Replace deprecated smhi pmp3g api with new SNOW api#220

Open
nopil3os wants to merge 3 commits intoschachmat:masterfrom
nopil3os:master
Open

Replace deprecated smhi pmp3g api with new SNOW api#220
nopil3os wants to merge 3 commits intoschachmat:masterfrom
nopil3os:master

Conversation

@nopil3os
Copy link
Copy Markdown

@nopil3os nopil3os commented Apr 8, 2026

SMHI deactivated the pmp3g api this month, breaking the wego backend.

This attempts to rejig it for the new api: https://opendata.smhi.se/metfcst/snow1gv1/introduction

Used Gemini to generate this.

@nopil3os nopil3os changed the title with help from gemini: replace deprecated smhi pmp3g api for new SNOW api with help from gemini: replace deprecated smhi pmp3g api with new SNOW api Apr 9, 2026
@nopil3os nopil3os marked this pull request as draft April 10, 2026 14:50
@nopil3os nopil3os marked this pull request as ready for review April 10, 2026 14:52
@kordianbruck
Copy link
Copy Markdown
Collaborator

kordianbruck commented Apr 11, 2026

Can you update your branch please to the latest master? I've fixed the lint warnings in master today.

Copy link
Copy Markdown

Copilot AI left a comment

Choose a reason for hiding this comment

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

Pull request overview

Updates the SMHI backend to use the new snow1g API endpoint after the old pmp3g endpoint was deactivated.

Changes:

  • Replaced the SMHI response model/types to match the new SNOW API response shape.
  • Updated parsing logic to read values from the new data object and use the new time field.
  • Switched the SMHI request URL to the snow1g/version/1 endpoint.
Comments suppressed due to low confidence (2)

backends/smhi.go:186

  • The loop over forecast.TimeSeries never updates currentPrediction, so parseCurrent always returns the first timeseries entry regardless of the current time. Update currentPrediction as you iterate (e.g., keep the latest prediction with ts <= now), and then break once ts.After(now) is true.
	for _, prediction := range forecast.TimeSeries {
		ts, err := time.Parse(time.RFC3339, prediction.Time)
		if err != nil {
			log.Fatalf("Failed to parse timestamp: %v\n", err)
		}

		if ts.After(currentTime) {
			break

backends/smhi.go:160

  • ts is parsed from the API timestamp (likely with an explicit timezone), but the day-bucketing logic compares ts.Day() against a separately initialized currentTime (time.Now() earlier). If local time != the API timezone, day boundaries can be off. Consider initializing the “current day” from the first parsed ts (or converting both to the same location with In(...)) so grouping is consistent.
		ts, err := time.Parse(time.RFC3339, prediction.Time)
		if err != nil {
			log.Fatalf("Failed to parse timestamp: %v\n", err)
		}

		if ts.Day() != currentTime.Day() {

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

Comment on lines 176 to 178
var currentPrediction *smhiTimeSeries = forecast.TimeSeries[0]
var currentTime time.Time = time.Now().UTC()

Copy link

Copilot AI Apr 11, 2026

Choose a reason for hiding this comment

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

currentPrediction := forecast.TimeSeries[0] will panic if SMHI returns an empty timeSeries. There’s also an ineffective empty-check just above this block (len(...) < 0). Please guard with len(...) == 0 (or <= 0) before indexing and handle the no-data case cleanly.

Copilot uses AI. Check for mistakes.
const (
// see http://opendata.smhi.se/apidocs/metfcst/index.html
smhiWuri = "https://opendata-download-metfcst.smhi.se/api/category/pmp3g/version/2/geotype/point/lon/%s/lat/%s/data.json"
// Ensure this URL is still valid for the new API version. Left unchanged based on prompt context.
Copy link

Copilot AI Apr 11, 2026

Choose a reason for hiding this comment

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

The comment above smhiWuri says the URL is “Left unchanged”, but the code is actually switching APIs and commenting out the old endpoint. This is misleading; please rewrite/remove the comment to accurately describe why the endpoint changed and which API it targets.

Suggested change
// Ensure this URL is still valid for the new API version. Left unchanged based on prompt context.
// Use the SMHI snow1g version 1 point-data API for this backend.
// The previous pmp3g version 2 endpoint is kept below as a reference to the old API target.

Copilot uses AI. Check for mistakes.
Comment on lines +208 to +210
condition := weatherConditions[int(prediction.Data.SymbolCode)]
cnd.Code = condition.WeatherCode
cnd.Desc = condition.Description
Copy link

Copilot AI Apr 11, 2026

Choose a reason for hiding this comment

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

condition := weatherConditions[int(prediction.Data.SymbolCode)] assumes the SMHI symbol_code is always present and within the hardcoded map. If it’s missing/zero or SMHI introduces new codes, this will silently produce an empty description and CodeUnknown. Please use the two-value map lookup and provide a sensible fallback description/code when the key isn’t found.

Suggested change
condition := weatherConditions[int(prediction.Data.SymbolCode)]
cnd.Code = condition.WeatherCode
cnd.Desc = condition.Description
symbolCode := int(prediction.Data.SymbolCode)
if condition, ok := weatherConditions[symbolCode]; ok {
cnd.Code = condition.WeatherCode
cnd.Desc = condition.Description
} else {
cnd.Code = iface.CodeUnknown
cnd.Desc = fmt.Sprintf("Unknown weather condition (symbol code %d)", symbolCode)
}

Copilot uses AI. Check for mistakes.
@kordianbruck kordianbruck changed the title with help from gemini: replace deprecated smhi pmp3g api with new SNOW api Replace deprecated smhi pmp3g api with new SNOW api Apr 11, 2026
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