Drayton Wiser Heating - port from ST?

Hi Matt, I have actually got this working very well now. I spent a lot of time messing with this and now have it all working ( I think).
As soon as I have finished testing I will post the app and drivers up for anyone else who wants it.
Mark.

HI Mark, how did you get on testing the app and drivers for the Drayton Wiser Heating. Do you have code for the app and drivers you can share? I have the same Wiser system and it would be nice to have it talking to Hubitat. I tried with the Smartthings port but failed miserably.
If you can help it would be greatly appreciated.
Neil

Hi Neil,
Have had this running for a few months and seems to work well. The only thing I didnā€™t do is get the hot water driver running as I donā€™t use that side of the system.
Radiators and heat works great.
Iā€™m at work at the moment but when I get time later I will post the drivers and app for you to use.
Mark.

HI Mark,
thanks for getting back to me. That would be great if you could post the drivers and app. I do not use the hot water function either so looks like yours would be the same configuration as mine.
Neil

/**

  • Drayton Wiser
  • Copyright 2018 Colin Chapman
  • 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.

*/
definition(
name: "Drayton Wiser (Connect)",
namespace: "colc1705",
author: "Colin Chapman",
description: "Connect Drayton Wiser to Smartthings",
iconUrl: "https://s3.amazonaws.com/smartapp-icons/Convenience/Cat-Convenience.png",
iconX2Url: "https://s3.amazonaws.com/smartapp-icons/Convenience/Cat-Convenience@2x.png",
iconX3Url: "https://s3.amazonaws.com/smartapp-icons/Convenience/Cat-Convenience@2x.png",
singleInstance: true)

preferences {

page(name: "mainPage", title:"Drayton Wiser Setup", content:"mainPage", install: true)

}

def installed() {
if (showDebug) log.debug "Installed with settings: ${settings}"

initialize()

}

def updated() {
if (showDebug) log.debug "Updated with settings: ${settings}"
unschedule()
unsubscribe()
initialize()
}

def initialize() {
if (showDebug) log.debug "initialize()"
getHubConfig()
runEvery1Minute("getHubConfig")
//getHubUrl("/data/domain/Room")
//sendMessageToHeatHub("/data/domain/", "GET", "")
}

def mainPage() {
if (showDebug) log.debug "mainPage"
return dynamicPage(name: "mainPage", title: "", install: true, uninstall: true) {
section("Title") {
input("hubIP", "string", title: "Hub IP address", description: "", required: true)
input("systemSecret", "string", title: "Hub Secret", required: true)
input("heatingBoost", "number", title: "Minutes for heating boost", required: false, defaultValue: 30)
input("waterBoost", "number", title: "Minutes for hot water boost", required: false, defaultValue: 60)
input("showDebug","bool", title: "Show debugging info", required: true, defaultValue: false)
}
}
}

def showDebugInfo() {
return showDebug
}

def test(dni = null) {
if (showDebug) log.debug "smartapp test($dni)"
//refreshAllChildren()
state.action = "test"
getHubUrl("/data/v2/domain/")
}

def refreshHub(dni) {
if (showDebug) log.debug "refreshHub()"
if (dni == null) dni = app.id + ":HUB"
def child = getChildDevice(dni)
//log.debug state.hubConfig.System.EcoModeEnabled
//log.debug state.hubConfig.System.OverrideType
//log.debug state.hubConfig.System.ComfortModeEnabled
child.setMode(state.hubConfig.System.OverrideType)
child.setEco(state.hubConfig.System.EcoModeEnabled)
child.setComfort(state.hubConfig.System.ComfortModeEnabled)
}

def refreshChild(dni) {
if (showDebug) log.debug "refreshChild($dni)"
def roomId = dni.split(":")[1]
def child = getChildDevice(dni)
def roomStatId
//log.debug roomId

if (roomId == "HW") {
	//if (showDebug) log.debug "Update Hot Water"
    def hotWater = state.hubConfig.HotWater[0]
    child.setState(hotWater.WaterHeatingState)
    child.setMode(hotWater.Mode)
    if (hotWater.OverrideTimeoutUnixTime) {
    	child.setBoost("On")
    } else {
    	child.setBoost("Off")
    }
} else {
	//if (showDebug) log.debug "Update room id{$roomId}"
    def rooms = state.hubConfig.Room
    rooms.each { room ->
        	if (roomId == room.id.toString()) {
            	
                child.setTemp(room.CalculatedTemperature/10, room.CurrentSetPoint/10)
                child.setMode(room.Mode)
                //child.setOutputState(room.ControlOutputState)
                child.setDemand(room.PercentageDemand)
                child.setWindowState(room.WindowState)
                if (room.OverrideTimeoutUnixTime) {
                	child.setBoost("On")
                } else {
                	child.setBoost("Off")
                }
                roomStatId = room.RoomStatId
                if (roomStatId) child.setHumidity(getHumidity(roomStatId))
            }
        }
}

}

def refreshAllChildren() {
if (showDebug) log.debug "refreshAllChildren()"
def children = getChildDevices()

children.each { child ->
		
		refreshChild(child.deviceNetworkId)
    
}

}

def getHubConfig() {
if (showDebug) log.debug "getHubConfig()"

def result = new hubitat.device.HubAction(
	method: "GET",
    path: "/data/domain/",
    headers: [
    	HOST: hubIP+":80",
        SECRET: systemSecret
    ],
    null,
    [callback: calledBackHandler]
    )
state.action = "Hub Config"
sendHubCommand(result)

}

def getHubUrl(path) {
if (showDebug) log.debug "getHubUrl($path)"

def result = new hubitat.device.HubAction(
	method: "GET",
    path: path,
    headers: [
    	HOST: hubIP+":80",
        SECRET: systemSecret
    ],
    null,
    [callback: calledBackHandler]
    )
//state.action = "Hub Config"
sendHubCommand(result)

}

def sendMessageToHeatHub(path, method, content) {
if (showDebug) log.debug "sendMessageToHeatHub($path, $method, $content)"

def result = new hubitat.device.HubAction(
method: method,
path: path,
headers: [
HOST: hubIP+":80",
SECRET: systemSecret
],
body: content,
null,
[callback: calledBackHandler]
)
//state.action = "Hub Config"
sendHubCommand(result)
}

void calledBackHandler(hubitat.device.HubResponse hubResponse) {
if (showDebug) log.debug "Entered calledBackHandler()..."
if (showDebug) log.debug hubResponse.status
//if (showDebug) log.debug "entering action: " + state.action

if (state.action == "test") log.debug hubResponse.json

if (state.action == "Hub Config") {
	state.hubConfig = hubResponse.json
    
	def rooms = state.hubConfig.Room   

	if (state.hubConfig.HotWater) {
	  	if (showDebug) log.debug "Got hot water"
	    createChildDevices(rooms, true)
	} else {
		if (showDebug) log.debug "No hot water"
		createChildDevices(rooms, false)
	}


}

if (state.action == "refreshChildren" ) {
	state.hubConfig = hubResponse.json
    refreshAllChildren()
}
	

if (hubResponse.status == 200) {
	if (state.action.contains("setPoint")) runIn(3, "getHubConfig")
	if (state.action == "ecoOn") getChildDevice(app.id + ":HUB").setEco(true)
	if (state.action == "ecoOff") getChildDevice(app.id + ":HUB").setEco(false)
    if (state.action == "comfortOn") getChildDevice(app.id + ":HUB").setComfort(true)
    if (state.action == "comfortOff") getChildDevice(app.id + ":HUB").setComfort(false)
    if (state.action.contains("changeroomManualMode")) {
    	def roomId = state.action.split(":")[1]
    	getChildDevice(app.id + ":$roomId").setMode("Manual")
        state.action = ""
    }
    if (state.action.contains("changeroomAutoMode")) {
    	def roomId = state.action.split(":")[1]
    	getChildDevice(app.id + ":$roomId").setMode("Auto")
        state.action = ""
    }
    if (state.action.contains("roomManualMode")) state.action = "change" + state.action
    if (state.action.contains("roomAutoMode")) state.action = "change" + state.action
    
    if (state.action == "hwManualChange") getChildDevice(app.id + ":HW").setMode("Manual")
    if (state.action == "hwAutoChange") getChildDevice(app.id + ":HW").setMode("Auto")
    if (state.action == "hwManual") state.action = "hwManualChange"
    if (state.action == "hwAuto") state.action = "hwAutoChange"
    
    if (state.action == "hwBoostOn") {
    	getChildDevice(app.id + ":HW").setBoost("on")
        getChildDevice(app.id + ":HW").setState("on")
        }
    if (state.action == "hwBoostOff") {
    	getChildDevice(app.id + ":HW").setBoost("off")
        getChildDevice(app.id + ":HW").setState("off")
        }
    if (state.action == "HotWaterOn") getChildDevice(app.id + ":HW").setState("on")
    if (state.action == "HotWaterOff") getChildDevice(app.id + ":HW").setState("off")
    
    if (state.action == "roomBoostOn") {
    	state.action = "refreshChildren"
        getHubUrl("/data/domain/")
    }
    if (state.action == "roomBoostOff") {
    	state.action = "refreshChildren"
        getHubUrl("/data/domain/")
    }
    
}
if (hubResponse.status == 403) {
	if (state.action == "homeModeChange") {
    	getChildDevice(app.id + ":HUB").setMode("Home")
        state.action = "refreshChildren"
        getHubUrl("/data/domain/")
        
    }
    if (state.action == "awayModeChange") {
    	getChildDevice(app.id + ":HUB").setMode("Away")
        state.action = "refreshChildren"
        getHubUrl("/data/domain/")
    }
    if (state.action == "homeMode") state.action = "homeModeChange"
    if (state.action == "awayMode") state.action = "awayModeChange"
	
    
    
}

//if (showDebug) log.debug "exiting action " + state.action

}

private void createChildDevices(rooms, hotwater) {
if (showDebug) log.debug "createChildDevices()"
def children = getChildDevices().deviceNetworkId
def child
def dni

dni = app.id + ":HUB"
if (children.contains(dni)) {
	if (showDebug) log.debug "Device ${dni} already exists"
    refreshHub(dni)
} else {
	try {
    	childDevice = addChildDevice("colc1705", "Drayton Wiser Hub", dni, null, ["label": "Drayton Hub"]) 
        refreshHub(dni)
    } catch (e) {
    	if (showDebug) log.debug "Error creating child device ${e}"
    }
}


for (HashMap room : rooms) {
	def dh
	dni = app.id + ":" + room.id
    if (children.contains(dni)) {
    	if (showDebug) log.debug "Device ${dni} already exists"
        refreshChild(dni)
    } else {
    	try {
        	if (room.RoomStatId) dh = "Drayton Wiser Room"
            if (room.SmartValveIds) dh = "Drayton Wiser TRV"
            childDevice = addChildDevice( "colc1705",dh, "$dni", null, ["label": "Drayton (${room.Name})"])
            //child.setTemp(room.CalculatedTemperature/10, room.CurrentSetPoint/10)
            refreshChild(dni)
    	} catch(e) {
    		if (showDebug) log.debug "Error creating child device ${e}"
    	}
    }
}

//add hot water
if (hotwater) {
	dni = app.id + ":HW"
    if (children.contains(dni)) {
    	if (showDebug) log.debug "Device ${dni} already exists"
        refreshChild(dni)
    } else {
		try {
            child = addChildDevice(app.namespace, "colc1705", "$dni", null, ["label": "Drayton Hot Water"])
            //child.setState(state.json.HotWater.WaterHeatingState)
            refreshChild(dni)
		} catch(e) {
			if (showDebug) log.debug "Error creating child device ${e}"
		}
    }
}

}

void setPoint(dni, setPoint) {
if (showDebug) log.debug "setPoint($dni, $setPoint)"
def roomId = dni.split(":")[1]
//if (showDebug) log.debug roomId
def newSP = setPoint * 10
if (roomId == "HW" ) {
if (showDebug) log.debug "This is the hotwater"

} else {
	state.action = "setPoint:" + roomId
    def payload
    payload = "{\"RequestOverride\":{\"Type\":\"Manual\", \"SetPoint\":" + newSP.toInteger().toString() + "}}"
    sendMessageToHeatHub(getRoomsEndpoint() + roomId.toString(), "PATCH", payload)
}

}

def setAwayMode(awayMode) {
if (showDebug) log.debug "setAwayMode($awayMode)"
def payload
def payload2
payload = "{"Type":" + (awayMode ? "2" : "0") + ","Originator": "App", "setPoint":" + (awayMode ? "50" : "0") + "}"
payload2 = "{"Type":" + (awayMode ? "2" : "0") + ", "setPoint":" + (awayMode ? "-200" : "0") + "}"
state.action = (awayMode ? "awayMode" : "homeMode")
return [sendMessageToHeatHub(getSystemEndpoint() + "RequestOverride", "PATCH", payload), delayAction(1000), sendMessageToHeatHub(getHotwaterEndpoint() + "2/RequestOverride", "PATCH", payload2)]
}

def setHotWaterManualMode(manualMode) {
if (showDebug) log.debug "setHotWaterManualMode($manualMode)"
def payload
def payload2
payload = "{"Mode":"" + (manualMode ? "Manual" : "Auto") + ""}"
payload2 = "{"RequestOverride":{"Type":"None","Originator" :"App","DurationMinutes":0,"SetPoint":0}}"
state.action = (manualMode ? "hwManual" : "hwAuto")
return [sendMessageToHeatHub(getHotwaterEndpoint() + "2", "PATCH", payload), delayAction(1000), sendMessageToHeatHub(getHotwaterEndpoint() + "2", "PATCH", payload2)]
}

def setEcoMode(ecoMode) {
if (showDebug) log.debug "setEcoMode($ecoMode)"
def payload
payload = "{"EcoModeEnabled":" + ecoMode + "}";
state.action = (ecoMode ? "ecoOn" : "ecoOff")
sendMessageToHeatHub(getSystemEndpoint(), "PATCH", payload);
//refresh();
}

def setComfort(comfort) {
if (showDebug) log.debug "setComfort($comfort)"
def payload
payload = "$comfort";
state.action = (comfort ? "comfortOn" : "comfortOff")
sendMessageToHeatHub(getSystemEndpoint(), "PATCH", payload);
}

def getHumidity(roomStatId) {
if (showDebug) log.debug "getHumidity($roomStatId)"
for (HashMap roomStat : state.hubConfig.RoomStat) {
if (roomStatId.toString().equals(roomStat.id.toString())) {
return roomStat.MeasuredHumidity
} else {
return 0
}
}
}

def setRoomManualMode(dni, manualMode) {
if (showDebug) log.debug "setRoomManualMode($dni, $manualMode)"
def roomId = dni.split(":")[1]
def payload
def payload2
payload = "{"Mode":"" + (manualMode ? "Manual" : "Auto") + ""}"
payload2 = "{"RequestOverride":{"Type":"None","Originator" :"App","DurationMinutes":0,"SetPoint":0}}"
state.action = (manualMode ? "roomManualMode:$roomId" : "roomAutoMode:$roomId")
return [sendMessageToHeatHub(getRoomsEndpoint() + roomId.toString(), "PATCH", payload), delayAction(1000), sendMessageToHeatHub(getRoomsEndpoint() + roomId.toString(), "PATCH", payload)]
}

def setRoomBoost(dni, boostTime, temp) {
def roomId = dni.split(":")[1]
def payload
if (boostTime == 0) {
state.action = "roomBoostOff"
payload = "{"RequestOverride":{"Type":"None","Originator":"App","DurationMinutes":0,"SetPoint":0}}"
} else {
boostTime = heatingBoost
state.action = "roomBoostOn"
payload = "{"RequestOverride":{"Type":"Manual","Originator":"App", "DurationMinutes":" + boostTime + ", "SetPoint":"+ (temp * 10).toInteger().toString() + "}}"
}
if (showDebug) log.debug "setRoomBoost($dni, $boostTime, $temp)"
sendMessageToHeatHub(getRoomsEndpoint() + roomId.toString(), "PATCH", payload)
}

def setHotWaterBoost(boostTime) {
def payload
if (boostTime == 0) {
state.action = "hwBoostOff"
payload = "{"RequestOverride":{"Type":"None","Originator":"App","DurationMinutes":" + boostTime + ","SetPoint":0}}"
} else {
boostTime = waterBoost
state.action = "hwBoostOn"
payload = "{"RequestOverride":{"Type":"Manual","Originator":"App","DurationMinutes":" + boostTime + ","SetPoint":1100}}"
}
if (showDebug) log.debug "setHotWaterBoost($dni, $boostTime)"
sendMessageToHeatHub(getHotwaterEndpoint() + "2", "PATCH", payload)
}

def turnHotWaterOn() {
if (showDebug) log.debug "turnHotWateOn()"
def payload
state.action = "HotWaterOn"
payload = "{"RequestOverride":{"Type":"Manual","SetPoint":1100}}"
sendMessageToHeatHub(getHotwaterEndpoint() + "2", "PATCH", payload)
}

def turnHotWaterOff() {
if (showDebug) log.debug "turnHotWateOff()"
def payload
state.action = "HotWaterOff"
payload = "{"RequestOverride":{"Type":"Manual","SetPoint":-200}}"
sendMessageToHeatHub(getHotwaterEndpoint() + "2", "PATCH", payload)
}

private delayAction(long time) {
new hubitat.device.HubAction("delay $time")
}

def getDeviceEndpoint() {
return "/data/domain/Device/"
}

def getRoomstatsEndpoint() {
return "/data/domain/RoomStat/"
}

def getTRVsEndpoint() {
return "/data/domain/SmartValve/"
}

def getRoomsEndpoint() {
return "/data/domain/Room/"
}

def getSchedulesEndpoint() {
return "/data/domain/Schedule/";
}

def getHeatChannelsEndpoint() {
return "/data/domain/HeatingChannel/"
}

def getSystemEndpoint() {
return "/data/domain/System/"
}

def getSystemEndpointv2() {
return "/data/v2/domain/System/"
}

def getStationEndpoint() {
return "/data/network/Station/"
}

def getDomainEndpoint() {
return "/data/domain/"
}

def getHotwaterEndpoint() {
return "/data/domain/HotWater/"
}

metadata {
definition (name: "Drayton Wiser Hub", namespace: "colc1705", author: "Colin Chapman") {
capability "Actuator"
capability "Polling"
capability "Refresh"
capability "Thermostat Mode"
capability "Switch"

    attribute "eco", "string"
    attribute "mode", "string"
    attribute "comfort", "string"
    
    command "test"
    command "ecoOn"
    command "ecoOff"
    command "homeMode"
    command "awayMode"
    command "comfortOn"
    command "comfortOff"
}


    
   
	main(["mode"])
    details(["mode","eco","comfort"])//,"test", "refresh"])
    
    //Uncomment below for V1 tile layout
	//details(["thermostat", "mode_auto", "mode_manual", "mode_off", "heatingSetpoint", "heatSliderControl", "boost", "boostSliderControl", "refresh"])
}

def parse(description) {
logEvent("parse()")

}

def initialize() {
logEvent("Initializing")
//state.json
//state.action
}

def installed() {
logEvent("Executing installed()")
//createChildDevices()
//response(refresh() + configure())
}

def configure() {
logEvent("Executing configure()")

}

def refresh() {
logEvent("Executing refresh()")

}

def updated() {
logEvent("Executing updated()")

}

def test() {
logEvent("test()")
parent.test(device.deviceNetworkId)

}

def setEco(ecoMode) {
logEvent("setEco($ecoMode)")
if (ecoMode) {
sendEvent(name: "eco", value: "on")
} else {
sendEvent(name: "eco", value: "off")
}
}

def setMode(mode) {
logEvent("setMode($mode)")
if (mode == "Away") {
sendEvent(name: "mode", value: "away")
} else {
sendEvent(name: "mode", value: "home")
}

}

def setComfort(mode) {
logEvent("setComfort($comfort)")
if (mode) {
sendEvent(name: "comfort", value: "on")
} else {
sendEvent(name: "comfort", value: "off")
}

}

def ecoOn() {
logEvent("ecoOn()")
parent.setEcoMode(true)
}

def ecoOff() {
logEvent("ecoOff()")
parent.setEcoMode(false)
}

def comfortOn() {
logEvent("comfortOn()")
parent.setComfort(false)
}

def comfortOff() {
logEvent("comfortOff()")
parent.setComfort(true)
}

def homeMode() {
logEvent("homeMode()")
parent.setAwayMode(false)
}

def awayMode() {
logEvent("awayMode()")
parent.setAwayMode(true)
}

def logEvent(event) {
if (parent.showDebugInfo()) {
log.debug event
} else {
//log.debug "Logging disabled"
}
}

metadata {
definition (name: "Drayton Wiser Room", namespace: "colc1705", author: "Colin Chapman", ocfDeviceType: "oic.d.thermostat", mnmn: "SmartThings", vid: "SmartThings-smartthings-Z-Wave_Thermostat") {
capability "Sensor"
capability "Actuator"
capability "Relative Humidity Measurement"
capability "Refresh"
capability "Thermostat"
capability "Temperature Measurement"
capability "Thermostat Heating Setpoint"
capability "Thermostat Operating State"
capability "Health Check"

    attribute "boost", "string"
    attribute "demand", "number"
    
    command "heatingSetpointDown" //"spDown"
    command "heatingSetpointUp" //"spUp"
    command "test"
    command "boostOn"
    command "boostOff"
   
   
    
}

    
    main(["thermostatMulti"])
    details(["thermostatMulti","mode","boost","demand"])
}

def updated() {
logEvent("updated()")

}

def parse(String description) {
logEvent("parse()")
}

def test() {
logEvent("test()")
logEvent("debugging on? " + parent.showDebugInfo())
//parent.test(device.deviceNetworkId)
}

def heatingSetpointUp() {
logEvent("heatingSetpointUp()")
def currentSP = device.currentState("heatingSetpoint").getDoubleValue()
def newSP = currentSP + 0.5
logEvent("Current setting: " + currentSP)
sendEvent(name: "heatingSetpoint", value: newSP, unit: "C", state: "heat")
sendEvent(name: "thermostatSetpoint", value: newSP, unit: "C", state: "heat")
parent.setPoint(device.deviceNetworkId, newSP)

}

def heatingSetpointDown() {
logEvent("heatingSetpointDown()")
def currentSP = device.currentState("heatingSetpoint").getDoubleValue()
def newSP = currentSP - 0.5
logEvent("Current setting: " + currentSP)
sendEvent(name: "heatingSetpoint", value: newSP, unit: "C", state: "heat")
sendEvent(name: "thermostatSetpoint", value: newSP, unit: "C", state: "heat")
parent.setPoint(device.deviceNetworkId, newSP)
}

def setHeatingSetpoint(setpoint) {
logEvent("setHeatingSetpoint($setpoint)")
sendEvent(name: "heatingSetpoint", value: setpoint, unit: "C", state: "heat")
sendEvent(name: "thermostatSetpoint", value: setpoint, unit: "C", state: "heat")
parent.setPoint(device.deviceNetworkId, setpoint)
}

def setTemp(temp, setPoint) {
logEvent(device.name + " is " + temp + "Ā°C")
sendEvent(name: "temperature", value: temp, unit: "Ā°C", state: "heat")
sendEvent(name: "heatingSetpoint", value: setPoint, unit: "C", state: "heat")
sendEvent(name: "thermostatSetpoint", value: setPoint, unit: "C", state: "heat")
}

def setHumidity(humidity) {
logEvent("setHumidity($humidity)")
sendEvent(name: "humidity", value: humidity, unit: "%")

}

def setMode(mode) {
logEvent("setMode($mode)")
sendEvent(name: "mode", value: mode)
}

def setBoost(boost) {
logEvent("setBoost($boost)")
sendEvent(name: "boost", value: boost)
}

def autoMode() {
logEvent("autoMode()")
parent.setRoomManualMode(device.deviceNetworkId, false)
}

def manualMode() {
logEvent("manualMode()")
parent.setRoomManualMode(device.deviceNetworkId, true)
}

def boostOn() {
logEvent("boostOn()")
def currentTemp = device.currentState("temperature").getDoubleValue()
currentTemp = 0.5*(Math.round(currentTemp/0.5))
def setPoint = currentTemp + 2
parent.setRoomBoost(device.deviceNetworkId,30,setPoint)
}

def boostOff() {
logEvent("boostOff()")
parent.setRoomBoost(device.deviceNetworkId,0,0)
}

def setOutputState(outputState) {
logEvent("setOutputState($outputState)")
sendEvent(name: "outputState", value: outputState)
}

def setDemand(demand) {
logEvent("setDemand($demand)")
sendEvent(name: "demand", value: demand)
}

def logEvent(event) {
if (parent.showDebugInfo()) {
log.debug event
} else {
//log.debug "Logging disabled"
}
}

metadata {
definition (name: "Drayton Wiser TRV", namespace: "colc1705", author: "Colin Chapman", ocfDeviceType: "oic.d.thermostat", mnmn: "SmartThings", vid: "SmartThings-smartthings-Z-Wave_Thermostat") {
capability "Thermostat"
capability "Temperature Measurement"
capability "Relative Humidity Measurement"
capability "Sensor"
capability "Battery"
capability "Refresh"
capability "Health Check"

    attribute "boost", "string"
    attribute "demand", "number"
    attribute "windowState", "string"
    attribute "battery", "string"
    
    command "heatingSetpointup" //"spDown"
    command "heatingSetpointDown" //"spUp"
    command "test"
    command "boostOn"
    command "boostOff"
    
    
}


    
    main(["thermostatMulti"])
    details(["thermostatMulti","mode","boost","demand","windowState"])
}

def updated() {
logEvent("updated()")

}

def parse(String description) {
logEvent("parse()")

}

def test() {
logEvent("test()")
parent.test(device.deviceNetworkId)
}

def heatingSetpointUp() {
logEvent("heatingSetpointUp()")
def currentSP = device.currentState("heatingSetpoint").getDoubleValue()
def newSP = currentSP + 0.5
logEvent("Current setting: " + currentSP)
sendEvent(name: "heatingSetpoint", value: newSP, unit: "C", state: "heat")
sendEvene(name: "thermostatSetpoint", value: newSP, unit: "C", state: "heat")
parent.setPoint(device.deviceNetworkId, newSP)

}

def heatingSetpointDown() {
logEvent("heatingSetpointDown()")
def currentSP = device.currentState("heatingSetpoint").getDoubleValue()
def newSP = currentSP - 0.5
logEvent("Current setting: " + currentSP)
sendEvent(name: "heatingSetpoint", value: newSP, unit: "C", state: "heat")
sendEvent(name: "thermostatSetpoint", value: newSP, unit: "C", state: "heat")
parent.setPoint(device.deviceNetworkId, newSP)
}

def setHeatingSetpoint(setpoint) {
logEvent("setHeatingSetpoint($setpoint)")
sendEvent(name: "heatingSetpoint", value: setpoint, unit: "C", state: "heat")
sendEvent(name: "thermostatSetpoint", value: setpoint, unit: "C", state: "heat")
parent.setPoint(device.deviceNetworkId, setpoint)
}

def setTemp(temp, setPoint) {
logEvent(device.name + " is " + temp + "Ā°C")
sendEvent(name: "temperature", value: temp, unit: "C", state: "heat")
sendEvent(name: "heatingSetpoint", value: setPoint, unit: "C", state: "heat")
sendEvent(name: "thermostatSetpoint", value: setpoint, unit: "C", state: "heat")
}

def setMode(mode) {
logEvent("setMode($mode)")
sendEvent(name: "mode", value: mode)
}
def setbatteryleval(battery) {
logEvent("setBatterylevel($battery)")
sendEvent(name: "batterylevel", value: battery, unit: "%")
}
def setBoost(boost) {
logEvent("setBoost($boost)")
sendEvent(name: "boost", value: boost)
}

def setWindowState(wState) {
logEvent("setWindowState($wState)")
sendEvent(name: "windowState", value: wState)
}

def autoMode() {
logEvent("autoMode()")
parent.setRoomManualMode(device.deviceNetworkId, false)
}

def manualMode() {
logEvent("manualMode()")
parent.setRoomManualMode(device.deviceNetworkId, true)
}

def boostOn() {
logEvent("boostOn()")
def currentTemp = device.currentState("temperature").getDoubleValue()
currentTemp = 0.5*(Math.round(currentTemp/0.5))
def setPoint = currentTemp + 2
parent.setRoomBoost(device.deviceNetworkId,30,setPoint)
}

def boostOff() {
logEvent("boostOff()")
parent.setRoomBoost(device.deviceNetworkId,0,0)
}
def setHumidity(humidity) {
logEvent("setHumidity($humidity)")
sendEvent(name: "humidity", value: humidity, unit: "%")
}

def setOutputState(outputState) {
logEvent("setOutputState($outputState)")
sendEvent(name: "outputState", value: outputState)
}

def setDemand(demand) {
logEvent("setDemand($demand)")
sendEvent(name: "demand", value: demand)
}

def logEvent(event) {
if (parent.showDebugInfo()) {
log.debug event
} else {
//log.debug "Logging disabled"
}
}

for anyone who wants it I have posted up the app and drivers for drayton wiser heating.
first is the app, second is the hub driver, third is the room stat driver and lastly the trv driver.
this is not my own work this was ported from smartthings, all I did was get it to work in Hubitat.

I have been using it for a few months and it works great. The only part not working is the hot water and battery reporting for the TRV's.

If anyone needs any help on how to install this then drop me a mail.
Mark.

Hi Mark,
thanks for posting that. It is working nicely from what I can see. do you get:
[error] org.codehaus.groovy.runtime.metaclass.MissingMethodExceptionNoStack: No signature of method: user_driver_colc1705_Drayton_Wiser_Room_501.setWindowState() is applicable for argument types: () values: [] (setWindowState)?

I will need to look and see if I can learn what I was doing wrong now.
Neil

Hi neil,
not had any errors for the window state, all mine are showing as closed matching what I see in the wiser app.

Hi Mark,
thanks I will try and work out what is causing the error, it will need to wait until I get back from work .

Neil

Slightly off topic, but just wondering how you found the performance of the trvs?

I struggled with them for months before giving up. The reliability was horrendous.

(I use an alternative system now which has been 100%)

Hi, I have only been using the Drayton wiser TRVā€™s for about 3 months and so far they have been rock solid. My only criticism would be one TRV is slightly noisy and if it were in a bedroom it would disturb me.
What did you change to.

=)

I have been using Drayton wiser for well over a year and have to say they have been solid.
I had one try die after replacing batteries (not sure why) but since replacing it they have all been good.
I use them all over the house, 6 trvā€™S and one room stat.
I also like that you can create a room and have more then one device so in my living room I have 2 radiators and a room stat, I never touch the trvs in that room as all changes are made off the room stat on the wall.

Thatā€™s interesting, I had never heard of these wired thermal actuators before, just looked them up on Amazon.

To be fair I was using them via a 3rd party dht through smartthings at the time, without the wiser hub. The trv was about 30 quid, and due to that, I believed I could justify buying more to end up with 7 zone heating. I found it would work for a week maybe, then I'd realise a rad hadn't heated up when it should have, checked the logs and saw it had actually dropped off the network days before. Battery pulls were fairly frequent.

Wasn't willing to shell out for a dedicated wiser hub, so ended up returning them and taking a crack with the thermal actuators.

Never looked back.

Hi Neil,

Did you figure out the setWindowState error at all? I'm getting the same issue.