action

package module
v0.0.0-...-073d35b Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: Nov 25, 2022 License: MIT Imports: 10 Imported by: 5

README

google-smart-home-action-go

Build Smart Home Actions for Google Assistant in Go

Introduction

The Google Smart Home Actions make it possible for the cloud-hosted Google Assistant to control devices built and operated by third parties. The purpose of this library is to simplify the process of building a third party home automation component that the Google Assistant can interact with. This library adds no additional processing capabilities on top of the Google Assistant APIs; it simply wraps the calls to simplify integration into a Go project.

At the moment this library provides no mechanisms to add authentication to your Google Smart Home Action - a separate OAuth capable framework is necessary. Initializing this framework requires a method be supplied to verify tokens - this is code you will write which will look up any Google-supplied tokens against the OAuth framework.

Google Smart Home Actions

The Google Smart Home framework exists to allow Google Assistant, running on smartphones, smart speakers, etc. to interface with devices made by any number of manufacturers. The Google Assistant is set up in a multitenant architecture; each Google account has its own Assistant profile. This Google account also has its own, distinct object store called a home graph, which contains the profile and state information of every device which all linked Google Smart Home Actions have exposed.

The above is broken down as follows:

  • each user has a Google account
  • each Google account has a single home graph
  • each Google account has zero or more Smart Home Actions linked
  • each Smart Home Action linked to a Google account adds zero or more devices to the Google account home graph
  • each user, through the Google Assistant, can request a state change of any device on the home graph

The code written in the Smart Home Action is responsible for:

  • properly exposing the profile and state of the devices under its control to the home graph
  • updating the home graph whenever an underlying device changes
  • accepting commands from the home graph to change the state of its devices

Using this library

This library simplifies the process of handling the Google Smart Home Action code flows. The major entites in the system are:

  1. devices. Each device describes a distinct entity that the Google Assistant can interact with. The Google Smart Home Action framework allows for a number of different device types to be specified; depending on the type set the Google Assistant may change how the device is referenced, visualized, etc. The type alone is not sufficient however, it is necessary to define relevant attributes as well (see below).
  2. device traits. Each device has a set of traits that describe what the Google Assistant can do with the device. A trait is composed of three distinct components:
  3. attributes, which describe the specific configuration of the trait as it applies to the device
  4. states, which describe the current state of the device
  5. commands, which describe how the Google Assistant is able to control the device with this trait

As an example, a Light is an example of a device which can have 2 traits: OnOff and Brightness.

  • The OnOff trait specifies attributes which defines if the device is able to be queried or whether the Google Assistant has to maintain the state internally (some devices are 'write only')
  • The OnOff trait specifies the state of on or off
  • The OnOff trait specifies the OnOff command which allows the state to be changed.
  • The Brightness trait has similiar attributes & states as the OnOff trait, but it specifies a pair of commands which allow the Google Assistant to either define a specific brightness level, or adjust the brightness by a relative amount.

This library has wrappers for some of the most common types of devices and traits to simplify the process of creating a representation of your actual device logic within the home graph. In order to provide flexibility for the consumer of the library, however, it also allows for manual definition of Devices and Traits that can be returned by any API call. Contributions for structured versions of any Smart Home Action device or trait is very much welcome!

Documentation

Index

Constants

View Source
const (
	RGB = "rgb"
	HSV = "hsv"
)

ColorModel defines which model of the color wheel the device supports.

View Source
const (
	// GoogleFulfillmentPath represents the HTTP path which the Google fulfillment hander will call
	GoogleFulfillmentPath = "/fulfillment"
)

Variables

View Source
var (
	// ErrSyncFailed is returned if the request to HomeGraph to force a SYNC operation failed.
	// The log will contain more information about what occurred.
	ErrSyncFailed = errors.New("sync failed")
	// ErrReportStateFailed is returned if the request to HomeGraph to update a device failed.
	// The log will contain more information about what occurred.
	ErrReportStateFailed = errors.New("report state failed")
)

Functions

This section is empty.

Types

type AccessTokenValidator

type AccessTokenValidator interface {
	// Validate performs the actual token validation. Returning an error will force validation to fail.
	// The user ID that corresponds to the token should be returned on success.
	Validate(context.Context, string) (string, error)
}

AccessTokenValidator allows for the auth token supplied by Google to be validated.

type Command

type Command struct {
	Name    string
	Generic *CommandGeneric

	BrightnessAbsolute *CommandBrightnessAbsolute
	BrightnessRelative *CommandBrightnessRelative
	ColorAbsolute      *CommandColorAbsolute
	OnOff              *CommandOnOff
	Mute               *CommandMute
	SetVolume          *CommandSetVolume
	AdjustVolume       *CommandSetVolumeRelative
	SetInput           *CommandSetInput
	NextInput          *CommandNextInput
	PreviousInput      *CommandPreviousInput
}

Command defines which command, and what details, are being specified. Only one of the contained fields will be set at any point in time.

func (Command) MarshalJSON

func (c Command) MarshalJSON() ([]byte, error)

MarshalJSON is a custom JSON serializer for our Command

func (*Command) UnmarshalJSON

func (c *Command) UnmarshalJSON(data []byte) error

UnmarshalJSON is a custom JSON deserializer for our Command

type CommandArg

type CommandArg struct {
	TargetDevices []DeviceArg
	Commands      []Command
}

CommandArg contains the fields used to execute a change on a set of devices. Only one of the various pointers in Command should be set per command.

type CommandBrightnessAbsolute

type CommandBrightnessAbsolute struct {
	Brightness int `json:"brightness"`
}

CommandBrightnessAbsolute requests to set the brightness to an absolute value See https://developers.google.com/assistant/smarthome/traits/brightness

type CommandBrightnessRelative

type CommandBrightnessRelative struct {
	RelativePercent int `json:"brightnessRelativePercent"`
	RelativeWeight  int `json:"brightnessRelativeWeight"`
}

CommandBrightnessRelative requests to set the brightness to a relative level Only one of the two fields will be set. See https://developers.google.com/assistant/smarthome/traits/brightness

type CommandColorAbsolute

type CommandColorAbsolute struct {
	Color struct {
		Name        string `json:"name"`
		Temperature int    `json:"temperature"`
		RGB         int    `json:"spectrumRGB"`
		HSV         struct {
			Hue        float64 `json:"hue"`
			Saturation float64 `json:"saturation"`
			Value      float64 `json:"value"`
		} `json:"spectrumHSV"`
	} `json:"color"`
}

CommandColorAbsolute requests to set the colour of a light to a particular value. Only one of temperature, RGB and HSV will be set. See https://developers.google.com/assistant/smarthome/traits/colorsetting

type CommandGeneric

type CommandGeneric struct {
	Command string                 `json:"command"`
	Params  map[string]interface{} `json:"params"`
}

CommandGeneric contains a command definition which hasn't been parsed into a specific command structure. This is intended to support newly defined commands which callers of this SDK may handle but this does not yet support.

type CommandMute

type CommandMute struct {
	Mute bool `json:"mute"`
}

CommandMute requests the device be muted. See https://developers.google.com/assistant/smarthome/traits/volume

type CommandNextInput

type CommandNextInput struct {
}

CommandNextInput requests the device input be changed to the next logical one. See https://developers.google.com/assistant/smarthome/traits/inputselector

type CommandOnOff

type CommandOnOff struct {
	On bool `json:"on"`
}

CommandOnOff requests to turn the entity on or off. See https://developers.google.com/assistant/smarthome/traits/onoff

type CommandPreviousInput

type CommandPreviousInput struct {
}

CommandPreviousInput requests the device input be changed to the previous logical one. See https://developers.google.com/assistant/smarthome/traits/inputselector

type CommandSetInput

type CommandSetInput struct {
	NewInput string `json:"newInput"`
}

CommandSetInput requests the device input be changed. See https://developers.google.com/assistant/smarthome/traits/inputselector

type CommandSetVolume

type CommandSetVolume struct {
	Level int `json:"volumeLevel"`
}

CommandSetVolume requests the device volume be set to the specified value. See https://developers.google.com/assistant/smarthome/traits/volume

type CommandSetVolumeRelative

type CommandSetVolumeRelative struct {
	Amount int `json:"relativeSteps"`
}

CommandSetVolumeRelative requests the device volume be increased or decreased. See https://developers.google.com/assistant/smarthome/traits/volume

type Device

type Device struct {
	// ID of the device
	ID string

	// Type of the device.
	// See https://developers.google.com/assistant/smarthome/guides is a list of possible types
	Type string

	// Traits of the device.
	// See https://developers.google.com/assistant/smarthome/traits for a list of possible traits
	// The set of assigned traits will dictate which actions can be performed on the device
	Traits map[string]bool

	// Name of the device.
	Name DeviceName

	// WillReportState using the ReportState API (should be true)
	WillReportState bool

	// RoomHint guides Google as to which room this device is in
	RoomHint string

	// Attributes linked to the defined traits
	Attributes map[string]interface{}

	// DeviceInfo that is physically defined
	DeviceInfo DeviceInfo

	// OtherDeviceIDs allows for this to be logically linked to other devices
	OtherDeviceIDs []OtherDeviceID

	// CustomData specified which will be included unmodified in subsequent requests.
	CustomData map[string]interface{}
}

Device represents a single provider-supplied device profile.

func NewDevice

func NewDevice(id string, typ string) *Device

NewDevice creates a new device ready for setting things in.

func NewLight

func NewLight(id string) *Device

NewLight creates a new device with the attributes for an on-off light. This can be customized with any of the light-related traits (Color, Brightness).

func NewOutlet

func NewOutlet(id string) *Device

NewOutlet creates a new device with the attributes for an on-off outlet.

func NewSimpleAVReceiver

func NewSimpleAVReceiver(id string, inputs []DeviceInput, maxLevel int, canMute bool, onlyCommand bool) *Device

NewSimpleAVReceiver creates a new device with the attributes for a simple AV receiver setup.

func NewSwitch

func NewSwitch(id string) *Device

NewSwitch creates a new device with the attributes for an on-off switch. This can be customized with the Brightness trait.

func (*Device) AddBrightnessTrait

func (d *Device) AddBrightnessTrait(onlyCommand bool) *Device

AddBrightnessTrait indicates this device is capable of having its brightness controlled. If the device does not support querying, set onlyCommand to true (i.e. a write-only switch). See https://developers.google.com/assistant/smarthome/traits/brightness

func (*Device) AddColourTemperatureTrait

func (d *Device) AddColourTemperatureTrait(minTempK int, maxTempK int, onlyCommand bool) *Device

AddColourTemperatureTrait indicates this device is capable of having its colour display controlled using the colour temperature model. This can be set alongside AddColorSetting to indicate both color temperature and another algorithm are supported. If the device does not support querying, set onlyCommand to true (i.e. a write-only lightbulb). See https://developers.google.com/assistant/smarthome/traits/colorsetting

func (*Device) AddColourTrait

func (d *Device) AddColourTrait(model string, onlyCommand bool) *Device

AddColourTrait indicates this device is capable of having its colour display controlled using the specified color model. It is mutually exclusive to support RGB or HSV. It is possible to support either one of RGB and HSV alongside color temperature. See AddColorTemperatureSetting If the device does not support querying, set onlyCommand to true (i.e. a write-only lightbulb). See https://developers.google.com/assistant/smarthome/traits/colorsetting

func (*Device) AddInputSelectorTrait

func (d *Device) AddInputSelectorTrait(availableInputs []DeviceInput, ordered bool) *Device

AddInputSelectorTrait indicates this device is capable of having its input selected. See https://developers.google.com/assistant/smarthome/traits/inputselector

func (*Device) AddOnOffTrait

func (d *Device) AddOnOffTrait(onlyCommand, onlyQuery bool) *Device

AddOnOffTrait indicates this device is capable of having its state toggled on or off. If the device can be commanded but not queried, set onlyCommand to true (i.e. a write-only switch). If the devie cannot be commanded but only queried, set onlyQuery to true (i.e. a sensor). See https://developers.google.com/assistant/smarthome/traits/onoff

func (*Device) AddVolumeTrait

func (d *Device) AddVolumeTrait(maxLevel int, canMute bool, onlyCommand bool) *Device

AddVolumeTrait indicates this device is capable of having its volume controlled See https://developers.google.com/assistant/smarthome/traits/volume

func (Device) MarshalJSON

func (d Device) MarshalJSON() ([]byte, error)

MarshalJSON is a custom JSON serializer for our Device

func (*Device) UnmarshalJSON

func (d *Device) UnmarshalJSON(data []byte) error

UnmarshalJSON is a custom JSON deserializer for our Device

type DeviceArg

type DeviceArg struct {
	ID         string
	CustomData map[string]interface{}
}

DeviceArg contains the common fields used when executing requests against a device. It has 2 fields of note: - the ID of the device - any custom data supplied for the device ID as part of the original response to SYNC

type DeviceInfo

type DeviceInfo struct {
	// Manufacturer of the device
	Manufacturer string
	// Model of the device
	Model string
	// HwVersion of the device
	HwVersion string
	// SwVersion of the device
	SwVersion string
}

DeviceInfo contains different properties of the device

type DeviceInput

type DeviceInput struct {
	Key   string            `json:"key"`
	Names []DeviceInputName `json:"names"`
}

DeviceInput represents a single input of a device

type DeviceInputName

type DeviceInputName struct {
	LanguageCode string   `json:"lang"`
	Synonyms     []string `json:"name_synonym"`
}

DeviceInputName represents the human-readable name shown for an input

type DeviceName

type DeviceName struct {
	// DefaultNames (not user settable)
	DefaultNames []string
	// Name supplied by the user for display purposes
	Name string
	// Nicknames given to this, should a user have multiple ways to refer to the device
	Nicknames []string
}

DeviceName contains different ways of identifying the device

type DeviceState

type DeviceState struct {
	Online bool
	Status string

	State map[string]interface{}
}

DeviceState contains the state of a device.

func NewDeviceState

func NewDeviceState(online bool) DeviceState

NewDeviceState creates a new device state to be added to as defined by the relevant traits on a device.

func (DeviceState) MarshalJSON

func (ds DeviceState) MarshalJSON() ([]byte, error)

MarshalJSON is a custom JSON serializer for our DeviceState

func (DeviceState) RecordBrightness

func (ds DeviceState) RecordBrightness(brightness int) DeviceState

RecordBrightness adds the current brightness to the device. Should only be applied to devices with the Brightness trait See https://developers.google.com/assistant/smarthome/traits/brightness

func (DeviceState) RecordColorHSV

func (ds DeviceState) RecordColorHSV(hue float64, saturation float64, value float64) DeviceState

RecordColorHSV adds the current color in HSV to the device. Should only be applied to devices with the ColorSetting trait See https://developers.google.com/assistant/smarthome/traits/colorsetting

func (DeviceState) RecordColorRGB

func (ds DeviceState) RecordColorRGB(spectrumRgb int) DeviceState

RecordColorRGB adds the current color in RGB to the device. Should only be applied to devices with the ColorSetting trait See https://developers.google.com/assistant/smarthome/traits/colorsetting

func (DeviceState) RecordColorTemperature

func (ds DeviceState) RecordColorTemperature(temperatureK int) DeviceState

RecordColorTemperature adds the current color temperature (in Kelvin) to the device. Should only be applied to devices with the ColorSetting trait See https://developers.google.com/assistant/smarthome/traits/colorsetting

func (DeviceState) RecordInput

func (ds DeviceState) RecordInput(input string) DeviceState

RecordInput adds the current input active to the device. Should only be applied to devices with the InputSelector trait See https://developers.google.com/assistant/smarthome/traits/inputselector

func (DeviceState) RecordOnOff

func (ds DeviceState) RecordOnOff(on bool) DeviceState

RecordOnOff adds the current on/off state to the device. Should only be applied to devices with the OnOff trait See https://developers.google.com/assistant/smarthome/traits/onoff

func (DeviceState) RecordVolume

func (ds DeviceState) RecordVolume(volume int, isMuted bool) DeviceState

RecordVolume adds the current volume state to the device. Should only be applied to devices with the Volume trait See https://developers.google.com/assistant/smarthome/traits/volume

func (*DeviceState) UnmarshalJSON

func (ds *DeviceState) UnmarshalJSON(data []byte) error

UnmarshalJSON is a custom JSON deserializer for our DeviceState

type ExecuteRequest

type ExecuteRequest struct {
	Commands []CommandArg
	AgentID  string
}

ExecuteRequest includes what is being asked for by the Google Assistant when making a change. The customData is a JSON object originally returned during the Sync operation.

type ExecuteResponse

type ExecuteResponse struct {
	UpdatedState   DeviceState
	UpdatedDevices []string
	OfflineDevices []string
	FailedDevices  map[string]struct {
		Devices []string
	}
}

ExecuteResponse includes the results of an Execute command to be sent back to the Google home graph after an execute. Between the UpdatedDevices and FailedDevices maps all device IDs in the Execute request should be accounted for.

type OtherDeviceID

type OtherDeviceID struct {
	AgentID  string
	DeviceID string
}

OtherDeviceID contains alternative ways to identify this device.

type Provider

Provider exposes methods that can be invoked by the Google Smart Home Action intents

type QueryRequest

type QueryRequest struct {
	Devices []DeviceArg
	AgentID string
}

QueryRequest includes what is being asked for by the Google Smart Home Action when querying.

type QueryResponse

type QueryResponse struct {
	States map[string]DeviceState
}

QueryResponse includes what should be returned in response to the query to the Google Home Smart Action. The States map should have the same IDs supplied in the request.

type Service

type Service struct {
	// contains filtered or unexported fields
}

Service links together the updates coming from the different sources and ensures they are consistent. Updates may come in via: - the GoogleCallbackHandler, which is registered externally on an HTTPS endpoint which the Google Smart Home Actions framework will POST to - the API calls made against this service by the underlying device

func NewService

func NewService(logger *zap.Logger, atValidator AccessTokenValidator, provider Provider, hgService *homegraph.Service) *Service

NewService creates a new service to handle Google Action operations. It is required that an access token validator be specified to properly process requests. This access token validator should be pointed to the same data source as the OAuth2 server configured in the Google Smart Home Actions portal in the OAuth2 account linking section.

func (*Service) GoogleFulfillmentHandler

func (s *Service) GoogleFulfillmentHandler(w http.ResponseWriter, r *http.Request)

GoogleFulfillmentHandler must be registered on an HTTPS endpoint at the path specified by GoogleFulfillmentPath This HTTPS endpoint needs to be registered on the Smart Home Actions fulfillment path. See https://developers.google.com/assistant/smarthome/concepts/fulfillment-authentication or https://developers.google.com/assistant/smarthome/develop/process-intents for details.

func (*Service) ReportState

func (s *Service) ReportState(ctx context.Context, agentUserID string, deviceStates map[string]DeviceState) error

ReportState is used to report a state change which occurred on a device to the Google HomeGraph. This should be called whenever a local action triggers a change, as well as after receiving an Execute callback. The supplied state argument should have a complete definition of the device state (i.e. do not perform incremental updates). The deviceStates map is indexed by device ID. This library does not attempt to report on state changes automatically as it is possible that the action triggers a change on the device that is not reflected in the initial request. It is best if the underlying service ensures that the Google HomeGraph is kept in sync through an explicit state update after execution.

func (*Service) RequestSync

func (s *Service) RequestSync(ctx context.Context, agentUserID string) error

RequestSync is used to trigger a Google HomeGraph sync operation. This should be called whenever the list of devices, or their properties, change. This will request a sync occur synchronously, so make sure that the Sync method is not blocked on anything this method may be doing.

type SyncResponse

type SyncResponse struct {
	Devices []*Device
}

SyncResponse contains the set of devices to supply to the Google Smart Home Action when setting up.

Directories

Path Synopsis
examples

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL