mirror of
https://github.com/mtan93/SmartThingsPublic.git
synced 2026-03-21 13:10:51 +00:00
Merge branch 'master' of github.com:SmartThingsCommunity/SmartThingsPublic
# By Juan Pablo Risso (3) and others # Via Kris Schaller (24) and others * 'master' of github.com:SmartThingsCommunity/SmartThingsPublic: PROB-870 - Harmony fails to save credentials add missing translations add event translation Removed canInstallLabs() remove segmented style input to prevent iOS crash PROB-537 - Fix error in line 335 MSA-68: Spruce Irrigation controller and soil moisture sensors. # This is a combination of 3 commits. # The first commit's message is: MSA-68: Spruce Irrigation controller and soil moisture sensors. DVCSMP-1480 Fixed ArrayIndexOutOfBoundsException Convert closure to method Revert "Convert closure to method" Closure was causing sandbox issues locally Bugfixes for codeReports Fix Homeseer Multi Instance encap parse PROB-398 Merge pull request #135 from kwarodom/fibaroSmokeSensor
This commit is contained in:
@@ -201,8 +201,8 @@ def completionPage() {
|
||||
|
||||
section("Switches") {
|
||||
input(name: "completionSwitches", type: "capability.switch", title: "Set these switches", description: null, required: false, multiple: true, submitOnChange: true)
|
||||
if (completionSwitches || androidClient()) {
|
||||
input(name: "completionSwitchesState", type: "enum", title: "To", description: null, required: false, multiple: false, options: ["on", "off"], style: "segmented", defaultValue: "on")
|
||||
if (completionSwitches) {
|
||||
input(name: "completionSwitchesState", type: "enum", title: "To", description: null, required: false, multiple: false, options: ["on", "off"], defaultValue: "on")
|
||||
input(name: "completionSwitchesLevel", type: "number", title: "Optionally, Set Dimmer Levels To", description: null, required: false, multiple: false, range: "(0..99)")
|
||||
}
|
||||
}
|
||||
|
||||
@@ -35,23 +35,11 @@ preferences {
|
||||
}
|
||||
|
||||
def mainPage() {
|
||||
if(canInstallLabs()) {
|
||||
def bridges = bridgesDiscovered()
|
||||
if (state.username && bridges) {
|
||||
return bulbDiscovery()
|
||||
} else {
|
||||
return bridgeDiscovery()
|
||||
}
|
||||
def bridges = bridgesDiscovered()
|
||||
if (state.username && bridges) {
|
||||
return bulbDiscovery()
|
||||
} else {
|
||||
def upgradeNeeded = """To use SmartThings Labs, your Hub should be completely up to date.
|
||||
|
||||
To update your Hub, access Location Settings in the Main Menu (tap the gear next to your location name), select your Hub, and choose "Update Hub"."""
|
||||
|
||||
return dynamicPage(name:"bridgeDiscovery", title:"Upgrade needed!", nextPage:"", install:false, uninstall: true) {
|
||||
section("Upgrade") {
|
||||
paragraph "$upgradeNeeded"
|
||||
}
|
||||
}
|
||||
return bridgeDiscovery()
|
||||
}
|
||||
}
|
||||
|
||||
@@ -326,6 +314,7 @@ def addBulbs() {
|
||||
d = addChildDevice("smartthings", "Hue Bulb", dni, newHueBulb?.value.hub, ["label":newHueBulb?.value.name])
|
||||
}
|
||||
log.debug "created ${d.displayName} with id $dni"
|
||||
d.refresh()
|
||||
} else {
|
||||
log.debug "$dni in not longer paired to the Hue Bridge or ID changed"
|
||||
}
|
||||
@@ -333,8 +322,8 @@ def addBulbs() {
|
||||
//backwards compatable
|
||||
newHueBulb = bulbs.find { (app.id + "/" + it.id) == dni }
|
||||
d = addChildDevice("smartthings", "Hue Bulb", dni, newHueBulb?.hub, ["label":newHueBulb?.name])
|
||||
d.refresh()
|
||||
}
|
||||
d.refresh()
|
||||
} else {
|
||||
log.debug "found ${d.displayName} with id $dni already exists, type: '$d.typeName'"
|
||||
if (bulbs instanceof java.util.Map) {
|
||||
@@ -764,14 +753,10 @@ private String convertHexToIP(hex) {
|
||||
[convertHexToInt(hex[0..1]),convertHexToInt(hex[2..3]),convertHexToInt(hex[4..5]),convertHexToInt(hex[6..7])].join(".")
|
||||
}
|
||||
|
||||
private Boolean canInstallLabs() {
|
||||
return hasAllHubsOver("000.011.00603")
|
||||
}
|
||||
|
||||
private Boolean hasAllHubsOver(String desiredFirmware) {
|
||||
return realHubFirmwareVersions.every { fw -> fw >= desiredFirmware }
|
||||
}
|
||||
|
||||
private List getRealHubFirmwareVersions() {
|
||||
return location.hubs*.firmwareVersionString.findAll { it }
|
||||
}
|
||||
}
|
||||
|
||||
@@ -419,9 +419,11 @@ def addDevice() {
|
||||
def d = getChildDevice(dni)
|
||||
if(!d) {
|
||||
def newAction = state.HarmonyActivities.find { it.key == dni }
|
||||
d = addChildDevice("smartthings", "Harmony Activity", dni, null, [label:"${newAction.value} [Harmony Activity]"])
|
||||
log.trace "created ${d.displayName} with id $dni"
|
||||
poll()
|
||||
if (newAction) {
|
||||
d = addChildDevice("smartthings", "Harmony Activity", dni, null, [label:"${newAction.value} [Harmony Activity]"])
|
||||
log.trace "created ${d.displayName} with id $dni"
|
||||
poll()
|
||||
}
|
||||
} else {
|
||||
log.trace "found ${d.displayName} with id $dni already exists"
|
||||
}
|
||||
|
||||
@@ -0,0 +1,31 @@
|
||||
'''Acceleration Detected'''.ko=가속화 감지됨
|
||||
'''Arrival Of'''.ko=도착
|
||||
'''Both Push and SMS?'''.ko=푸시 메시지와 SMS를 모두 사용하시겠습니까?
|
||||
'''Button Pushed'''.ko=버튼이 눌렸습니다
|
||||
'''Contact Closes'''.ko=접점 닫힘
|
||||
'''Contact Opens'''.ko=접점 열림
|
||||
'''Departure Of'''.ko=출발
|
||||
'''Message Text'''.ko=문자 메시지
|
||||
'''Minutes'''.ko=분
|
||||
'''Motion Here'''.ko=동작
|
||||
'''Phone Number (for SMS, optional)'''.ko=휴대전화 번호(문자 메시지 - 옵션)
|
||||
'''Receive notifications when anything happens in your home.'''.ko=집 안에 무슨 일이 일어나면 알림이 전송됩니다.
|
||||
'''Smoke Detected'''.ko=연기가 감지되었습니다
|
||||
'''Switch Turned Off'''.ko=스위치 꺼짐
|
||||
'''Switch Turned On'''.ko=스위치 꺼짐
|
||||
'''Choose one or more, when...'''.ko=다음의 경우 하나 이상 선택
|
||||
'''Yes'''.ko=예
|
||||
'''No'''.ko=아니요
|
||||
'''Send this message (optional, sends standard status message if not specified)'''.ko=이 메시지 전송(선택적, 지정되지 않은 경우 표준 상태 메시지를 보냅니다)
|
||||
'''Via a push notification and/or an SMS message'''.ko=푸시 알림 및/또는 문자 메시지를 통해
|
||||
'''Set for specific mode(s)'''.ko=특정 모드 설정
|
||||
'''Tap to set'''.ko=눌러서 설정
|
||||
'''Minimum time between messages (optional, defaults to every message)'''.ko=메시지작 간 최소 시간(선택 사항, 모든 메시지의 기본 설정)
|
||||
'''If outside the US please make sure to enter the proper country code'''.ko=미국 이외 거주자는 적절한 국가 코드를 입력했는지 확인하십시오
|
||||
'''Water Sensor Wet'''.ko=Water Sensor에서 물이 감지되었습니다
|
||||
'''{{ triggerEvent.linkText }} has arrived at the {{ location.name }}'''.ko={{ triggerEvent.linkText }}님이 {{ location.name }}에 도착했습니다
|
||||
'''{{ triggerEvent.linkText }} has arrived at {{ location.name }}'''.ko={{ triggerEvent.linkText }}님이 {{ location.name }}에 도착했습니다
|
||||
'''{{ triggerEvent.linkText }} has left the {{ location.name }}'''.ko={{ triggerEvent.linkText }}님이 {{ location.name }}을(를) 떠났습니다
|
||||
'''{{ triggerEvent.linkText }} has left {{ location.name }}'''.ko={{ triggerEvent.linkText }}님이 {{ location.name }}을(를) 떠났습니다
|
||||
'''Assign a name'''.ko=이름 배정
|
||||
'''Choose Modes'''.ko=모드 선택
|
||||
@@ -20,19 +20,19 @@
|
||||
* 2014-10-03: Added capability.button device picker and button.pushed event subscription. For Doorbell.
|
||||
*/
|
||||
definition(
|
||||
name: "Notify Me When",
|
||||
namespace: "smartthings",
|
||||
author: "SmartThings",
|
||||
description: "Receive notifications when anything happens in your home.",
|
||||
category: "Convenience",
|
||||
iconUrl: "https://s3.amazonaws.com/smartapp-icons/Meta/window_contact.png",
|
||||
iconX2Url: "https://s3.amazonaws.com/smartapp-icons/Meta/window_contact@2x.png"
|
||||
name: "Notify Me When",
|
||||
namespace: "smartthings",
|
||||
author: "SmartThings",
|
||||
description: "Receive notifications when anything happens in your home.",
|
||||
category: "Convenience",
|
||||
iconUrl: "https://s3.amazonaws.com/smartapp-icons/Meta/window_contact.png",
|
||||
iconX2Url: "https://s3.amazonaws.com/smartapp-icons/Meta/window_contact@2x.png"
|
||||
)
|
||||
|
||||
preferences {
|
||||
section("Choose one or more, when..."){
|
||||
input "button", "capability.button", title: "Button Pushed", required: false, multiple: true //tw
|
||||
input "motion", "capability.motionSensor", title: "Motion Here", required: false, multiple: true
|
||||
input "motion", "capability.motionSensor", title: "Motion Here", required: false, multiple: true
|
||||
input "contact", "capability.contactSensor", title: "Contact Opens", required: false, multiple: true
|
||||
input "contactClosed", "capability.contactSensor", title: "Contact Closes", required: false, multiple: true
|
||||
input "acceleration", "capability.accelerationSensor", title: "Acceleration Detected", required: false, multiple: true
|
||||
@@ -47,11 +47,11 @@ preferences {
|
||||
input "messageText", "text", title: "Message Text", required: false
|
||||
}
|
||||
section("Via a push notification and/or an SMS message"){
|
||||
input("recipients", "contact", title: "Send notifications to") {
|
||||
input "phone", "phone", title: "Phone Number (for SMS, optional)", required: false
|
||||
paragraph "If outside the US please make sure to enter the proper country code"
|
||||
input "pushAndPhone", "enum", title: "Both Push and SMS?", required: false, options: ["Yes", "No"]
|
||||
}
|
||||
input("recipients", "contact", title: "Send notifications to") {
|
||||
input "phone", "phone", title: "Phone Number (for SMS, optional)", required: false
|
||||
paragraph "If outside the US please make sure to enter the proper country code"
|
||||
input "pushAndPhone", "enum", title: "Both Push and SMS?", required: false, options: ["Yes", "No"]
|
||||
}
|
||||
}
|
||||
section("Minimum time between messages (optional, defaults to every message)") {
|
||||
input "frequency", "decimal", title: "Minutes", required: false
|
||||
@@ -71,7 +71,7 @@ def updated() {
|
||||
|
||||
def subscribeToEvents() {
|
||||
subscribe(button, "button.pushed", eventHandler) //tw
|
||||
subscribe(contact, "contact.open", eventHandler)
|
||||
subscribe(contact, "contact.open", eventHandler)
|
||||
subscribe(contactClosed, "contact.closed", eventHandler)
|
||||
subscribe(acceleration, "acceleration.active", eventHandler)
|
||||
subscribe(motion, "motion.active", eventHandler)
|
||||
@@ -99,49 +99,55 @@ def eventHandler(evt) {
|
||||
}
|
||||
|
||||
private sendMessage(evt) {
|
||||
def msg = messageText ?: defaultText(evt)
|
||||
String msg = messageText
|
||||
Map options = [:]
|
||||
|
||||
if (!messageText) {
|
||||
msg = defaultText(evt)
|
||||
options = [translatable: true, triggerEvent: evt]
|
||||
}
|
||||
log.debug "$evt.name:$evt.value, pushAndPhone:$pushAndPhone, '$msg'"
|
||||
|
||||
if (location.contactBookEnabled) {
|
||||
sendNotificationToContacts(msg, recipients)
|
||||
}
|
||||
else {
|
||||
if (location.contactBookEnabled) {
|
||||
sendNotificationToContacts(msg, recipients, options)
|
||||
} else {
|
||||
if (!phone || pushAndPhone != 'No') {
|
||||
log.debug 'sending push'
|
||||
options.method = 'push'
|
||||
//sendPush(msg)
|
||||
}
|
||||
if (phone) {
|
||||
options.phone = phone
|
||||
log.debug 'sending SMS'
|
||||
//sendSms(phone, msg)
|
||||
}
|
||||
sendNotification(msg, options)
|
||||
}
|
||||
|
||||
if (!phone || pushAndPhone != "No") {
|
||||
log.debug "sending push"
|
||||
sendPush(msg)
|
||||
}
|
||||
if (phone) {
|
||||
log.debug "sending SMS"
|
||||
sendSms(phone, msg)
|
||||
}
|
||||
}
|
||||
if (frequency) {
|
||||
state[evt.deviceId] = now()
|
||||
}
|
||||
}
|
||||
|
||||
private defaultText(evt) {
|
||||
if (evt.name == "presence") {
|
||||
if (evt.value == "present") {
|
||||
if (evt.name == 'presence') {
|
||||
if (evt.value == 'present') {
|
||||
if (includeArticle) {
|
||||
"$evt.linkText has arrived at the $location.name"
|
||||
'{{ triggerEvent.linkText }} has arrived at the {{ location.name }}'
|
||||
}
|
||||
else {
|
||||
"$evt.linkText has arrived at $location.name"
|
||||
'{{ triggerEvent.linkText }} has arrived at {{ location.name }}'
|
||||
}
|
||||
}
|
||||
else {
|
||||
} else {
|
||||
if (includeArticle) {
|
||||
"$evt.linkText has left the $location.name"
|
||||
'{{ triggerEvent.linkText }} has left the {{ location.name }}'
|
||||
}
|
||||
else {
|
||||
"$evt.linkText has left $location.name"
|
||||
'{{ triggerEvent.linkText }} has left {{ location.name }}'
|
||||
}
|
||||
}
|
||||
}
|
||||
else {
|
||||
evt.descriptionText
|
||||
} else {
|
||||
'{{ triggerEvent.descriptionText }}'
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -316,60 +316,40 @@ private def parseEventMessage(String description) {
|
||||
parts.each { part ->
|
||||
part = part.trim()
|
||||
if (part.startsWith('devicetype:')) {
|
||||
def valueString = part.split(":")[1].trim()
|
||||
event.devicetype = valueString
|
||||
part -= "devicetype:"
|
||||
event.devicetype = part.trim()
|
||||
}
|
||||
else if (part.startsWith('mac:')) {
|
||||
def valueString = part.split(":")[1].trim()
|
||||
if (valueString) {
|
||||
event.mac = valueString
|
||||
}
|
||||
part -= "mac:"
|
||||
event.mac = part.trim()
|
||||
}
|
||||
else if (part.startsWith('networkAddress:')) {
|
||||
def valueString = part.split(":")[1].trim()
|
||||
if (valueString) {
|
||||
event.ip = valueString
|
||||
}
|
||||
part -= "networkAddress:"
|
||||
event.ip = part.trim()
|
||||
}
|
||||
else if (part.startsWith('deviceAddress:')) {
|
||||
def valueString = part.split(":")[1].trim()
|
||||
if (valueString) {
|
||||
event.port = valueString
|
||||
}
|
||||
part -= "deviceAddress:"
|
||||
event.port = part.trim()
|
||||
}
|
||||
else if (part.startsWith('ssdpPath:')) {
|
||||
def valueString = part.split(":")[1].trim()
|
||||
if (valueString) {
|
||||
event.ssdpPath = valueString
|
||||
}
|
||||
part -= "ssdpPath:"
|
||||
event.ssdpPath = part.trim()
|
||||
}
|
||||
else if (part.startsWith('ssdpUSN:')) {
|
||||
part -= "ssdpUSN:"
|
||||
def valueString = part.trim()
|
||||
if (valueString) {
|
||||
event.ssdpUSN = valueString
|
||||
}
|
||||
event.ssdpUSN = part.trim()
|
||||
}
|
||||
else if (part.startsWith('ssdpTerm:')) {
|
||||
part -= "ssdpTerm:"
|
||||
def valueString = part.trim()
|
||||
if (valueString) {
|
||||
event.ssdpTerm = valueString
|
||||
}
|
||||
event.ssdpTerm = part.trim()
|
||||
}
|
||||
else if (part.startsWith('headers')) {
|
||||
part -= "headers:"
|
||||
def valueString = part.trim()
|
||||
if (valueString) {
|
||||
event.headers = valueString
|
||||
}
|
||||
event.headers = part.trim()
|
||||
}
|
||||
else if (part.startsWith('body')) {
|
||||
part -= "body:"
|
||||
def valueString = part.trim()
|
||||
if (valueString) {
|
||||
event.body = valueString
|
||||
}
|
||||
event.body = part.trim()
|
||||
}
|
||||
}
|
||||
event
|
||||
|
||||
@@ -473,68 +473,48 @@ private def parseXmlBody(def body) {
|
||||
}
|
||||
|
||||
private def parseDiscoveryMessage(String description) {
|
||||
def device = [:]
|
||||
def event = [:]
|
||||
def parts = description.split(',')
|
||||
parts.each { part ->
|
||||
part = part.trim()
|
||||
if (part.startsWith('devicetype:')) {
|
||||
def valueString = part.split(":")[1].trim()
|
||||
device.devicetype = valueString
|
||||
part -= "devicetype:"
|
||||
event.devicetype = part.trim()
|
||||
}
|
||||
else if (part.startsWith('mac:')) {
|
||||
def valueString = part.split(":")[1].trim()
|
||||
if (valueString) {
|
||||
device.mac = valueString
|
||||
}
|
||||
part -= "mac:"
|
||||
event.mac = part.trim()
|
||||
}
|
||||
else if (part.startsWith('networkAddress:')) {
|
||||
def valueString = part.split(":")[1].trim()
|
||||
if (valueString) {
|
||||
device.ip = valueString
|
||||
}
|
||||
part -= "networkAddress:"
|
||||
event.ip = part.trim()
|
||||
}
|
||||
else if (part.startsWith('deviceAddress:')) {
|
||||
def valueString = part.split(":")[1].trim()
|
||||
if (valueString) {
|
||||
device.port = valueString
|
||||
}
|
||||
part -= "deviceAddress:"
|
||||
event.port = part.trim()
|
||||
}
|
||||
else if (part.startsWith('ssdpPath:')) {
|
||||
def valueString = part.split(":")[1].trim()
|
||||
if (valueString) {
|
||||
device.ssdpPath = valueString
|
||||
}
|
||||
part -= "ssdpPath:"
|
||||
event.ssdpPath = part.trim()
|
||||
}
|
||||
else if (part.startsWith('ssdpUSN:')) {
|
||||
part -= "ssdpUSN:"
|
||||
def valueString = part.trim()
|
||||
if (valueString) {
|
||||
device.ssdpUSN = valueString
|
||||
}
|
||||
event.ssdpUSN = part.trim()
|
||||
}
|
||||
else if (part.startsWith('ssdpTerm:')) {
|
||||
part -= "ssdpTerm:"
|
||||
def valueString = part.trim()
|
||||
if (valueString) {
|
||||
device.ssdpTerm = valueString
|
||||
}
|
||||
event.ssdpTerm = part.trim()
|
||||
}
|
||||
else if (part.startsWith('headers')) {
|
||||
part -= "headers:"
|
||||
def valueString = part.trim()
|
||||
if (valueString) {
|
||||
device.headers = valueString
|
||||
}
|
||||
event.headers = part.trim()
|
||||
}
|
||||
else if (part.startsWith('body')) {
|
||||
part -= "body:"
|
||||
def valueString = part.trim()
|
||||
if (valueString) {
|
||||
device.body = valueString
|
||||
}
|
||||
event.body = part.trim()
|
||||
}
|
||||
}
|
||||
device
|
||||
event
|
||||
}
|
||||
|
||||
def doDeviceSync(){
|
||||
|
||||
Reference in New Issue
Block a user