# README
sense
This package is an incomplete implementation of an entirely UNOFFICIAL and UNSUPPORTED API to access data for a Sense Energy Monitor account. This repository has no affiliation with Sense.
Because this is unsupported, this package may stop working at any time.
The API in this package is not stable and I may change it at any time.
Usage
import (
"github.com/dnesting/sense"
"github.com/dnesting/sense/realtime"
)
func main() {
ctx := context.Background()
client, err := sense.Connect(ctx, sense.PasswordCredentials{
Email: "[email protected]",
Password: "secret",
})
if err != nil {
log.Fatal(err)
}
fmt.Println("Monitors configured under account", client.AccountID)
for _, m := range client.Monitors {
fmt.Println("-", m.ID)
// Use the realtime Stream API to grab one data point.
fn := func(_ context.Context, msg realtime.Message) error {
if rt, ok := msg.(*realtime.RealtimeUpdate); ok {
fmt.Println(" current power consumption", rt.W, "W")
return realtime.Stop
}
return nil
}
if err := client.Stream(ctx, m.ID, fn); err != nil {
log.Fatal(err)
}
}
}
MFA
If your account requires multi-factor authentication, you can accommodate that like:
mfaFunc := func() (string, error) {
// obtain your MFA code somehow, we'll just use a fixed value to demonstrate
return "12345", nil
}
client, err := sense.Connect(ctx, sense.PasswordCredentials{
Email: "[email protected]",
Password: "secret",
MfaFn: mfaFunc,
})
Your mfaFunc
will be called when needed.
Notes
This implementation is incomplete, and what's there is incompletely tested. If you wish to contribute, here's how the project is laid out:
|-- internal
| |-- client contains an (incomplete) OpenAPI spec and
| | auto-generated code that does the heavy lifting
| |-- ratelimited implements some HTTP rate limiting
| `-- senseutil helper functions, mocks for testing, etc.
|-- realtime contains a complete-ish AsyncAPI spec but
| hand-generated code implementing the real-time
| WebSockets API
|-- senseauth implements the Sense artisinal OAuth
`-- sensecli helpers that CLI tools might find useful
Debugging
If you need the gory internals to figure something out:
httpClient := sense.SetDebug(log.Default(), nil)
client, err := sense.Connect(ctx, credentials, sense.WithHTTPClient(httpClient))
# Packages
No description provided by the author
Package realtime implements the unofficial and unsupported Sense real-time API.
Package senseauth implements the api.sense.com OAuth flow.
Package sensecli just contains some helpers used to set up binaries that need Sense credentials.
# Functions
Connect instantiates a new Sense [Client], configured with the provided options.
New creates a new unauthenticated Sense client, configured according to the provided options.
SetDebug enables debug logging using the given logger and returns an [*http.Client] that wraps baseClient, logging requests and responses to the same logger.
WithApiUrl sets the base URLs for the Sense API.
WithDeviceID sets the X-Sense-Device-Id header on requests to the Sense API.
WithHttpClient sets the HTTP client used to make requests to the Sense API.
WithInternalClient is for internal use.
WithRateLimit applies a rate limit to requests made to the Sense API.
# Variables
ErrAuthenticationNeeded is wrapped by errors returned from many functions in this package whenever authentication is needed and the client is unauthenticated or its credentials are no longer valid.
# Structs
Client is the primary high-level object used to interact with the Sense API.
No description provided by the author
Monitor is a Sense monitor, which is a physical device that measures power usage.
PasswordCredentials holds the credentials used to authenticate to the Sense API.
# Interfaces
Credentials holds the credentials used to authenticate to the Sense API.
# Type aliases
Option is a function that can be passed to New or Connect to configure the resulting Client.