-
Notifications
You must be signed in to change notification settings - Fork 5
/
command.go
202 lines (179 loc) · 6.27 KB
/
command.go
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
package action
import (
"encoding/json"
"fmt"
)
// Command defines which command, and what details, are being specified.
// Only one of the contained fields will be set at any point in time.
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
}
// MarshalJSON is a custom JSON serializer for our Command
func (c Command) MarshalJSON() ([]byte, error) {
var details interface{}
switch c.Name {
case "action.devices.commands.BrightnessAbsolute":
details = c.BrightnessAbsolute
case "action.devices.commands.BrightnessRelative":
details = c.BrightnessRelative
case "action.devices.commands.ColorAbsolute":
details = c.ColorAbsolute
case "action.devices.commands.OnOff":
details = c.OnOff
case "action.devices.commands.mute":
details = c.Mute
case "action.devices.commands.setVolume":
details = c.SetVolume
case "action.devices.commands.volumeRelative":
details = c.AdjustVolume
case "action.devices.commands.SetInput":
details = c.SetInput
case "action.devices.commands.NextInput":
details = c.NextInput
case "action.devices.commands.PreviousInput":
details = c.PreviousInput
default:
return json.Marshal(c.Generic)
}
var tmp struct {
Command string `json:"command"`
Params interface{} `json:"params"`
}
tmp.Command = c.Name
tmp.Params = details
return json.Marshal(tmp)
}
// UnmarshalJSON is a custom JSON deserializer for our Command
func (c *Command) UnmarshalJSON(data []byte) error {
var tmp struct {
Command string `json:"command"`
Params json.RawMessage `json:"params"`
}
err := json.Unmarshal(data, &tmp)
if err != nil {
return err
}
c.Name = tmp.Command
var details interface{}
switch tmp.Command {
case "action.devices.commands.BrightnessAbsolute":
c.BrightnessAbsolute = &CommandBrightnessAbsolute{}
details = c.BrightnessAbsolute
case "action.devices.commands.BrightnessRelative":
c.BrightnessRelative = &CommandBrightnessRelative{}
details = c.BrightnessRelative
case "action.devices.commands.ColorAbsolute":
c.ColorAbsolute = &CommandColorAbsolute{}
details = c.ColorAbsolute
case "action.devices.commands.OnOff":
c.OnOff = &CommandOnOff{}
details = c.OnOff
case "action.devices.commands.mute":
c.Mute = &CommandMute{}
details = c.Mute
case "action.devices.commands.setVolume":
c.SetVolume = &CommandSetVolume{}
details = c.SetVolume
case "action.devices.commands.volumeRelative":
c.AdjustVolume = &CommandSetVolumeRelative{}
details = c.AdjustVolume
case "action.devices.commands.SetInput":
c.SetInput = &CommandSetInput{}
details = c.SetInput
case "action.devices.commands.NextInput":
c.NextInput = &CommandNextInput{}
details = c.NextInput
case "action.devices.commands.PreviousInput":
c.PreviousInput = &CommandPreviousInput{}
details = c.PreviousInput
default:
c.Generic = &CommandGeneric{}
err := json.Unmarshal(data, c.Generic)
if err != nil {
return err
}
return nil
}
err = json.Unmarshal(tmp.Params, details)
if err != nil {
return fmt.Errorf("error unmarshaling command Params into details: %w", err)
}
return nil
}
// 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 CommandGeneric struct {
Command string `json:"command"`
Params map[string]interface{} `json:"params"`
}
// CommandBrightnessAbsolute requests to set the brightness to an absolute value
// See https://developers.google.com/assistant/smarthome/traits/brightness
type CommandBrightnessAbsolute struct {
Brightness int `json:"brightness"`
}
// 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 CommandBrightnessRelative struct {
RelativePercent int `json:"brightnessRelativePercent"`
RelativeWeight int `json:"brightnessRelativeWeight"`
}
// 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 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"`
}
// CommandOnOff requests to turn the entity on or off.
// See https://developers.google.com/assistant/smarthome/traits/onoff
type CommandOnOff struct {
On bool `json:"on"`
}
// CommandMute requests the device be muted.
// See https://developers.google.com/assistant/smarthome/traits/volume
type CommandMute struct {
Mute bool `json:"mute"`
}
// CommandSetVolume requests the device volume be set to the specified value.
// See https://developers.google.com/assistant/smarthome/traits/volume
type CommandSetVolume struct {
Level int `json:"volumeLevel"`
}
// CommandSetVolumeRelative requests the device volume be increased or decreased.
// See https://developers.google.com/assistant/smarthome/traits/volume
type CommandSetVolumeRelative struct {
Amount int `json:"relativeSteps"`
}
// CommandSetInput requests the device input be changed.
// See https://developers.google.com/assistant/smarthome/traits/inputselector
type CommandSetInput struct {
NewInput string `json:"newInput"`
}
// CommandNextInput requests the device input be changed to the next logical one.
// See https://developers.google.com/assistant/smarthome/traits/inputselector
type CommandNextInput struct {
}
// CommandPreviousInput requests the device input be changed to the previous logical one.
// See https://developers.google.com/assistant/smarthome/traits/inputselector
type CommandPreviousInput struct {
}