Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Rolling up staging to acceptance #38034

Merged
merged 9 commits into from
Jul 21, 2020
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
/**
Copyright Sinopé Technologies
1.3.0
1.3.1
SVN-571
* 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.
Expand All @@ -21,12 +21,12 @@ metadata {
input("FloorSensorTypeParam", "enum", title:"Probe type (Default: 10k)",
description: "Choose floor sensors probe. The floor sensor provided with the thermostats are 10K.", options: ["10k", "12k"], multiple: false, required: false)

input("FloorMaxAirTemperatureParam", "number", title:"Ambient limit (5C to 36C / 41F to 96)", range: "5..96",
description: "The maximum ambient temperature limit when in floor control mode.", required: false)
input("FloorLimitMinParam", "number", title:"Floor low limit (5C to 34C / 41F to 93F)", range: "5..93",
description: "The minimum temperature limit of the floor when in ambient control mode.", required: false)
input("FloorLimitMaxParam", "number", title:"Floor high limit (7C to 36C / 45F to 96F)", range: "7..96",
description: "The maximum temperature limit of the floor when in ambient control mode.", required: false)
input("FloorMaxAirTemperatureParam", "number", title:"Ambient limit in Celsius (5C to 36C)", range: "5..36",
description: "The maximum ambient temperature limit in Celsius when in floor control mode.", required: false)
input("FloorLimitMinParam", "number", title:"Floor low limit in Celsius (5C to 34C)", range: "5..34",
description: "The minimum temperature limit in Celsius of the floor when in ambient control mode.", required: false)
input("FloorLimitMaxParam", "number", title:"Floor high limit in Celsius (7C to 36C)", range: "7..36",
description: "The maximum temperature limit of the floor in Celsius when in ambient control mode.", required: false)
// input("AuxLoadParam", "number", title:"Auxiliary load value (Default: 0)", range:("0..65535"),
// description: "Enter the power in watts of the heating element connected to the auxiliary output.", required: false)
input("trace", "bool", title: "Trace", description: "Set it to true to enable tracing")
Expand Down Expand Up @@ -155,6 +155,14 @@ def updated() {

runEvery15Minutes(refresh_misc)

if(KbdLockParam == "Lock" || KbdLockParam == '0'){
traceEvent(settings.logFilter,"device lock",settings.trace)
cmds += zigbee.writeAttribute(0x0204, 0x0001, 0x30, 0x01)
}
else{
traceEvent(settings.logFilter,"device unlock",settings.trace)
cmds += zigbee.writeAttribute(0x0204, 0x0001, 0x30, 0x00)
}
if(AirFloorModeParam == "Floor" || AirFloorModeParam == '1'){//Floor mode
traceEvent(settings.logFilter,"Set to Floor mode",settings.trace)
cmds += zigbee.writeAttribute(0xFF01, 0x0105, 0x30, 0x0002)
Expand Down Expand Up @@ -196,15 +204,15 @@ def updated() {
if(FloorMaxAirTemperatureParam){
def MaxAirTemperatureValue
traceEvent(settings.logFilter,"FloorMaxAirTemperature param. scale: ${state?.scale}, Param value: ${FloorMaxAirTemperatureParam}",settings.trace)
if(state?.scale == 'F')
if(FloorMaxAirTemperatureParam >= 41)
{
MaxAirTemperatureValue = fahrenheitToCelsius(FloorMaxAirTemperatureParam).toInteger()
MaxAirTemperatureValue = checkTemperature(FloorMaxAirTemperatureParam)//check if the temperature is between the maximum and minimum
MaxAirTemperatureValue = fahrenheitToCelsius(MaxAirTemperatureValue).toInteger()
}
else//state?.scale == 'C'
{
MaxAirTemperatureValue = FloorMaxAirTemperatureParam.toInteger()
}
MaxAirTemperatureValue = checkTemperature(MaxAirTemperatureValue)//check if the temperature is between the maximum and minimum
MaxAirTemperatureValue = MaxAirTemperatureValue * 100
cmds += zigbee.writeAttribute(0xFF01, 0x0108, 0x29, MaxAirTemperatureValue)
}
Expand All @@ -216,15 +224,15 @@ def updated() {
if(FloorLimitMinParam){
def FloorLimitMinValue
traceEvent(settings.logFilter,"FloorLimitMin param. scale: ${state?.scale}, Param value: ${FloorLimitMinParam}",settings.trace)
if(state?.scale == 'F')
if(FloorLimitMinParam >= 41)
{
FloorLimitMinValue = fahrenheitToCelsius(FloorLimitMinParam).toInteger()
FloorLimitMinValue = checkTemperature(FloorLimitMinParam)//check if the temperature is between the maximum and minimum
FloorLimitMinValue = fahrenheitToCelsius(FloorLimitMinValue).toInteger()
}
else//state?.scale == 'C'
{
FloorLimitMinValue = FloorLimitMinParam.toInteger()
}
FloorLimitMinValue = checkTemperature(FloorLimitMinValue)//check if the temperature is between the maximum and minimum
FloorLimitMinValue = FloorLimitMinValue * 100
cmds += zigbee.writeAttribute(0xFF01, 0x0109, 0x29, FloorLimitMinValue)
}
Expand All @@ -236,15 +244,15 @@ def updated() {
if(FloorLimitMaxParam){
def FloorLimitMaxValue
traceEvent(settings.logFilter,"FloorLimitMax param. scale: ${state?.scale}, Param value: ${FloorLimitMaxParam}",settings.trace)
if(state?.scale == 'F')
if(FloorLimitMaxParam >= 45)
{
FloorLimitMaxValue = fahrenheitToCelsius(FloorLimitMaxParam).toInteger()
FloorLimitMaxValue = checkTemperature(FloorLimitMaxParam)//check if the temperature is between the maximum and minimum
FloorLimitMaxValue = fahrenheitToCelsius(FloorLimitMaxValue).toInteger()
}
else//state?.scale == 'C'
{
FloorLimitMaxValue = FloorLimitMaxParam.toInteger()
}
FloorLimitMaxValue = checkTemperature(FloorLimitMaxValue)//check if the temperature is between the maximum and minimum
FloorLimitMaxValue = FloorLimitMaxValue * 100
cmds += zigbee.writeAttribute(0xFF01, 0x010A, 0x29, FloorLimitMaxValue)
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -26,12 +26,12 @@ metadata {
// input("PumpProtectionParam", "enum", titile: "Pump Protection (Default: Off)", options: ["On", "Off"], required: false
// description: "Activate the main output 1 minute every 24 hours to ensure the hydronics system pump does not seize.")

input("FloorMaxAirTemperatureParam", "number", title:"Ambient limit (5C to 36C / 41F to 96)", range: "5..96",
description: "The maximum ambient temperature limit \nwhen in floor control mode.", required: false)
input("FloorLimitMinParam", "number", title:"Floor low limit (5C to 34C / 41F to 93F)", range: "5..93",
description: "The minimum temperature limit of the floor when in ambient control mode.", required: false)
input("FloorLimitMaxParam", "number", title:"Floor high limit (7C to 36C / 45F to 96F)", range: "7..96",
description: "The maximum temperature limit of the floor when in ambient control mode.", required: false)
input("FloorMaxAirTemperatureParam", "number", title:"Ambient limit in Celsius (5C to 36C)", range: "5..36",
description: "The maximum ambient temperature limit in Celsius when in floor control mode.", required: false)
input("FloorLimitMinParam", "number", title:"Floor low limit in Celsius (5C to 34C)", range: "5..34",
description: "The minimum temperature limit in Celsius of the floor when in ambient control mode.", required: false)
input("FloorLimitMaxParam", "number", title:"Floor high limit in Celsius (7C to 36C)", range: "7..36",
description: "The maximum temperature limit of the floor in Celsius when in ambient control mode.", required: false)
// input("AuxLoadParam", "number", title:"Auxiliary load value (Default: 0)", range:("0..65535"),
// description: "Enter the power in watts of the heating element connected to the auxiliary output.", required: false)
input("trace", "bool", title: "Trace", description: "Set it to true to enable tracing")
Expand Down Expand Up @@ -246,15 +246,15 @@ def updated() {
if(FloorMaxAirTemperatureParam){
def MaxAirTemperatureValue
traceEvent(settings.logFilter,"FloorMaxAirTemperature param. scale: ${state?.scale}, Param value: ${FloorMaxAirTemperatureParam}",settings.trace)
if(state?.scale == 'F')
if(FloorMaxAirTemperatureParam >= 41)
{
MaxAirTemperatureValue = fahrenheitToCelsius(FloorMaxAirTemperatureParam).toInteger()
MaxAirTemperatureValue = checkTemperature(FloorMaxAirTemperatureParam)//check if the temperature is between the maximum and minimum
MaxAirTemperatureValue = fahrenheitToCelsius(MaxAirTemperatureValue).toInteger()
}
else//state?.scale == 'C'
{
MaxAirTemperatureValue = FloorMaxAirTemperatureParam.toInteger()
}
MaxAirTemperatureValue = checkTemperature(MaxAirTemperatureValue)//check if the temperature is between the maximum and minimum
MaxAirTemperatureValue = MaxAirTemperatureValue * 100
cmds += zigbee.writeAttribute(0xFF01, 0x0108, 0x29, MaxAirTemperatureValue)
}
Expand All @@ -266,15 +266,15 @@ def updated() {
if(FloorLimitMinParam){
def FloorLimitMinValue
traceEvent(settings.logFilter,"FloorLimitMin param. scale: ${state?.scale}, Param value: ${FloorLimitMinParam}",settings.trace)
if(state?.scale == 'F')
if(FloorLimitMinParam >= 41)
{
FloorLimitMinValue = fahrenheitToCelsius(FloorLimitMinParam).toInteger()
FloorLimitMinValue = checkTemperature(FloorLimitMinParam)//check if the temperature is between the maximum and minimum
FloorLimitMinValue = fahrenheitToCelsius(FloorLimitMinValue).toInteger()
}
else//state?.scale == 'C'
{
FloorLimitMinValue = FloorLimitMinParam.toInteger()
}
FloorLimitMinValue = checkTemperature(FloorLimitMinValue)//check if the temperature is between the maximum and minimum
FloorLimitMinValue = FloorLimitMinValue * 100
cmds += zigbee.writeAttribute(0xFF01, 0x0109, 0x29, FloorLimitMinValue)
}
Expand All @@ -286,15 +286,15 @@ def updated() {
if(FloorLimitMaxParam){
def FloorLimitMaxValue
traceEvent(settings.logFilter,"FloorLimitMax param. scale: ${state?.scale}, Param value: ${FloorLimitMaxParam}",settings.trace)
if(state?.scale == 'F')
if(FloorLimitMaxParam >= 45)
{
FloorLimitMaxValue = fahrenheitToCelsius(FloorLimitMaxParam).toInteger()
FloorLimitMaxValue = checkTemperature(FloorLimitMaxParam)//check if the temperature is between the maximum and minimum
FloorLimitMaxValue = fahrenheitToCelsius(FloorLimitMaxValue).toInteger()
}
else//state?.scale == 'C'
{
FloorLimitMaxValue = FloorLimitMaxParam.toInteger()
}
FloorLimitMaxValue = checkTemperature(FloorLimitMaxValue)//check if the temperature is between the maximum and minimum
FloorLimitMaxValue = FloorLimitMaxValue * 100
cmds += zigbee.writeAttribute(0xFF01, 0x010A, 0x29, FloorLimitMaxValue)
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -164,6 +164,7 @@ private handleLevelReport(physicalgraph.zwave.Command cmd) {
shadeValue = "partially open"
descriptionText = "${device.displayName} shade is ${level}% open"
}
checkLevelReport(level)
def levelEvent = createEvent(name: "level", value: level, unit: "%", displayed: false)
def stateEvent = createEvent(name: "windowShade", value: shadeValue, descriptionText: descriptionText, isStateChange: levelEvent.isStateChange)

Expand All @@ -181,15 +182,6 @@ def zwaveEvent(physicalgraph.zwave.commands.switchmultilevelv3.SwitchMultilevelS
response(zwave.switchMultilevelV1.switchMultilevelGet().format()) ]
}

def zwaveEvent(physicalgraph.zwave.commands.manufacturerspecificv2.ManufacturerSpecificReport cmd) {
def msr = String.format("%04X-%04X-%04X", cmd.manufacturerId, cmd.productTypeId, cmd.productId)
updateDataValue("MSR", msr)
if (cmd.manufacturerName) {
updateDataValue("manufacturer", cmd.manufacturerName)
}
createEvent([descriptionText: "$device.displayName MSR: $msr", isStateChange: false])
}

def zwaveEvent(physicalgraph.zwave.commands.batteryv1.BatteryReport cmd) {
def map = [ name: "battery", unit: "%" ]
if (cmd.batteryLevel == 0xFF || cmd.batteryLevel == 0) {
Expand Down Expand Up @@ -222,13 +214,15 @@ def zwaveEvent(physicalgraph.zwave.Command cmd) {
def open() {
log.debug "open()"
def level = switchDirection ? 0 : 99
levelChangeFollowUp(level)
zwave.basicV1.basicSet(value: level).format()
// zwave.basicV1.basicSet(value: 0xFF).format()
}

def close() {
log.debug "close()"
def level = switchDirection ? 99 : 0
levelChangeFollowUp(level)
zwave.basicV1.basicSet(value: level).format()
//zwave.basicV1.basicSet(value: 0).format()
}
Expand All @@ -239,6 +233,7 @@ def setLevel(value, duration = null) {
level = switchDirection ? 99-level : level
if (level < 0) level = 0
if (level > 99) level = 99
levelChangeFollowUp(level)
zwave.basicV1.basicSet(value: level).format()
}

Expand Down Expand Up @@ -266,4 +261,29 @@ def refresh() {
zwave.switchMultilevelV1.switchMultilevelGet().format(),
zwave.batteryV1.batteryGet().format()
], 1500)
}

def levelChangeFollowUp(expectedLevel) {
state.expectedValue = expectedLevel
state.levelChecks = 0
runIn(5, "checkLevel", [overwrite: true])
}

def checkLevelReport(value) {
if (state.expectedValue != null) {
if ((state.expectedValue == 99 && value >= 99) ||
(value >= state.expectedValue - 2 && value <= state.expectedValue + 2)) {
unschedule("checkLevel")
}
}
}

def checkLevel() {
if (state.levelChecks != null && state.levelChecks < 5) {
state.levelChecks = state.levelChecks + 1
runIn(5, "checkLevel", [overwrite: true])
sendHubCommand(zwave.switchMultilevelV1.switchMultilevelGet())
} else {
unschedule("checkLevel")
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -66,12 +66,16 @@ def getATTRIBUTE_HISTORICAL_CONSUMPTION() { 0x0400 }
def parse(String description) {
log.debug "description is $description"
def event = zigbee.getEvent(description)
def descMap = zigbee.parseDescriptionAsMap(description)
def powerDiv = 1
def energyDiv = 100

if (event) {
log.info "event enter:$event"
if (event.name== "power") {
if (event.name == "switch" && !descMap.isClusterSpecific && descMap.commandInt == 0x0B) {
log.info "Ignoring default response with desc map: $descMap"
return [:]
} else if (event.name== "power") {
event.value = event.value/powerDiv
event.unit = "W"
} else if (event.name== "energy") {
Expand All @@ -82,7 +86,6 @@ def parse(String description) {
sendEvent(event)
} else {
List result = []
def descMap = zigbee.parseDescriptionAsMap(description)
log.debug "Desc Map: $descMap"

List attrData = [[clusterInt: descMap.clusterInt ,attrInt: descMap.attrInt, value: descMap.value]]
Expand Down Expand Up @@ -153,4 +156,4 @@ def configure() {
zigbee.onOffConfig() +
zigbee.configureReporting(zigbee.SIMPLE_METERING_CLUSTER, ATTRIBUTE_READING_INFO_SET, DataType.UINT48, 1, 600, 1) +
zigbee.electricMeasurementPowerConfig(1, 600, 1)
}
}
12 changes: 10 additions & 2 deletions devicetypes/smartthings/zigbee-multi-switch.src/zigbee-multi-switch.groovy
100755 → 100644
Original file line number Diff line number Diff line change
Expand Up @@ -48,6 +48,14 @@ metadata {
fingerprint profileId: "0104", inClusters: "0000, 0002, 0004, 0003, 0006, 0009, 0019", manufacturer: "DAWON_DNS", model: "PM-S240R-ZB", deviceJoinName: "Dawon Switch 1" //DAWOS DNS In-Wall Switch PM-S240R-ZB
fingerprint profileId: "0104", inClusters: "0000, 0002, 0004, 0003, 0006, 0009, 0019", manufacturer: "DAWON_DNS", model: "PM-S340-ZB", deviceJoinName: "Dawon Switch 1" //DAWOS DNS In-Wall Switch PM-S340-ZB
fingerprint profileId: "0104", inClusters: "0000, 0002, 0004, 0003, 0006, 0009, 0019", manufacturer: "DAWON_DNS", model: "PM-S340R-ZB", deviceJoinName: "Dawon Switch 1" //DAWOS DNS In-Wall Switch PM-S340R-ZB

// eWeLink
// Raw Description 01 0104 0100 00 05 0000 0003 0004 0005 0006 01 0000
fingerprint manufacturer: "eWeLink", model: "ZB-SW02", deviceJoinName: "eWeLink Switch" //eWeLink 2 Gang Switch 1
// Raw Description 01 0104 0100 00 05 0000 0003 0004 0005 0006 01 0000
fingerprint manufacturer: "eWeLink", model: "ZB-SW03", deviceJoinName: "eWeLink Switch" //eWeLink 3 Gang Switch 1
// Raw Description 01 0104 0100 00 05 0000 0003 0004 0005 0006 01 0000
fingerprint manufacturer: "eWeLink", model: "ZB-SW04", deviceJoinName: "eWeLink Switch" //eWeLink 4 Gang Switch 1
}
// simulator metadata
simulator {
Expand Down Expand Up @@ -232,9 +240,9 @@ private getChildCount() {
return 3
} else if (device.getDataValue("model") == "E220-KR2N0Z0-HA") {
return 2
} else if (device.getDataValue("model") == "E220-KR3N0Z0-HA") {
} else if (device.getDataValue("model") == "E220-KR3N0Z0-HA" || device.getDataValue("model") == "ZB-SW03") {
return 3
} else if (device.getDataValue("model") == "E220-KR4N0Z0-HA") {
} else if (device.getDataValue("model") == "E220-KR4N0Z0-HA" || device.getDataValue("model") == "ZB-SW04") {
return 4
} else if (device.getDataValue("model") == "E220-KR5N0Z0-HA") {
return 5
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -92,6 +92,9 @@ metadata {

// Q Smart Lights
fingerprint profileId: "0104", inClusters: "0000, 0003, 0004, 0005, 0006, 0008, 0300, 0B05, 1000, FEDC", outClusters: "000A, 0019", manufacturer: "Neuhaus Lighting Group", model: "ZBT-ExtendedColor", deviceJoinName: "Q-Smart Light", mnmn:"SmartThings", vid: "generic-rgbw-color-bulb-1800K-6500K"

// Ajax Online
fingerprint manufacturer: "Ajaxonline", model: "AJ-RGBCCT 5 in 1", deviceJoinName: "Ajax Light", mnmn: "SmartThings", vid: "generic-rgbw-color-bulb-2000K-6500K"
}

// UI tile definitions
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -189,6 +189,10 @@ def setLevel(data, rate = null) {

def pause() {
log.info "pause()"
// If the window shade isn't moving when we receive a pause() command then just echo back the current state for the mobile client.
if (device.currentValue("windowShade") != "opening" && device.currentValue("windowShade") != "closing") {
sendEvent(name: "windowShade", value: device.currentValue("windowShade"), isStateChange: true, displayed: false)
}
zigbee.command(CLUSTER_WINDOW_COVERING, COMMAND_PAUSE)
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -408,6 +408,7 @@ private def handleBatteryAlarmReport(cmd) {
case 0x01: //power has been applied, check if the battery level updated
log.debug "Batteries replaced. Queueing a battery get."
runIn(10, "queryBattery", [overwrite: true, forceForLocallyExecuting: true])
state.batteryQueries = 0
result << response(secure(zwave.batteryV1.batteryGet()))
break;
case 0x0A:
Expand Down Expand Up @@ -693,9 +694,11 @@ private Boolean secondsPast(timestamp, seconds) {

private queryBattery() {
log.debug "Running queryBattery"
if (!state.lastbatt || now() - state.lastbatt > 10*1000) {
if (state.batteryQueries == null) state.batteryQueries = 0
if ((!state.lastbatt || now() - state.lastbatt > 10*1000) && state.batteryQueries < 5) {
log.debug "It's been more than 10s since battery was updated after a replacement. Querying battery."
runIn(10, "queryBattery", [overwrite: true, forceForLocallyExecuting: true])
state.batteryQueries = state.batteryQueries + 1
sendHubCommand(secure(zwave.batteryV1.batteryGet()))
}
}
Expand Down
Loading