Go library to connect to Amazon Alexa Smarthome Skill API v3
This project was created to control smarthome devices (e.g. Homematic) via Amazon Echo. It implements Amazon Alexa`s Smart Home Skill API. So far, not all device types or possibilities enabled by Alexa are supported. But it should not be very challenging to add this capabilities as needed. Have a look at the features and roadmap sections for more information.
- Discover defined smarthome devices by Alexa (Alexa.Discovery Interface)
- Authenticate an Alexa-User and grant access based on his Amazon profile (Alexa.Authorization Interface)
- Turn capable devices on or off (Alexa.PowerController Interface)
- Report health and current state for capable devices (Alexa Interface)
- Query temperature sensor values (Alexa.TemperatureSensor Interface)
- Easily extend supported functionality on your own
- Supports HTTP-BasicAuth for any requests handled (recommend use of https)
- Optionally all responses, send back to alexa, can be validated with the official JSON-Schema (extremely helpful for debugging)
- Of course, all those prerequisites to Smart Home Skill Development whould be very helpful
- I asume you authenticate an Alexa user by using LWA. To support other OAuth2 providers, you need to add a custom directive processor to handle authentication directives.
You can install this package in the usual way by using go get.
go get github.com/betom84/go-alexa
The following example starts an https server listening for Alexa directives. Of course you also can start an http server or don´t use BasicAuth (simply skip the assignments), but i would not recommend that.
package main
import(
"net/http"
"os"
"github.com/betom84/go-alexa/smarthome"
"github.com/betom84/go-alexa/smarthome/common/discoverable"
)
func main() {
endpoints := []discoverable.Endpoint{
discoverable.Endpoint{...},
discoverable.Endpoint{...},
}
authority := smarthome.Authority{
ClientID: "my-client-id",
ClientSecret: "my-client-secret",
RestrictedUsers: []string{"amzn-user@mail.com"},
}
handler := smarthome.NewDefaultHandler(&authority, endpoints)
handler.BasicAuth.Username = "alexa"
handler.BasicAuth.Password = "supersecret"
handler.DeviceFactory = DeviceFactory{}
err = http.ListenAndServeTLS(":https", "ssl/certificate.pem", "ssl/private-key.pem", handler)
if err != nil {
panic(err)
}
}
I asume you use LWA for account linking. You must add the scope profile
in the "Account Linking" section in the skill developer console. Then the users email address can be compared with the RestrictedUsers
to grant access.
In that example we only allow the Alexa-User with the e-mail amzn-user@mail.com
to get access. See amazon documentation for more information.
The endpoint model contains the information expected by Alexa´s Discover directive. The properties from Cookie
are used to create a device with the registered DeviceFactory. Also capabilities controllable by Alexa are defined within endpoint model. That means, devices created by the factory needs to satisfy the according capability interface.
The DeviceFactory
used above is needed to create a device which is capable of the action intended by Alexa. This device will be passed to the DirectiveProcessor
to finally perform the intended action. By using smarthome.NewDefaultHandler()
to create the handler, all supported processors are automatically added. Therefore devices need to satisfy the appropriate capability interfaces to work with these processors.
type DeviceFactory struct{}
func (f *DeviceFactory) NewDevice(epType string, id string) (interface{}, error) {
// return anything capable of the intended action
}
You can also implement a DirectiveProcessor
by your own.
import (
...
"github.com/betom84/go-alexa/smarthome/common"
)
type CustomDirectiveProcessor struct{}
func (p CustomDirectiveProcessor) Process(directive *common.Directive, device interface{}) (*common.Response, error) {
// perform the action intended by the directive at the device
}
func (p CustomDirectiveProcessor) IsCapable(directive *common.Directive) bool {
// return true if your processor is responsible for the given directive
}
And add it to the previously created handler.
handler.AddDirectiveProcessor(CustomDirectiveProcessor{})
By default only errors get logged to stderr
. Change default logging behaviour by creating a new instance with custom writer and severenity by using smarthome.NewDefaultLogger(...)
. Alternativly assign a custom smarthome.Logger
implementation to smarthome.Log
to override logging for your needs.
t.b.d.
- Support asynchronous responses and automatically use them if processing a directive takes to long
- Looking forward to find a better way to control window blinds (instead of simply turning them on and off)
This project is licensed under the MIT License.