From 7fdb99524e1dd797e3866c7118c3fc3eedbfb05c Mon Sep 17 00:00:00 2001 From: twack Date: Sat, 5 Mar 2016 23:15:21 -0800 Subject: [PATCH] i18n alignment for smartsense-motion-sensor --- .../i18n/messages.properties | 42 ++- .../smartsense-motion-sensor.groovy | 257 ++++++++++-------- 2 files changed, 171 insertions(+), 128 deletions(-) diff --git a/devicetypes/smartthings/smartsense-motion-sensor.src/i18n/messages.properties b/devicetypes/smartthings/smartsense-motion-sensor.src/i18n/messages.properties index f1b7c52..c28062b 100644 --- a/devicetypes/smartthings/smartsense-motion-sensor.src/i18n/messages.properties +++ b/devicetypes/smartthings/smartsense-motion-sensor.src/i18n/messages.properties @@ -1,13 +1,39 @@ - -# Generated on Wed Feb 24 14:28:26 CST 2016 by dylan -'''Adjust temperature by this many degrees'''.ko=몇 도씩 온도를 조절하십시오 -'''Degrees'''.ko=온도 -'''Temperature Offset'''.ko=온도 직접 설정 -'''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=기준 온도를 원하는대로 몇 도 올리거나 내려서 설정할 수 있습니다. +#============================================================================== +# Copyright 2016 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 +# 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=배터리 -'''{{ device.displayName }} battery has too much power: (> 3.5) volts.'''.ko={{ device.displayName }} 배터리 전력이 너무 높습니다(3.5볼트 초과). -'''{{ device.displayName }} battery was {{ value }}'''.ko={{ device.displayName }} 배터리가 {{ value }}였습니다 +'''Temperature Offset'''.ko=온도 직접 설정 +'''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 }} motion has stopped'''.ko={{ device.displayName }} 동작이 중단되었습니다 '''{{ device.displayName }} was {{ value }}°C'''.ko={{ device.displayName }}이(가) {{ value }}°C였습니다 '''{{ 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 }}였습니다 +#============================================================================== \ No newline at end of file diff --git a/devicetypes/smartthings/smartsense-motion-sensor.src/smartsense-motion-sensor.groovy b/devicetypes/smartthings/smartsense-motion-sensor.src/smartsense-motion-sensor.groovy index e787c24..fa76425 100644 --- a/devicetypes/smartthings/smartsense-motion-sensor.src/smartsense-motion-sensor.groovy +++ b/devicetypes/smartthings/smartsense-motion-sensor.src/smartsense-motion-sensor.groovy @@ -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 of the License at: + * 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. + * 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 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 { @@ -19,18 +29,17 @@ metadata { capability "Motion Sensor" capability "Configuration" capability "Battery" - capability "Temperature Measurement" + capability "Temperature Measurement" 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: "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: "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-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,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: "3325" + fingerprint inClusters: "0000,0001,0003,0402,0500,0020,0B05", outClusters: "0019", manufacturer: "CentraLite", model: "3326" + fingerprint inClusters: "0000,0001,0003,000F,0020,0402,0500", outClusters: "0019", manufacturer: "SmartThings", model: "motionv4", deviceJoinName: "Motion Sensor" } simulator { @@ -47,7 +56,7 @@ metadata { ]) } 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 } } @@ -86,7 +95,7 @@ metadata { def parse(String description) { log.debug "description: $description" - + Map map = [:] if (description?.startsWith('catchall:')) { map = parseCatchAllMessage(description) @@ -97,55 +106,55 @@ def parse(String description) { else if (description?.startsWith('temperature: ')) { map = parseCustomMessage(description) } - else if (description?.startsWith('zone status')) { - map = parseIasMessage(description) - } - + else if (description?.startsWith('zone status')) { + map = parseIasMessage(description) + } + log.debug "Parse returned $map" def result = map ? createEvent(map) : null - - if (description?.startsWith('enroll request')) { - List cmds = enrollResponse() - log.debug "enroll response: ${cmds}" - result = cmds?.collect { new physicalgraph.device.HubAction(it) } - } - return result + + if (description?.startsWith('enroll request')) { + List cmds = enrollResponse() + log.debug "enroll response: ${cmds}" + result = cmds?.collect { new physicalgraph.device.HubAction(it) } + } + return result } private Map parseCatchAllMessage(String description) { - Map resultMap = [:] - def cluster = zigbee.parse(description) - if (shouldProcessMessage(cluster)) { - switch(cluster.clusterId) { - case 0x0001: - resultMap = getBatteryResult(cluster.data.last()) - break + Map resultMap = [:] + def cluster = zigbee.parse(description) + if (shouldProcessMessage(cluster)) { + switch(cluster.clusterId) { + case 0x0001: + resultMap = getBatteryResult(cluster.data.last()) + break - case 0x0402: - // temp is last 2 data values. reverse to swap endian - String temp = cluster.data[-2..-1].reverse().collect { cluster.hex1(it) }.join() - def value = getTemperature(temp) - resultMap = getTemperatureResult(value) - break + case 0x0402: + // temp is last 2 data values. reverse to swap endian + String temp = cluster.data[-2..-1].reverse().collect { cluster.hex1(it) }.join() + def value = getTemperature(temp) + resultMap = getTemperatureResult(value) + break case 0x0406: - log.debug 'motion' - resultMap.name = 'motion' - break - } - } + log.debug 'motion' + resultMap.name = 'motion' + break + } + } - return resultMap + return resultMap } private boolean shouldProcessMessage(cluster) { - // 0x0B is default response indicating message got through - // 0x07 is bind message - boolean ignoredMessage = cluster.profileId != 0x0104 || - cluster.command == 0x0B || - cluster.command == 0x07 || - (cluster.data.size() > 0 && cluster.data.first() == 0x3e) - return !ignoredMessage + // 0x0B is default response indicating message got through + // 0x07 is bind message + boolean ignoredMessage = cluster.profileId != 0x0104 || + cluster.command == 0x0B || + cluster.command == 0x07 || + (cluster.data.size() > 0 && cluster.data.first() == 0x3e) + return !ignoredMessage } private Map parseReportAttributeMessage(String description) { @@ -154,7 +163,7 @@ private Map parseReportAttributeMessage(String description) { map += [(nameAndValue[0].trim()):nameAndValue[1].trim()] } log.debug "Desc Map: $descMap" - + Map resultMap = [:] if (descMap.cluster == "0402" && descMap.attrId == "0000") { def value = getTemperature(descMap.value) @@ -163,14 +172,14 @@ private Map parseReportAttributeMessage(String description) { else if (descMap.cluster == "0001" && descMap.attrId == "0020") { resultMap = getBatteryResult(Integer.parseInt(descMap.value, 16)) } - else if (descMap.cluster == "0406" && descMap.attrId == "0000") { - def value = descMap.value.endsWith("01") ? "active" : "inactive" - resultMap = getMotionResult(value) - } - + else if (descMap.cluster == "0406" && descMap.attrId == "0000") { + def value = descMap.value.endsWith("01") ? "active" : "inactive" + resultMap = getMotionResult(value) + } + return resultMap } - + private Map parseCustomMessage(String description) { Map resultMap = [:] if (description?.startsWith('temperature: ')) { @@ -181,44 +190,44 @@ private Map parseCustomMessage(String description) { } private Map parseIasMessage(String description) { - List parsedMsg = description.split(' ') - String msgCode = parsedMsg[2] + List parsedMsg = description.split(' ') + String msgCode = parsedMsg[2] + + Map resultMap = [:] + switch(msgCode) { + case '0x0020': // Closed/No Motion/Dry + resultMap = getMotionResult('inactive') + break - Map resultMap = [:] - switch(msgCode) { - case '0x0020': // Closed/No Motion/Dry - resultMap = getMotionResult('inactive') - break + case '0x0021': // Open/Motion/Wet + resultMap = getMotionResult('active') + break - case '0x0021': // Open/Motion/Wet - resultMap = getMotionResult('active') - break + case '0x0022': // Tamper Alarm + log.debug 'motion with tamper alarm' + resultMap = getMotionResult('active') + break - case '0x0022': // Tamper Alarm - log.debug 'motion with tamper alarm' - resultMap = getMotionResult('active') - break + case '0x0023': // Battery Alarm + break - case '0x0023': // Battery Alarm - break + case '0x0024': // Supervision Report + log.debug 'no motion with tamper alarm' + resultMap = getMotionResult('inactive') + break - case '0x0024': // Supervision Report - log.debug 'no motion with tamper alarm' - resultMap = getMotionResult('inactive') - break + case '0x0025': // Restore Report + break - case '0x0025': // Restore Report - break + case '0x0026': // Trouble/Failure + log.debug 'motion with failure alarm' + resultMap = getMotionResult('active') + break - case '0x0026': // Trouble/Failure - log.debug 'motion with failure alarm' - resultMap = getMotionResult('active') - break - - case '0x0028': // Test Mode - break - } - return resultMap + case '0x0028': // Test Mode + break + } + return resultMap } def getTemperature(value) { @@ -236,7 +245,8 @@ private Map getBatteryResult(rawValue) { def result = [ name: 'battery', - value: '--' + value: '--', + translatable: true ] def volts = rawValue / 10 @@ -244,10 +254,10 @@ private Map getBatteryResult(rawValue) { if (rawValue == 0 || rawValue == 255) {} else { 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 { - if (device.getDataValue("manufacturer") == "SmartThings") { + if (device.getDataValue("manufacturer") == "SmartThings") { 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, 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] if (pct != null) { result.value = pct - result.descriptionText = "${linkText} battery was ${result.value}%" + def value = pct + result.descriptionText = "{{ device.displayName }} battery was {{ value }}" } } else { @@ -269,7 +280,7 @@ private Map getBatteryResult(rawValue) { def maxVolts = 3.0 def pct = (volts - minVolts) / (maxVolts - minVolts) 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) { log.debug 'TEMP' - def linkText = getLinkText(device) if (tempOffset) { def offset = tempOffset as int def v = value as int 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 [ name: 'temperature', value: value, - descriptionText: descriptionText + descriptionText: descriptionText, + translatable: true ] } private Map getMotionResult(value) { log.debug 'motion' - String linkText = getLinkText(device) - String descriptionText = value == 'active' ? "${linkText} detected motion" : "${linkText} motion has stopped" + String descriptionText = value == 'active' ? "{{ device.displayName }} detected motion" : "{{ device.displayName }} motion has stopped" + //String descriptionText = '{{ device.displayName }} is {{ value | translate }}' return [ name: 'motion', value: value, - descriptionText: descriptionText + descriptionText: descriptionText, + translatable: true ] } def refresh() { - log.debug "refresh called" + log.debug "refresh executed" def refreshCmds = [ "st rattr 0x${device.deviceNetworkId} 1 0x402 0", "delay 200", "st rattr 0x${device.deviceNetworkId} 1 1 0x20", "delay 200" @@ -355,19 +372,19 @@ private hex(value) { } private String swapEndianHex(String hex) { - reverseArray(hex.decodeHex()).encodeHex() + reverseArray(hex.decodeHex()).encodeHex() } private byte[] reverseArray(byte[] array) { - int i = 0; - int j = array.length - 1; - byte tmp; - while (j > i) { - tmp = array[j]; - array[j] = array[i]; - array[i] = tmp; - j--; - i++; - } - return array -} + int i = 0; + int j = array.length - 1; + byte tmp; + while (j > i) { + tmp = array[j]; + array[j] = array[i]; + array[i] = tmp; + j--; + i++; + } + return array +} \ No newline at end of file