rot finished

This commit is contained in:
2026-01-09 11:56:40 +01:00
parent 1ee0afa088
commit ac99f291a7
30 changed files with 5581 additions and 293 deletions

View File

@@ -0,0 +1,96 @@
package solar
import (
"encoding/xml"
"fmt"
"io"
"net/http"
"strings"
"time"
)
// SolarData contains current solar and geomagnetic conditions
type SolarData struct {
SolarFluxIndex int `json:"sfi"` // Solar Flux Index
Sunspots int `json:"sunspots"` // Number of sunspots
AIndex int `json:"a_index"` // A-index (geomagnetic activity)
KIndex int `json:"k_index"` // K-index (geomagnetic activity)
GeomagField string `json:"geomag"` // Geomagnetic field status
UpdatedAt string `json:"updated"` // Last update time
}
// HamQSLResponse matches the XML structure from hamqsl.com
type HamQSLResponse struct {
XMLName xml.Name `xml:"solar"`
SolarData SolarDataXML `xml:"solardata"`
}
type SolarDataXML struct {
Updated string `xml:"updated"`
SolarFlux string `xml:"solarflux"`
AIndex string `xml:"aindex"`
KIndex string `xml:"kindex"`
Sunspots string `xml:"sunspots"`
GeomagField string `xml:"geomagfield"`
}
type Client struct {
httpClient *http.Client
lastUpdate time.Time
cachedData *SolarData
}
func New() *Client {
return &Client{
httpClient: &http.Client{
Timeout: 10 * time.Second,
},
}
}
// GetSolarData fetches current solar data from HamQSL
// Data is cached for 15 minutes to avoid excessive requests
func (c *Client) GetSolarData() (*SolarData, error) {
// Return cached data if less than 15 minutes old
if c.cachedData != nil && time.Since(c.lastUpdate) < 15*time.Minute {
return c.cachedData, nil
}
resp, err := c.httpClient.Get("http://www.hamqsl.com/solarxml.php")
if err != nil {
return nil, fmt.Errorf("failed to fetch solar data: %w", err)
}
defer resp.Body.Close()
if resp.StatusCode != http.StatusOK {
return nil, fmt.Errorf("unexpected status code: %d", resp.StatusCode)
}
body, err := io.ReadAll(resp.Body)
if err != nil {
return nil, fmt.Errorf("failed to read response: %w", err)
}
var hamqslData HamQSLResponse
if err := xml.Unmarshal(body, &hamqslData); err != nil {
return nil, fmt.Errorf("failed to parse XML: %w", err)
}
// Parse the data
solarData := &SolarData{
GeomagField: hamqslData.SolarData.GeomagField,
UpdatedAt: hamqslData.SolarData.Updated,
}
// Parse numeric values (trim spaces)
fmt.Sscanf(strings.TrimSpace(hamqslData.SolarData.SolarFlux), "%d", &solarData.SolarFluxIndex)
fmt.Sscanf(strings.TrimSpace(hamqslData.SolarData.AIndex), "%d", &solarData.AIndex)
fmt.Sscanf(strings.TrimSpace(hamqslData.SolarData.KIndex), "%d", &solarData.KIndex)
fmt.Sscanf(strings.TrimSpace(hamqslData.SolarData.Sunspots), "%d", &solarData.Sunspots)
// Cache the data
c.cachedData = solarData
c.lastUpdate = time.Now()
return solarData, nil
}