Skip to content

Commit 63ceb95

Browse files
committed
feat: datadis datasource can filter by cups now
1 parent 7ef6c88 commit 63ceb95

File tree

3 files changed

+84
-3
lines changed

3 files changed

+84
-3
lines changed

docs/datasources/datadis.md

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -18,21 +18,24 @@ interval = '24h0m0s' # Fetch once per day (default: 24h)
1818
[datasources.datadis.config]
1919
username = 'your-datadis-username' # Required
2020
password = 'your-datadis-password' # Required
21+
cups = '' # Optional: Comma-separated list of CUPS to filter
2122
```
2223

2324
### Configuration Parameters
2425

2526
- **username** (required): Your Datadis account username
2627
- **password** (required): Your Datadis account password
28+
- **cups** (optional): Comma-separated list of CUPS identifiers to filter which supplies to fetch. If not set or empty, fetches data for all supplies in the account. Example: `'ES0021000000000001AA,ES0021000000000002BB'`
2729
- **interval**: How often to fetch data (default: 24h). Since consumption data is typically updated daily, fetching more frequently is not recommended.
2830

2931
## Data Collection
3032

3133
The datasource:
3234
1. Authenticates with the Datadis API using your credentials
3335
2. Retrieves all electricity supplies associated with your account
34-
3. For each supply, fetches hourly consumption data for the current month
35-
4. Creates a block for each hourly measurement
36+
3. Filters supplies based on the `cups` configuration (if specified)
37+
4. For each supply, fetches hourly consumption data for the current month
38+
5. Creates a block for each hourly measurement
3639

3740
## Block Structure
3841

pkg/config/config.toml.sample

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -145,6 +145,8 @@ max_items = 50 # Maximum items to fetch across all feeds (default: 50, max: 200
145145
# [datasources.datadis.config]
146146
# username = '' # Required: Your Datadis username
147147
# password = '' # Required: Your Datadis password
148+
# cups = '' # Optional: Comma-separated list of CUPS to filter (e.g., 'ES0000000000000001AA,ES0000000000000002BB')
149+
# # If not set or empty, fetches data for all supplies in the account
148150

149151
# # Importer - Generic datasource for importing blocks from external sources
150152
# # This allows external tools to push blocks via HTTP API

pkg/datasources/datadis/datasource.go

Lines changed: 77 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,7 @@ func init() {
2020
type Config struct {
2121
Username string `toml:"username"`
2222
Password string `toml:"password"`
23+
CUPS string `toml:"cups,omitempty"` // Optional: comma-separated list of CUPS to filter
2324
}
2425

2526
// Validate checks if the configuration is valid
@@ -175,7 +176,14 @@ func (d *Datasource) FetchBlocks(ctx context.Context, blockCh chan<- core.Block)
175176

176177
blockCount := 0
177178

178-
for _, supply := range d.supplies {
179+
// Filter supplies if CUPS is configured
180+
suppliesToFetch := d.supplies
181+
if d.config.CUPS != "" {
182+
suppliesToFetch = d.filterSuppliesByConfig()
183+
l.Debugf("Filtering to %d supplies based on config", len(suppliesToFetch))
184+
}
185+
186+
for _, supply := range suppliesToFetch {
179187
select {
180188
case <-ctx.Done():
181189
return ctx.Err()
@@ -268,6 +276,74 @@ func (d *Datasource) Close() error {
268276
return nil
269277
}
270278

279+
// filterSuppliesByConfig filters supplies based on configured CUPS
280+
func (d *Datasource) filterSuppliesByConfig() []datadis.Supply {
281+
if d.config.CUPS == "" {
282+
return d.supplies
283+
}
284+
285+
// Parse comma-separated CUPS list
286+
configuredCUPS := make(map[string]bool)
287+
for _, cups := range splitAndTrim(d.config.CUPS, ",") {
288+
configuredCUPS[cups] = true
289+
}
290+
291+
var filtered []datadis.Supply
292+
for _, supply := range d.supplies {
293+
if configuredCUPS[supply.Cups] {
294+
filtered = append(filtered, supply)
295+
}
296+
}
297+
298+
return filtered
299+
}
300+
301+
// splitAndTrim splits a string by delimiter and trims whitespace
302+
func splitAndTrim(s, delimiter string) []string {
303+
var result []string
304+
for _, item := range splitString(s, delimiter) {
305+
trimmed := trimSpace(item)
306+
if trimmed != "" {
307+
result = append(result, trimmed)
308+
}
309+
}
310+
return result
311+
}
312+
313+
// splitString splits a string by delimiter
314+
func splitString(s, delimiter string) []string {
315+
if s == "" {
316+
return nil
317+
}
318+
var result []string
319+
start := 0
320+
for i := 0; i < len(s); i++ {
321+
if i+len(delimiter) <= len(s) && s[i:i+len(delimiter)] == delimiter {
322+
result = append(result, s[start:i])
323+
start = i + len(delimiter)
324+
i += len(delimiter) - 1
325+
}
326+
}
327+
result = append(result, s[start:])
328+
return result
329+
}
330+
331+
// trimSpace removes leading and trailing whitespace
332+
func trimSpace(s string) string {
333+
start := 0
334+
end := len(s)
335+
336+
for start < end && (s[start] == ' ' || s[start] == '\t' || s[start] == '\n' || s[start] == '\r') {
337+
start++
338+
}
339+
340+
for end > start && (s[end-1] == ' ' || s[end-1] == '\t' || s[end-1] == '\n' || s[end-1] == '\r') {
341+
end--
342+
}
343+
344+
return s[start:end]
345+
}
346+
271347
// Factory creates a new instance of the datasource
272348
func (d *Datasource) Factory(instanceName string, config interface{}) (core.Datasource, error) {
273349
return NewDatasource(instanceName, config)

0 commit comments

Comments
 (0)