Skip to content

Commit

Permalink
Support arbitrary sensor IDs properly
Browse files Browse the repository at this point in the history
The previous implementation of the Result type assumed a specific sensor
ID would be present when unmarshaling JSON, which isn't always going to
be the case.

This approach converts the type into an anonymous struct which properly
supports us setting a custom sensor ID for incoming power.
  • Loading branch information
poolski committed Apr 10, 2024
1 parent e737efe commit 7024c84
Showing 1 changed file with 9 additions and 18 deletions.
27 changes: 9 additions & 18 deletions cmd/client/client.go
Original file line number Diff line number Diff line change
Expand Up @@ -35,12 +35,10 @@ type APIResponse struct {
ID int `json:"id"` // ID is the unique identifier of the response.
Type string `json:"type"` // Type is the type of the response.
Success bool `json:"success"` // Success indicates whether the response was successful or not.
Result struct {
ImportedElectricity []struct {
Start int `json:"start"`
End int `json:"end"`
Change float64 `json:"change"` // Change is the amount of electricity imported.
} `json:"sensor.smart_meter_electricity_import_2"`
Result map[string][]struct {
Change float64 `json:"change"`
End int64 `json:"end"`
Start int64 `json:"start"`
} `json:"result"` // Result contains the data returned by the API.
Error struct {
Code string `json:"code"`
Expand Down Expand Up @@ -239,18 +237,17 @@ func getResults(c *Client) ([][]float64, error) {
// What we're doing is creating an offset from the current *day* based on a multiple of
// 24 hours, each time we iterate through the a "row" of the results slice.
results := make([][]float64, c.Config.Days)
sensorID := viper.GetString("sensor_id")
if sensorID == "" {
return nil, fmt.Errorf("sensor_id is required")
}

for i := range results {
c.MessageID++

offset := time.Duration((i+1)*24) * time.Hour
start := time.Now().Add(-offset).Truncate(24 * time.Hour).Format("2006-01-02T15:04:05.000Z")

sensorID := viper.GetString("sensor_id")
if sensorID == "" {
return nil, fmt.Errorf("sensor_id is required")
}

msg := map[string]interface{}{
"id": c.MessageID,
"type": "recorder/statistics_during_period",
Expand All @@ -277,15 +274,9 @@ func getResults(c *Client) ([][]float64, error) {
if !data.Success {
return nil, fmt.Errorf("api response error: %v", data.Error)
}

if len(data.Result.ImportedElectricity) != hoursInADay {
return nil, fmt.Errorf("expected %d sets of results, got %d", hoursInADay, len(data.Result.ImportedElectricity))
}

changeSlice := make([]float64, hoursInADay)
log.Debug().Msgf("got %d results", len(data.Result.ImportedElectricity))
for j := range changeSlice {
changeSlice[j] = data.Result.ImportedElectricity[j].Change
changeSlice[j] = data.Result[sensorID][j].Change
}
results[i] = changeSlice
}
Expand Down

0 comments on commit 7024c84

Please sign in to comment.