Author Topic: Need help getting started, trying to get themostat with heat/cool setpoints  (Read 312 times)

Offline Jeff D

  • Sr. Newbie
  • *
  • Posts: 35
  • Karma: +0/-0
I'm one of those folks who like the old UI5 hot/cold set-points for the thermostat controller and wanted to get the same working for UI7 on the plus. I found a unused controller plugin in the default plugins for 2-setpoints and after looking through the UI5 and UI7 json and xml files thought I had something which should work. The plugin xml looks to be correctly configured to support hot-setpoint and cool-setpoint json calls. My thermostat supports both these commands as was used in UI5.

What I see in the vera web UI in the scene editor is that my commands are listed as turning the termostat to auto mode and then ON with the cool value then ON with the hot value. Testing out with delays I've changed to three delayed steps: set hot, set cool, set auto. First the themostat selects heat mode, then the heat setpoint gets set correctly, but the cool setpoint also gets set.  I didn't see anything in the UI which indicates anything other than it getting set ON with a temp value of 68.

I don't totally understand how the xml and json files are used by the UI and how it gets its information because these should be setpoint commands not ON/OFF commands and the UI appears to think this is a ON command. I just need to be sure the set heat setpoint and cool setpoints are independent and both being called with the correct values (I'm assuming the values displayed in the UI are correctly getting parsed) But given my setting auto, setting hot setpoint and setting cool setpoint look to be converted into set auto; set on temp (cool val); set on temp (hot value) it doesn't look correct.

Can anyone explain the flow of how this works? I'm interested in are how does the UI decide this is a ON at temp level instead of the set heat-setpoint command? When the scene controller dispatches to the plugin what is that execution flow?


Offline rigpapa

  • Sr. Member
  • ****
  • Posts: 465
  • Karma: +66/-0
Your post doesn't give quite enough detail to frame what you're actually looking at, and why you are drawing the conclusions you are. More specifics always helps. That said, I've recently implemented four dual-heating-cooling thermostat plugins, two of which are currently published, so I've been elbows deep in this stuff for a while, and I can tell you what I've observed.

First, you're welcome to look at my plugin code, which is here: and here:

Control of a thermostat is split among several services:
  • urn:upnp-org:serviceId:HVAC_UserOperatingMode1 - According to UPnP, this principally handles the operating mode and state of the thermostat. The desired operating mode is saved in the state variable ModeTarget, and is set with the SetModeTarget option (you give it a single parameter NewModeTarget; do not set the state variable directly). The most basic modes are "Off", "HeatOn", "CoolOn" and "AutoChangeOver". There are others, and you can see the full list here: If you set the mode to "HeatOn", this does not automatically start heating--it tells the thermostat to honor the heating setpoint (more later) and start heating if the measured ambient temperature drops below that point (many thermostats also have a differential of 1 or 2 degrees, meaning the temp has to drop that far below the setpoint before it starts heating). Cooling does the same--calls for cooling when ambient exceeds the cooling setpoint. AutoChangeOver will automatically switch between heating and cooling as needed (not all thermostats support this). The ModeStatus variable in UPnP is supposed to reflect the current operating state of the unit, but Vera does not use it this way--for some reason they created an additional service and variable in which to store that data, and so on Vera, ModeStatus pretty much just follows ModeTarget and isn't really useful. Vera also does not implement the full range of variables, values and actions described by the PDF. But the basics are there.
  • urn:upnp-org:serviceId:HVAC_FanOperatingMode1 - Another UPnP service, this describes the desired operating mode of the fan. The Mode variable can have value "Auto", "ContinuousOn" or "PeriodicOn", with "Auto" referring to thermostat- or unit-controlled operation of the fan (fan on when heating or cooling, off otherwise, typically), where "ContinuousOn" means the fan runs all the time, and "PeriodicOn" means the fan runs for some set duty cycle (e.g. 15 minutes every hour). The FanStatus state variable will tell you "On" or "Off" if the fan is currently running or not, respectively. The SetMode action is used to set the fan's operating mode (again, don't set the state variable directly, use the action; it takes on parameter: NewMode. This service is the closest to the UPnP definition of the bunch, I think.
  • urn:upnp-org:serviceId:TemperatureSetpoint1 - This is where things start to go afield. According to UPnP, setting the temperature setpoint could require two actions: SetApplication and SetCurrentSetpoint. The former is used to tell the thermostat what setpoint is being set, heating or cooling. The second sets it. For dual setpoint thermostats, that makes sense. For single-setpoint, you just don't worry about the Application. In the Vera world, you don't use SetApplication, but rather to you call SetCurrentSetpoint in one of two hacked-in versions of the UPnP service, urn:upnp-org:serviceId:TemperatureSetpoint1_Heat or urn:upnp-org:serviceId:TemperatureSetpoint1_Cool. The action (in either service) take a single parameter NewCurrentSetpoint for the setpoint value. The setpoints are stored in state variables named CurrentSetpoint in whichever of the two hacked-in services applies (_Heat or _Cool). The UI goes to some work to hide alter these names slightly, so if you are looking at them on the Advanced > Variables tab for the device, one is called "CurrentSetpoint Heat" and the other "CurrentSetpoint Cool", although these are not the actual variable name (it's just "CurrentSetpoint" and the heat/cool part is derived from the service it's in--a trick unique to thermostats in UI7 as far as I've seen). Vera also maintains a CurrentSetpoint variable in the "real" UPnP service urn:upnp-org:serviceId:TemperatureSetpoint1, but I have never bothered to figure out what its heuristic is for filling that value (heating, or cooling? when? why?) since it hasn't been important to my implementations.
  • urn:upnp-org:serviceId:TemperatureSensor1 - This service is where the thermostat stores its current measured ambient temperature, in the CurrentTemperature. There are no useful actions in this service for Vera, just the state variable.
  • urn:micasaverde-com:serviceId:HVAC_OperatingState1 - This is another oddball. This is a Vera-specific service (don't be fooled by its similarity to the UPnP service names) that Vera uses to store the current operating state of the unit in the ModeState state variable, instead of keeping it in urn:upnp-org:serviceId:HVAC_UserOperatingMode1 service variable ModeStatus, which is defined for exactly this purpose. Why, I don't know. But anyway, this special service and variable has its own set of values to tell you what the unit is doing: Idle (not heating or cooling, equivalent to UPnP "InDeadBand"), "Heating" (unit is heating, eq to UPnP "HeatOn"), "Cooling" (unit is cooling, eq to UPnP "CoolOn"), "FanOnly" (not heating or cooling but fan is running, which has no UPnP analogue in HVAC_UserOperatingMode1 but is reflected in HVAC_FanOperatingMode1), and three I've never seen in use, "PendingHeat", "PendingCool" and "Vent". The UI relies heavily on this variable to show the correct state for the user in the built-in presentations of thermostats.

I don't totally understand how the xml and json files are used by the UI

Before we go on, let's address this. The files names are prefix in a helpful way. The S_.xml files are called service files, and they contain the variables and actions defined by the service bearing their name (e.g. S_HVAC_UserOperatingMode1.xml contains the definitions for urn:upnp-org:serviceId:HVAC_UserOperatingMode1). It is not a complete description of the service (some UPnP services implement more than the file defines), nor is the actual implementation required to implement everything that's in the S_.xml file (that is, there can be actions declared in the file that aren't implemented in the Vera or plugin). In any case, the variable definitions tell you what variables the service defines, their data type, and in some cases, the possible values the variable may contain, if it's a limit range smaller than the type might suggest (for example, the thermostat operating mode only can be certain values, you can't set it to "fred" and expect it to know what you want it to do). The actions section describes each action by name, its arguments, and whether they are input, output, and optional. They are a great source of information about a service, and IMO, Vera does not use this information enough, and you'll see why shortly.

The json files, or specifically the D_.json files, are called static json (I supposed because they are not generated on the fly by a request), and they describe the controls that appear on the dashboard cards, the controls on the control panel view, what tabs are created in the UI for manipulating and monitoring the device, and what events the device responds to. The eventlist section (now called "eventlist2" for UI7) describes what conditions can trigger a scene or notification. This is redundant, IMO, because the service files have a flag for the variables defined called "sendsEvents", and a true value on this flag, combined with the type and other information in the file, already form a basis on which triggers could be discovered. The "Controls" section defines which controls appear on the device control panel. A subset of those controls can appear on the UI dashboard card for the device (the ones you see that have the "ControlGroup" value are those that will appear on the dashboard as well as the control panel). Among the things that the "Controls" section contains are various control-specific ways to triggering an action in response to the user manipulating a control. For example, when you push a regular pushbutton, the "Controls" section for that pushbutton will have a "Command" section that defines the service and action to be performed, the parameters to be passed, and what value those parameters should have. Some controls, like input fields, are a bit more complicated, and don't have defined values, but rather make reference to the DOM element ID of the input field as a source for plucking the value that needs to be passed in the action's parameter.

Scenes pretty much work the same way, building on knowledge from the static json file (but ignoring the service file). When you define a scene, you are choosing actions and, as needed, values. When you run a scene, all Vera does is run those actions in sequence. So if you create a scene to set the operating mode to heating and the heating setpoint to 66F, the actions will be something like urn:upnp-org:serviceId:HVAC_UserOperatingMode1 SetModeTarget with parameter NewTargetMode=HeatOn, and then urn:upnp-org:serviceId:TemperatureSetpoint1 SetCurrentSetpoint_Heat with parameter NewCurrentSetpoint=66.

Similarly, you can just execute commands in Lua code yourself using luup.call_action(). This sequence of commands, for example, might be what one would use to set the thermostat up for being away from the house for the day:

Code: [Select]
devNumber = 999 -- device number of your thermostat

-- Set the heating setpoint to 64
luup.call_action( "urn:upnp-org:serviceId:TemperatureSetpoint1_Heat", "SetCurrentSetpoint", { NewCurrentSetpoint=64 }, devNumber )

-- Set the cooling setpoint to 76
luup.call_action( "urn:upnp-org:serviceId:TemperatureSetpoint1_Cool", "SetCurrentSetpoint", { NewCurrentSetpoint=76 }, devNumber )

-- Set the fan operating mode to Auto
luup.call_action( "urn:upnp-org:serviceId:HVAC_FanOperatingMode1", "SetMode", { NewMode="Auto" }, devNumber )

-- Set the unit operating mode to AutoChangeOver
luup.call_action( "urn:upnp-org:serviceId:HVAC_UserOperatingMode1", "SetTargetMode", { NewTargetMode="AutoChangeOver" }, devNumber )

There is much more to all of this than just the above, of course, but these are the basics. Is your head exploding yet?

You're wandering into quicksand a bit, too. Vera's UI7 is a mess in the area of thermostat UI. They make a lot of assumptions based on certain implementations (like Nest), and there a lot of exceptions coded for various other implementations. In some cases, the engineers made their exception choices based on device category, and some on device type, and in the oddest of cases, the actual filename of the static json associated with the device. There are some behaviors that can be controlled by state variables, and more that are not. These inconsistent choices, together with some bugs, make it challenging to implement a thermostat that works consistently with others in UI7, and still presents as a thermostat in the iOS and Android apps, and third-party applications like ImperiHome. It seems they've never really taken the time to refactor their handling of thermostats into more generic conditions. It looks like they were trying at one point, but then that apparently must have given way to time pressure/turn-and-burn let's get this one working, now this one, etc. I try not to be a software engineering purist neckbeard type, but this is really an area where they need to step back and look at the big picture, maybe start over. But this makes it a very tricky area to play in, and I've never been entirely successful exclusively using Vera's pre-defined static json and service definitions; I can get it to 80%, but there's always something that ends up not working right, and it's been because of an exception in UI7 that's tripped it up and I wish I could turn off, or isn't there to turn on when I need it.

Whether or not independent heating and cooling setpoints works with your thermostat is another matter. Honestly, and maybe its because I'm so bogged down by the details of how I look at these things now, I can't really make heads or tails of your explanation and what problem you are trying to solve. But you did ask how it works, and there it is. Hopefully there's enough here to trigger some "ah-hahs" for you and move you forward.

Sorry for the text wall! :-)
Author of Rachio, Deus Ex Machina II, Intesis WMP Gateway, SiteSensor, DelayLight, Auto Virtual Thermostat and VirtualSensor plugins. Vera Plus w/100+ Z-wave devices. Vera3 sandbox.

Offline Don Phillips

  • Hero Member
  • *****
  • Posts: 1272
  • Karma: +31/-32
Did not understand most of that but gave your a +1 for being such a helpful person.
Vera 3, 1.7.1030, CT101 t-stat, Everspring motion detector, GE/Jasco switch, Leviton outlet, AeonLabs sensor, NuTone garage door, Blue Iris, Sricam SP011, iPhone locator, APCUPSD, VeraMate, VeraAlerts, PLEG, House Modes, Countdown Timer, DVR, Virtual/Multi Switch, Weatherunderground, LB60Z-1 bulb

Offline Jeff D

  • Sr. Newbie
  • *
  • Posts: 35
  • Karma: +0/-0
Thank for all that information rigpapa! WOW, that may be more than expecting for and exactly what I need.

Yes, your post connected a lot of the dots. It sounds like this may not be a straight forward as it should be, and you've given some great examples. I'm using a Trane thermostat which is a few years old. I just recently took my Vera3 offline thinking I could get UI5 functions in UI7 with a little work.

I tried to work around what I though was happening breaking up a simple set cool, set hot into:
set set heat mode, set heat point
wait 5 seconds
set cool, set cool point
wait 5 seconds
set auto

But, as you described, there controls have both a hot and cold adjustment and both seem to be examined after setting the mode and only the last one is set. For example, set hot, set heat setpoint and cool set point is used. If I set both heat and cool setpoints after setting heat mode I don't see both setpoints getting changed.  I need to look at this again, my daughter was doing a great job relaying the results but I may have lost track after 20 tests.

The source code isn't the easiest thing to follow, but I don't have a great json viewer/editor. I'm a text-editor guy but this is hard for me to follow.

I'll clone your repos and take a look. You may have exactly what I need. I only started on this path because I though there was a need and I'm curious.

Offline akbooer

  • Master Member
  • *******
  • Posts: 5972
  • Karma: +258/-69
  • "Less is more"
+1 from me too, @rigpapa!

This will help in my Z-Way plugin implementation for openLuup. 

I don't have any thermostats, so implementing code for handling them has been a mystery up to now, particularly with the debacle that was the change between UI5 and UI7.
3x Vera Lite-UI5/Edge-UI7, 25x Fibaro, 23x TKB, 9x MiniMote, 2x NorthQ Power, 2x Netatmo, 1x Foscam FI9831P, 9x Philips Hue,
Razberry, MySensors Arduino, HomeWave, AltUI, AltHue, DataYours, Grafana, openLuup, ZWay, ZeroBrane Studio.

Offline zedrally

  • Hero Member
  • *****
  • Posts: 1083
  • Karma: +5/-4
  • Black Cat Control Systems
After reading this I'd be afraid of what UI8 might bring in tipping all of this over.
Rigpapa, you're doing an amazing service here.
+1 from me as well.
Living in the Land of Oz, give me a vegemite sandwich. Home Seer, Vera Lite & Edge, Popp, Black Cat Smart Hub & Vera G, Black Cat Lite 1 & 2's a Black Cat Dimmer or 2, Fantem Tec and then some  Black Cat Cat's Eye PIR's & Door-Window Sensors, RFXComm, Broadlink RMPro & Mini plus a Z-UNO or 2.

Offline brwill

  • Sr. Newbie
  • *
  • Posts: 30
  • Karma: +0/-2
PendingHeat and PendingCool are poorly named states representing Minimum Off Times. Some thermostats allow the programming of the minimum amount of time that must pass before the furnace or the compressor can fire up after the most recent On cycle. I have mine both set to 9 minutes (which is the maximum that my thermostat will allow); hence after the furnace has burned and the set point temperature has been reached, the furnace cannot come on again for at least 9 minutes. Similarly, the cooling cycle requires a minimum of 9 minutes from the end of one on period until the start of another.

At least, these are the conditions that trigger PendingHeat and PendingCool with my system. (Thermostat XL624)