Code by Scott שאול בן ישוע
Join API Driver.groovy 6.64 KB
Newer Older
1
2
3
4
5
6
7
8
9
10
11
12
13
14
/**
*  Join API Device
*
*
*  Copyright 2018 Stephan Hackett
*
*  Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except
*  in compliance with the License. You may obtain a copy of the License at:
*
*      http://www.apache.org/licenses/LICENSE-2.0
*
*  Unless required by applicable law or agreed to in writing, software distributed under the License is distributed
*  on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License
*  for the specific language governing permissions and limitations under the License.
Stephan Hackett's avatar
Stephan Hackett committed
15
* 		
16
17
*
*/
Stephan Hackett's avatar
Stephan Hackett committed
18

19
def version() {"v1.0.20190603b"}
20
21

preferences {
Stephan Hackett's avatar
Stephan Hackett committed
22
    input("apiKey", "text", title: "Join API Key:", description: "")
23
24
25
    if(getValidated()){
  		input("deviceName", "enum", title: "Select Device:", description: "", multiple: true, required: false, options: getValidated("deviceList"))
        input("myTitle", "text", title: "Notification Title:", description: "")
Stephan Hackett's avatar
Stephan Hackett committed
26
27
28
29
30
31
32
33
		input("myImage", "text", title: "Icon URI:", description: "(Image to be displayed in notification as well as status bar)")
  		input("url", "text", title: "URL:", description: "(URL to be opened when Notification is clicked)")
		input("sound", "text", title: "Sound URI:", description: "(URL of notification sound to be played)")
		input("image", "text", title: "Image URI:", description: "(URL of image to be displayed in the notification body)")
		input("myApp", "text", title: "Open App by Name:", description: "(Name of Android app to open)")
		input("myPackage", "text", title: "Open App by Package:", description: "(Name of Android Package to open)")
		input("smsnumber", "number", title: "Phone # to send SMS text TO:", description: "(Text will be sent FROM the Join Device selected above)")
		input("action", "text", title: "Actions for Notification:", description: "(separate multiple actions with commas)")
34
35
		input("logEnable", "bool", title: "Enable Debug Logging?:", required: true)

36
37
38
39
    }
}

metadata {
Stephan Hackett's avatar
Stephan Hackett committed
40
  	definition (name: "Join API Device", namespace: "stephack", author: "Stephan Hackett", importUrl: "https://raw.githubusercontent.com/stephack/Hubitat/master/drivers/Join%20API%20Driver/Join%20API%20Driver.groovy") {
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
    	capability "Notification"
    	capability "Actuator"
    	capability "Speech Synthesis"
  	}
}

def installed() {
 	initialize()
}

def updated() {
 	initialize()   
}

def initialize() {
    state.version = version()
Stephan Hackett's avatar
Stephan Hackett committed
57
58
	state.devices = deviceName

59
60
61
}

def getValidated(type){
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
	if(apiKey){
		if(type=="deviceList" && logEnable){log.debug "Generating Device List..."}
		else if(logEnable) log.debug "Validating Key..."

		def validated = false

		def params = [
			uri: "https://joinjoaomgcd.appspot.com/_ah/api/registration/v1/listDevices?apikey=${apiKey}",
		]
		if(logEnable) log.debug "Validation params: ${params}"

		if ((apiKey =~ /[A-Za-z0-9]{30}/)) {
			try{
				httpGet(params){response ->
					if(response.status != 200) {
						log.error "Received HTTP error ${response.status}. Check your keys!"
					}
					else {
						if(type=="deviceList"){
							if(logEnable) log.debug "Device list generated"
							deviceOptions = response.data.records.deviceName
							if(logEnable) log.debug "Device List: ${deviceOptions}"
						}
						else {
							if(logEnable) log.debug "Keys validated"
							validated = true
						}
					}
				}
			}
			catch (Exception e) {
				log.error "An invalid key was probably entered. Join API Server Returned: ${e}"
			} 
		}
		else {
			log.error "API key '${apiKey}' is not properly formatted!"
		}
		if(type=="deviceList") return deviceOptions
		return validated
	}
102
103
104
}

def speak(message) {
105
    if (deviceName) { log.info "Sending Speech Request: ${message} to Device: $deviceName"}
Stephan Hackett's avatar
Stephan Hackett committed
106
107
108
109
110
111
112
113
114
115
116
117
118
119

    def apiUri =  "https://joinjoaomgcd.appspot.com/_ah/api/messaging/v1/sendPush?apikey=${apiKey}"
    def apiParams = ""
	
	if(deviceName && deviceName instanceof List) {
		deviceName = deviceName.join(',')
	}
	
    if(deviceName) apiParams += "&deviceNames=" + URLEncoder.encode(deviceName, "UTF-8")
    if(message) apiParams += "&say=" + URLEncoder.encode(message, "UTF-8")
    
    def params = [
        uri: apiUri + apiParams,
    ]
120
	if(logEnable) log.debug "Speak params: ${params}"
Stephan Hackett's avatar
Stephan Hackett committed
121
122
123
124
125
126
127
  	
    if ((apiKey =~ /[A-Za-z0-9]{30}/)) {
    	httpGet(params){response ->
      		if(response.status != 200) {
        		log.error "Received HTTP error ${response.status}. Check your keys!"
      		}
      		else {
128
        		if(logEnable) log.debug "Message Received by Join API Server"
Stephan Hackett's avatar
Stephan Hackett committed
129
130
131
132
133
134
      		}
    	}
  	}
  	else {
    	log.error "API key '${apiKey}' is not properly formatted!"
    }
135
136
137
}

def deviceNotification(message) {
138
139
140
141
142
143
144
145
	def actionInline = ""
	if(message.contains("[A]")) {
		def multiMessage = message.split("\\[A\\]")
		message = multiMessage[0]
		actionInline = multiMessage[1]
	}
	   
	if (deviceName) { log.info "Sending Message: ${message} to Device: $deviceName"}
146
147
148

    def apiUri =  "https://joinjoaomgcd.appspot.com/_ah/api/messaging/v1/sendPush?apikey=${apiKey}"
    def apiParams = ""
Stephan Hackett's avatar
Stephan Hackett committed
149
150
151
152
153
154
	
	if(deviceName && deviceName instanceof List) {
		deviceName = deviceName.join(',')
	}
	
	if(deviceName) apiParams += "&deviceNames=${deviceName}"
155
156
    if(myTitle) apiParams += "&title=" + URLEncoder.encode(myTitle, "UTF-8")
    if(message) apiParams += "&text=" + URLEncoder.encode(message, "UTF-8")
157
    if(myImage) apiParams += "&smallicon=" + URLEncoder.encode(myImage, "UTF-8")
158
    if(url) apiParams += "&url=" + URLEncoder.encode(url, "UTF-8")
Stephan Hackett's avatar
Stephan Hackett committed
159
160
161
162
163
	
	if(sound) apiParams += "&sound=" + URLEncoder.encode(sound, "UTF-8")
    if(image) apiParams += "&image=" + URLEncoder.encode(image, "UTF-8")
    if(myApp) apiParams += "&app=" + URLEncoder.encode(myApp, "UTF-8")
	if(myPackage) apiParams += "&appPackage=" + URLEncoder.encode(myPackage, "UTF-8")
Stephan Hackett's avatar
Stephan Hackett committed
164
	if(smsnumber) apiParams += "&smsnumber=" + smsnumber + "&smstext=" + URLEncoder.encode(message, "UTF-8")
Stephan Hackett's avatar
Stephan Hackett committed
165
	
166
167
168
169
170
171
172
	//Inline action overide actions listed in the preferences
	if(actionInline != ""){
		if(logEnable) log.debug "Inline actions found. Over-riding driver preferences."
		action = actionInline.replace(",", "|||")
		apiParams += "&actions=" + URLEncoder.encode(action, "UTF-8")
	}	   
	else if(action){
Stephan Hackett's avatar
Stephan Hackett committed
173
174
175
		action = action.replace(",", "|||")
		apiParams += "&actions=" + URLEncoder.encode(action, "UTF-8")
	}
176
177
178
179
    
    def params = [
        uri: apiUri + apiParams,
    ]
180
    if(logEnable) log.debug params
181
182
183
184
185
186
187
  	
    if ((apiKey =~ /[A-Za-z0-9]{30}/)) {
    	httpGet(params){response ->
      		if(response.status != 200) {
        		log.error "Received HTTP error ${response.status}. Check your keys!"
      		}
      		else {
188
        		if(logEnable) log.debug "Message Received by Join API Server"
189
190
191
192
193
194
195
      		}
    	}
  	}
  	else {
    	log.error "API key '${apiKey}' is not properly formatted!"
    }
}