GoControl GC-TBZ48 Thermostat Setup Help

Looking at the XML, the device only seems to support HEAT and AUTO. I’ve not looked at the database, but it’s possible that if there are other modes stated, that they are added with the hope that they will work - not that they actually do. ie sometimes people add things to the database thinking that the database change will help, but if the device doesn’t support the feature, it won’t :wink:

I see the manual suggests it should support other modes though - maybe there are different versions (??) and it might be worth clarifying this with the manufacturer.

My XML has the following for mode (GC-TBZ48):

    <entry>
      <commandClass>THERMOSTAT_MODE</commandClass>
      <thermostatModeCommandClass>
        <version>1</version>
        <instances>1</instances>
        <versionSupported>1</versionSupported>
        <modeTypes>
          <modeType>COOL</modeType>
          <modeType>OFF</modeType>
          <modeType>AUX_HEAT</modeType>
          <modeType>AUTO</modeType>
          <modeType>HEAT</modeType>
        </modeTypes>
        <isGetSupported>true</isGetSupported>
      </thermostatModeCommandClass>
    </entry>

Since the thermostat is working correctly from the front panel, I would assume it is properly set up (they can be configured for heat only, if desired).

I manually configure all my items using text files, not PaperUI. I can give you what I use if you want to take a look. I also have a widget front end for control and rules for Away/Home utilizing Alarm system status as occupancy sensor.

Hi TinFoil,
Thanks for the offer, it would be great to see what you’re doing. I’ve yet, after several attempts, received any kind of response from the manufacturer. What crap. Anyway I’m really interested to see what configuring devices using text files looks like. That may be an answer as it seems I have a functioning device but it doesn’t match the openHAB configuration database.

Here is my entire xml file for one of my thermostats.

<node>
  <deviceClass>
    <basicDeviceClass>ROUTING_SLAVE</basicDeviceClass>
    <genericDeviceClass>THERMOSTAT</genericDeviceClass>
    <specificDeviceClass>THERMOSTAT_GENERAL_V2</specificDeviceClass>
  </deviceClass>
  <homeId>0xc489505b</homeId>
  <nodeId>3</nodeId>
  <version>4</version>
  <manufacturer>0x14f</manufacturer>
  <deviceId>0x5437</deviceId>
  <deviceType>0x5442</deviceType>
  <listening>true</listening>
  <frequentlyListening>false</frequentlyListening>
  <routing>true</routing>
  <security>false</security>
  <beaming>true</beaming>
  <maxBaudRate>40000</maxBaudRate>
  <supportedCommandClasses>
    <entry>
      <commandClass>THERMOSTAT_SETPOINT</commandClass>
      <thermostatSetpointCommandClass>
        <version>1</version>
        <instances>1</instances>
        <versionSupported>2</versionSupported>
        <setpoints>
          <entry>
            <setpointType>COOLING</setpointType>
            <setpoint>
              <setpointType>COOLING</setpointType>
              <initialised>true</initialised>
              <initCount>0</initCount>
              <outer-class reference="../../../.."/>
            </setpoint>
          </entry>
          <entry>
            <setpointType>HEATING</setpointType>
            <setpoint>
              <setpointType>HEATING</setpointType>
              <initialised>true</initialised>
              <initCount>0</initCount>
              <outer-class reference="../../../.."/>
            </setpoint>
          </entry>
        </setpoints>
        <isGetSupported>true</isGetSupported>
      </thermostatSetpointCommandClass>
    </entry>
    <entry>
      <commandClass>ASSOCIATION_GROUP_INFO</commandClass>
      <associationGroupInfoCommandClass>
        <version>1</version>
        <instances>1</instances>
        <versionSupported>1</versionSupported>
        <autoSubscribeGroups>
          <int>1</int>
        </autoSubscribeGroups>
      </associationGroupInfoCommandClass>
    </entry>
    <entry>
      <commandClass>ASSOCIATION</commandClass>
      <associationCommandClass>
        <version>2</version>
        <instances>1</instances>
        <versionSupported>2</versionSupported>
        <maxGroups>3</maxGroups>
      </associationCommandClass>
    </entry>
    <entry>
      <commandClass>DEVICE_RESET_LOCALLY</commandClass>
      <deviceResetLocallyCommandClass>
        <version>1</version>
        <instances>1</instances>
        <versionSupported>1</versionSupported>
      </deviceResetLocallyCommandClass>
    </entry>
    <entry>
      <commandClass>ZWAVE_PLUS_INFO</commandClass>
      <zwavePlusCommandClass>
        <version>1</version>
        <instances>1</instances>
        <versionSupported>2</versionSupported>
        <zwPlusVersion>1</zwPlusVersion>
        <zwPlusRole>5</zwPlusRole>
        <zwPlusNodeType>0</zwPlusNodeType>
        <zwPlusDeviceType>0x1200</zwPlusDeviceType>
        <zwPlusInstallerIcon>0x1200</zwPlusInstallerIcon>
        <isGetSupported>true</isGetSupported>
      </zwavePlusCommandClass>
    </entry>
    <entry>
      <commandClass>THERMOSTAT_FAN_STATE</commandClass>
      <thermostatFanStateCommandClass>
        <version>1</version>
        <instances>1</instances>
        <versionSupported>1</versionSupported>
        <fanStateTypes>
          <fanStateType>IDLE</fanStateType>
          <fanStateType>RUNNING</fanStateType>
        </fanStateTypes>
        <isGetSupported>true</isGetSupported>
      </thermostatFanStateCommandClass>
    </entry>
    <entry>
      <commandClass>FIRMWARE_UPDATE_MD</commandClass>
      <firmwareUpdateCommandClass>
        <version>1</version>
        <instances>1</instances>
        <versionSupported>2</versionSupported>
      </firmwareUpdateCommandClass>
    </entry>
    <entry>
      <commandClass>THERMOSTAT_OPERATING_STATE</commandClass>
      <thermostatOperatingStateCommandClass>
        <version>1</version>
        <instances>1</instances>
        <versionSupported>1</versionSupported>
        <isGetSupported>true</isGetSupported>
      </thermostatOperatingStateCommandClass>
    </entry>
    <entry>
      <commandClass>BASIC</commandClass>
      <basicCommandClass>
        <version>0</version>
        <instances>0</instances>
        <versionSupported>0</versionSupported>
        <isGetSupported>true</isGetSupported>
      </basicCommandClass>
    </entry>
    <entry>
      <commandClass>SCENE_ACTIVATION</commandClass>
      <sceneActivationCommandClass>
        <version>1</version>
        <instances>1</instances>
        <versionSupported>1</versionSupported>
      </sceneActivationCommandClass>
    </entry>
    <entry>
      <commandClass>MULTI_CMD</commandClass>
      <multiCommandCommandClass>
        <version>1</version>
        <instances>1</instances>
        <versionSupported>1</versionSupported>
      </multiCommandCommandClass>
    </entry>
    <entry>
      <commandClass>THERMOSTAT_MODE</commandClass>
      <thermostatModeCommandClass>
        <version>1</version>
        <instances>1</instances>
        <versionSupported>1</versionSupported>
        <modeTypes>
          <modeType>AUX_HEAT</modeType>
          <modeType>OFF</modeType>
          <modeType>AUTO</modeType>
          <modeType>COOL</modeType>
          <modeType>HEAT</modeType>
        </modeTypes>
        <isGetSupported>true</isGetSupported>
      </thermostatModeCommandClass>
    </entry>
    <entry>
      <commandClass>MANUFACTURER_SPECIFIC</commandClass>
      <manufacturerSpecificCommandClass>
        <version>1</version>
        <instances>1</instances>
        <versionSupported>1</versionSupported>
        <initSerialNumber>false</initSerialNumber>
        <deviceManufacturer>335</deviceManufacturer>
        <deviceType>21570</deviceType>
        <deviceId>21559</deviceId>
      </manufacturerSpecificCommandClass>
    </entry>
    <entry>
      <commandClass>BATTERY</commandClass>
      <batteryCommandClass>
        <version>1</version>
        <instances>1</instances>
        <versionSupported>1</versionSupported>
        <batteryLevel>100</batteryLevel>
        <batteryLow>false</batteryLow>
        <isGetSupported>true</isGetSupported>
      </batteryCommandClass>
    </entry>
    <entry>
      <commandClass>SENSOR_MULTILEVEL</commandClass>
      <multiLevelSensorCommandClass>
        <version>1</version>
        <instances>1</instances>
        <versionSupported>1</versionSupported>
        <sensors>
          <entry>
            <multilevelSensorType>TEMPERATURE</multilevelSensorType>
            <multilevelSensor>
              <sensorType>TEMPERATURE</sensorType>
              <initialised>true</initialised>
            </multilevelSensor>
          </entry>
        </sensors>
        <isGetSupported>true</isGetSupported>
      </multiLevelSensorCommandClass>
    </entry>
    <entry>
      <commandClass>NO_OPERATION</commandClass>
      <noOperationCommandClass>
        <version>1</version>
        <instances>0</instances>
        <versionSupported>1</versionSupported>
      </noOperationCommandClass>
    </entry>
    <entry>
      <commandClass>CLOCK</commandClass>
      <clockCommandClass>
        <version>1</version>
        <instances>1</instances>
        <versionSupported>1</versionSupported>
      </clockCommandClass>
    </entry>
    <entry>
      <commandClass>THERMOSTAT_FAN_MODE</commandClass>
      <thermostatFanModeCommandClass>
        <version>1</version>
        <instances>1</instances>
        <versionSupported>1</versionSupported>
        <fanModeTypes>
          <fanModeType>AUTO_LOW</fanModeType>
          <fanModeType>ON_LOW</fanModeType>
        </fanModeTypes>
        <isGetSupported>true</isGetSupported>
      </thermostatFanModeCommandClass>
    </entry>
    <entry>
      <commandClass>VERSION</commandClass>
      <versionCommandClass>
        <version>2</version>
        <instances>1</instances>
        <versionSupported>2</versionSupported>
        <libraryType>LIB_SLAVE_ROUTING</libraryType>
        <protocolVersion>4.5</protocolVersion>
        <applicationVersion>1.0</applicationVersion>
        <hardwareVersion>1</hardwareVersion>
      </versionCommandClass>
    </entry>
    <entry>
      <commandClass>CONFIGURATION</commandClass>
      <configurationCommandClass>
        <version>1</version>
        <instances>1</instances>
        <versionSupported>1</versionSupported>
        <configParameters/>
      </configurationCommandClass>
    </entry>
    <entry>
      <commandClass>POWERLEVEL</commandClass>
      <powerLevelCommandClass>
        <version>1</version>
        <instances>1</instances>
        <versionSupported>1</versionSupported>
        <powerLevel>0</powerLevel>
        <powerTimeout>0</powerTimeout>
      </powerLevelCommandClass>
    </entry>
    <entry>
      <commandClass>SCENE_ACTUATOR_CONF</commandClass>
      <sceneActuatorConfigurationCommandClass>
        <version>1</version>
        <instances>1</instances>
        <versionSupported>1</versionSupported>
      </sceneActuatorConfigurationCommandClass>
    </entry>
  </supportedCommandClasses>
  <securedCommandClasses/>
  <associationGroups>
    <entry>
      <int>1</int>
      <associationGroup>
        <index>1</index>
        <name>Lifeline</name>
        <profile1>0x0</profile1>
        <profile2>0x0</profile2>
        <commands>
          <commandClass>THERMOSTAT_SETPOINT</commandClass>
          <commandClass>THERMOSTAT_MODE</commandClass>
          <commandClass>BATTERY</commandClass>
          <commandClass>DEVICE_RESET_LOCALLY</commandClass>
          <commandClass>SENSOR_MULTILEVEL</commandClass>
          <commandClass>THERMOSTAT_FAN_STATE</commandClass>
          <commandClass>THERMOSTAT_FAN_MODE</commandClass>
          <commandClass>THERMOSTAT_OPERATING_STATE</commandClass>
          <commandClass>CONFIGURATION</commandClass>
        </commands>
        <associations>
          <associationMember>
            <node>1</node>
            <endpoint>0</endpoint>
          </associationMember>
        </associations>
      </associationGroup>
    </entry>
    <entry>
      <int>2</int>
      <associationGroup>
        <index>2</index>
        <name>Cool Control</name>
        <profile1>0x20</profile1>
        <profile2>0x1</profile2>
        <commands/>
        <associations/>
      </associationGroup>
    </entry>
    <entry>
      <int>3</int>
      <associationGroup>
        <index>3</index>
        <name>Heat Control</name>
        <profile1>0x20</profile1>
        <profile2>0x2</profile2>
        <commands/>
        <associations/>
      </associationGroup>
    </entry>
  </associationGroups>
  <nodeNeighbors>
    <int>1</int>
  </nodeNeighbors>
  <lastSent>2019-05-09 18:03:17.65 UTC</lastSent>
  <lastReceived>2019-05-09 18:03:17.142 UTC</lastReceived>
</node>

I don’t see anything too significant with the exception of the mode which I sent earlier.

I configured my Z Wave network through Habmin using the Z Wave Binding. I have an Aeotech Z Stick, plugged into a RPi which exposes the Z Wave serial link to a network socket. Openhab connects to this socket and emulates the port for the Z Wave Binding.

My Item file for my thermostats:

Number TH_Main_TempSensor      { channel="zwave:device:66d251de:node3:sensor_temperature" }
Number TH_Main_CoolingSetPoint { channel="zwave:device:66d251de:node3:thermostat_setpoint_cooling" }
Number TH_Main_HeatingSetPoint { channel="zwave:device:66d251de:node3:thermostat_setpoint_heating" }
Number TH_Main_FanMode         { channel="zwave:device:66d251de:node3:thermostat_fanmode" }
Number TH_Main_Mode            { channel="zwave:device:66d251de:node3:thermostat_mode" }
Number TH_Main_State           { channel="zwave:device:66d251de:node3:thermostat_state" }
Number TH_Main_FanRunTime
Number TH_Main_FanState
Number TH_Main_AutoSetPointControl        // 0 = No auto, 1 = Auto Enable, 2 = Force Away
Number TH_Main_AutoAwayHeatingSetPoint
Number TH_Main_AutoAwayCoolingSetPoint
Number TH_Main_AutoHomeHeatingSetPoint
Number TH_Main_AutoHomeCoolingSetPoint

Number TH_Base_TempSensor      { channel="zwave:device:66d251de:node4:sensor_temperature" }
Number TH_Base_CoolingSetPoint { channel="zwave:device:66d251de:node4:thermostat_setpoint_cooling" }
Number TH_Base_HeatingSetPoint { channel="zwave:device:66d251de:node4:thermostat_setpoint_heating" }
Number TH_Base_FanMode         { channel="zwave:device:66d251de:node4:thermostat_fanmode" }
Number TH_Base_Mode            { channel="zwave:device:66d251de:node4:thermostat_mode" }
Number TH_Base_State           { channel="zwave:device:66d251de:node4:thermostat_state" }
Number TH_Base_FanRunTime
Number TH_Base_FanState
Number TH_Base_AutoSetPointControl        // 0 = No auto, 1 = Auto Enable, 2 = Force Away
Number TH_Base_AutoAwayHeatingSetPoint
Number TH_Base_AutoAwayCoolingSetPoint
Number TH_Base_AutoHomeHeatingSetPoint
Number TH_Base_AutoHomeCoolingSetPoint

Number TH_Up_TempSensor        { channel="zwave:device:66d251de:node5:sensor_temperature" }
Number TH_Up_CoolingSetPoint   { channel="zwave:device:66d251de:node5:thermostat_setpoint_cooling" }
Number TH_Up_HeatingSetPoint   { channel="zwave:device:66d251de:node5:thermostat_setpoint_heating" }
Number TH_Up_FanMode           { channel="zwave:device:66d251de:node5:thermostat_fanmode" }
Number TH_Up_Mode              { channel="zwave:device:66d251de:node5:thermostat_mode" }
Number TH_Up_State             { channel="zwave:device:66d251de:node5:thermostat_state" }
Number TH_Up_FanRunTime
Number TH_Up_FanState
Number TH_Up_AutoSetPointControl        // 0 = No auto, 1 = Auto Enable, 2 = Force Away
Number TH_Up_AutoAwayHeatingSetPoint
Number TH_Up_AutoAwayCoolingSetPoint
Number TH_Up_AutoHomeHeatingSetPoint
Number TH_Up_AutoHomeCoolingSetPoint

Items with no channel definition are used as global variables.

HTML for template widget:

<!-- Remaining to do:
	Limit min/max setpoints (possibly using script for increase/decrease)
	Confirmation for filter reset
-->

<link rel="stylesheet" type="text/css" href="/static/thermostat/style2.css"></link>

<!-- Begin Upstairs Thermostat -->
<div class="thermkeypad">
	<div class="thermkeypadRow" style="font-size: 1.5em;">
		Upstairs Thermostat
	</div>
	<div class="thermkeypadRow">
		<div class="thermkeypadCell">
			<button ng-click="sendCmd('TH_Up_Mode','0')" ng-class="{'selected_mode': itemValue('TH_Up_Mode')=='0', 'not_selected_mode': itemValue('TH_Up_Mode')!='0'}">Off</button>
		</div>
		<div class="thermkeypadCell">
			<button ng-click="sendCmd('TH_Up_Mode','1')" ng-class="{'selected_mode': itemValue('TH_Up_Mode')=='1', 'not_selected_mode': itemValue('TH_Up_Mode')!='1'}">Heat</button>
		</div>
		<div class="thermkeypadCell">
			<button ng-click="sendCmd('TH_Up_Mode','2')" ng-class="{'selected_mode': itemValue('TH_Up_Mode')=='2', 'not_selected_mode': itemValue('TH_Up_Mode')!='2'}">Cool</button>
		</div>
		<div class="thermkeypadCell">
			<button ng-click="sendCmd('TH_Up_Mode','3')" ng-class="{'selected_mode': itemValue('TH_Up_Mode')=='3', 'not_selected_mode': itemValue('TH_Up_Mode')!='3'}">Auto</button>
		</div>
	</div>
	<div class="thermkeypadRow">
		<div class="thermkeypadCell">
			<div style="font-size: 0.7em; margin-top: 10px;">Fan Control</div>
			<div style="margin: 5px 10% 5px 10%;">
				<button ng-click="sendCmd('TH_Up_FanMode','0')" ng-class="{'selected_mode': itemValue('TH_Up_FanMode')=='0', 'not_selected_mode': itemValue('TH_Up_FanMode')!='0'}" style="font-size: 0.7em;">Auto</button>
			</div>
			<div style="margin: 5px 10% 5px 10%;">
				<button ng-click="sendCmd('TH_Up_FanMode','1')" ng-class="{'selected_mode': itemValue('TH_Up_FanMode')=='1', 'not_selected_mode': itemValue('TH_Up_FanMode')!='1'}" style="font-size: 0.7em;">On</button>
			</div>
			<div style="font-size: 0.7em;">Runtime:</div>
			<div style="font-size: 0.7em;">{{'%.01f' | sprintf:itemValue('TH_Up_FanRunTime')/3600}} Hours</div>
			<div style="margin: 5px 10% 5px 10%;">
				<button  ng-click="sendCmd('TH_Up_FanRunTime','0')" class="not_selected_mode" style="font-size: 0.7em;">Reset</button>
			</div>
		</div>
		<div class="thermkeypadCell">
			<div style="width: 100%; margin-top: 10px;">
				<button class="adjustbtn" ng-click="sendCmd('TH_Up_HeatingSetPoint',+itemValue('TH_Up_HeatingSetPoint')+1)">
          <svg class="adjustimg" viewBox="0 0 100 50" preserveAspectRatio="none">
          	<polygon points="0,50 100,50 50,0" style="fill: #D02;" />
          </svg>
				</button>
			</div>
			<div class="LCDPNL_SP">{{itemValue('TH_Up_HeatingSetPoint')}}</div>
			<div style="width: 100%; margin-bottom: 10px;">
				<button class="adjustbtn" ng-click="sendCmd('TH_Up_HeatingSetPoint',+itemValue('TH_Up_HeatingSetPoint')-1)">
          <svg class="adjustimg" viewBox="0 0 100 50" preserveAspectRatio="none">
          	<polygon points="0,0 100,0 50,50" style="fill: #02D;" />
          </svg>
				</button>
			</div>
		</div>
		<div class="thermkeypadCell">
			<div style="width: 100%; margin-top: 10px;">
				<button class="adjustbtn" ng-click="sendCmd('TH_Up_CoolingSetPoint',+itemValue('TH_Up_CoolingSetPoint')+1)">
          <svg class="adjustimg" viewBox="0 0 100 50" preserveAspectRatio="none">
          	<polygon points="10,40 90,40 50,10" style="fill: #D02; stroke-width: 10; stroke: #D02;" />
          </svg>
				</button>
			</div>
			<div class="LCDPNL_SP">{{itemValue('TH_Up_CoolingSetPoint')}}</div>
			<div style="width: 100%; margin-bottom: 10px;">
				<button class="adjustbtn" ng-click="sendCmd('TH_Up_CoolingSetPoint',+itemValue('TH_Up_CoolingSetPoint')-1)">
          <svg class="adjustimg" viewBox="0 0 100 50" preserveAspectRatio="none">
          	<polygon points="0,0 100,0 50,50" style="fill: #02D;" />
          </svg>
				</button>
			</div>
		</div>
		<div class="thermkeypadCell">
			<div>Current</div>
			<div>Temp:</div>
			<div style="font-size: 3em;">{{itemValue('TH_Up_TempSensor')}}</div>
			<div ng-if="itemValue('TH_Up_State')=='0'">Idle</div>
			<div ng-if="itemValue('TH_Up_State')=='1'">Heating</div>
			<div ng-if="itemValue('TH_Up_State')=='2'">Cooling</div>
			<div ng-if="itemValue('TH_Up_State')=='3'">Wait</div>
			<div ng-if="itemValue('TH_Up_State')=='4'">Wait</div>
		</div>
	</div>
</div>
<!-- Begin Main Thermostat -->
<div class="thermkeypad">
	<div class="thermkeypadRow" style="font-size: 1.5em;">
		Main Thermostat
	</div>
	<div class="thermkeypadRow">
		<div class="thermkeypadCell">
			<button ng-click="sendCmd('TH_Main_Mode','0')" ng-class="{'selected_mode': itemValue('TH_Main_Mode')=='0', 'not_selected_mode': itemValue('TH_Main_Mode')!='0'}">Off</button>
		</div>
		<div class="thermkeypadCell">
			<button ng-click="sendCmd('TH_Main_Mode','1')" ng-class="{'selected_mode': itemValue('TH_Main_Mode')=='1', 'not_selected_mode': itemValue('TH_Main_Mode')!='1'}">Heat</button>
		</div>
		<div class="thermkeypadCell">
			<button ng-click="sendCmd('TH_Main_Mode','2')" ng-class="{'selected_mode': itemValue('TH_Main_Mode')=='2', 'not_selected_mode': itemValue('TH_Main_Mode')!='2'}">Cool</button>
		</div>
		<div class="thermkeypadCell">
			<button ng-click="sendCmd('TH_Main_Mode','3')" ng-class="{'selected_mode': itemValue('TH_Main_Mode')=='3', 'not_selected_mode': itemValue('TH_Main_Mode')!='3'}">Auto</button>
		</div>
	</div>
	<div class="thermkeypadRow">
		<div class="thermkeypadCell">
			<div style="font-size: 0.7em; margin-top: 10px;">Fan Control</div>
			<div style="margin: 5px 10% 5px 10%;">
				<button ng-click="sendCmd('TH_Main_FanMode','0')" ng-class="{'selected_mode': itemValue('TH_Main_FanMode')=='0', 'not_selected_mode': itemValue('TH_Main_FanMode')!='0'}" style="font-size: 0.7em;">Auto</button>
			</div>
			<div style="margin: 5px 10% 5px 10%;">
				<button ng-click="sendCmd('TH_Main_FanMode','1')" ng-class="{'selected_mode': itemValue('TH_Main_FanMode')=='1', 'not_selected_mode': itemValue('TH_Main_FanMode')!='1'}" style="font-size: 0.7em;">On</button>
			</div>
			<div style="font-size: 0.7em;">Runtime:</div>
			<div style="font-size: 0.7em;">{{'%.01f' | sprintf:itemValue('TH_Main_FanRunTime')/3600}} Hours</div>
			<div style="margin: 5px 10% 5px 10%;">
				<button  ng-click="sendCmd('TH_Main_FanRunTime','0')" class="not_selected_mode" style="font-size: 0.7em;">Reset</button>
			</div>
		</div>
		<div class="thermkeypadCell">
			<div style="width: 100%; margin-top: 10px;">
				<button class="adjustbtn" ng-click="sendCmd('TH_Main_HeatingSetPoint',+itemValue('TH_Main_HeatingSetPoint')+1)">
          <svg class="adjustimg" viewBox="0 0 100 50" preserveAspectRatio="none">
          	<polygon points="0,50 100,50 50,0" style="fill: #D02;" />
          </svg>
				</button>
			</div>
			<div class="LCDPNL_SP">{{itemValue('TH_Main_HeatingSetPoint')}}</div>
			<div style="width: 100%; margin-bottom: 10px;">
				<button class="adjustbtn" ng-click="sendCmd('TH_Main_HeatingSetPoint',+itemValue('TH_Main_HeatingSetPoint')-1)">
          <svg class="adjustimg" viewBox="0 0 100 50" preserveAspectRatio="none">
          	<polygon points="0,0 100,0 50,50" style="fill: #02D;" />
          </svg>
				</button>
			</div>
		</div>
		<div class="thermkeypadCell">
			<div style="width: 100%; margin-top: 10px;">
				<button class="adjustbtn" ng-click="sendCmd('TH_Main_CoolingSetPoint',+itemValue('TH_Main_CoolingSetPoint')+1)">
          <svg class="adjustimg" viewBox="0 0 100 50" preserveAspectRatio="none">
          	<polygon points="0,50 100,50 50,0" style="fill: #D02;" />
          </svg>
				</button>
			</div>
			<div class="LCDPNL_SP">{{itemValue('TH_Main_CoolingSetPoint')}}</div>
			<div style="width: 100%; margin-bottom: 10px;">
				<button class="adjustbtn" ng-click="sendCmd('TH_Main_CoolingSetPoint',+itemValue('TH_Main_CoolingSetPoint')-1)">
          <svg class="adjustimg" viewBox="0 0 100 50" preserveAspectRatio="none">
          	<polygon points="0,0 100,0 50,50" style="fill: #02D;" />
          </svg>
				</button>
			</div>
		</div>
		<div class="thermkeypadCell">
			<div>Current</div>
			<div>Temp:</div>
			<div style="font-size: 3em;">{{itemValue('TH_Main_TempSensor')}}</div>
			<div ng-if="itemValue('TH_Main_State')=='0'">Idle</div>
			<div ng-if="itemValue('TH_Main_State')=='1'">Heating</div>
			<div ng-if="itemValue('TH_Main_State')=='2'">Cooling</div>
			<div ng-if="itemValue('TH_Main_State')=='3'">Wait</div>
			<div ng-if="itemValue('TH_Main_State')=='4'">Wait</div>
		</div>
	</div>
</div>
<!-- Begin Basement Thermostat -->
<div class="thermkeypad">
	<div class="thermkeypadRow" style="font-size: 1.5em;">
		Basement Thermostat
	</div>
	<div class="thermkeypadRow">
		<div class="thermkeypadCell">
			<button ng-click="sendCmd('TH_Base_Mode','0')" ng-class="{'selected_mode': itemValue('TH_Base_Mode')=='0', 'not_selected_mode': itemValue('TH_Base_Mode')!='0'}">Off</button>
		</div>
		<div class="thermkeypadCell">
			<button ng-click="sendCmd('TH_Base_Mode','1')" ng-class="{'selected_mode': itemValue('TH_Base_Mode')=='1', 'not_selected_mode': itemValue('TH_Base_Mode')!='1'}">Heat</button>
		</div>
		<div class="thermkeypadCell">
			<button ng-click="sendCmd('TH_Base_Mode','2')" ng-class="{'selected_mode': itemValue('TH_Base_Mode')=='2', 'not_selected_mode': itemValue('TH_Base_Mode')!='2'}">Cool</button>
		</div>
		<div class="thermkeypadCell">
			<button ng-click="sendCmd('TH_Base_Mode','3')" ng-class="{'selected_mode': itemValue('TH_Base_Mode')=='3', 'not_selected_mode': itemValue('TH_Base_Mode')!='3'}">Auto</button>
		</div>
	</div>
	<div class="thermkeypadRow">
		<div class="thermkeypadCell">
			<div style="font-size: 0.7em; margin-top: 10px;">Fan Control</div>
			<div style="margin: 5px 10% 5px 10%;">
				<button ng-click="sendCmd('TH_Base_FanMode','0')" ng-class="{'selected_mode': itemValue('TH_Base_FanMode')=='0', 'not_selected_mode': itemValue('TH_Base_FanMode')!='0'}" style="font-size: 0.7em;">Auto</button>
			</div>
			<div style="margin: 5px 10% 5px 10%;">
				<button ng-click="sendCmd('TH_Base_FanMode','1')" ng-class="{'selected_mode': itemValue('TH_Base_FanMode')=='1', 'not_selected_mode': itemValue('TH_Base_FanMode')!='1'}" style="font-size: 0.7em;">On</button>
			</div>
			<div style="font-size: 0.7em;">Runtime:</div>
			<div style="font-size: 0.7em;">{{'%.01f' | sprintf:itemValue('TH_Base_FanRunTime')/3600}} Hours</div>
			<div style="margin: 5px 10% 5px 10%;">
				<button  ng-click="sendCmd('TH_Base_FanRunTime','0')" class="not_selected_mode" style="font-size: 0.7em;">Reset</button>
			</div>
		</div>
		<div class="thermkeypadCell">
			<div style="width: 100%; margin-top: 10px;">
				<button class="adjustbtn" ng-click="sendCmd('TH_Base_HeatingSetPoint',+itemValue('TH_Base_HeatingSetPoint')+1)">
          <svg class="adjustimg" viewBox="0 0 100 50" preserveAspectRatio="none">
          	<polygon points="0,50 100,50 50,0" style="fill: #D02;" />
          </svg>
				</button>
			</div>
			<div class="LCDPNL_SP">{{itemValue('TH_Base_HeatingSetPoint')}}</div>
			<div style="width: 100%; margin-bottom: 10px;">
				<button class="adjustbtn" ng-click="sendCmd('TH_Base_HeatingSetPoint',+itemValue('TH_Base_HeatingSetPoint')-1)">
          <svg class="adjustimg" viewBox="0 0 100 50" preserveAspectRatio="none">
          	<polygon points="0,0 100,0 50,50" style="fill: #02D;" />
          </svg>
				</button>
			</div>
		</div>
		<div class="thermkeypadCell">
			<div style="width: 100%; margin-top: 10px;">
				<button class="adjustbtn" ng-click="sendCmd('TH_Base_CoolingSetPoint',+itemValue('TH_Base_CoolingSetPoint')+1)">
          <svg class="adjustimg" viewBox="0 0 100 50" preserveAspectRatio="none">
          	<polygon points="0,50 100,50 50,0" style="fill: #D02;" />
          </svg>
				</button>
			</div>
			<div class="LCDPNL_SP">{{itemValue('TH_Base_CoolingSetPoint')}}</div>
			<div style="width: 100%; margin-bottom: 10px;">
				<button class="adjustbtn" ng-click="sendCmd('TH_Base_CoolingSetPoint',+itemValue('TH_Base_CoolingSetPoint')-1)">
          <svg class="adjustimg" viewBox="0 0 100 50" preserveAspectRatio="none">
          	<polygon points="0,0 100,0 50,50" style="fill: #02D;" />
          </svg>
				</button>
			</div>
		</div>
		<div class="thermkeypadCell">
			<div>Current</div>
			<div>Temp:</div>
			<div style="font-size: 3em;">{{itemValue('TH_Base_TempSensor')}}</div>
			<div ng-if="itemValue('TH_Base_State')=='0'">Idle</div>
			<div ng-if="itemValue('TH_Base_State')=='1'">Heating</div>
			<div ng-if="itemValue('TH_Base_State')=='2'">Cooling</div>
			<div ng-if="itemValue('TH_Base_State')=='3'">Wait</div>
			<div ng-if="itemValue('TH_Base_State')=='4'">Wait</div>
		</div>
	</div>
</div>

All three of my thermostats are in one widget as I have designed it for a phone screen. I have a separate CSS sheet to help it look nice.

I have mine setup for 2 degrees of dead band to reduce cycling. The run timer is for the air handler to know when to change the filter. For some reason the fan status point from the stat never would change states, so I have to calculate using rules if it is on or not.

Edit:
It has been a while since I set these up. I actually configured the Things using Habmin and the Items using the item file (above). The json for the thing is below. I hope this helps.

 "zwave:device:66d251de:node3": {
    "class": "org.eclipse.smarthome.core.thing.internal.ThingImpl",
    "value": {
      "label": "Thermostat - Main Floor",
      "bridgeUID": {
        "segments": [
          "zwave",
          "serial_zstick",
          "66d251de"
        ]
      },
      "channels": [
        {
          "acceptedItemType": "Number",
          "kind": "STATE",
          "uid": {
            "segments": [
              "zwave",
              "device",
              "66d251de",
              "node3",
              "scene_number"
            ]
          },
          "channelTypeUID": {
            "segments": [
              "zwave",
              "scene_number"
            ]
          },
          "label": "Scene Number",
          "description": "Triggers when a scene button is pressed",
          "configuration": {
            "properties": {}
          },
          "properties": {
            "binding:*:DecimalType": "SCENE_ACTIVATION"
          },
          "defaultTags": []
        },
        {
          "acceptedItemType": "Number",
          "kind": "STATE",
          "uid": {
            "segments": [
              "zwave",
              "device",
              "66d251de",
              "node3",
              "sensor_temperature"
            ]
          },
          "channelTypeUID": {
            "segments": [
              "zwave",
              "sensor_temperature"
            ]
          },
          "label": "Sensor (temperature)",
          "description": "Indicates the current temperature",
          "configuration": {
            "properties": {
              "config_scale": "1"
            }
          },
          "properties": {
            "binding:*:DecimalType": "SENSOR_MULTILEVEL;type\u003dTEMPERATURE"
          },
          "defaultTags": []
        },
        {
          "acceptedItemType": "Number",
          "kind": "STATE",
          "uid": {
            "segments": [
              "zwave",
              "device",
              "66d251de",
              "node3",
              "thermostat_mode"
            ]
          },
          "channelTypeUID": {
            "segments": [
              "zwave",
              "linear_gctbz48_00_000_thermostat_mode"
            ]
          },
          "label": "Thermostat mode",
          "description": "Sets the thermostat mode",
          "configuration": {
            "properties": {}
          },
          "properties": {
            "binding:*:DecimalType": "THERMOSTAT_MODE"
          },
          "defaultTags": []
        },
        {
          "acceptedItemType": "Number",
          "kind": "STATE",
          "uid": {
            "segments": [
              "zwave",
              "device",
              "66d251de",
              "node3",
              "thermostat_state"
            ]
          },
          "channelTypeUID": {
            "segments": [
              "zwave",
              "thermostat_state"
            ]
          },
          "label": "Thermostat Operating State",
          "description": "Sets the thermostat operating state",
          "configuration": {
            "properties": {}
          },
          "properties": {
            "binding:*:DecimalType": "THERMOSTAT_OPERATING_STATE"
          },
          "defaultTags": []
        },
        {
          "acceptedItemType": "Number",
          "kind": "STATE",
          "uid": {
            "segments": [
              "zwave",
              "device",
              "66d251de",
              "node3",
              "thermostat_setpoint_cooling"
            ]
          },
          "channelTypeUID": {
            "segments": [
              "zwave",
              "thermostat_setpoint"
            ]
          },
          "label": "Setpoint (cooling)",
          "description": "Sets the thermostate setpoint",
          "configuration": {
            "properties": {
              "config_scale": "1"
            }
          },
          "properties": {
            "binding:*:DecimalType": "THERMOSTAT_SETPOINT;type\u003dCOOLING"
          },
          "defaultTags": []
        },
        {
          "acceptedItemType": "Number",
          "kind": "STATE",
          "uid": {
            "segments": [
              "zwave",
              "device",
              "66d251de",
              "node3",
              "thermostat_setpoint_heating"
            ]
          },
          "channelTypeUID": {
            "segments": [
              "zwave",
              "thermostat_setpoint"
            ]
          },
          "label": "Setpoint (heating)",
          "description": "Sets the thermostate setpoint",
          "configuration": {
            "properties": {
              "config_scale": "1"
            }
          },
          "properties": {
            "binding:*:DecimalType": "THERMOSTAT_SETPOINT;type\u003dHEATING"
          },
          "defaultTags": []
        },
        {
          "acceptedItemType": "Number",
          "kind": "STATE",
          "uid": {
            "segments": [
              "zwave",
              "device",
              "66d251de",
              "node3",
              "thermostat_fanmode"
            ]
          },
          "channelTypeUID": {
            "segments": [
              "zwave",
              "linear_gctbz48_00_000_thermostat_fanmode"
            ]
          },
          "label": "Thermostat fan mode",
          "description": "Sets the thermostat fan mode",
          "configuration": {
            "properties": {}
          },
          "properties": {
            "binding:*:DecimalType": "THERMOSTAT_FAN_MODE"
          },
          "defaultTags": []
        },
        {
          "acceptedItemType": "Number",
          "kind": "STATE",
          "uid": {
            "segments": [
              "zwave",
              "device",
              "66d251de",
              "node3",
              "thermostat_fanstate"
            ]
          },
          "channelTypeUID": {
            "segments": [
              "zwave",
              "linear_gctbz48_00_000_thermostat_fanstate"
            ]
          },
          "label": "Thermostat fan state",
          "description": "Sets the thermostat fan state",
          "configuration": {
            "properties": {}
          },
          "properties": {
            "binding:*:DecimalType": "THERMOSTAT_FAN_STATE"
          },
          "defaultTags": []
        },
        {
          "acceptedItemType": "Number",
          "kind": "STATE",
          "uid": {
            "segments": [
              "zwave",
              "device",
              "66d251de",
              "node3",
              "battery-level"
            ]
          },
          "channelTypeUID": {
            "segments": [
              "system",
              "battery-level"
            ]
          },
          "label": "Battery Level",
          "configuration": {
            "properties": {}
          },
          "properties": {
            "binding:*:PercentType": "BATTERY"
          },
          "defaultTags": []
        },
        {
          "acceptedItemType": "Number",
          "kind": "STATE",
          "uid": {
            "segments": [
              "zwave",
              "device",
              "66d251de",
              "node3",
              "time_offset"
            ]
          },
          "channelTypeUID": {
            "segments": [
              "zwave",
              "time_offset"
            ]
          },
          "label": "Clock Time Offset",
          "description": "Provides the current time difference for the devices time",
          "configuration": {
            "properties": {
              "config_offset": 60
            }
          },
          "properties": {
            "binding:*:DecimalType": "CLOCK"
          },
          "defaultTags": []
        }
      ],
      "configuration": {
        "properties": {
          "action_heal": false,
          "action_reinit": false,
          "action_failed": false,
          "group_1": [
            "node_1_0"
          ],
          "action_remove": false,
          "group_3": [],
          "binding_pollperiod": 1800,
          "group_2": []
        }
      },
      "properties": {
        "zwave_class_basic": "ROUTING_SLAVE",
        "zwave_class_generic": "THERMOSTAT",
        "zwave_frequent": "false",
        "zwave_neighbours": "1",
        "modelId": "GoControl GC-TBZ48",
        "zwave_version": "1.0",
        "zwave_listening": "true",
        "zwave_plus_devicetype": "THERMOSTAT_HVAC",
        "manufacturerId": "014F",
        "manufacturerRef": "5442:5431,5442:5436,5442:5437",
        "dbReference": "622",
        "zwave_deviceid": "21559",
        "zwave_nodeid": "3",
        "vendor": "Linear Corp",
        "zwave_routing": "true",
        "zwave_beaming": "true",
        "zwave_class_specific": "THERMOSTAT_GENERAL_V2",
        "zwave_manufacturer": "335",
        "zwave_devicetype": "21570"
      },
      "uid": {
        "segments": [
          "zwave",
          "device",
          "66d251de",
          "node3"
        ]
      },
      "thingTypeUID": {
        "segments": [
          "zwave",
          "linear_gctbz48_00_000"
        ]
      }
    }
  }

Honestly all I remember having to do was change the device from C to F in Habmin and possibly add it to the association group 1. It has been running flawlessly for several months.

How can our XML files look so different? @chris, how does this work? Same device and manufacturer IDs but the file is built almost completely different.

Different versions of OH use a different XML file format - there’s not a lot of difference actually, but the newer versions break the command classes into endpoints, where the old version doesn’t.

The file from @TinFoil was not created with any recent version of OH - probably it is OH1

I’m using 2.3.0 on Ubuntu 18.04. I just started with OH last year.

Edit:
Now I’m a little leery too upgrade to 2.4. I may give it a shot with a disk snapshot and see what happens.

So that answers the question then :slight_smile:

Hey @TinFoil, what’s the firmware revision of your thermostats? I have 022200. I had customer service on chat this morning (not terribly helpful) but he did tell me how to look up the firmware version. I’ll see if I can verify if this is the latest version next Monday. @chris, do you keep a log of device versions?

Same FW 022200 here. I only checked one of mine.

Edit:
@DaveL Did you start on OH 2.4 or has this system been upgraded?
I’m considering trying the following:

  1. spin up a fresh Ubuntu 18.04 VM, install OH, add Z Wave network, and see what happens.
  2. Snapshot my current OH VM and do an upgrade and see if it works right.

I started on OH 2.4. Been very happy with it overall, this has been really the only snag. Well, that and I was using the Insteon binding and PLM for a bit, what a PITA…I gave up on that.

What do you mean by a log? I don’t really “log” anything as such…

The database can differentiate between versions if there are differences, and if people create database entries for new versions.

@chris, I was asking, if you can differentiate by Firmware revisions, how do you do that? Wondering if the binding was addressing the current firmware or if @TinFoil and I have something newer. If it can differentiate, and we arguably have the newest devices, can the database be updated to include our version?

Yes, as I answered above, the database can differentiate between versions if there are differences, and if people create database entries for new versions.

So there would need to be two different database entries for the different versions.

https://www.cd-jackson.com/index.php/zwave/zwave-device-database/zwave-device-database-guide

However, since you both have the same version, there isn’t anything to differentiate.

Specific to the HVAC mode, the XML from the database includes all 5 modes. I’m not sure why yours only has off and heat. I got called out yesterday morning and haven’t had a chance to spin up a new VM to test. Is it possible to manually update the XML for your installation using the OH2 XML from the DB? I still dont understand why yours doesn’t match mine or the DB.

Agreed, I’m unsure why mine doesn’t match the DB. I’m going to have to go the route of manual configuration, after figuring out how to do that. This seems to be that answer:

If the other channels were added at a later date one needs to delete the Thing and readd it to pick up the database (and therefore binding) changes.

Thanks sihui, but I just pulled this thing in a few weeks ago. The last edits in the database are months old. Believe me, I don’t want to go the manual configuration route, its one more thing this non-programmer would need to learn and I have enough on my plate LOL

Hi TinFoil,

Any chance you can share the CSS file? I’d like to get this to work but have no experience with html.

Also do you have the widget code saved in a .json?

Here is the CSS:


.thermkeypad{
  min-width: 300px;
  max-width: 500px;
  width: 100%;
  background-color: #000;
  border-radius: 10px;
  border: 4px solid #AAA;
  left: 0;
  top: 0;
  white-space: nowrap;
  padding: 3px;
  margin-bottom: 10px;
}

.thermkeypad .thermkeypadRow {
  width: calc(100% - 0px);
  padding: 0px;
  margin: 0px;
  border-style: none;
  padding: 0px;
  text-align: center;
}

.thermkeypad .thermkeypadCell {
  width: calc(25% - 10px);
  padding: 0px;
  margin: 0px;
  border-style: none;
  padding: 0px;
  text-align: center;
  display: inline-block;
  vertical-align: middle;
}

.thermkeypad .adjustimg {
	max-width: 100%;
	min-width: 100%;
	max-height: 100%;
	min-height: 100%;
	display: block;
}
.thermkeypad .adjustbtn {
	width: 50%;
	max-height: 30px;
	margin: 0px 25% 0px 25%;
	padding: 0px;
	border: none;
	outline: none;
	display: block;
}
.thermkeypad button {
	width: 90%;
	border: 2px solid #AAA;
	border-radius: 5px;
	background-color: black;
	outline: none;
}
.thermkeypad .LCDPNL_SP {
	width: 50%;
  background-color: #000;
  border-radius: 10px;
  color: #000;
  border: 2px solid #AAA;
  margin: 5px 25% 5px 25%;
  color: white;
  font-size: 1.25em;
  /* display: inline-block; */
}
.thermkeypad .selected_mode {
  background-color: #A00;
}
.thermkeypad .not_selected_mode {
  background-color: #300;
}

And I do not have it is a json file. Sorry about that. If you want the timers to work, there is some rules that I use to make that work. Note that my HTML has all 3 units in it, so you may need to adjust as necessary.