-
Notifications
You must be signed in to change notification settings - Fork 6
/
Copy pathDynamic_Hue_Animated_Scene_Controller.groovy
203 lines (172 loc) · 6.11 KB
/
Dynamic_Hue_Animated_Scene_Controller.groovy
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
203
metadata {
definition (name: "Dynamic Hue Animated Scene Controller", namespace: "hueKeo", author: "Joe Rosiak") {
capability "Switch"
capability "Refresh"
command "activateViaJson", ["string"]
command "setSceneName", ["string"]
command "setZoneName", ["string"]
}
preferences {
input name: "hueIp", type: "string", title: "Hue Bridge IP", description: "Enter the IP of your Hue Bridge", required: true
input name: "hueZone", type: "string", title: "Hue Zone/Room Name", description: "Enter the Hue Zone or Room name", required: true
input name: "sceneName", type: "string", title: "Animated Scene Name", description: "Enter the Animated Scene name", required: true
input name: "apiKey", type: "password", title: "Hue API Key", description: "Enter your Hue Bridge API Key", required: true
}
}
def installed() {
log.debug "Installing Hue Animated Scene Controller"
initialize()
}
def updated() {
log.debug "Updating Hue Animated Scene Controller settings"
initialize()
}
def initialize() {
log.debug "Initializing Hue Animated Scene Controller"
}
def on() {
log.debug "Turning on the Hue Animated Scene"
activateScene()
}
def off() {
log.debug "Turning off the lights in the Hue Zone"
deactivateZone()
}
def refresh() {
log.debug "Refreshing Hue Animated Scene Controller"
// Placeholder for future refresh functionality
}
def activateViaJson(String jsonInput) {
log.debug "Setting Scene and Zone with JSON input: ${jsonInput}"
try {
def parsedJson = new groovy.json.JsonSlurper().parseText(jsonInput)
def newZoneName = parsedJson.zone
def newSceneName = parsedJson.scene
def action = parsedJson.action
if (!newZoneName || !newSceneName) {
log.error "Zone or Scene not provided in the JSON input"
return
}
// Now activate or deactivate the scene based on the action
if (action == "on") {
activateSceneById(newZoneName, newSceneName)
} else if (action == "off") {
deactivateZone(newZoneName)
} else {
log.error "Invalid action provided: ${action}. Expected 'on' or 'off'."
}
} catch (Exception e) {
log.error "Error parsing JSON input: ${e.message}"
}
}
def activateSceneById(zoneName, sceneName) {
if (!hueIp || !apiKey) {
log.error "Hue IP or API key is not set. Please configure the device."
return
}
def zoneId = getZoneId(zoneName)
if (!zoneId) {
log.error "Failed to get zone ID for zone: ${zoneName}"
return
}
def sceneId = getSceneId(zoneId, sceneName)
if (!sceneId) {
log.error "Failed to get scene ID for scene: ${sceneName} in zone: ${zoneName}"
return
}
def url = "http://${hueIp}/api/${apiKey}/groups/${zoneId}/action"
def body = [scene: sceneId]
try {
def params = [
uri: url,
body: body,
contentType: "application/json"
]
httpPut(params) { resp ->
if (resp.status == 200) {
log.debug "Successfully activated scene: ${sceneName} in zone: ${zoneName}"
} else {
log.error "Failed to activate scene: ${sceneName}. Response: ${resp.status}"
}
}
} catch (Exception e) {
log.error "Error activating scene: ${e.message}"
}
}
def deactivateZone(zoneName = null) {
// Use the passed-in zoneName if provided; otherwise, fall back to the configured zone in preferences
def hueZone = zoneName ?: hueZone
// Check if the required values (hueIp, hueZone, apiKey) are set
if (!hueIp || !hueZone || !apiKey) {
log.error "Hue IP, Zone, or API key is not set. Please configure the device."
return
}
// Retrieve the zone ID
def zoneId = getZoneId(hueZone)
if (!zoneId) {
log.error "Failed to find Hue zone with name: ${hueZone}"
return
}
// Formulate the URL and request body to turn off the lights
def url = "http://${hueIp}/api/${apiKey}/groups/${zoneId}/action"
def body = [on: false]
try {
def params = [
uri: url,
body: body,
contentType: "application/json"
]
// Send the HTTP PUT request
httpPut(params) { resp ->
if (resp.status == 200) {
log.debug "Turned off the lights in zone: ${hueZone}"
} else {
log.error "Failed to turn off the lights in zone: ${hueZone}. Response: ${resp.status}"
}
}
} catch (Exception e) {
log.error "Error turning off the zone: ${e.message}"
}
}
def getZoneId(zoneName) {
def url = "http://${hueIp}/api/${apiKey}/groups"
def zoneId = null
try {
httpGet([uri: url, contentType: "application/json"]) { resp ->
if (resp.status == 200) {
def groups = resp.data
groups.each { id, group ->
if (group.name == zoneName) {
zoneId = id
}
}
} else {
log.error "Failed to retrieve zones. Response: ${resp.status}"
}
}
} catch (Exception e) {
log.error "Error retrieving zones: ${e.message}"
}
return zoneId
}
def getSceneId(zoneId, sceneName) {
def url = "http://${hueIp}/api/${apiKey}/scenes"
def sceneId = null
try {
httpGet([uri: url, contentType: "application/json"]) { resp ->
if (resp.status == 200) {
def scenes = resp.data
scenes.each { id, scene ->
if (scene.name == sceneName && scene.group == zoneId) {
sceneId = id
}
}
} else {
log.error "Failed to retrieve scenes. Response: ${resp.status}"
}
}
} catch (Exception e) {
log.error "Error retrieving scenes: ${e.message}"
}
return sceneId
}