-
-
Notifications
You must be signed in to change notification settings - Fork 5
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
initial client covering consumer Octopus REST API endpoints
- Loading branch information
1 parent
6809cfc
commit fba9d64
Showing
23 changed files
with
1,841 additions
and
1 deletion.
There are no files selected for viewing
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,2 @@ | ||
github: [dwillcocks] | ||
custom: https://share.octopus.energy/dusk-shark-465 |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,14 @@ | ||
version: 2 | ||
updates: | ||
- package-ecosystem: "github-actions" | ||
directory: "/" | ||
schedule: | ||
interval: "daily" | ||
assignees: | ||
- "dwillcocks" | ||
- package-ecosystem: "gomod" | ||
directory: "/" | ||
schedule: | ||
interval: "daily" | ||
assignees: | ||
- "dwillcocks" |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,34 @@ | ||
name: tests | ||
|
||
on: | ||
push: | ||
|
||
jobs: | ||
build: | ||
strategy: | ||
matrix: | ||
go-version: [1.15.x, 1.16.x] | ||
|
||
runs-on: ubuntu-latest | ||
|
||
steps: | ||
- name: Checkout | ||
id: checkout | ||
uses: actions/[email protected] | ||
|
||
- name: Set up Go | ||
id: installGo | ||
uses: actions/setup-go@v2 | ||
with: | ||
go-version: ${{ matrix.version }} | ||
|
||
- name: Lint | ||
id: lint | ||
uses: golangci/golangci-lint-action@v2 | ||
with: | ||
skip-go-installation: true | ||
|
||
- name: GoGoGo | ||
run: | | ||
go build ./... | ||
go test ./... |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,2 @@ | ||
.idea/ | ||
example/ |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1 +1,58 @@ | ||
# octopus_energy_client_go | ||
<p align=center> | ||
<img alt=logo src="https://github.com/danopstech/octopusenergy/raw/main/.docs/assets/workswith.png" height=150 /> | ||
<h3 align=center>Octopus Energy Golang API client</h3> | ||
</p> | ||
|
||
--- | ||
[![PkgGoDev](https://pkg.go.dev/badge/github.com/danopstech/octopusenergy/)](https://pkg.go.dev/github.com/danopstech/octopusenergy/) | ||
[![License](https://img.shields.io/github/license/danopstech/octopusenergy)](/LICENSE) | ||
[![Release](https://img.shields.io/github/release/danopstech/octopusenergy.svg)](https://github.com/danopstech/octopusenergy/releases/latest) | ||
[![tests](https://github.com/danopstech/octopusenergy/actions/workflows/build.yaml/badge.svg)](https://github.com/danopstech/octopusenergy/actions/workflows/build.yaml) | ||
|
||
This package provides a Golang client to [Octopus Energy's API](https://developer.octopus.energy/docs/api/). Octopus Energy provides a REST API for customers to interact with our platform. Amongst other things, it provides functionality for: | ||
|
||
- Browsing energy products, tariffs and their charges. | ||
- Retrieving details about a UK electricity meter-point. | ||
- Browsing the half-hourly consumption of an electricity or gas meter. | ||
- Determining the grid-supply-point (GSP) for a UK postcode. | ||
|
||
If you are an Octopus Energy customer, you can generate an API key from your [online dashboard](https://octopus.energy/dashboard/developer/). | ||
|
||
### Authentication | ||
Authentication is required for all API end-points when using this API client. This is performed via [HTTP Basic Auth](https://en.wikipedia.org/wiki/Basic_access_authentication). This is configured when you instantiate a new client with a config object. | ||
**Warning: Do not share your secret API keys with anyone.** | ||
|
||
### Not an Octopus Energy customer? | ||
Please read about the Octopus tariffs and ensure they are right for you, if you think they are, then please use my [referral link](https://share.octopus.energy/dusk-shark-465). (at the time of writing this we will both receive £50 credit) | ||
|
||
### Usage | ||
More in the examples folder | ||
|
||
```golang | ||
ctx, cancel := context.WithTimeout(context.Background(), time.Second*30) | ||
defer cancel() | ||
|
||
var netClient = http.Client{ | ||
Timeout: time.Second * 10, | ||
} | ||
|
||
client := octopusenergy.NewClient(octopusenergy.NewConfig(). | ||
WithApiKeyFromEnvironments(). | ||
WithHTTPClient(netClient), | ||
) | ||
|
||
consumption, err := client.Consumption.GetPagesWithContext(ctx, &octopusenergy.ConsumptionGetOptions{ | ||
MPN: "1111111111", // <--- replace | ||
SerialNumber: "1111111111", // <--- replace | ||
FuelType: octopusenergy.FuelTypeElectricity, | ||
PeriodFrom: octopusenergy.Time(time.Now().Add(-48 * time.Hour)), | ||
}) | ||
|
||
if err != nil { | ||
log.Fatalf("failed to getting consumption: %s", err.Error()) | ||
} | ||
``` | ||
|
||
### Links | ||
- [Octopus Energy API Docs](https://developer.octopus.energy/docs/api/) | ||
- [Get API Key](https://octopus.energy/dashboard/developer/) |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,64 @@ | ||
package octopusenergy | ||
|
||
import ( | ||
"log" | ||
"net/http" | ||
"os" | ||
) | ||
|
||
// Config provides service configuration for client. | ||
type Config struct { | ||
// Required for Authentication on all API end-points when using this client. | ||
// If you are an Octopus Energy customer, you can generate an API key from your online dashboard | ||
// https://octopus.energy/dashboard/developer/. | ||
ApiKey string | ||
|
||
// All API requests will use this base URL. | ||
Endpoint *string | ||
|
||
// The HTTP client to use when sending requests. Defaults to `http.DefaultClient`. | ||
HTTPClient *http.Client | ||
} | ||
|
||
// NewConfig returns a new Config pointer that can be chained with builder | ||
// methods to set multiple configuration values inline without using pointers. | ||
// | ||
// client := octopusenergy.NewClient(octopusenergy.NewConfig(). | ||
// WithApiKey("your-api-key"), | ||
// )) | ||
func NewConfig() *Config { | ||
return &Config{} | ||
} | ||
|
||
// WithApiKey sets a config ApiKey value returning a Config pointer for chaining. | ||
func (c *Config) WithApiKey(apiKey string) *Config { | ||
c.ApiKey = apiKey | ||
return c | ||
} | ||
|
||
// WithApiKeyFromEnvironments sets a config ApiKey value from environments valuable | ||
// returning a Config pointer for chaining. | ||
func (c *Config) WithApiKeyFromEnvironments() *Config { | ||
apiKey, ok := os.LookupEnv(apiKeyEnvKey) | ||
if !ok { | ||
log.Fatalln("could not find api key in environment variable 'OCTOPUS_ENERGY_API_KEY'") | ||
} | ||
if apiKey == "" { | ||
log.Fatalln("the api key in environment variable 'OCTOPUS_ENERGY_API_KEY' is blank") | ||
} | ||
|
||
c.ApiKey = apiKey | ||
return c | ||
} | ||
|
||
// WithEndpoint sets a config Endpoint value returning a Config pointer for chaining. | ||
func (c *Config) WithEndpoint(endpoint string) *Config { | ||
c.Endpoint = &endpoint | ||
return c | ||
} | ||
|
||
// WithHTTPClient sets a config HTTP Client value returning a Config pointer for chaining. | ||
func (c *Config) WithHTTPClient(HTTPClient http.Client) *Config { | ||
c.HTTPClient = &HTTPClient | ||
return c | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,121 @@ | ||
package octopusenergy | ||
|
||
import ( | ||
"context" | ||
"fmt" | ||
"net/http" | ||
"net/url" | ||
"time" | ||
) | ||
|
||
// ConsumptionService handles communication with the consumption related Octopus API. | ||
type ConsumptionService service | ||
|
||
// ConsumptionGetOptions is the options for GetConsumption. | ||
type ConsumptionGetOptions struct { | ||
// The Meter Point Number this is the electricity meter-point’s MPAN or gas meter-point’s MPRN | ||
MPN string `url:"-"` | ||
|
||
// The meter’s serial number. | ||
SerialNumber string `url:"-"` | ||
|
||
// Fueltype: electricity or gas | ||
FuelType FuelType `url:"-"` | ||
|
||
// Show consumption from the given datetime (inclusive). This parameter can be provided on its own. | ||
PeriodFrom *time.Time `url:"period_from,omitempty" layout:"2006-01-02T15:04:05Z" optional:"true"` | ||
|
||
// Show consumption to the given datetime (exclusive). | ||
// This parameter also requires providing the period_from parameter to create a range. | ||
PeriodTo *time.Time `url:"period_to,omitempty" layout:"2006-01-02T15:04:05Z" optional:"true"` | ||
|
||
// Page size of returned results. | ||
// Default is 100, maximum is 25,000 to give a full year of half-hourly consumption details. | ||
PageSize *int `url:"page_size,omitempty" optional:"true"` | ||
|
||
// Ordering of results returned. | ||
// Default is that results are returned in reverse order from latest available figure. | ||
// Valid values: * ‘period’, to give results ordered forward. * ‘-period’, (default), to give results ordered from most recent backwards. | ||
OrderBy *string `url:"order_by,omitempty" optional:"true"` | ||
|
||
// Aggregates consumption over a specified time period. | ||
// A day is considered to start and end at midnight in the server’s timezone. | ||
// The default is that consumption is returned in half-hour periods. Accepted values are: * ‘hour’ * ‘day’ * ‘week’ * ‘month’ * ‘quarter’ | ||
GroupBy *string `url:"group_by,omitempty" optional:"true"` | ||
|
||
// Pagination page to be returned on this request | ||
Page *int `url:"page,omitempty" optional:"true"` | ||
} | ||
|
||
// ConsumptionGetOutput is the returned struct from GetConsumption. | ||
type ConsumptionGetOutput struct { | ||
Count int `json:"count"` | ||
Next string `json:"next"` | ||
Previous string `json:"previous"` | ||
Results []struct { | ||
Consumption float64 `json:"consumption"` | ||
IntervalStart string `json:"interval_start"` | ||
IntervalEnd string `json:"interval_end"` | ||
} `json:"results"` | ||
} | ||
|
||
// Get consumption data for give meter details. This endpoint is paginated, it will return | ||
// next and previous links if returned data is larger than the set page size, you are responsible | ||
// to request the next page if required. | ||
func (s *ConsumptionService) Get(options *ConsumptionGetOptions) (*ConsumptionGetOutput, error) { | ||
return s.GetWithContext(context.Background(), options) | ||
} | ||
|
||
// GetWithContext same as Get except it takes a Context. | ||
func (s *ConsumptionService) GetWithContext(ctx context.Context, options *ConsumptionGetOptions) (*ConsumptionGetOutput, error) { | ||
path := fmt.Sprintf("v1/%s-meter-points/%s/meters/%s/consumption", options.FuelType.String(), options.MPN, options.SerialNumber) | ||
rel := &url.URL{Path: path} | ||
u := s.client.BaseURL.ResolveReference(rel) | ||
url, err := addParameters(u, options) | ||
if err != nil { | ||
return nil, err | ||
} | ||
|
||
req, err := http.NewRequestWithContext(ctx, "GET", url.String(), nil) | ||
if err != nil { | ||
return nil, err | ||
} | ||
|
||
res := ConsumptionGetOutput{} | ||
if err := s.client.sendRequest(req, &res); err != nil { | ||
return nil, err | ||
} | ||
|
||
return &res, nil | ||
} | ||
|
||
// GetPages same as Get except it returns all pages in one request. | ||
func (s *ConsumptionService) GetPages(options *ConsumptionGetOptions) (*ConsumptionGetOutput, error) { | ||
return s.GetPagesWithContext(context.Background(), options) | ||
} | ||
|
||
// GetPagesWithContext same as GetPages except it takes a Context. | ||
func (s *ConsumptionService) GetPagesWithContext(ctx context.Context, options *ConsumptionGetOptions) (*ConsumptionGetOutput, error) { | ||
options.PageSize = Int(1500) | ||
options.Page = nil | ||
|
||
fullResp := ConsumptionGetOutput{} | ||
var lastPage bool | ||
var i int | ||
|
||
for !lastPage { | ||
page, err := s.GetWithContext(ctx, options) | ||
if err != nil { | ||
return nil, err | ||
} | ||
fullResp.Count = page.Count | ||
fullResp.Results = append(fullResp.Results, page.Results...) | ||
if page.Next == "" { | ||
lastPage = true | ||
} | ||
i++ | ||
options.Page = Int(i) | ||
} | ||
|
||
return &fullResp, nil | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,33 @@ | ||
package octopusenergy | ||
|
||
import ( | ||
"time" | ||
) | ||
|
||
// String returns a pointer to the string value passed in. | ||
// This is a helper function when you need to provide pointers to | ||
// optional fields in the input options object. | ||
func String(v string) *string { | ||
return &v | ||
} | ||
|
||
// Int returns a pointer to the int value passed in. | ||
// This is a helper function when you need to provide pointers to | ||
// optional fields in the input options object. | ||
func Int(v int) *int { | ||
return &v | ||
} | ||
|
||
// Bool returns a pointer to the bool value passed in. | ||
// This is a helper function when you need to provide pointers to | ||
// optional fields in the input options object. | ||
func Bool(v bool) *bool { | ||
return &v | ||
} | ||
|
||
// Time returns a pointer to the time.Time value passed in. | ||
// This is a helper function when you need to provide pointers to | ||
// optional fields in the input options object. | ||
func Time(v time.Time) *time.Time { | ||
return &v | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,33 @@ | ||
package octopusenergy_test | ||
|
||
import ( | ||
"fmt" | ||
"time" | ||
|
||
"github.com/danopstech/octopusenergy" | ||
) | ||
|
||
func ExampleBool() { | ||
boolPtr := octopusenergy.Bool(true) | ||
fmt.Println(*boolPtr) | ||
// Output: true | ||
} | ||
|
||
func ExampleString() { | ||
stringPtr := octopusenergy.String("example") | ||
fmt.Println(*stringPtr) | ||
// Output: example | ||
} | ||
|
||
func ExampleInt() { | ||
intPtr := octopusenergy.Int(5) | ||
fmt.Println(*intPtr) | ||
// Output: 5 | ||
} | ||
|
||
func ExampleTime() { | ||
wayBack := time.Date(1974, time.May, 19, 1, 2, 3, 4, time.UTC) | ||
timePtr := octopusenergy.Time(wayBack) | ||
fmt.Println(*timePtr) | ||
// Output: 1974-05-19 01:02:03.000000004 +0000 UTC | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,6 @@ | ||
package octopusenergy | ||
|
||
// errorResponse is the returned body when API error accrues | ||
type errorResponse struct { | ||
Detail string `json:"detail"` | ||
} |
Oops, something went wrong.