Update rise-and-shine.groovy
[smartapps.git] / official / smartblock-manager.groovy
1 /**
2  *  Copyright 2015 SmartThings
3  *
4  *  Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except
5  *  in compliance with the License. You may obtain a copy of the License at:
6  *
7  *      http://www.apache.org/licenses/LICENSE-2.0
8  *
9  *  Unless required by applicable law or agreed to in writing, software distributed under the License is distributed
10  *  on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License
11  *  for the specific language governing permissions and limitations under the License.
12  *
13  */
14 import com.sun.corba.se.spi.activation._ServerImplBase
15
16 /**
17  *  SmartBlock Manager
18  *
19  *  Author: Steve Vlaminck
20  *
21  *  Date: 2013-12-24
22  */
23
24 definition(
25         name: "SmartBlock Manager",
26         namespace: "vlaminck/Minecraft",
27         author: "SmartThings",
28         description: "A SmartApp for managing SmartBlocks",
29         iconUrl: "http://f.cl.ly/items/0p2c222z0p2K0y3y3w2M/SmartApp-icon.png",
30         iconX2Url: "http://f.cl.ly/items/0p2c222z0p2K0y3y3w2M/SmartApp-icon.png",
31         oauth: [displayName: "SmartBlock Manager", displayLink: ""]
32 )
33
34 preferences {
35
36         page(name: "listPage")
37         page(name: "serverPage")
38         page(name: "blockPage")
39         page(name: "linkerPage")
40         page(name: "notifierPage")
41         page(name: "chatPage")
42
43         section("SmartBlock Manager") {
44                 input name: "explanation1", title: "Every time you place a SmartBlock in Minecraft, a new SmartThings Device will be created. These Devices can be used in various SmartApps like \"Minecraft Notifier\", or \"Switch State Matcher\"", description: "", type: "paragraph", element: "paragraph", required: false
45                 input name: "explanation2", title: "In order for SmartThings to send commands back to your Minecraft SmartBlocks, you will have to enter your Server Address via the SmartThings iOS or Android app", description: "", type: "paragraph", element: "paragraph", required: false
46         }
47 }
48
49 def listPage() {
50
51         log.debug "listPage"
52
53         def linkerApps = findAllChildAppsByName("SmartBlock Linker")
54         def linkerState = linkerApps ? "complete" : ""
55         def linkerDescription = linkerApps.collect { it.label ?: it.name }.sort().join("\n")
56
57         def notifierApps = findAllChildAppsByName("SmartBlock Notifier")
58         def notifierState = notifierApps ? "complete" : ""
59         def notifierDescription = notifierApps.collect { it.label ?: it.name }.sort().join("\n")
60
61         def chatApps = findAllChildAppsByName("SmartBlock Chat Sender")
62         def chatState = chatApps ? "complete" : ""
63         def chatDescription = chatApps.collect { it.label ?: it.name }.sort().join("\n")
64
65         return dynamicPage(name: "listPage", title: "Configure Your SmartBlocks", install: true, uninstall: true) {
66                 section {
67                         href(
68                                 name: "toLinkerPage",
69                                 title: "Link SmartBlocks To Switches",
70                                 description: linkerDescription,
71                                 page: "linkerPage",
72                                 state: linkerState
73                         )
74                         href(
75                                 name: "toNotifierPage",
76                                 title: "Get Notified When a SmartBlock updates",
77                                 description: notifierDescription,
78                                 page: "notifierPage",
79                                 state: notifierState
80                         )
81                         href(
82                                 name: "toChatPage",
83                                 title: "Send Notifications into Minecraft",
84                                 description: chatDescription,
85                                 page: "chatPage",
86                                 state: chatState
87                         )
88                 }
89
90                 section {
91                         input(
92                                 name: "serverIp",
93                                 title: "In order for SmartThings to send commands back to the SmartBlocks on your Minecraft server, you will have to enter your Server Address",
94                                 type: "text",
95                                 required: false
96                         )
97                 }
98         }
99 }
100
101 def serverPage() {
102         log.debug "serverPage"
103         dynamicPage(name: "serverPage", title: "Connect SmartThings To Your Minecraft Server") {
104                 section {
105                         input(
106                                 name: "serverIp",
107                                 title: "In order for SmartThings to send commands back to the SmartBlocks on your Minecraft server, you will have to enter your Server Address",
108                                 type: "text",
109                                 required: false
110                         )
111                 }
112         }
113 }
114
115
116 def linkerPage() {
117         dynamicPage(name: "linkerPage", title: "Link SmartBlocks To Switches") {
118                 section {
119                         app(
120                                 title: "Link a SmartBlock to a switch",
121                                 name: "blockLinker-new",
122                                 namespace: "vlaminck/Minecraft",
123                                 appName: "SmartBlock Linker",
124                                 page: "linkerPage",
125                                 multiple: true,
126                                 params: ["blocks": getChildDevices()]
127                         )
128                 }
129         }
130
131 }
132
133 def notifierPage() {
134         return dynamicPage(name: "notifierPage", title: "Get Notified When a SmartBlock is updated") {
135                 section {
136                         app(
137                                 title: "Get Notified",
138                                 name: "blockNotifier-new",
139                                 namespace: "vlaminck/Minecraft",
140                                 appName: "SmartBlock Notifier",
141                                 multiple: true
142                         )
143                 }
144         }
145 }
146
147 def chatPage() {
148         return dynamicPage(name: "chatPage", title: "Send Notifications into Minecraft") {
149                 section {
150                         app(
151                                 title: "Send Notifications",
152                                 name: "chatSender-new",
153                                 namespace: "vlaminck/Minecraft",
154                                 appName: "SmartBlock Chat Sender",
155                                 multiple: true
156                         )
157                 }
158         }
159 }
160
161 mappings {
162         path("/block") { // any need for GET?
163                 action:
164                 [
165                         POST  : "createBlock",
166                         PUT   : "updateBlock",
167                         DELETE: "deleteBlock"
168                 ]
169         }
170         path("/ack") {
171                 action:
172                 [
173                         POST: "ack"
174                 ]
175         }
176 }
177
178 def createBlock() {
179         def data = request.JSON
180         def blockCoordinates = blockCoordinates(data)
181         def blockDNI = blockDNI(data)
182         def block = block(data)
183
184         if (block) {
185                 log.debug "Block ${block?.label} with id $blockDNI already exists"
186         } else {
187                 block = addChildDevice("vlaminck/Minecraft", "Smart Block", blockDNI, null, [name: "SmartBlock", label: "SmartBlock $blockCoordinates"])
188         }
189
190         block?.setCoordinates(data.x, data.y, data.z)
191         block?.setDestroyed(false)
192         block?.setWorldSeed(data?.worldSeed)
193         block?.setDimensionName(data?.dimensionName)
194         block?.setPlacedBy(data?.placedBy)
195
196         if (serverIp) {
197                 block.setServerIp(serverIp)
198         }
199
200         log.debug "created ${block?.label} with id $blockDNI"
201 }
202
203 def ack() {
204         log.debug "ack params : $params"
205         log.debug "ack JSON : ${request.JSON}"
206
207         sendDataToBlock(request?.JSON, false)
208 }
209
210 def updateBlock() {
211         sendDataToBlock(request?.JSON, true)
212 }
213
214 def sendDataToBlock(data, isStateChange) {
215
216         def blockCoordinates = blockCoordinates(data)
217         def blockDNI = blockDNI(data)
218         def block = block(data)
219         log.debug "updating Block ${block?.label} with id $blockDNI"
220
221         block?.neighborBlockChange(data)
222
223         if (data.worldSeed) {
224                 block.setWorldSeed(data.worldSeed)
225         }
226
227         if (data.dimensionName) {
228                 block.setDimensionName(data.dimensionName)
229         }
230
231         if (data.placedBy) {
232                 block.setPlacedBy(data.placedBy)
233         }
234
235         block.setServerIp(serverIp)
236
237 }
238
239 def deleteBlock() {
240         def data = request.JSON
241         def blockDNI = blockDNI(data)
242         def block = block(data)
243
244         block?.setDestroyed(true)
245
246
247
248         log.debug "attempting to delete Block ${block?.label} with id $blockDNI"
249         deleteChildDevice(blockDNI)
250 }
251
252 private blockCoordinates(data) {
253         return "(${data?.x},${data?.y},${data?.z})"
254 }
255
256 private blockDNI(data) {
257         "${data.worldSeed}|${data.dimensionName}|${blockCoordinates(data)}".encodeAsMD5()
258 }
259
260 private block(data) {
261         return getChildDevice(blockDNI(data))
262 }
263
264 def installed() {
265         log.debug "Installed with settings: ${settings}"
266
267         initialize()
268 }
269
270 def updated() {
271         log.debug "Updated with settings: ${settings}"
272
273         unsubscribe()
274         initialize()
275 }
276
277 def initialize() {
278         // update all children with serverIp.
279         if (serverIp) {
280                 getChildDevices().each { block ->
281                         block.setServerIp(serverIp)
282                 }
283         }
284
285 }
286
287 public getServerURL() {
288         return "http://${serverIp}:3333"
289 }