Skip to content

Instantly share code, notes, and snippets.

@ReneeVandervelde
Last active April 26, 2024 23:22
Show Gist options
  • Save ReneeVandervelde/a38e80fc6e7ea81c8c3b38c30c29670b to your computer and use it in GitHub Desktop.
Save ReneeVandervelde/a38e80fc6e7ea81c8c3b38c30c29670b to your computer and use it in GitHub Desktop.
Hubitat Device Driver for Linkstyle Water valve.
/*
* Linkstyle Zigbee Valve for Hubitat/Smartthings
*
* NOTICE:
* Based on Smartthings Tuya valve device definition
* Modified to remove auto-off and cleaned up logging and formatting.
* Copyright 2020 SmartThings Licensed under the Apache License, Version 2.0
*
* 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.
*/
metadata {
definition(name: "Linkstyle Water Valve", namespace: "Linkstyle", author: "Renee Vandervelde", ocfDeviceType: "oic.d.watervalve", vid: "generic-valve") {
capability "Actuator"
capability "Configuration"
capability "Refresh"
capability "Health Check"
capability "Valve"
capability "Battery"
capability "Switch"
fingerprint profileId: "0104", model: "TS0601", manufacturer: "_TZE200_81isopgh", endpointId: "01", inClusters: "0000,0004,0005,EF00", outClusters: "0019,000A", application: "48", deviceJoinName: "Linkstyle Water Valve"
}
}
def parse(String description) {
Map map = [:]
if (description?.startsWith('catchall:')) {
log.debug "description is $description"
log.debug description
map = parseCatchAllMessage(description)
if (map != [:]) {
log.debug "ok send event: $map.name : $map.value"
sendEvent(name: map.name, value: map.value)
}
}
else {
log.warn "DID NOT PARSE MESSAGE for description : $description"
}
}
def close() {
log.debug "close"
zigbee.command(0xEF00, 0x0, "00010101000100")
}
def open() {
log.debug "open"
zigbee.command(0xEF00, 0x0, "00010101000101")
}
def off() {
close()
}
def on() {
open()
}
def refresh() {
log.debug "called refresh"
zigbee.command(0xEF00, 0x0, "00020100")
}
def ping() {
refresh()
}
def update() {}
def configure() {
log.debug "Configuring Reporting and Bindings."
zigbee.onOffConfig() + zigbee.levelConfig() + zigbee.onOffRefresh() + zigbee.levelRefresh()
}
private Map parseCatchAllMessage(String description) {
// Create a map from the raw zigbee message to make parsing more intuitive
def msg = zigbee.parse(description)
Map result = [:]
switch(msg.clusterId) {
case 0xEF00:
def attribute = getAttribute(msg.data)
def value = getAttributeValue(msg.data)
switch (attribute) {
case "valve":
switch(value) {
case 0:
result = [
name: 'valve',
value: 'closed',
data: [buttonNumber: 1],
descriptionText: "$device.displayName button was pressed",
isStateChange: true
]
sendEvent(name: 'switch', value:"off", displayed: true )
break;
case 1:
result = [
name: 'valve',
value: 'open',
data: [buttonNumber: 1],
descriptionText: "$device.displayName button was pressed",
isStateChange: true
]
sendEvent(name: 'switch', value:"on", displayed: true )
break;
}
break;
}
break;
}
return result
}
private String getAttribute(ArrayList _data) {
String retValue = ""
if (_data.size() >= 5) {
if (_data[2] == 1 && _data[3] == 1 && _data[4] == 0) {
retValue = "valve"
}
else if (_data[2] == 2 && _data[3] == 2 && _data[4] == 0) {
retValue = "level"
}
}
return retValue
}
private int getAttributeValue(ArrayList _data) {
int retValue = 0
if (_data.size() >= 6) {
int dataLength = _data[5] as Integer
int power = 1;
for (i in dataLength..1) {
retValue = retValue + power * _data[i+5]
power = power * 256
}
}
return retValue
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment