[Resurrected] Advanced Honeywell T6 Pro Z-Wave Thermostat Driver

Advanced Honeywell T6 Pro Z-Wave Thermostat Driver

By request I've pulled the code for @bcopeland's excellent driver and have merged in several requested updates. (Thank you @jch for sending me a device for testing.)

Old thread location: [NOT MAINTAINED] Advanced Honeywell T6 Pro Z-Wave Thermostat Driver

DRIVER CAPABILITIES

  • Battery
  • Power Source
  • Relative Humidity Measuremennt
  • Temperature Measurement
  • Thermostat (obviously)

ADVANCED FEATURES

  • Clock Synchronization (regularly scheduled clock synchronization to prevent clock drift)
  • Access to all 42 configuration options - This thing does a lot! And you won't have to keep scrolling through the on screen menus to set it all.
  • Power Source monitoring for power failure (when utilizing c-wire and battery backup)

Available via HPM or for direct import from:
https://raw.githubusercontent.com/thebearmay/hubitat/main/bcopeland/Advanced-Honeywell-T6-Pro-Thermostat.groovy

Version changes:
(v1.2.15)

  • update temperature and humidity if null (adding a new device issue)

(v1.2.14)

  • refresh will create temperature and humidity events regardless of deltas

(v1.2.13)

  • add thermostatFanOperatingState attribute
  • replace sendAllTemps with deltaTempRpt and deltaHumRpt

(v1.2.12)

  • Basic Report missing operation state condition correction

(v1.2.11)

  • code reversion fix on “scale”

(v1.2.10)

  • change order on mains reconnect event to sync the clock first

(v1.2.9)

  • change the lastActivity check to use the device property instead of an attribute
  • check for a temperature scale not equal to requested scale
  • minor code cleanup

(v1.2.7/1.2.8)

  • Fix typo in 1.2.6

(v1.2.6)

  • Add force Clock Sync time option
  • Add lastActivity attribute
  • Add Clock Sync if mains reconnected event occurs

(v1.2.5)

  • Force temperature precision to the 10ths position
  • Fix setpoint rounding issue
  • Add option to always create temperature and humidity events even if no change
  • Fully implement presence sensor capability from jken99 pull request (note: required usage of standard presence values: [ "present", "not present"]

(v1.2.4)

  • Merge jken99 pull request (presence)

(v1.2.1 - 1.2.3)

  • Post 269 modifications
  • Minor house keeping to pull over from base line code
8 Likes

The spurious Fahrenheit temperature events appear to be related to the refresh command. When the Thermostat Scheduler calls for a refresh, that causes a Fahrenheit temperature event;


When I manually use the refresh command on the device page, that also causes a Fahrenheit temperature event.

Without calling refresh I'm not seeing many temperature events. Does the thermostat only report temperature events when the temperature changes by some value? Maybe I should have the Scheduler ask for a refresh periodically, even though it generates Fahrenheit events.

I'll throw it on mine

@thebearmay Not sure if this can be done with the Honeywell (It works with my Sinope though) Can the back light be controlled via z-wave? Use Case: At a particular time (or indoor lux level) when you walk past a particular motion sensor the back light of the thermostat will briefly come on for a set amount of time (lets say 30 seconds). As I said I do this with my Sinope, but wondered if it could be done with the t6... :slight_smile: Just an idea.

This driver has a command button for the thermostat back light: Idle Brightness
Zero is off, Five is maximum brightness.

I suppose I could use that to motion sense>set custom attribute illum to 5 for 60 seconds, set attribute illum to 0 exit. Hmmm... Will have to think about this one.

I do adjust brightness dynamically based on time of day, but leveraging Motion around the thermostat would great to

1 Like

I swapped the 0:1 to be 1:0 at line 307 and now refresh gives temperatures in Celsius:

307 cmds.add(zwave.sensorMultilevelV5.sensorMultilevelGet(sensorType: 1, scale: configParam2==0?1:0))

The variable configParam2 is an enum where 0->Fahrenheit and 1->Celsius, but the code at lines 461 and 494 and 567 all map cmd.scale as 0->Celsius and 1->Fahrenheit.
Maybe if I look at this harder I can make them match each other rather than being reversed.

Thanks, I’ll make that change, and then run through the code and make sure that it’s consistant.

1 Like

I used the Dashboard Thermostat tile to raise the set point from 13C. Each click of the up-arrow in the Thermostat tile raised the temperature by a half degree C, but the Thermostat display quickly jumped to the next higher rounded degree. My last click showed 19.5C but the display jumped to 20C. The heat came on but stopped when the temperature hit 19.5C. I looked at the Advanced T6 Driver debug logs and saw:

setHeatingSetpoint(13.5) called
setHeatingSetpoint(14.5) called
setHeatingSetpoint(15.5) called
setHeatingSetpoint(16.5) called
setHeatingSetpoint(17.5) called
setHeatingSetpoint(18) called
setHeatingSetpoint(18.5) called
setHeatingSetpoint(19) called
setHeatingSetpoint(19.5) called

Even though the Thermostat tile displayed a set point of 20C, the actual value sent to the thermostat by the driver was only 19.5C and that's where the heat shut off. Looking at the Driver event list showed command-setHeatingSetpoint command events, but the corresponding heatingSetpoint events were all rounded integers:

heatingSetpoint     14 C
heatingSetpoint     15 C
heatingSetpoint     16 C
heatingSetpoint     17 C
heatingSetpoint     18 C
heatingSetpoint     19 C
heatingSetpoint     20 C

Those event numbers are the rounded-up values from above. The event says the set point is 20C, but the debug log shows that it's really only been set to 19.5C.

Checking the debug log, the thermostat is reporting temperatures to one decimal place:

got temp: 18.5
got temp: 19.0
got temp: 19.3
got temp: 19.5
got temp: 19.8
got temp: 20.0

It's the events generated by the Driver that have the incorrect rounded values.

The Thermostat tile is sending the correct half-degree information to the Driver, and the Driver is sending that half-degree information to the actual thermostat, but the Driver is generating an event that is unhelpfully rounding up and that event causes the Thermostat tile to display that incorrect rounded-up value when it hears the event.

I went back to the Thermostat tile and used the down-arrow; the temperature display went from 20C to 19.5C and stayed there (no rounding). I pushed the up-arrow and the temperature went back up to 20C. The log showed:

setHeatingSetpoint(19.5) called
setHeatingSetpoint(20) called

and the heat came on and shut off when it reached 20C. The Driver event list had showedthecommand-setHeatingSetpoint command events, but no heatingSetpoint events. The lack of events is why using the down-arrow in the Thermostat tile didn't round.

Something is amiss with rounding and event reporting. Surely the events should show the actual set points, not rounded set points? The rounded set point events fool the Thermostat tile into showing them even though they are rounded and incorrect.

Think I saw that code the other day when I looking for something else. Should be an easy fix.

Edit: Does changing line this around line 486

    if (newmode==mode) {
        eventProcess(name: "thermostatSetpoint", value: Math.round(value), unit: unit, type: state.isDigital?"digital":"physical")
    }

to

    if (newmode==mode) {
        eventProcess(name: "thermostatSetpoint", value: Math.round(value*10)/10, unit: unit, type: state.isDigital?"digital":"physical")
    }

solve the problem?

1 Like

Almost - I had to do the same rounding fix to the setPoint events on line 497 and 501 and that fixed the rounding for both thermostatSetpoint and heatingSetpoint (and for coolingSetpoint for next summer). Now when I use the Thermostat tile to move a half-degree, the generated event temperatures match the tile temperatures. (The Thermostat tile actually shows the temperature going from 16.5C to 17.0C and then immediately the generated event changes the temperature from 17.0C to 17C without the decimal. I suppose one could insert the Groovy equivalent of a printf("%.1f",...) to preserve the trailing .0 in the event, but it's good enough.)

Pushed up a new version with the rounding changes and changed the temperature format to a fixed 00.0

1 Like

If you use the %.1f format, I don't think you need Math.round or the *10/10 trick at all. The format does the rounding for you (if it works the same way in Groovy as everywhere else). There may be some disagreement on whether 0.05 rounds up or down, but who cares when it's only a tenth of a degree difference!

eventProcess(name: "thermostatSetpoint", value: String.format("%.1f",value), ...

True I could simplify that. Thanks.

1 Like

Something I can't figure out is why the debug log shows incoming temperature information from the thermostat that is not getting sent out as an event, even though eventProcess() is called right after the log.debug statement (lines 461-462). Does eventProcess() suppress duplicate events, so if the temperature is the same as last time eventProcess() just ignores it? Not what I want. Even though I have Thermostat Scheduler calling refresh every five minutes, I don't see any temperature event unless the value is different from last time. How can I force eventProcess() to create the event?

By default an event will not be created if there isn't a change in value.

1 Like

Can an event be forced?

This is a pain if I'm graphing the values, since if I pick a time range where the value hasn't changed, the graph is empty because there are no events in that time range. I really do want to make sure the temperature gets logged on a regular basis even if it hasn't changed. I suppose I can write a script to process the temperature event log and create pseudo-events to fill in the gaps, but I was hoping I could fix the problem at source.

It can be forced by adding isStateChange:true after the unit in the eventProcess() command. Think I have Grafana set to interpret a missing value as the same as the previous - forget what the setting was though.

"Same as previous" only works if you send a previous to the graphing program and let the graphing program select the time slice. If you pre-select the data by time before sending it to the graphing program, and if the selected time slice doesn't have a previous, that's a problem.

Perhaps we could add a parameter allowDuplicate to the driver that when set would always display events, even if duplicate.

At the very least, a refresh should display all the events, even ones that haven't changed. (Or invent some other command that does this.) I'm not sure how to code that, but it might involve having refresh save and then set the allowDuplicate flag before it asks for all the values from the thermostat, so that as the values come back they all forcibly create events. (I'm assuming that values come back asynchronously?) After some period of wait time, restore allowDuplicate back to its original saved state.

Or something like that. I'm not a device driver coder. Yet.

1 Like