Merge pull request #588 from twack/i18n-smartsense-motion-sensor

INTL-289 i18n alignment for smartsense-motion-sensor
This commit is contained in:
Dylan Bijnagte
2016-03-11 11:32:50 -06:00
2 changed files with 171 additions and 128 deletions

View File

@@ -1,13 +1,39 @@
#==============================================================================
# Generated on Wed Feb 24 14:28:26 CST 2016 by dylan # Copyright 2016 SmartThings
'''Adjust temperature by this many degrees'''.ko=몇 도씩 온도를 조절하십시오 #
'''Degrees'''.ko=온도 # Licensed under the Apache License, Version 2.0 (the "License"); you may not
'''Temperature Offset'''.ko=온도 직접 설정 # use this file except in compliance with the License. You may obtain a copy
'''This feature allows you to correct any temperature variations by selecting an offset. Ex: If your sensor consistently reports a temp that's 5 degrees too warm, you'd enter '-5'. If 3 degrees too cold, enter '+3'.'''.ko=기준 온도를 원하는대로 몇 도 올리거나 내려서 설정할 수 있습니다. # 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.
#==============================================================================
# Purpose: SmartSense Motion Sensor i18n Translation File
#
# Filename: SmartSense-Motion-Sensor.src/i18n/messages.properties
#
# Change History:
# 1. 20160116 TW Initial release with formal Korean translation.
# 2. 20160224 TW Updated formal Korean translations from Mike Stoller.
#==============================================================================
# Korean (ko)
# Device Preferences
'''battery'''.ko=배터리 '''battery'''.ko=배터리
'''{{ device.displayName }} battery has too much power: (> 3.5) volts.'''.ko={{ device.displayName }} 배터리 전력이 너무 높습니다(3.5볼트 초과). '''Temperature Offset'''.ko=온도 직접 설정
'''{{ device.displayName }} battery was {{ value }}'''.ko={{ device.displayName }} 배터리가 {{ value }}였습니다 '''This feature allows you to correct any temperature variations by selecting an offset. Ex: If your sensor consistently reports a temp that's 5 degrees too warm, you'd enter '-5'. If 3 degrees too cold, enter '+3'.'''.ko=기준 온도를 원하는대로 몇 도 올리거나 내려서 설정할 수 있습니다.
'''Degrees'''.ko=온도
'''Adjust temperature by this many degrees'''.ko=몇 도씩 온도를 조절하십시오
'''Give your device a name'''.ko=장치 이름을 지정
# Events descriptionText
'''{{ device.displayName }} detected motion'''.ko={{ device.displayName }}가 움직임을 감지하였습니다. '''{{ device.displayName }} detected motion'''.ko={{ device.displayName }}가 움직임을 감지하였습니다.
'''{{ device.displayName }} motion has stopped'''.ko={{ device.displayName }} 동작이 중단되었습니다 '''{{ device.displayName }} motion has stopped'''.ko={{ device.displayName }} 동작이 중단되었습니다
'''{{ device.displayName }} was {{ value }}°C'''.ko={{ device.displayName }}이(가) {{ value }}°C였습니다 '''{{ device.displayName }} was {{ value }}°C'''.ko={{ device.displayName }}이(가) {{ value }}°C였습니다
'''{{ device.displayName }} was {{ value }}°F'''.ko={{ device.displayName }}이(가) {{ value }}°F였습니다 '''{{ device.displayName }} was {{ value }}°F'''.ko={{ device.displayName }}이(가) {{ value }}°F였습니다
'''{{ device.displayName }} battery has too much power: (> 3.5) volts.'''.ko={{ device.displayName }} 배터리 전력이 너무 높습니다(3.5볼트 초과).
'''{{ device.displayName }} battery was {{ value }}'''.ko={{ device.displayName }} 배터리가 {{ value }}였습니다
#==============================================================================

View File

@@ -1,17 +1,27 @@
/** /*
* SmartSense Motion/Temp Sensor ===============================================================================
* Copyright 2016 SmartThings
* *
* Copyright 2014 SmartThings * 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
* Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except * of the License at:
* in compliance with the License. You may obtain a copy of the License at:
* *
* http://www.apache.org/licenses/LICENSE-2.0 * 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 * Unless required by applicable law or agreed to in writing, software
* on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
* for the specific language governing permissions and limitations under the License. * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
* License for the specific language governing permissions and limitations
* under the License.
===============================================================================
* Purpose: SmartSense Motion Sensor DTH File
* *
* Filename: SmartSense-Motion-Sensor.src/SmartSense-Motion-Sensor.groovy
*
* Change History:
* 1. 20160116 TW - Update/Edit to support i18n translations
* 2. 20160125 TW = Incorporated new battery mapping from TM
===============================================================================
*/ */
metadata { metadata {
@@ -19,18 +29,17 @@ metadata {
capability "Motion Sensor" capability "Motion Sensor"
capability "Configuration" capability "Configuration"
capability "Battery" capability "Battery"
capability "Temperature Measurement" capability "Temperature Measurement"
capability "Refresh" capability "Refresh"
command "enrollResponse" command "enrollResponse"
fingerprint inClusters: "0000,0001,0003,0402,0500,0020,0B05", outClusters: "0019", manufacturer: "CentraLite", model: "3305-S" fingerprint inClusters: "0000,0001,0003,0402,0500,0020,0B05", outClusters: "0019", manufacturer: "CentraLite", model: "3305-S"
fingerprint inClusters: "0000,0001,0003,0402,0500,0020,0B05", outClusters: "0019", manufacturer: "CentraLite", model: "3325-S", deviceJoinName: "Motion Sensor" fingerprint inClusters: "0000,0001,0003,0402,0500,0020,0B05", outClusters: "0019", manufacturer: "CentraLite", model: "3325-S", deviceJoinName: "Motion Sensor"
fingerprint inClusters: "0000,0001,0003,0402,0500,0020,0B05", outClusters: "0019", manufacturer: "CentraLite", model: "3305" fingerprint inClusters: "0000,0001,0003,0402,0500,0020,0B05", outClusters: "0019", manufacturer: "CentraLite", model: "3305"
fingerprint inClusters: "0000,0001,0003,0402,0500,0020,0B05", outClusters: "0019", manufacturer: "CentraLite", model: "3325" fingerprint inClusters: "0000,0001,0003,0402,0500,0020,0B05", outClusters: "0019", manufacturer: "CentraLite", model: "3325"
fingerprint inClusters: "0000,0001,0003,0402,0500,0020,0B05", outClusters: "0019", manufacturer: "CentraLite", model: "3326" fingerprint inClusters: "0000,0001,0003,0402,0500,0020,0B05", outClusters: "0019", manufacturer: "CentraLite", model: "3326"
fingerprint inClusters: "0000,0001,0003,0402,0500,0020,0B05", outClusters: "0019", manufacturer: "CentraLite", model: "3326-L", deviceJoinName: "Iris Motion Sensor" fingerprint inClusters: "0000,0001,0003,000F,0020,0402,0500", outClusters: "0019", manufacturer: "SmartThings", model: "motionv4", deviceJoinName: "Motion Sensor"
fingerprint inClusters: "0000,0001,0003,000F,0020,0402,0500", outClusters: "0019", manufacturer: "SmartThings", model: "motionv4", deviceJoinName: "Motion Sensor"
} }
simulator { simulator {
@@ -47,7 +56,7 @@ metadata {
]) ])
} }
section { section {
input title: "Temperature Offset", description: "This feature allows you to correct any temperature variations by selecting an offset. Ex: If your sensor consistently reports a temp that's 5 degrees too warm, you'd enter \"-5\". If 3 degrees too cold, enter \"+3\".", displayDuringSetup: false, type: "paragraph", element: "paragraph" input title: "Temperature Offset", description: "This feature allows you to correct any temperature variations by selecting an offset. Ex: If your sensor consistently reports a temp that's 5 degrees too warm, you'd enter '-5'. If 3 degrees too cold, enter '+3'.", displayDuringSetup: false, type: "paragraph", element: "paragraph"
input "tempOffset", "number", title: "Degrees", description: "Adjust temperature by this many degrees", range: "*..*", displayDuringSetup: false input "tempOffset", "number", title: "Degrees", description: "Adjust temperature by this many degrees", range: "*..*", displayDuringSetup: false
} }
} }
@@ -86,7 +95,7 @@ metadata {
def parse(String description) { def parse(String description) {
log.debug "description: $description" log.debug "description: $description"
Map map = [:] Map map = [:]
if (description?.startsWith('catchall:')) { if (description?.startsWith('catchall:')) {
map = parseCatchAllMessage(description) map = parseCatchAllMessage(description)
@@ -97,55 +106,55 @@ def parse(String description) {
else if (description?.startsWith('temperature: ')) { else if (description?.startsWith('temperature: ')) {
map = parseCustomMessage(description) map = parseCustomMessage(description)
} }
else if (description?.startsWith('zone status')) { else if (description?.startsWith('zone status')) {
map = parseIasMessage(description) map = parseIasMessage(description)
} }
log.debug "Parse returned $map" log.debug "Parse returned $map"
def result = map ? createEvent(map) : null def result = map ? createEvent(map) : null
if (description?.startsWith('enroll request')) { if (description?.startsWith('enroll request')) {
List cmds = enrollResponse() List cmds = enrollResponse()
log.debug "enroll response: ${cmds}" log.debug "enroll response: ${cmds}"
result = cmds?.collect { new physicalgraph.device.HubAction(it) } result = cmds?.collect { new physicalgraph.device.HubAction(it) }
} }
return result return result
} }
private Map parseCatchAllMessage(String description) { private Map parseCatchAllMessage(String description) {
Map resultMap = [:] Map resultMap = [:]
def cluster = zigbee.parse(description) def cluster = zigbee.parse(description)
if (shouldProcessMessage(cluster)) { if (shouldProcessMessage(cluster)) {
switch(cluster.clusterId) { switch(cluster.clusterId) {
case 0x0001: case 0x0001:
resultMap = getBatteryResult(cluster.data.last()) resultMap = getBatteryResult(cluster.data.last())
break break
case 0x0402: case 0x0402:
// temp is last 2 data values. reverse to swap endian // temp is last 2 data values. reverse to swap endian
String temp = cluster.data[-2..-1].reverse().collect { cluster.hex1(it) }.join() String temp = cluster.data[-2..-1].reverse().collect { cluster.hex1(it) }.join()
def value = getTemperature(temp) def value = getTemperature(temp)
resultMap = getTemperatureResult(value) resultMap = getTemperatureResult(value)
break break
case 0x0406: case 0x0406:
log.debug 'motion' log.debug 'motion'
resultMap.name = 'motion' resultMap.name = 'motion'
break break
} }
} }
return resultMap return resultMap
} }
private boolean shouldProcessMessage(cluster) { private boolean shouldProcessMessage(cluster) {
// 0x0B is default response indicating message got through // 0x0B is default response indicating message got through
// 0x07 is bind message // 0x07 is bind message
boolean ignoredMessage = cluster.profileId != 0x0104 || boolean ignoredMessage = cluster.profileId != 0x0104 ||
cluster.command == 0x0B || cluster.command == 0x0B ||
cluster.command == 0x07 || cluster.command == 0x07 ||
(cluster.data.size() > 0 && cluster.data.first() == 0x3e) (cluster.data.size() > 0 && cluster.data.first() == 0x3e)
return !ignoredMessage return !ignoredMessage
} }
private Map parseReportAttributeMessage(String description) { private Map parseReportAttributeMessage(String description) {
@@ -154,7 +163,7 @@ private Map parseReportAttributeMessage(String description) {
map += [(nameAndValue[0].trim()):nameAndValue[1].trim()] map += [(nameAndValue[0].trim()):nameAndValue[1].trim()]
} }
log.debug "Desc Map: $descMap" log.debug "Desc Map: $descMap"
Map resultMap = [:] Map resultMap = [:]
if (descMap.cluster == "0402" && descMap.attrId == "0000") { if (descMap.cluster == "0402" && descMap.attrId == "0000") {
def value = getTemperature(descMap.value) def value = getTemperature(descMap.value)
@@ -163,14 +172,14 @@ private Map parseReportAttributeMessage(String description) {
else if (descMap.cluster == "0001" && descMap.attrId == "0020") { else if (descMap.cluster == "0001" && descMap.attrId == "0020") {
resultMap = getBatteryResult(Integer.parseInt(descMap.value, 16)) resultMap = getBatteryResult(Integer.parseInt(descMap.value, 16))
} }
else if (descMap.cluster == "0406" && descMap.attrId == "0000") { else if (descMap.cluster == "0406" && descMap.attrId == "0000") {
def value = descMap.value.endsWith("01") ? "active" : "inactive" def value = descMap.value.endsWith("01") ? "active" : "inactive"
resultMap = getMotionResult(value) resultMap = getMotionResult(value)
} }
return resultMap return resultMap
} }
private Map parseCustomMessage(String description) { private Map parseCustomMessage(String description) {
Map resultMap = [:] Map resultMap = [:]
if (description?.startsWith('temperature: ')) { if (description?.startsWith('temperature: ')) {
@@ -181,44 +190,44 @@ private Map parseCustomMessage(String description) {
} }
private Map parseIasMessage(String description) { private Map parseIasMessage(String description) {
List parsedMsg = description.split(' ') List parsedMsg = description.split(' ')
String msgCode = parsedMsg[2] String msgCode = parsedMsg[2]
Map resultMap = [:]
switch(msgCode) {
case '0x0020': // Closed/No Motion/Dry
resultMap = getMotionResult('inactive')
break
Map resultMap = [:] case '0x0021': // Open/Motion/Wet
switch(msgCode) { resultMap = getMotionResult('active')
case '0x0020': // Closed/No Motion/Dry break
resultMap = getMotionResult('inactive')
break
case '0x0021': // Open/Motion/Wet case '0x0022': // Tamper Alarm
resultMap = getMotionResult('active') log.debug 'motion with tamper alarm'
break resultMap = getMotionResult('active')
break
case '0x0022': // Tamper Alarm case '0x0023': // Battery Alarm
log.debug 'motion with tamper alarm' break
resultMap = getMotionResult('active')
break
case '0x0023': // Battery Alarm case '0x0024': // Supervision Report
break log.debug 'no motion with tamper alarm'
resultMap = getMotionResult('inactive')
break
case '0x0024': // Supervision Report case '0x0025': // Restore Report
log.debug 'no motion with tamper alarm' break
resultMap = getMotionResult('inactive')
break
case '0x0025': // Restore Report case '0x0026': // Trouble/Failure
break log.debug 'motion with failure alarm'
resultMap = getMotionResult('active')
break
case '0x0026': // Trouble/Failure case '0x0028': // Test Mode
log.debug 'motion with failure alarm' break
resultMap = getMotionResult('active') }
break return resultMap
case '0x0028': // Test Mode
break
}
return resultMap
} }
def getTemperature(value) { def getTemperature(value) {
@@ -236,7 +245,8 @@ private Map getBatteryResult(rawValue) {
def result = [ def result = [
name: 'battery', name: 'battery',
value: '--' value: '--',
translatable: true
] ]
def volts = rawValue / 10 def volts = rawValue / 10
@@ -244,10 +254,10 @@ private Map getBatteryResult(rawValue) {
if (rawValue == 0 || rawValue == 255) {} if (rawValue == 0 || rawValue == 255) {}
else { else {
if (volts > 3.5) { if (volts > 3.5) {
result.descriptionText = "${linkText} battery has too much power (${volts} volts)." result.descriptionText = "{{ device.displayName }} battery has too much power: (> 3.5) volts."
} }
else { else {
if (device.getDataValue("manufacturer") == "SmartThings") { if (device.getDataValue("manufacturer") == "SmartThings") {
volts = rawValue // For the batteryMap to work the key needs to be an int volts = rawValue // For the batteryMap to work the key needs to be an int
def batteryMap = [28:100, 27:100, 26:100, 25:90, 24:90, 23:70, def batteryMap = [28:100, 27:100, 26:100, 25:90, 24:90, 23:70,
22:70, 21:50, 20:50, 19:30, 18:30, 17:15, 16:1, 15:0] 22:70, 21:50, 20:50, 19:30, 18:30, 17:15, 16:1, 15:0]
@@ -261,7 +271,8 @@ private Map getBatteryResult(rawValue) {
def pct = batteryMap[volts] def pct = batteryMap[volts]
if (pct != null) { if (pct != null) {
result.value = pct result.value = pct
result.descriptionText = "${linkText} battery was ${result.value}%" def value = pct
result.descriptionText = "{{ device.displayName }} battery was {{ value }}"
} }
} }
else { else {
@@ -269,7 +280,7 @@ private Map getBatteryResult(rawValue) {
def maxVolts = 3.0 def maxVolts = 3.0
def pct = (volts - minVolts) / (maxVolts - minVolts) def pct = (volts - minVolts) / (maxVolts - minVolts)
result.value = Math.min(100, (int) pct * 100) result.value = Math.min(100, (int) pct * 100)
result.descriptionText = "${linkText} battery was ${result.value}%" result.descriptionText = "{{ device.displayName }} battery was {{ value }}"
} }
} }
} }
@@ -279,33 +290,39 @@ private Map getBatteryResult(rawValue) {
private Map getTemperatureResult(value) { private Map getTemperatureResult(value) {
log.debug 'TEMP' log.debug 'TEMP'
def linkText = getLinkText(device)
if (tempOffset) { if (tempOffset) {
def offset = tempOffset as int def offset = tempOffset as int
def v = value as int def v = value as int
value = v + offset value = v + offset
} }
def descriptionText = "${linkText} was ${value}°${temperatureScale}" def descriptionText
if ( temperatureScale == 'C' )
descriptionText = '{{ device.displayName }} was {{ value }}°C'
else
descriptionText = '{{ device.displayName }} was {{ value }}°F'
return [ return [
name: 'temperature', name: 'temperature',
value: value, value: value,
descriptionText: descriptionText descriptionText: descriptionText,
translatable: true
] ]
} }
private Map getMotionResult(value) { private Map getMotionResult(value) {
log.debug 'motion' log.debug 'motion'
String linkText = getLinkText(device) String descriptionText = value == 'active' ? "{{ device.displayName }} detected motion" : "{{ device.displayName }} motion has stopped"
String descriptionText = value == 'active' ? "${linkText} detected motion" : "${linkText} motion has stopped" //String descriptionText = '{{ device.displayName }} is {{ value | translate }}'
return [ return [
name: 'motion', name: 'motion',
value: value, value: value,
descriptionText: descriptionText descriptionText: descriptionText,
translatable: true
] ]
} }
def refresh() { def refresh() {
log.debug "refresh called" log.debug "refresh executed"
def refreshCmds = [ def refreshCmds = [
"st rattr 0x${device.deviceNetworkId} 1 0x402 0", "delay 200", "st rattr 0x${device.deviceNetworkId} 1 0x402 0", "delay 200",
"st rattr 0x${device.deviceNetworkId} 1 1 0x20", "delay 200" "st rattr 0x${device.deviceNetworkId} 1 1 0x20", "delay 200"
@@ -355,19 +372,19 @@ private hex(value) {
} }
private String swapEndianHex(String hex) { private String swapEndianHex(String hex) {
reverseArray(hex.decodeHex()).encodeHex() reverseArray(hex.decodeHex()).encodeHex()
} }
private byte[] reverseArray(byte[] array) { private byte[] reverseArray(byte[] array) {
int i = 0; int i = 0;
int j = array.length - 1; int j = array.length - 1;
byte tmp; byte tmp;
while (j > i) { while (j > i) {
tmp = array[j]; tmp = array[j];
array[j] = array[i]; array[j] = array[i];
array[i] = tmp; array[i] = tmp;
j--; j--;
i++; i++;
} }
return array return array
} }