-
Notifications
You must be signed in to change notification settings - Fork 12
/
smart_plug.go
147 lines (131 loc) · 3.09 KB
/
smart_plug.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
package kasa
import (
"encoding/json"
"log"
"regexp"
"strings"
)
// get timers
// change wifi network
// factory reset {"system":{"reset":{"delay":1}}}
// SmartPlug Allow to interact with either the SmartPlug HS100 and HS110
type SmartPlug interface {
GetAlias() string
GetInfo() (DeviceInfo, error)
TurnOn() error
TurnOff() error
SwitchOnOff() error
Reboot() error
ScanAPs() ([]AP, error)
}
// HS100 Allow to interact with the SmartPlug HS100
type HS100 SmartPlug
// HS103 Allow to interact with the SmartPlug HS103
type HS103 SmartPlug
// HS110 Allow to interact with the SmartPlug HS110
type HS110 SmartPlug
// HS200 Allow to interact with the SmartPlug HS200
type HS200 SmartPlug
type smartPlug struct {
DeviceID string
Alias string
Auth auth
}
func (s smartPlug) GetAlias() string {
return s.Alias
}
func (s smartPlug) GetInfo() (DeviceInfo, error) {
var deviceInfo DeviceInfo
res, err := s.getAuthRequest(requestBody{
Method: methodPassthrough,
Params: params{
DeviceID: s.DeviceID,
RequestData: "{\"system\": {\"get_sysinfo\": {}}}",
},
}).execute()
if err != nil {
return deviceInfo, err
}
res.ResponseData = strings.Replace(res.ResponseData, "{\"system\":{\"get_sysinfo\":", "", 1)
res.ResponseData = strings.Replace(res.ResponseData, "}}", "", 1)
err = json.Unmarshal([]byte(res.ResponseData), &deviceInfo)
if err != nil {
log.Fatal(err)
}
return deviceInfo, nil
}
func (s smartPlug) TurnOn() error {
_, err := s.getAuthRequest(requestBody{
Method: methodPassthrough,
Params: params{
DeviceID: s.DeviceID,
RequestData: "{\"system\": {\"set_relay_state\": {\"state\": 1}}}",
},
}).execute()
return err
}
func (s smartPlug) TurnOff() error {
_, err := s.getAuthRequest(requestBody{
Method: methodPassthrough,
Params: params{
DeviceID: s.DeviceID,
RequestData: "{\"system\": {\"set_relay_state\": {\"state\": 0}}}",
},
}).execute()
return err
}
func (s smartPlug) SwitchOnOff() error {
info, err := s.GetInfo()
if err != nil {
return err
}
if info.RelayState == 1 {
return s.TurnOff()
}
return s.TurnOn()
}
func (s smartPlug) Reboot() error {
_, err := s.getAuthRequest(requestBody{
Method: methodPassthrough,
Params: params{
DeviceID: s.DeviceID,
RequestData: "{\"system\":{\"reboot\":{\"delay\":1}}}",
},
}).execute()
if err.Error() == "Request timeout" {
err = nil
}
return err
}
func (s smartPlug) ScanAPs() ([]AP, error) {
aps := make([]AP, 0)
res, err := s.getAuthRequest(requestBody{
Method: methodPassthrough,
Params: params{
DeviceID: s.DeviceID,
RequestData: "{\"netif\":{\"get_scaninfo\":{\"refresh\":1}}}",
},
}).execute()
if err != nil {
return nil, err
}
re := regexp.MustCompile(`.*ap_list":(\[.*\])`)
data := re.FindStringSubmatch(res.ResponseData)
if len(data) < 2 {
return aps, nil
}
err = json.Unmarshal([]byte(data[1]), &aps)
if err != nil {
log.Fatal(err)
}
return aps, nil
}
func (s smartPlug) getAuthRequest(reqBody requestBody) authRequest {
return authRequest{
Auth: s.Auth,
Request: request{
URL: cloudURL,
RequestBody: reqBody,
},
}
}