summaryrefslogtreecommitdiffstats
path: root/fmi_client.go
diff options
context:
space:
mode:
Diffstat (limited to 'fmi_client.go')
-rw-r--r--fmi_client.go88
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)
+}