Page 1 of 1

[ANSWERED]: Outside Temp to Stelpro STZW402+ Thermostat

PostPosted: Fri Apr 29, 2016 6:12 pm
by jimM
Hi all,
I have 3 of these line voltage thermostats installed controlling baseboard heaters (240v) and working well in Indigo after defining them as General Thermostat V2 models. Very happy so far. If all goes well I will have 1 of these in every room as baseboards are the backup system for the heat pump.

One of the features I would like to make use of is their ability to display outside temperature from either a remote sensor or an 'app' according to their manual:
"In order to display the outdoor temperature, an external sensor needs to be part of the Z-Wave network. It may be a physical sensor or a weather station app.
Refer to your Z-Wave hub controller instructions manual to find how to associate both devices. On some Z-Wave hub controllers, an app may be used to provide the outdoor temperature."


I would suspect in the case of a sensor it would have to be somehow associated with the sensor through pairing? (new to the z-wave part of Indigo so excuse my lack of buzzword in case it has another definition) Anyhow I would be interested in that method as a fallback.

What really interests me is the ability to send the stat the outside temp from an app, more specifically from the variable I have been maintaining in Indigo over the past many years from my own weather station (a Davis VP2 using Weather Display and the IWS plugin I use from way back when). Don't know if I can somehow bind/associate the variable directly to the stat using a python script/applescript or other feature of Indigo, or possibly send a raw command to the stats in a trigger on temp change. I checked other forums googling to see if I could get hints and on another forum they are updating the stats from the controlling application using weather underground info so I know it can be done.

Can anyone point me in the right direction? If it can be accomplished using a variable it wouldn't be a stretch to think one could send them the data from any of the weather plugins as well. It would be very cool to glance at the stat and see the outside temp from any room in the house coming from the on site weather station, or for anyone else even from their weather plugin's temp output,

Having been away from the site for a while I'm not as up to date as I used to be on using some of the newer technologies in Indigo such as sending raw commands or virtual devices but am more than willing to learn how to make this happen. (can't believe this home has been controlled with Indigo for almost 9 years !!)
Many thanks for any advice to get started on this latest WAF project.
Jim

Re: Getting Outside Temp to the Stelpro STZW402+ Thermostat

PostPosted: Sat Apr 30, 2016 12:02 pm
by matt (support)
Hi Jim,

I'm not sure how it the Stelpro wants to handle that, but try sending the following raw Z-Wave command to it:

0x31 0x05 0x01 0x01 0x17

If that works (shows any value on the Stelpro for the outside sensor), then I can explain how to encode/calculate the bytes given a temperature variable. If that doesn't work, then I'm not sure how to figure this out. I'd suggest an email to Stelpro for the technical details and we can go from there.

Re: [ANSWERED]: Outside Temp to Stelpro STZW402+ Thermostat

PostPosted: Sat Apr 30, 2016 4:02 pm
by jimM
Matt,
If the intent was to send 23C it worked !!!!! Displaying on the stat as listed in the user guide and everything else is working as advertised.
:D

Re: [ANSWERED]: Outside Temp to Stelpro STZW402+ Thermostat

PostPosted: Sat Apr 30, 2016 4:56 pm
by matt (support)
Cool that worked. 8)

Okay, there is some magic to get everything encoded correctly but try:

Code: Select all
import math

tempVarId = 1639161279               # your variable ID here
targetDevId = 189563274               # your thermostat ID here

tempVar = indigo.variables[tempVarId]
valfloat = float(tempVar.value)         # note value must be integer or float (with no degree symbol or F/C characters)

valunits = 2         # 1: Celsius, 2: Fahrenheit

valprecision = 0      # or use 1 to show 0.1 precision
if valprecision > 0:
   valraw = int(round(valfloat * math.pow(10, valprecision)))
else:
   valraw = int(valfloat)

valtype = 1            # temperature (don't change)

if valraw < 0:
   valraw *= -1
   if valraw > 0x800000000000:
      valsize = 7
      shifter = 48
   elif valraw > 0x8000000000:
      valsize = 6
      shifter = 40
   elif valraw > 0x80000000:
      valsize = 5
      shifter = 32
   elif valraw > 0x800000:
      valsize = 4
      shifter = 24
   elif valraw > 0x8000:
      valsize = 3
      shifter = 16
   elif valraw > 0x80:
      valsize = 2
      shifter = 8
   else:
      valsize = 1
      shifter = 0
   valraw *= -1
else:
   if valraw > 0x7FFFFFFFFFFF:
      valsize = 7
      shifter = 48
   elif valraw > 0x7FFFFFFFFF:
      valsize = 6
      shifter = 40
   elif valraw > 0x7FFFFFFF:
      valsize = 5
      shifter = 32
   elif valraw > 0x7FFFFF:
      valsize = 4
      shifter = 24
   elif valraw > 0x7FFF:
      valsize = 3
      shifter = 16
   elif valraw > 0x7F:
      valsize = 2
      shifter = 8
   else:
      valsize = 1
      shifter = 0

valscale = 0
if valunits > 0:
   valscale = valunits - 1

packet = [0x31, 0x05, valtype]

byte1 = (valprecision & 0x07) << 5
byte1 |= (valscale & 0x03) << 3
byte1 |= (valsize & 0x07)
packet.append(byte1)

for index in range(1, valsize + 1):
   byteval = (valraw >> shifter) & 0xFF
   packet.append(byteval)
   shifter -= 8

zwavePlugin = indigo.server.getPlugin("com.perceptiveautomation.indigoplugin.zwave")
zwavePlugin.executeAction("sendRawZwaveCommand", deviceId=targetDevId, props={'payload':packet})

Re: [ANSWERED]: Outside Temp to Stelpro STZW402+ Thermostat

PostPosted: Sat Apr 30, 2016 6:00 pm
by jimM
I put that code in a trigger on change of the variable OutsideTemp as an embedded python script, right?
EDIT: DUH... of course that's what I need to do.

OK After embedding it as a python script, entering the var ref ID as well as the target device ID and selecting Celcius and precision, compiled and ran the script on a manual change of the variable, and voila!!

Also, using your raw command example I googled a hex chart and started sending all kinds of numbers. The unit receives all positive numbers from 0 to 140 or so (in Hex), and does its negatives numbers moving down from 255 (FF which is -1) , down to 9D which I got as -99C

So what if I had 12 of these stats all needing the update from the variable? Can I get it to send it to them all at once?

Re: [ANSWERED]: Outside Temp to Stelpro STZW402+ Thermostat

PostPosted: Sun May 01, 2016 12:22 am
by matt (support)
You'll want to change it to loop over all the devices. Try the following and edit the array at the top to have all of your Stelpro device IDs:

Code: Select all
import math

tempVarId = 1639161279               # your variable ID here
targetDevIds = [189563274, another, another, another]               # your thermostat IDs here

tempVar = indigo.variables[tempVarId]
valfloat = float(tempVar.value)         # note value must be integer or float (with no degree symbol or F/C characters)

valunits = 2         # 1: Celsius, 2: Fahrenheit

valprecision = 0      # or use 1 to show 0.1 precision
if valprecision > 0:
   valraw = int(round(valfloat * math.pow(10, valprecision)))
else:
   valraw = int(valfloat)

valtype = 1            # temperature (don't change)

if valraw < 0:
   valraw *= -1
   if valraw > 0x800000000000:
      valsize = 7
      shifter = 48
   elif valraw > 0x8000000000:
      valsize = 6
      shifter = 40
   elif valraw > 0x80000000:
      valsize = 5
      shifter = 32
   elif valraw > 0x800000:
      valsize = 4
      shifter = 24
   elif valraw > 0x8000:
      valsize = 3
      shifter = 16
   elif valraw > 0x80:
      valsize = 2
      shifter = 8
   else:
      valsize = 1
      shifter = 0
   valraw *= -1
else:
   if valraw > 0x7FFFFFFFFFFF:
      valsize = 7
      shifter = 48
   elif valraw > 0x7FFFFFFFFF:
      valsize = 6
      shifter = 40
   elif valraw > 0x7FFFFFFF:
      valsize = 5
      shifter = 32
   elif valraw > 0x7FFFFF:
      valsize = 4
      shifter = 24
   elif valraw > 0x7FFF:
      valsize = 3
      shifter = 16
   elif valraw > 0x7F:
      valsize = 2
      shifter = 8
   else:
      valsize = 1
      shifter = 0

valscale = 0
if valunits > 0:
   valscale = valunits - 1

packet = [0x31, 0x05, valtype]

byte1 = (valprecision & 0x07) << 5
byte1 |= (valscale & 0x03) << 3
byte1 |= (valsize & 0x07)
packet.append(byte1)

for index in range(1, valsize + 1):
   byteval = (valraw >> shifter) & 0xFF
   packet.append(byteval)
   shifter -= 8

zwavePlugin = indigo.server.getPlugin("com.perceptiveautomation.indigoplugin.zwave")
for devId in targetDevIds:
   zwavePlugin.executeAction("sendRawZwaveCommand", deviceId=devId, props={'payload':packet})

Re: [ANSWERED]: Outside Temp to Stelpro STZW402+ Thermostat

PostPosted: Sun May 01, 2016 8:53 am
by jimM
Perfect!
I let the separate triggers (for each unit) run all last night and also got lucky as the temp dropped below 0C (32F) probably for the last time this season so got to test positive and negative territory. It showed the negative symbol on the stat as hoped/expected.
Just loaded your 2nd suggested script and it worked perfectly while manually changing the variable, so will let that run all day at 5 minute intervals as the temp rises and should be a good test.

Another observation for anyone thinking of integrating these stats, the STZW402+ displays all Celsius temps in .5C resolution, so I selected precision of "1" in the script for .1 precision. Somehow when the stat gets the temp from Indigo, it automatically rounds to .5C .
For example, Indigo (using your script) sends it a 12.2C outside temp, and it displays to the nearest .5C which in this case is 12.0. In Fahrenheit the stat displays in 1 F resolution so no need to ask for precision of .1 unless it.'s coming in from the station that way, so everything just works!

I'll let you know how testing goes later with 36 updates per hour in total to the 3 stats shouldn't take long . but WOW, all the stats are displaying the outside temp right now, from a single trigger in Indigo.... this is very cool and something that will add a lot of value to my system and I'm sure many others. So far the Stelpro z-wave stat is a very nicely behaving 240 Line voltage baseboard thermostat and easily integrates to Indigo with your support as seen in this thread!

I can't thank you enough for this advice especially on a weekend!!! Your support is the best Matt (and Jay!)

Re: [ANSWERED]: Outside Temp to Stelpro STZW402+ Thermostat

PostPosted: Mon May 02, 2016 5:18 pm
by jimM
Hi Matt et al,

Just to close the loop on this as resolved, the script Matt provided above has been working flawlessly on the 3 Stelpro STZW402+ z-wave stats I installed.
The outside temperature is coming from a variable set in Indigo 6 from my weather station software, but regardless of the source as long as a variable is set up and updated from anywhere, the outside temperature is sent to all the thermostats using this script which is just awesome! Every stat is updated by the raw command in the script which loops for multiples, and through about 900 updates over the past weekend all 3 thermostats are receiving the updates and displaying the outside temperature I'd guess within milliseconds of each other. I'm surprised with the speed of the updates both to and from the stat (room temp and set point) as well, compared to the old setup.

This is a great product (as simple as it's function compared to most thermostats).. but I've been waiting a long time for non-cloud based Line voltage baseboard stats to be available for my locally controlled HA ecosystem. Up until now I was using a very expensive Venstar stat/Aube relay setup and not getting this level of simplicity or features. The outside temp being displayed in every room with a stat puts the finishing touch on it... a number of steps easier than going to a device to see outside temp from my weather software or web page, so many thanks for Indigo's support of this feature Matt/Jay, and for making it as easy as you did!
Jim

Re: [ANSWERED]: Outside Temp to Stelpro STZW402+ Thermostat

PostPosted: Fri May 06, 2016 2:13 pm
by jimM
Hi again,
I've been running the above excellent script all week and things are going very well. So yesterday I decided to optimize things a bit just to get the most out of Indigo and maybe have a bit less clutter in the log and traffic on the network. The Stelpro stats are receiving updates from the OutsideTemp variable every 5 minutes and as I see them all updated in the same script it occurred to me that:
1. The stats display at .5 C resolution so even when the OutsideTemp var changed by .1 and resulted in no change to the .5 resolution display on the stat, the messages were still being sent.
2. Once I get all 13 installed that's a lot of logging and network traffic lol

So, I figured I could enhance the trigger that controls the sending of the messages and get even more efficiency from Indigo, but since I only know Applescript I used that for my proof of concept. Here's the work in progress so far, and it's working :

A. Set up variable - outSideTemp - what's coming in from the weather station or other source like the web or someplace
B. Setup variable - outSideTempRounded
C. Set up a trigger on change of variable outSideTemp
D. In the Conditions tab, I placed the following Applescript code: (because I'm still a python newb)

Code: Select all
tell application "IndigoServer"
   if (the value of variable "outSideTemp" = the value of variable "outSideTempRounded") then
      return false
      #Incoming Temp already equals the previously rounded/sent temp so take no action
   end if
   set a to value of variable "outSideTemp"
   set theint to (round a rounding down)            # keeps everything before the decimal  e.g 16.7 becomes 16
   set thedec to (round ((a - theint) * 2)) / 2      #results in rounding everything after the decinal to the nearest .5
   if (the value of variable "outSideTempRounded" = theint + thedec as text) then
         #theint + thedec joins the number back together
          #Incoming Temp was rounded to .5 and equals the previously rounded/sent temp so take no action
        return false   
   end if
   set the value of variable "OutsideTempRounded" to theint + thedec as text   #set the rounded variable
   return true
   #Incoming Temp was rounded to .5C and does not equal the previously rounded/sent temp so process this for sending
end tell
#credit to a number of Applescript  forums for parts of the code of course
E . Pasted and configured Matt's python script from above to be executed in the actions tab. I also created a Log item to write to the screen that the incoming temp of x.x was rounded to x.y and sent out to the stats.

So far so good and works great!
The script takes the incoming temp and if it's already equal to the variable outSideTempRounded, returns False to the trigger halting it. When it does change it usually just increments slightly by a couple tenths up or down in a 5 minute period so it is rounded in the script and if it still equals the rounded temp variable, it returns False again and prevents the redundant temp being sent. Finally if the temp changed more than .5C due to the rounding it returns True and the trigger's script (from the post above) fires. It also sets the outSideTempRounded variable to the newly rounded temp ready to send the stat by the trigger's Action script.

The result is now Indigo only sends out to the stat the messages when they are required instead of x messages per hour to N number of stats which can fill the log and the network.. There are 2 things I need to reconcile though, and looking for advice on how to handle that.
1. converting the condition script to python. Edit- not required, A/S is expected in the conditions tab.
2. When the condition returns true the python script fires and processes rounding on the same OutsideTempRounded variable but this time in .1C resolution. The resolution is only a minor issue because the stat rounds what it receives too, but what I am hoping is that I can have the script not round at all and just package the previously rounded variable and send it out. Every time I touch that masterpiece of a script though I break it lol.

EDIT - So turns out this post was more "scripting therapy" (or I am a python newb) than a support request :oops: as upon re-reading it I figured out that it just needed more thought!
This was a simple adjustment to make just needed to look learn/experiment with the python script to see how it was working. In the condition script I left it as Applescript as it was expected to be A/S in that tab.
In the Python script all that was needed was to modify the If statement to take out the rounding function from the set valRaw portion of the statement so that:
Code: Select all
valraw = int(round(valfloat * math.pow(10, valprecision)))

becomes
Code: Select all
valraw = int(valfloat * math.pow(10, valprecision))

This sends the previously rounded temp (as a result of the condition script) in C to the stats without affecting the Fahrenheit function of the script where there is no rounding, due to the stat displaying F in 1 degree resolution.

The trigger enhancement works really well now. I've even created some logging code to see when the trigger fires and how it decides whether to send the outside temp message or not to that stats. There is also a Timer set up to handle the case where the outside temperature may not have changed more than .5 C in a 4 hour period. That's a stat limitation for displaying the same temp before reverting to inside set point display. A trigger resends the last temp again and restarts the 4 hour Timer countdown.
It's only been a couple weeks since getting the first 3 of these Stelpro z-Wave thermostats and already have them fully integrated with my Indigo system using only the general thermostat definition and a couple triggers and some great support!
Hope this helps anyone else setting up these stats with Indigo!
Jim