diff options
Diffstat (limited to '')
| -rw-r--r-- | fmi_client.go | 88 |
1 files changed, 88 insertions, 0 deletions
diff --git a/fmi_client.go b/fmi_client.go new file mode 100644 index 0000000..e4b59b2 --- /dev/null +++ b/fmi_client.go @@ -0,0 +1,88 @@ +// fmi_client.go - FMI API client library +package main + +import ( + "fmt" + "io" + "net/http" + "net/url" + "time" +) + +// FMIClient handles FMI API interactions +type FMIClient struct { + BaseURL string + HTTPClient *http.Client + WeatherMapper *WeatherMapper +} + +// NewFMIClient creates a new FMI client +func NewFMIClient() *FMIClient { + return &FMIClient{ + BaseURL: "https://opendata.fmi.fi/wfs", + HTTPClient: &http.Client{Timeout: 30 * time.Second}, + WeatherMapper: NewWeatherMapper(), + } +} + +// GetForecast fetches and parses forecast for a location +func (c *FMIClient) GetForecast(location string) (*OWMResponse, error) { + // Build request URL + url, err := c.buildURL(location) + if err != nil { + return nil, fmt.Errorf("building URL: %w", err) + } + + // Fetch XML data + xmlData, err := c.fetchXML(url) + if err != nil { + return nil, fmt.Errorf("fetching XML: %w", err) + } + + // Parse XML + forecastData, err := ParseForecastXML(xmlData) + if err != nil { + return nil, fmt.Errorf("parsing XML: %w", err) + } + + // Convert to OWM format + response, err := forecastData.ToOWMResponse(c.WeatherMapper) + if err != nil { + return nil, fmt.Errorf("converting to OWM format: %w", err) + } + + return response, nil +} + +func (c *FMIClient) buildURL(location string) (string, error) { + baseURL, err := url.Parse(c.BaseURL) + if err != nil { + return "", err + } + + q := baseURL.Query() + q.Set("service", "WFS") + q.Set("version", "2.0.0") + q.Set("request", "getFeature") + q.Set("storedquery_id", "fmi::forecast::harmonie::surface::point::multipointcoverage") + q.Set("place", location) + q.Set("parameters", "Temperature,PrecipitationRate,Humidity,Pressure,dewPoint,visibility,WindSpeedMS,WindDirection,WindGust,TotalCloudCover,WeatherSymbol3") + + baseURL.RawQuery = q.Encode() + return baseURL.String(), nil +} + +func (c *FMIClient) fetchXML(url string) ([]byte, error) { + resp, err := c.HTTPClient.Get(url) + if err != nil { + return nil, err + } + defer resp.Body.Close() + + if resp.StatusCode != http.StatusOK { + body, _ := io.ReadAll(resp.Body) + return nil, fmt.Errorf("HTTP %d: %s", resp.StatusCode, string(body)) + } + + return io.ReadAll(resp.Body) +} |
