Skip to content

Commit

Permalink
Merge pull request SmartThingsCommunity#3268 from SmartThingsCommunit…
Browse files Browse the repository at this point in the history
…y/master

Rolling up master to staging
  • Loading branch information
workingmonk authored Jul 17, 2018
2 parents c2bcf3b + ed8dfcb commit 65f14f5
Show file tree
Hide file tree
Showing 20 changed files with 1,576 additions and 157 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -259,7 +259,7 @@ def zwaveEvent(physicalgraph.zwave.commands.batteryv1.BatteryReport cmd) {
log.debug "location: "+location
def timeDate = location.timeZone ? new Date().format("yyyy MMM dd EEE h:mm:ss a", location.timeZone) : new Date().format("yyyy MMM dd EEE h:mm:ss")

if (value == 0xFF) { // Special value for low battery alert
if (cmd.batteryLevel == 0xFF) { // Special value for low battery alert
sendEvent(name: "battery", value: 1, descriptionText: "${device.displayName} has a low battery", isStateChange: true)
} else {
sendEvent(name: "battery", value: cmd.batteryLevel, descriptionText: "Current battery level")
Expand Down

Large diffs are not rendered by default.

Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,8 @@ metadata {

command "reset"

fingerprint mfr: "010F", prod: "0602", model: "1001", deviceJoinName: "Fibaro Wall Plug EU ZW5"
fingerprint mfr: "010F", prod: "0602", model: "1001", deviceJoinName: "Fibaro Wall Plug EU ZW5" // EU
fingerprint mfr: "010F", prod: "1801", model: "1000", deviceJoinName: "Fibaro Wall Plug ZW5" // UK
fingerprint deviceId: "0x1001", inClusters:"0x5E,0x22,0x59,0x56,0x7A,0x32,0x71,0x73,0x31,0x85,0x70,0x72,0x5A,0x8E,0x25,0x86"

}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -304,24 +304,34 @@ def zwaveEvent(physicalgraph.zwave.commands.switchbinaryv1.SwitchBinaryReport cm

def zwaveEvent(physicalgraph.zwave.commands.meterv3.MeterReport cmd, ep=null) {
log.warn "${device.displayName} - MeterReport received, value: ${cmd.scaledMeterValue} scale: ${cmd.scale} ep: $ep"
if (ep==1) {
if (!ep || ep==1) {
log.warn "chanell1"
switch (cmd.scale) {
case 0: sendEvent([name: "energy", value: cmd.scaledMeterValue, unit: "kWh"]); break;
case 2: sendEvent([name: "power", value: cmd.scaledMeterValue, unit: "W"]); break;
case 0: sendEvent([name: "energy", value: cmd.scaledMeterValue, unit: "kWh"]);
break;
case 2: sendEvent([name: "power", value: cmd.scaledMeterValue, unit: "W"]);
break;
}
if (device.currentValue("energy") != null) {
multiStatusEvent("${device.currentValue("power")} W / ${device.currentValue("energy")} kWh")
} else {
multiStatusEvent("${device.currentValue("power")} W / 0.00 kWh")
}
if (device.currentValue("energy") != null) {multiStatusEvent("${device.currentValue("power")} W / ${device.currentValue("energy")} kWh")}
else {multiStatusEvent("${device.currentValue("power")} W / 0.00 kWh")}
}

if (ep==2) {
log.warn "chanell2"
switch (cmd.scale) {
case 0: getChild(2)?.sendEvent([name: "energy", value: cmd.scaledMeterValue, unit: "kWh"]); break;
case 2: getChild(2)?.sendEvent([name: "power", value: cmd.scaledMeterValue, unit: "W"]); break;
case 0: getChild(2)?.sendEvent([name: "energy", value: cmd.scaledMeterValue, unit: "kWh"]);
break;
case 2: getChild(2)?.sendEvent([name: "power", value: cmd.scaledMeterValue, unit: "W"]);
break;
}
if (device.currentValue("energy") != null) {
ch2MultiStatusEvent("${getChild(2)?.currentValue("power")} W / ${getChild(2)?.currentValue("energy")} kWh")
} else {
ch2MultiStatusEvent("${getChild(2)?.currentValue("power")} W / 0.00 kWh")
}
if (device.currentValue("energy") != null) {ch2MultiStatusEvent("${getChild(2)?.currentValue("power")} W / ${getChild(2)?.currentValue("energy")} kWh")}
else {ch2MultiStatusEvent("${getChild(2)?.currentValue("power")} W / 0.00 kWh")}
}
}

Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,151 @@
/**
* Copyright 2018 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.
*
*
* Orvibo Contact Sensor
*
* Author: Deng Biaoyi
*
* Date:2018-07-03
*/
import physicalgraph.zigbee.clusters.iaszone.ZoneStatus
import physicalgraph.zigbee.zcl.DataType

metadata {
definition(name: "Orvibo Contact Sensor", namespace: "smartthings", author: "[email protected]", runLocally: false, minHubCoreVersion: '000.017.0012', executeCommandsLocally: false, mnmn:"SmartThings", vid:"generic-contact-3", ocfDeviceType: "x.com.st.d.sensor.contact") {
capability "Battery"
capability "Configuration"
capability "Contact Sensor"
capability "Refresh"
capability "Health Check"
capability "Sensor"

fingerprint profileId: "0104", deviceId: "0402", inClusters: "0000,0003,0500,0001", manufacturer: "ORVIBO", model: "e70f96b3773a4c9283c6862dbafb6a99"
}

simulator {

status "open": "zone status 0x0021 -- extended status 0x00"
status "close": "zone status 0x0000 -- extended status 0x00"

for (int i = 0; i <= 90; i += 10) {
status "battery 0x${i}": "read attr - raw: 2E6D01000108210020C8, dni: 2E6D, endpoint: 01, cluster: 0001, size: 08, attrId: 0021, encoding: 20, value: ${i}"
}
}

tiles(scale: 2) {
multiAttributeTile(name: "contact", type: "generic", width: 6, height: 4) {
tileAttribute("device.contact", key: "PRIMARY_CONTROL") {
attributeState "open", label: '${name}', icon: "st.contact.contact.open", backgroundColor: "#e86d13"
attributeState "closed", label: '${name}', icon: "st.contact.contact.closed", backgroundColor: "#00A0DC"
}
}

valueTile("battery", "device.battery", decoration: "flat", inactiveLabel: false, width: 2, height: 2) {
state "battery", label: '${currentValue}% battery', unit: ""
}

standardTile("refresh", "device.refresh", inactiveLabel: false, decoration: "flat", width: 2, height: 2) {
state "default", action: "refresh.refresh", icon: "st.secondary.refresh"
}

main(["contact"])
details(["contact", "battery", "refresh"])
}
}

def parse(String description) {
log.debug "description: $description"

def result = [:]
Map map = zigbee.getEvent(description)
if (!map) {
if (description?.startsWith('zone status')) {
ZoneStatus zs = zigbee.parseZoneStatus(description)
map = zs.isAlarm1Set() ? getContactResult('open') : getContactResult('closed')
result = createEvent(map)
}else if(description?.startsWith('enroll request')){
List cmds = zigbee.enrollResponse()
log.debug "enroll response: ${cmds}"
result = cmds?.collect { new physicalgraph.device.HubAction(it) }
}else {
Map descMap = zigbee.parseDescriptionAsMap(description)
if (descMap?.clusterInt == 0x0001 && descMap?.commandInt != 0x07 && descMap?.value) {
if(descMap?.attrInt==0x0021){
map = getBatteryPercentageResult(Integer.parseInt(descMap.value, 16))
result = createEvent(map)
}
} else if (descMap?.clusterInt == 0x0500 && descMap?.attrInt == 0x0002) {
def zs = new ZoneStatus(zigbee.convertToInt(descMap.value, 16))
map = getContactResult(zs.isAlarm1Set() ? "open" : "closed")
result = createEvent(map)
}
}
}else{
result = createEvent(map)
}
log.debug "Parse returned $result"

result
}

def installed(){
log.debug "call installed()"
sendEvent(name: "checkInterval", value:20 * 60 + 1 * 60, displayed: false, data: [protocol: "zigbee", hubHardwareId: device.hub.hardwareID, offlinePingable: "1"])
refresh()
}
/**
* PING is used by Device-Watch in attempt to reach the Device
* */
def ping() {
log.debug "ping is called"
zigbee.readAttribute(zigbee.IAS_ZONE_CLUSTER, zigbee.ATTRIBUTE_IAS_ZONE_STATUS) + zigbee.readAttribute(zigbee.POWER_CONFIGURATION_CLUSTER, 0x0021)
}

def refresh() {
log.debug "Refreshing Battery and ZONE Status"
def refreshCmds = zigbee.readAttribute(zigbee.POWER_CONFIGURATION_CLUSTER, 0x0021) +
zigbee.readAttribute(zigbee.IAS_ZONE_CLUSTER, zigbee.ATTRIBUTE_IAS_ZONE_STATUS)
refreshCmds + zigbee.enrollResponse()
}

def configure() {
sendEvent(name: "checkInterval", value:20 * 60 + 1 * 60, displayed: false, data: [protocol: "zigbee", hubHardwareId: device.hub.hardwareID, offlinePingable: "1"])
log.debug "Configuring Reporting, IAS CIE, and Bindings."
//The electricity attribute is reported without bind and reporting CFG. The TI plan reports the power once in about 10 minutes; the NXP plan reports the electricity once in 20 minutes
refresh()
}

def getBatteryPercentageResult(rawValue) {
log.debug "Battery Percentage rawValue = ${rawValue} -> ${rawValue / 2}%"
def result = [:]

if (0 <= rawValue && rawValue <= 200) {
result.name = 'battery'
result.translatable = true
result.value = Math.round(rawValue / 2)
result.descriptionText = "${device.displayName} battery was ${result.value}%"
}

result
}

def getContactResult(value) {
log.debug 'Contact Status'
def linkText = getLinkText(device)
def descriptionText = "${linkText} was ${value == 'open' ? 'opened' : 'closed'}"
[
name : 'contact',
value : value,
descriptionText: descriptionText
]
}
Original file line number Diff line number Diff line change
Expand Up @@ -42,7 +42,7 @@
*/

metadata {
definition (name: "GE Link Bulb", namespace: "smartthings", author: "SmartThings", ocfDeviceType: "oic.d.light", runLocally: true, minHubCoreVersion: '000.017.0012', executeCommandsLocally: false) {
definition (name: "GE Link Bulb", namespace: "smartthings", author: "SmartThings", ocfDeviceType: "oic.d.light", runLocally: true, minHubCoreVersion: '000.017.0012', executeCommandsLocally: false, mnmn: "SmartThings", vid: "generic-dimmer") {

capability "Actuator"
capability "Configuration"
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,150 @@
/*
* Copyright 2018 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.
*
* Orvibo Moisture Sensor
*
* Author: Deng Biaoyi/[email protected]
*
* Date:2018-07-03
*/
import physicalgraph.zigbee.clusters.iaszone.ZoneStatus
import physicalgraph.zigbee.zcl.DataType

metadata {
definition(name: "Orvibo Moisture Sensor", namespace: "smartthings", author: "SmartThings", vid: "generic-leak", mnmn:"SmartThings", ocfDeviceType: "x.com.st.d.sensor.moisture") {
capability "Configuration"
capability "Refresh"
capability "Water Sensor"
capability "Sensor"
capability "Health Check"
capability "Battery"

fingerprint profileId: "0104", deviceId: "0402", inClusters: "0000,0003,0500,0001", outClusters: "0019", manufacturer: "Heiman", model: "2f077707a13f4120846e0775df7e2efe"
}

simulator {

status "dry": "zone status 0x0020 -- extended status 0x00"
status "wet": "zone status 0x0021 -- extended status 0x00"

for (int i = 0; i <= 90; i += 10) {
status "battery 0021 0x${i}": "read attr - raw: 8C900100010A21000020C8, dni: 8C90, endpoint: 01, cluster: 0001, size: 0A, attrId: 0021, result: success, encoding: 20, value: ${i}"
}
}

tiles(scale: 2) {
multiAttributeTile(name:"water", type: "generic", width: 6, height: 4){
tileAttribute ("device.water", key: "PRIMARY_CONTROL") {
attributeState "dry", icon:"st.alarm.water.dry", backgroundColor:"#ffffff"
attributeState "wet", icon:"st.alarm.water.wet", backgroundColor:"#00a0dc"
}
}

valueTile("battery", "device.battery", decoration: "flat", inactiveLabel: false, width: 2, height: 2) {
state "battery", label:'${currentValue}% battery', unit:""
}

standardTile("refresh", "device.refresh", inactiveLabel: false, decoration: "flat", width: 2, height: 2) {
state "default", action: "refresh.refresh", icon: "st.secondary.refresh"
}

main "water"
details(["water", "battery", "refresh"])
}
}

def parse(String description) {
log.debug "description: $description"

def result
Map map = zigbee.getEvent(description)

if (!map) {
if (description?.startsWith('zone status')) {
map = getMoistureResult(description)
} else if(description?.startsWith('enroll request')){
List cmds = zigbee.enrollResponse()
log.debug "enroll response: ${cmds}"
result = cmds?.collect { new physicalgraph.device.HubAction(it) }
}else {
Map descMap = zigbee.parseDescriptionAsMap(description)
if (descMap?.clusterInt == 0x0500 && descMap.attrInt == 0x0002) {
map = getMoistureResult(description)
} else if (descMap?.clusterInt == 0x0001 && descMap?.attrInt == 0x0021 && descMap?.commandInt != 0x07 && descMap?.value) {
map = getBatteryPercentageResult(Integer.parseInt(descMap.value, 16))
}
}
}
if(map&&!result){
result = createEvent(map)
}
log.debug "Parse returned $result"

result
}

def ping() {
refresh()
}

def refresh() {
log.debug "Refreshing Values"
def refreshCmds = []
refreshCmds += zigbee.readAttribute(zigbee.POWER_CONFIGURATION_CLUSTER, 0x0021)
refreshCmds += zigbee.readAttribute(zigbee.IAS_ZONE_CLUSTER, zigbee.ATTRIBUTE_IAS_ZONE_STATUS) +
zigbee.enrollResponse()

refreshCmds
}

def installed(){
log.debug "call installed()"
sendEvent(name: "checkInterval", value: 20 * 60 + 1 * 60, displayed: false, data: [protocol: "zigbee", hubHardwareId: device.hub.hardwareID, offlinePingable: "1"])
}

def configure() {
sendEvent(name: "checkInterval", value: 20 * 60 + 1 * 60, displayed: false, data: [protocol: "zigbee", hubHardwareId: device.hub.hardwareID, offlinePingable: "1"])

log.debug "Configuring Reporting"
def configCmds = []
configCmds += zigbee.configureReporting(zigbee.POWER_CONFIGURATION_CLUSTER, 0x0021, DataType.UINT8, 30, 21600, 0x10)
refresh() + configCmds
}

def getMoistureResult(description) {
ZoneStatus zs = zigbee.parseZoneStatus(description)
def value = zs?.isAlarm1Set()?"wet":"dry"
[
name : 'water',
value : value,
descriptionText: "${device.displayName} is $value",
translatable : true
]
}

def getBatteryPercentageResult(rawValue) {
log.debug "Battery Percentage"
def result = [:]

if (0 <= rawValue && rawValue <= 200) {
result.name = 'battery'
result.translatable = true
result.value = Math.round(rawValue / 2)
result.descriptionText = "${device.displayName} battery was ${result.value}%"
}

log.debug "${device.displayName} battery was ${result.value}%"
result
}
Loading

0 comments on commit 65f14f5

Please sign in to comment.