-
Notifications
You must be signed in to change notification settings - Fork 1
Expand file tree
/
Copy pathdatadis.go
More file actions
155 lines (133 loc) · 4.83 KB
/
Copy pathdatadis.go
File metadata and controls
155 lines (133 loc) · 4.83 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
// Package datadis provides a client for the Datadis API to fetch electricity consumption data.
// Datadis is a Spanish electricity data platform that provides access to consumption information.
package datadis
import (
"encoding/json"
"fmt"
"io/ioutil"
"net/http"
"net/url"
"time"
)
// Client represents a Datadis API client with authentication token and HTTP client.
type Client struct {
client *http.Client
token string
baseURL string
}
// Supply represents an electricity supply point with associated metadata.
type Supply struct {
Address string `json:"address"`
Cups string `json:"cups"`
Province string `json:"province"`
DistributorCode string `json:"distributorCode"`
PostalCode string `json:"postalCode"`
Municipality string `json:"municipality"`
Distributor string `json:"distributor"`
PointType int `json:"pointType"`
ValidDateFrom string `json:"validDateFrom"`
ValidDateTo string `json:"validDateTo"`
}
// Measurment represents a single electricity consumption measurement.
type Measurment struct {
Cups string `json:"cups"`
Date string `json:"date"`
Time string `json:"time"`
Consumption float32 `json:"consumptionKWh"`
ObtainMethod string `json:"obtainMethod"`
}
// NewClient creates and returns a new Datadis API client with default configuration.
func NewClient() *Client {
return &Client{
client: &http.Client{},
baseURL: "https://datadis.es/api-private/api",
}
}
// Login authenticates with the Datadis API using the provided username and password.
// On successful login, the authentication token is stored in the client for subsequent API calls.
// Returns an error if the login fails or if the HTTP request encounters an issue.
func (c *Client) Login(username, password string) error {
req, err := http.NewRequest("POST", fmt.Sprintf("https://datadis.es/nikola-auth/tokens/login?username=%s&password=%s", username, password), nil)
if err != nil {
return err
}
req.Header.Add("Content-Type", "text/plain")
resp, err := c.client.Do(req)
if err != nil {
return err
}
defer resp.Body.Close()
token, err := ioutil.ReadAll(resp.Body)
if err != nil {
return err
}
if resp.StatusCode != http.StatusOK {
return fmt.Errorf("login failed (status %d): %s", resp.StatusCode, string(token))
}
c.token = string(token)
return nil
}
// ConsumptionData retrieves electricity consumption measurements for a given supply within a date range.
// The from and to parameters specify the time range (formatted as YYYY/MM).
// Returns a slice of Measurment objects containing consumption data, or an error if the request fails.
// The API response is validated for HTTP status code before parsing JSON.
func (c *Client) ConsumptionData(supply *Supply, from, to time.Time) ([]Measurment, error) {
sto := to.Format("2006/01")
sfrom := from.Format("2006/01")
query := fmt.Sprintf("cups=%s&distributorCode=%s&startDate=%s&endDate=%s&measurementType=%d&pointType=%d", supply.Cups, supply.DistributorCode, url.QueryEscape(sfrom), url.QueryEscape(sto), 0, supply.PointType)
u := fmt.Sprintf("%s/get-consumption-data?%s", c.baseURL, query)
req, err := http.NewRequest("GET", u, nil)
if err != nil {
return nil, err
}
req.Header.Add("Accept", "application/json")
req.Header.Add("Authorization", fmt.Sprintf("Bearer %s", c.token))
resp, err := c.client.Do(req)
if err != nil {
return nil, err
}
defer resp.Body.Close()
body, err := ioutil.ReadAll(resp.Body)
if err != nil {
return nil, err
}
if resp.StatusCode != http.StatusOK {
return nil, fmt.Errorf("API error (status %d): %s", resp.StatusCode, string(body))
}
var measurements []Measurment
err = json.Unmarshal(body, &measurements)
if err != nil {
return nil, fmt.Errorf("failed to parse JSON response: %w (body: %s)", err, string(body))
}
return measurements, nil
}
// Supplies retrieves the list of electricity supply points associated with the authenticated account.
// Returns a slice of Supply objects, or an error if the request fails.
// The API response is validated for HTTP status code before parsing JSON.
func (c *Client) Supplies() ([]Supply, error) {
u := fmt.Sprintf("%s/get-supplies", c.baseURL)
req, err := http.NewRequest("GET", u, nil)
if err != nil {
return nil, err
}
req.Header.Add("Accept", "application/json")
req.Header.Add("Authorization", fmt.Sprintf("Bearer %s", c.token))
resp, err := c.client.Do(req)
if err != nil {
return nil, err
}
defer resp.Body.Close()
body, err := ioutil.ReadAll(resp.Body)
if err != nil {
return nil, err
}
if resp.StatusCode != http.StatusOK {
return nil, fmt.Errorf("API error (status %d): %s", resp.StatusCode, string(body))
}
var supplies []Supply
err = json.Unmarshal(body, &supplies)
if err != nil {
return nil, fmt.Errorf("failed to parse JSON response: %w (body: %s)", err, string(body))
}
return supplies, nil
}