Sunday, January 14, 2018

Control Filtrete Wifi Thermostat with Alexa  -  Part 3 of 3

This is Part 3 of the tutorial on how to use Alexa to control a Filtrete Wifi thermostat, which doesn’t offer an official Alexa skill. In Part 1, I covered how to set up a Node-RED server on Raspberry Pi, install the Node-RED skill and link up the thermostat in Alexa. In Part 2, I covered how to read current temperature of the thermostat. In this last part of the tutorial I'm going to show you how to set target temperature on the thermostat.

Keep State - 1

The Filtrete Wifi thermostat operates in two modes: Heat and Cool. To set the target temperature, the API states that you must also specify the mode of operation. You can get the current mode from get_tstat - it is the tmode field in the returned JSON structure, as shown in Part 2 of the tutorial.
So, instead of calling get_tstat to get operating mode every time we set target temperature, we do this only once and cache its value. To check if a value has been cached, we look into the context.global variable in Node-RED. This is basically what the get_tmode_if_null node does.
The get_tmode_if_null node
Below is the code of the get_tmode_if_null node. Note that this node has two output slots. If tmode is not present in context.global.data, the first slot is selected, otherwise the second slot is selected. The first slot is linked to a get_tstat node, which is identical to the one we explained in Part 2.

// 'get_tmode_if_null' node

if (context.global.data.tmode === null)
{
    return [[msg],null];
}
else
{
    return [[], msg];
}

Keep State - 2

In the above setup, if tmode is not found in the cache, get_tstat will be called. When this happens, the original msg object that carries the target temperature get destroyed and is replaced by the result of the get_tstat. To get around this, we save the target temperature before doing anything else. This is basically what the save node does. Similarly, when we eventually finish setting the target temperature and report success to Alexa, we need to supply the original request back to Alexa. For this reason, we also need to cache the original request msg. Below is the code of the save node.

// 'save' node

context.global.data = context.global.data || {};
context.global.data.msg = msg;
if (!isNaN(msg.payload))
{
    context.global.data.target = msg.payload;
}
return msg;

Assemble a HTTP POST Request

Now, we have all the necessary ingredients to set a target temperature on the thermostat. This is what create_post_req does. Note that this node receives its input from two possible sources - the get_tstat node if we need to get the current operating mode, or the get_tmode_if_null node otherwise. Also note that this node has two output slots - the first one for sending the assembled request to the thermostat, and the second for reporting an error to Alexa if requested target temperature is out of range. Finally, note that this is the place where we save the current operating mode to context.global.data. Let's take a look at the code first:

// 'create_post_req' node

if (context.global.data.tmode === null)
{
    context.global.data.tmode = msg.payload.tmode;
}

var tmode = context.global.data.tmode;
var target = context.global.data.target;

if (target < 10 || target > 25) {
    var range = {
        min: 10.0,
        max: 25.0
    };
    msg.payload = false;
    msg.extra = range;
    
    return [[],msg];
}

target = Math.round(target * 9/5 + 32);
var ret;
switch (tmode)
{
    case 1:
        ret = {payload: {tmode:tmode, t_heat:target}};
        break;
    case 2:
        ret = {payload: {tmode:tmode, t_cool:target}};
        break;
    default:
        ret = {payload: {tmode:tmode, t_heat:target}};
        break;
}

return [[ret], null]
Remember, Alexa works with Celsius internally, so the target temperature received in the request is always in Celsius. First, we make sure the new target temperature is within a pre-defined range - in this case, my range is from 10 degree Celsius to 25 degree Celsius. Then, we convert the temperature to Fahrenheit required by the thermostat. Finally, we create the request payload with two variables - tmode and t_heat or t_cool.
If the target temperature is out of range, we return the response to Alexa immediately. To do this, we attach an alexa home resp to the second slot of the create_post_req node.

Post Request to Thermostat

Create an http request node, set the Method to POST and URL to [THERMOSTAT_IP_ADDRESS]/tstat. Then connect it to the first output slot of the create_post_req node.
The post_tstat node

Return success to Alexa

Create a function node with the following code:

// 'return_result' node

if (msg.payload.success === 0)
{
    var success = RED.util.cloneMessage(context.global.data.msg);
    success.payload = true;
    success.extra = {
        targetTemperature: {
            value: context.global.data.target
        }
    }
    return success;
}
else
{
    return null;
}
We then attach an alexa home resp to the output slot of the return_result node. to complete the flow.
The return_result node

The End

Remember to hit the Deploy on top of the Node-RED GUI to deploy your changes. Now, you can ask Alexa to set a target temperature on your Filtrete Wifi theromostat!
That's it! I hope you enjoyed reading this tutorial.

5 comments:

  1. Your tutorial was very helpful, this was my first attempt and I was successful creating the interface between my thermostat and Alexa. The commands to get and set the temperatures are straight forward. But what commands, or where can I get the commands to change the fan mode?

    ReplyDelete
  2. These are some of the finest tips given above about furnace repair. Such a useful article.
    Heating and Cooling Toronto

    ReplyDelete
  3. These points are kinda helpful in decor manner. Otherwise, I don't usually go for ductless air conditioning.

    https://www.furnaceac.com/

    ReplyDelete
  4. These tips for installation for ductless ac is so helpful. And the size vs capacity of AC is entirely necessary when planning to buy a ac unit.
    http://www.cosmopolitanmechanical.ca/

    ReplyDelete
  5. VERY INFORMATIVE ARTICLE. Thanks
    www.cosmopolitanmechanical.ca

    ReplyDelete

Using Google App Script and Google Sheets to create a class sign-up system

G Suite and Google App Script I've been learning to use G Suite and Google Apps Script lately. G Suite is a neat little platform that, a...