good catch, i didnt realise.
No. I copied the code using the raw tab. Very strange.
@Fuzzyligic would it be hard to change the temperture from Celsius to Fahrenheit? I f it easy could you walk me through it as I would like to learn. Thanks
this in fact would be very very easy as the tado web service reports back both Celsius and Fahrenheit. Probably what would be best would be to add a preference for which one you would like. Let me take a look later today if i have time and I will give you step by step on how I do it.
OK well i knocked up the code, however i have hit a major snag i cannot overcome unless i change completely how i do this.
the problem is that i cannot change the value of the tiles to either C or Fahrenheit as i cannot change the display value of the device type dynamically. to do this i would need to create a smartapp and install a different device type whether you choose C or F as your display value⌠this is too much work for me to figure out now.
but this is on my todo list as i want to write an encompassing Smartapp to install the device type and run the query, at the moment i am running far too many individual queries to Tado where i could do this all in one.
but for the moment i will explain how i work out things when logging into Tado.com, i use Fiddler 4 installed on my PC and then just log into Tado. this captures and displays the traffic sent and received from Tado
so in the original code i was running was getting the temperature display from the insideTemp Value from /mobile/1.6/GetCurrentState
but this value is in Celsius and not Fahrenheit, however the hvacstate shows the following
as you can see the InsideTemperature Field here shows both Celsius and Fahrenheit Values.
so in the original code you can see in the sendCommand function that we query a few different URLâs to get the values we need
private sendCommand(method, args = ) {
def methods = [
âstatusâ: [
uri: âhttps://my.tado.comâ,
path: â/mobile/1.6/getCurrentStateâ,
requestContentType: âapplication/jsonâ,
query: [username:settings.username, password:settings.password]
],
âhvacStatusâ: [
uri: âhttps://my.tado.comâ,
path: â/api/v1/home/â + state.homeId + â/hvacStateâ,
requestContentType: âapplication/jsonâ,
query: [username:settings.username, password:settings.password]
],
âtemperatureâ: [
uri: âhttps://my.tado.comâ,
path: â/api/v2/homes/â + state.homeId + â/zones/1/overlayâ,
requestContentType: âapplication/jsonâ,
query: [username:settings.username, password:settings.password],
body: args[0]
],
âweatherStatusâ: [
uri: âhttps://my.tado.comâ,
path: â/api/v1/home/â + state.homeId + â/weatherâ,
requestContentType: âapplication/jsonâ,
query: [username:settings.username, password:settings.password]
]
]
def request = methods.getAt(method)
log.debug "Http Params ("+request+")"
try{
log.debug "Executing 'sendCommand'"
if (method == "status"){
httpGet(request) { resp ->
parseResponse(resp)
}
}else if (method == "hvacStatus"){
httpGet(request) { resp ->
parseHvacResponse(resp)
}
}else if (method == "temperature"){
httpPut(request) { resp ->
parseputResponse(resp)
}
}else if (method == "weatherStatus"){
log.debug "calling weatherStatus Method"
httpGet(request) { resp ->
parseweatherResponse(resp)
}
}else{
httpGet(request)
}
} catch(Exception e){
debug("___exception: " + e)
}
}
If you break down this the only things we are interested in is the Status and HVACStatus. if you look at the method evaluation you can see that we run either the parseResponse or the parseHvacResponse functions for the values from the selected methods.
so the original parseResponse where we get the Temp from shows
// Parse incoming device messages to generate events
private parseResponse(resp) {
log.debug("Executing parseResponse: "+resp.data)
log.debug("Output status: "+resp.status)
def temperatureUnit = âCâ
def humidityUnit = â%â
if(resp.status == 200) {
log.debug(âExecuting parseResponse.successTrueâ)
def temperature = Math.round(resp.data.insideTemp)
log.debug("Read temperature: " + temperature)
sendEvent(name: 'temperature', value: temperature, unit: temperatureUnit)
log.debug("Send Temperature Event Fired")
state.homeId = resp.data.homeId
log.debug("Got HomeID Value: " + state.homeId)
def autoOperation = resp.data.autoOperation
if(resp.data.operation == "NO_FREEZE"){
autoOperation = "OFF"
}else if(resp.data.operation == "MANUAL"){
autoOperation = "MANUAL"
}
log.debug("Read autoOperation: " + autoOperation)
sendEvent(name: 'autoOperation', value: autoOperation)
log.debug("Send autoOperation Event Fired")
}else if(resp.status == 201){
log.debug("Something was created/updated")
}
}
the modified code removes the temperature evaluation from this function as this is only in celsius
// Parse incoming device messages to generate events
private parseResponse(resp) {
log.debug("Executing parseResponse: "+resp.data)
log.debug("Output status: "+resp.status)
def temperatureUnit = â${settings.tempunit}â
def humidityUnit = â%â
if(resp.status == 200) {
log.debug(âExecuting parseResponse.successTrueâ)
state.homeId = resp.data.homeId
log.debug("Got HomeID Value: " + state.homeId)
def autoOperation = resp.data.autoOperation
if(resp.data.operation == "NO_FREEZE"){
autoOperation = "OFF"
}else if(resp.data.operation == "MANUAL"){
autoOperation = "MANUAL"
}
log.debug("Read autoOperation: " + autoOperation)
sendEvent(name: 'autoOperation', value: autoOperation)
log.debug("Send autoOperation Event Fired")
}else if(resp.status == 201){
log.debug("Something was created/updated")
}
}
so we know we need to get the temperature from HVACStatus as it displays in both Celsius and Fahrenheit, so the original ParseHvacResponse was
private parseHvacResponse(resp) {
log.debug("Executing parseHvacResponse: "+resp.data)
log.debug("Output status: "+resp.status)
def temperatureUnit = âCâ
def humidityUnit = â%â
if(resp.status == 200) {
log.debug(âExecuting parseHvacResponse.successTrueâ)
def humidity
if (resp.data.humidity.percentage != null){
humidity = resp.data.humidity.percentage
}else{
humidity = "--"
}
log.debug("Read humidity: " + humidity)
sendEvent(name: 'humidity', value: humidity,unit: humidityUnit)
}
def ACMode
def ACFanSpeed
def setPointTemp
if (resp.data.acSetting.power == "OFF"){
ACMode = "OFF"
log.debug("Read ACMode: " + ACMode)
ACFanSpeed = "OFF"
log.debug("Read acFanSpeed: " + ACFanSpeed)
setPointTemp = "0"
log.debug("Read setPointTemp: " + setPointTemp)
}
else if (resp.data.acSetting.power == "ON"){
ACMode = resp.data.acSetting.mode
log.debug("Read ACMode: " + ACMode)
ACFanSpeed = resp.data.acSetting.fanSpeed
log.debug("Read acFanSpeed: " + ACFanSpeed)
if (ACMode == "DRY"){
setPointTemp = "--"
}else if (ACMode == "AUTO"){
setPointTemp = "--"
}else{
setPointTemp = Math.round(resp.data.acSetting.temperature.celsius)
}
log.debug("Read setPointTemp: " + setPointTemp)
}
else{
log.debug("Executing parseHvacResponse.successFalse")
}
sendEvent(name: 'ACFanSpeed', value: ACFanSpeed)
log.debug("Send ACFanSpeed Event Fired")
sendEvent(name: 'ACMode', value: ACMode)
log.debug("Send ACMode Event Fired")
sendEvent(name: 'setPointTemp', value: setPointTemp, unit: temperatureUnit)
log.debug("Send setPointTemp Event Fired")
}
but the updated code is
private parseHvacResponse(resp) {
log.debug("Executing parseHvacResponse: "+resp.data)
log.debug("Output status: "+resp.status)
def temperatureUnit = âFâ
def temperatureUnitName = fahrenheit
def humidityUnit = "%"
if(resp.status == 200) {
log.debug("Executing parseHvacResponse.successTrue")
def temperature = Math.round(resp.data.insideTemperature."${temperatureUnitName}")
log.debug("Read temperature: " + temperature)
sendEvent(name: 'temperature', value: temperature, unit: temperatureUnit)
log.debug("Send Temperature Event Fired")
def humidity
if (resp.data.humidity.percentage != null){
humidity = resp.data.humidity.percentage
}else{
humidity = "--"
}
log.debug("Read humidity: " + humidity)
sendEvent(name: 'humidity', value: humidity,unit: humidityUnit)
}
def ACMode
def ACFanSpeed
def setPointTemp
if (resp.data.acSetting.power == "OFF"){
ACMode = "OFF"
log.debug("Read ACMode: " + ACMode)
ACFanSpeed = "OFF"
log.debug("Read acFanSpeed: " + ACFanSpeed)
setPointTemp = "0"
log.debug("Read setPointTemp: " + setPointTemp)
}
else if (resp.data.acSetting.power == "ON"){
ACMode = resp.data.acSetting.mode
log.debug("Read ACMode: " + ACMode)
ACFanSpeed = resp.data.acSetting.fanSpeed
log.debug("Read acFanSpeed: " + ACFanSpeed)
if (ACMode == "DRY"){
setPointTemp = "--"
}else if (ACMode == "AUTO"){
setPointTemp = "--"
}else{
setPointTemp = Math.round(resp.data.acSetting.temperature."${temperatureUnitName}")
}
log.debug("Read setPointTemp: " + setPointTemp)
}
else{
log.debug("Executing parseHvacResponse.successFalse")
}
sendEvent(name: 'ACFanSpeed', value: ACFanSpeed)
log.debug("Send ACFanSpeed Event Fired")
sendEvent(name: 'ACMode', value: ACMode)
log.debug("Send ACMode Event Fired")
sendEvent(name: 'setPointTemp', value: setPointTemp, unit: temperatureUnit)
log.debug("Send setPointTemp Event Fired")
}
take note on how we are getting the temperature value and substituting the Json resp path to the value.
this is the main point of how we get the data, the remainder of the changes revolve around changing where is says C or Celsius to be F & Fahrenheit respectivelyâŚ
the full code of the changes is below , word of warning though, i have not tested this at all due to time constraints, please try and let me know the results, alternatively if there is any debugging needed please attempt and let me know if you get stuck. I hope this helps?
@Fuzzyligic Hey i just want to thank you for explaining the changes to me and the effort you put forward which is alot more that I expected. I will try it this weekend when I get home. Thanks I will have to buy you a pint or so at your favorite pub. Thanks
Hi,
Just wanted to thank you for the tado support working great ⌠wanted to ask a questionâŚ
I am using smart tiles and noticed the temperature seems to never check automatically I need to launch âthingsâ and manually push refresh to get the temperature updated have I missed a step ?
thankd
you havenât missed anything, the device type doesnât schedule an update yet, just use pollster to the updates for the device.
I had tado for a while but out in the drawer waiting for St integration. Currently using sensibo which works ok but itâs unstable as the distance to the pod is a bit too far for zigbee.
How is this device type working on st ? Anyone using it with thermostat director in smartthings? Would you recommend it ? Hopefully tado is stable. As its wifi should be.
Tado for me is stable, I donât have issues with these device types but as for using with thermostat director I donât know. I still use the Tado schedules etc. And just use these to override the behaviour when needed. I think that is a safer option with STâs unreliability, however the device types do conform to the thermostat capability if you decided to remove all schedules from Tado and use ST for the scheduling I am sure it should just work.
I have in the pipeline a Tado smartapp to tie all the products together, however I am still trying to hack through their oAuth procedure as Tado were unwilling to assist me
Thanks for that. Sucks they are not willing to help. Wonder why, resources perhaps.
Iâll give it a try soon and see how it goes with thermostat director !
@Fuzzyligic after copy the taco-cooling-ac.groovy to Device handler type Iâm SmartThing IDE and save/published for me, then ? what is next step ?
I can not see the device show in my SmartThings ?, Is that because i am using the iPhone, and this source code currently working for Android device ?, Please advise, If you can have detail install instruction, that will be great ? By the way, There is no SmartApp to control this device ?, Only Device Type need create ?
once the device type has been created you then need to click on your My Devices tab in the IDE and then choose add new device. then you add your device and name it what you want and then choose the Tado Thermostat Device Handler from the Type Menu as shown
then click create then all you need to do is find the device in the SmartThings app and look at the device properties, and enter your Tado username and password once done all you need to do is hit refresh and the device should update.
these releases donât schedule the refresh too well, so it would be best to add the device into the pollster smartapp to refresh the status every 5 minutes.
I am working on updated device handlers and smartapps but time has been short recently and ive been struggling with the motivation, but i will have something ready i imagine in the next few weeks
just replied via PM, please read and action accordingly
@Fuzzyligic, Thanks for your remind, I have change the password for safety issue. but I have check the source I copy are exactly same as you mention, and It still same message as I face, even I create the device againâŚsee below message, Error in line 393, What is that mean. I am using the iPhone 6s+ , iOS 9.0.2, and SmartThing and Tado Apps are all latest version.
1503f0b1-9349-48cf-b36d-c90933bc6d14 ä¸ĺ10:10:24: error groovy.lang.MissingMethodException: No signature of method: script14597788066271803256152.debug() is applicable for argument types: (java.lang.String) values: [___exception: groovyx.net.http.HttpResponseException: Not Found]
Possible solutions: input(java.lang.String), getAt(java.lang.String), getLog(), dry(), run(), dump() @ line 393
1503f0b1-9349-48cf-b36d-c90933bc6d14 ä¸ĺ10:10:23: debug Executing 'sendCommandâ
1503f0b1-9349-48cf-b36d-c90933bc6d14 ä¸ĺ10:10:23: debug Http Params ([uri:https://my.tado.com, path:/api/v2/homes/null/zones/1/overlay, requestContentType:application/json, query:[username:mitXXXXXX@gXXX.com, password:xxxxxxxxxx], body:{âsettingâ:{âtypeâ:âAIR_CONDITIONINGâ,âpowerâ:âOFFâ},âterminationâ:{âtypeâ:âTADO_MODEâ}}])
1503f0b1-9349-48cf-b36d-c90933bc6d14 ä¸ĺ10:10:23: debug Executing 'sendCommand.offCommandâ
1503f0b1-9349-48cf-b36d-c90933bc6d14 ä¸ĺ10:10:23: debug Executing âoffâ
@Fuzzyligic. It work with your newest code, However, I notice that we only can read Temperature and Humidity from the device, but we can not set the temp, Turn on of Turn off the AC, either in change mode to AC, Fan, Dry,Do you plan to add those function in the future ?
I am able to turn on and off the AC using the on and off buttons and set the temps for the heating and cooling modes, however you cannot set the temps in Fan, Dry or Auto Modes in the Tado App either this is a limitation of those modes and the API does not accept these commands. ideally i would like to hide the setpoint tiles if you are in the heat and dry modes, but ST currently does not support this.
i do have further improvements planned but i am still limited by Tadoâs API
(post withdrawn by author, will be automatically deleted in 24 hours unless flagged)
You might want to edit this post to remove your user Id and password
ok it seems when you are sending the commands you are getting the exception: groovyx.net.http.HttpResponseException: Unprocessable Entity
Looking at this it seems the issue is that your device is different to mine as the fanspeed does not support AUTO mode so if you search your device handler and replace
fanSpeed:"AUTO"
with
fanSpeed:âHIGHâ
the on and off and temp setpoints should begin to work
The problem with this whole endevour is that there is no documented API so everything i am doing is by trial and error, but yours is a good example where there is marked differences between the locations