Using indoor dew-point and node-red to control temperature/relative humidity

Can you share your flow? I think I have all of the sensors calculating dewpoint and have just been manually adjusting cooling setpoint manually when I think to check the dewpoint.

Sent you a PR to support Celsius in your app

1 Like

Thanks, now committed.

2 Likes

Sorry for the delay. Some dude with an RV knocked my fence down :zipper_mouth_face:

Here you go:

There are 4 steps:

  1. Set the desired dew-point (flow.Td) based on Mode
  2. Every minute calculate the current dew-point (flow.dewpoint)
  3. When flow.dewpoint > flow.Td set the cooling setpoint to be 3 degrees lower than the current thermostat temperature
  4. Keep cooling on until flow.dewpoint + 2.5 <= flow.Td. Then set the cooling setpoint to be 3 degrees higher than the current thermostat temperature. This turns off cooling.
Sequence
[
    {
        "id": "b67db659.3919c",
        "type": "tab",
        "label": "Flow 2",
        "disabled": false,
        "info": ""
    },
    {
        "id": "8b3b629f.362e68",
        "type": "cronplus",
        "z": "b67db659.3919c",
        "name": "",
        "outputField": "payload",
        "timeZone": "",
        "persistDynamic": false,
        "commandResponseMsgOutput": "output1",
        "outputs": 1,
        "options": [
            {
                "name": "schedule1",
                "topic": "schedule1",
                "payloadType": "default",
                "payload": "",
                "expressionType": "cron",
                "expression": "15 */1 * * * * *",
                "location": "",
                "offset": "0",
                "solarType": "all",
                "solarEvents": "sunrise,sunset"
            }
        ],
        "x": 120.00003051757812,
        "y": 375.99998474121094,
        "wires": [
            [
                "72693efb.fe4e5"
            ]
        ]
    },
    {
        "id": "72693efb.fe4e5",
        "type": "hubitat device",
        "z": "b67db659.3919c",
        "deviceLabel": "THD - Indoor Average",
        "name": "",
        "server": "a22e0ea9.276dc8",
        "deviceId": "1794",
        "attribute": "",
        "sendEvent": false,
        "x": 330.0000305175781,
        "y": 375.99998474121094,
        "wires": [
            [
                "74f079df.b7c15"
            ]
        ]
    },
    {
        "id": "74f079df.b7c15",
        "type": "function",
        "z": "b67db659.3919c",
        "name": "Dew-point calculator",
        "func": "function f2c(F) {\nvar C = 5 * ((F-32)/9);\nreturn C;\n}\nfunction dpC(T,RH) {\nvar Td = 243.04 * (Math.log(RH/100)+((17.625*T)/(243.04+T)))/(17.625-Math.log(RH/100)-((17.625*T)/(243.04+T)));\nreturn Td;\n}\nfunction c2f(C) {\nvar F = parseFloat((32 + (9*(C/5))).toFixed(2));\nreturn F;\n}\nvar tempf = msg.payload.temperature.value;\nvar rel_hum = msg.payload.humidity.value;\nvar tempc = f2c(tempf);\nvar dewpointc = dpC(tempc,rel_hum);\nmsg.payload = c2f(dewpointc);\nmsg.topic = \"dewpoint\";\nreturn msg;",
        "outputs": 1,
        "noerr": 0,
        "initialize": "",
        "finalize": "",
        "libs": [],
        "x": 580.0000305175781,
        "y": 375.99998474121094,
        "wires": [
            [
                "d82c144c.e53a78"
            ]
        ]
    },
    {
        "id": "d82c144c.e53a78",
        "type": "rbe",
        "z": "b67db659.3919c",
        "name": "",
        "func": "rbe",
        "gap": "",
        "start": "",
        "inout": "out",
        "property": "payload",
        "x": 735.0000305175781,
        "y": 375.99998474121094,
        "wires": [
            [
                "8ca6579f.678508",
                "554a8ded.3d0ab4"
            ]
        ],
        "l": false
    },
    {
        "id": "8ca6579f.678508",
        "type": "mqtt out",
        "z": "b67db659.3919c",
        "name": "Indoor Dewpoint",
        "topic": "dewpoint",
        "qos": "2",
        "retain": "true",
        "respTopic": "",
        "contentType": "",
        "userProps": "",
        "correl": "",
        "expiry": "",
        "broker": "40144fb8.a1c1e",
        "x": 870.0000305175781,
        "y": 375.99998474121094,
        "wires": []
    },
    {
        "id": "77766a94.96202c",
        "type": "comment",
        "z": "b67db659.3919c",
        "name": "Using cron, calculate the current dew-point (flow.dewpoint) every minute",
        "info": "",
        "x": 310,
        "y": 320,
        "wires": []
    },
    {
        "id": "abc34a6c.d6b518",
        "type": "mqtt in",
        "z": "b67db659.3919c",
        "name": "Indoor Dewpoint",
        "topic": "dewpoint",
        "qos": "2",
        "datatype": "auto",
        "broker": "40144fb8.a1c1e",
        "x": 120,
        "y": 620,
        "wires": [
            [
                "464e0d0d.b6b5fc"
            ]
        ]
    },
    {
        "id": "27947d64.bd36b2",
        "type": "switch",
        "z": "b67db659.3919c",
        "name": "cool only",
        "property": "thermostat_mode",
        "propertyType": "flow",
        "rules": [
            {
                "t": "eq",
                "v": "cool",
                "vt": "str"
            }
        ],
        "checkall": "true",
        "repair": false,
        "outputs": 1,
        "x": 480,
        "y": 620,
        "wires": [
            [
                "543889d2.c9e69"
            ]
        ]
    },
    {
        "id": "543889d2.c9e69",
        "type": "switch",
        "z": "b67db659.3919c",
        "name": "dewpoint > Td",
        "property": "dewpoint",
        "propertyType": "flow",
        "rules": [
            {
                "t": "gt",
                "v": "Td",
                "vt": "flow"
            },
            {
                "t": "else"
            }
        ],
        "checkall": "true",
        "repair": false,
        "outputs": 2,
        "x": 660,
        "y": 620,
        "wires": [
            [
                "da57a88e.5a2338"
            ],
            [
                "9e0e6134.f253f"
            ]
        ]
    },
    {
        "id": "da57a88e.5a2338",
        "type": "delay",
        "z": "b67db659.3919c",
        "name": "",
        "pauseType": "delay",
        "timeout": "1",
        "timeoutUnits": "minutes",
        "rate": "1",
        "nbRateUnits": "1",
        "rateUnits": "second",
        "randomFirst": "1",
        "randomLast": "5",
        "randomUnits": "seconds",
        "drop": false,
        "x": 835,
        "y": 620,
        "wires": [
            [
                "82d8be1e.e702e8"
            ]
        ],
        "l": false
    },
    {
        "id": "9e0e6134.f253f",
        "type": "change",
        "z": "b67db659.3919c",
        "name": "reset",
        "rules": [
            {
                "t": "set",
                "p": "reset",
                "pt": "msg",
                "to": "true",
                "tot": "bool"
            }
        ],
        "action": "",
        "property": "",
        "from": "",
        "to": "",
        "reg": false,
        "x": 790,
        "y": 680,
        "wires": [
            [
                "da57a88e.5a2338"
            ]
        ]
    },
    {
        "id": "82d8be1e.e702e8",
        "type": "switch",
        "z": "b67db659.3919c",
        "name": "thermostatOperatingState = idle",
        "property": "thermostatOperatingState",
        "propertyType": "flow",
        "rules": [
            {
                "t": "eq",
                "v": "idle",
                "vt": "str"
            }
        ],
        "checkall": "true",
        "repair": false,
        "outputs": 1,
        "x": 1030,
        "y": 620,
        "wires": [
            [
                "6870f3dd.b1a4bc"
            ]
        ]
    },
    {
        "id": "6870f3dd.b1a4bc",
        "type": "delay",
        "z": "b67db659.3919c",
        "name": "",
        "pauseType": "delay",
        "timeout": "20",
        "timeoutUnits": "seconds",
        "rate": "1",
        "nbRateUnits": "5",
        "rateUnits": "minute",
        "randomFirst": "1",
        "randomLast": "5",
        "randomUnits": "seconds",
        "drop": true,
        "x": 1215,
        "y": 620,
        "wires": [
            [
                "e82af4c4.1e37a8"
            ]
        ],
        "l": false
    },
    {
        "id": "e82af4c4.1e37a8",
        "type": "change",
        "z": "b67db659.3919c",
        "name": "command = setCoolingSetpoint; msg.arguments = flow.thermostatTemp - 3",
        "rules": [
            {
                "t": "set",
                "p": "command",
                "pt": "msg",
                "to": "setCoolingSetpoint",
                "tot": "str"
            },
            {
                "t": "set",
                "p": "arguments",
                "pt": "msg",
                "to": "$flowContext(\"thermostatTemp\") - 3",
                "tot": "jsonata"
            }
        ],
        "action": "",
        "property": "",
        "from": "",
        "to": "",
        "reg": false,
        "x": 1550,
        "y": 620,
        "wires": [
            [
                "1af11300.efe175"
            ]
        ]
    },
    {
        "id": "1af11300.efe175",
        "type": "delay",
        "z": "b67db659.3919c",
        "name": "",
        "pauseType": "delay",
        "timeout": "2",
        "timeoutUnits": "seconds",
        "rate": "1",
        "nbRateUnits": "1",
        "rateUnits": "second",
        "randomFirst": "1",
        "randomLast": "5",
        "randomUnits": "seconds",
        "drop": false,
        "x": 1875,
        "y": 620,
        "wires": [
            [
                "bef35bc0.f957e"
            ]
        ],
        "l": false
    },
    {
        "id": "bef35bc0.f957e",
        "type": "hubitat command",
        "z": "b67db659.3919c",
        "deviceLabel": "Honeywell T6 Pro",
        "name": "",
        "server": "662851c4.3ccad",
        "deviceId": "3493",
        "command": "",
        "commandArgs": "",
        "x": 2030,
        "y": 620,
        "wires": [
            []
        ]
    },
    {
        "id": "71957000.55082",
        "type": "comment",
        "z": "b67db659.3919c",
        "name": "In cool mode, if the dewpoint is > flow.Td, and the thermostat operating state is idle, then setCoolingSetpoint to be 3 degrees less than the current thermostat temperature",
        "info": "",
        "x": 610,
        "y": 500,
        "wires": []
    },
    {
        "id": "6a3cff24.f2bbb8",
        "type": "comment",
        "z": "b67db659.3919c",
        "name": "On purpose, there is a 1 minute resetable delay between dewpoint > flow.td and proceeding with the sequence",
        "info": "",
        "x": 420,
        "y": 560,
        "wires": []
    },
    {
        "id": "464e0d0d.b6b5fc",
        "type": "change",
        "z": "b67db659.3919c",
        "name": "toNumber",
        "rules": [
            {
                "t": "set",
                "p": "payload",
                "pt": "msg",
                "to": "$number(payload)",
                "tot": "jsonata"
            }
        ],
        "action": "",
        "property": "",
        "from": "",
        "to": "",
        "reg": false,
        "x": 310,
        "y": 620,
        "wires": [
            [
                "27947d64.bd36b2"
            ]
        ]
    },
    {
        "id": "db3c4992.69d1d",
        "type": "switch",
        "z": "b67db659.3919c",
        "name": "cooling",
        "property": "payload.value",
        "propertyType": "msg",
        "rules": [
            {
                "t": "eq",
                "v": "cooling",
                "vt": "str"
            }
        ],
        "checkall": "true",
        "repair": false,
        "outputs": 1,
        "x": 320,
        "y": 920,
        "wires": [
            [
                "bf281453.584498"
            ]
        ]
    },
    {
        "id": "4c526ef8.c7e47",
        "type": "hubitat device",
        "z": "b67db659.3919c",
        "name": "Honeywell T6 Pro",
        "server": "662851c4.3ccad",
        "deviceId": "3493",
        "attribute": "thermostatOperatingState",
        "sendEvent": true,
        "x": 130,
        "y": 920,
        "wires": [
            [
                "db3c4992.69d1d"
            ]
        ]
    },
    {
        "id": "4cbb0abf.4861fc",
        "type": "switch",
        "z": "b67db659.3919c",
        "name": "msg.payload <= flow.Td",
        "property": "payload",
        "propertyType": "msg",
        "rules": [
            {
                "t": "lte",
                "v": "Td",
                "vt": "flow"
            }
        ],
        "checkall": "true",
        "repair": false,
        "outputs": 1,
        "x": 990,
        "y": 920,
        "wires": [
            [
                "789d2bfe.082f7c"
            ]
        ]
    },
    {
        "id": "bf281453.584498",
        "type": "change",
        "z": "b67db659.3919c",
        "name": "payload = flow.dewpoint; payload = payload + 2.5",
        "rules": [
            {
                "t": "set",
                "p": "payload",
                "pt": "msg",
                "to": "dewpoint",
                "tot": "flow"
            },
            {
                "t": "set",
                "p": "payload",
                "pt": "msg",
                "to": "$number(payload) + 2.5",
                "tot": "jsonata"
            }
        ],
        "action": "",
        "property": "",
        "from": "",
        "to": "",
        "reg": false,
        "x": 630,
        "y": 920,
        "wires": [
            [
                "1c982cca.d24fe3",
                "4cbb0abf.4861fc"
            ]
        ]
    },
    {
        "id": "1c982cca.d24fe3",
        "type": "delay",
        "z": "b67db659.3919c",
        "name": "1 min",
        "pauseType": "delay",
        "timeout": "1",
        "timeoutUnits": "minutes",
        "rate": "1",
        "nbRateUnits": "1",
        "rateUnits": "second",
        "randomFirst": "1",
        "randomLast": "5",
        "randomUnits": "seconds",
        "drop": false,
        "x": 450,
        "y": 840,
        "wires": [
            [
                "4f1907d3.ef95c"
            ]
        ]
    },
    {
        "id": "4f1907d3.ef95c",
        "type": "switch",
        "z": "b67db659.3919c",
        "name": "thermostatOperatingState = cooling",
        "property": "thermostatOperatingState",
        "propertyType": "global",
        "rules": [
            {
                "t": "eq",
                "v": "cooling",
                "vt": "str"
            }
        ],
        "checkall": "true",
        "repair": false,
        "outputs": 1,
        "x": 690,
        "y": 840,
        "wires": [
            [
                "bf281453.584498"
            ]
        ]
    },
    {
        "id": "554a8ded.3d0ab4",
        "type": "change",
        "z": "b67db659.3919c",
        "name": "flow.dewpoint",
        "rules": [
            {
                "t": "set",
                "p": "dewpoint",
                "pt": "flow",
                "to": "payload",
                "tot": "msg"
            }
        ],
        "action": "",
        "property": "",
        "from": "",
        "to": "",
        "reg": false,
        "x": 860,
        "y": 420,
        "wires": [
            []
        ]
    },
    {
        "id": "789d2bfe.082f7c",
        "type": "change",
        "z": "b67db659.3919c",
        "name": "command = setCoolingSetpoint; msg.arguments = flow.thermostatTemp + 3",
        "rules": [
            {
                "t": "set",
                "p": "command",
                "pt": "msg",
                "to": "setCoolingSetpoint",
                "tot": "str"
            },
            {
                "t": "set",
                "p": "arguments",
                "pt": "msg",
                "to": "$flowContext(\"thermostatTemp\") + 3",
                "tot": "jsonata"
            }
        ],
        "action": "",
        "property": "",
        "from": "",
        "to": "",
        "reg": false,
        "x": 1410,
        "y": 920,
        "wires": [
            [
                "6590f9a2.4efef"
            ]
        ]
    },
    {
        "id": "6590f9a2.4efef",
        "type": "delay",
        "z": "b67db659.3919c",
        "name": "",
        "pauseType": "delay",
        "timeout": "2",
        "timeoutUnits": "seconds",
        "rate": "1",
        "nbRateUnits": "1",
        "rateUnits": "second",
        "randomFirst": "1",
        "randomLast": "5",
        "randomUnits": "seconds",
        "drop": false,
        "x": 1735,
        "y": 920,
        "wires": [
            [
                "bf4d1bd.cd23d68"
            ]
        ],
        "l": false
    },
    {
        "id": "bf4d1bd.cd23d68",
        "type": "hubitat command",
        "z": "b67db659.3919c",
        "deviceLabel": "Honeywell T6 Pro",
        "name": "",
        "server": "662851c4.3ccad",
        "deviceId": "3493",
        "command": "",
        "commandArgs": "",
        "x": 1890,
        "y": 920,
        "wires": [
            []
        ]
    },
    {
        "id": "5124f62e.574a38",
        "type": "comment",
        "z": "b67db659.3919c",
        "name": "Keep cooling until \"flow.dewpoint + 2.5\" <= flow.Td, then raise the thermostat temperature by 3 degrees to turn off cooling",
        "info": "",
        "x": 460,
        "y": 760,
        "wires": []
    },
    {
        "id": "67502278.2c3254",
        "type": "change",
        "z": "b67db659.3919c",
        "name": "flow.Td=56.0 (Sleep)",
        "rules": [
            {
                "t": "set",
                "p": "Td",
                "pt": "flow",
                "to": "56",
                "tot": "num"
            }
        ],
        "action": "",
        "property": "",
        "from": "",
        "to": "",
        "reg": false,
        "x": 560,
        "y": 160,
        "wires": [
            []
        ]
    },
    {
        "id": "8d0fc388.5f83f8",
        "type": "change",
        "z": "b67db659.3919c",
        "name": "flow.Td=57.5 (Home)",
        "rules": [
            {
                "t": "set",
                "p": "Td",
                "pt": "flow",
                "to": "57.5",
                "tot": "num"
            }
        ],
        "action": "",
        "property": "",
        "from": "",
        "to": "",
        "reg": false,
        "x": 560,
        "y": 200,
        "wires": [
            []
        ]
    },
    {
        "id": "1a979012.481e",
        "type": "change",
        "z": "b67db659.3919c",
        "name": "flow.Td=61.0 (Away)",
        "rules": [
            {
                "t": "set",
                "p": "Td",
                "pt": "flow",
                "to": "61",
                "tot": "num"
            }
        ],
        "action": "",
        "property": "",
        "from": "",
        "to": "",
        "reg": false,
        "x": 560,
        "y": 240,
        "wires": [
            []
        ]
    },
    {
        "id": "9e89461b.0cca5",
        "type": "switch",
        "z": "b67db659.3919c",
        "name": "Sleep/Home/Away",
        "property": "payload.value",
        "propertyType": "msg",
        "rules": [
            {
                "t": "eq",
                "v": "Sleep",
                "vt": "str"
            },
            {
                "t": "eq",
                "v": "Home",
                "vt": "str"
            },
            {
                "t": "eq",
                "v": "Away",
                "vt": "str"
            }
        ],
        "checkall": "true",
        "repair": false,
        "outputs": 3,
        "x": 330,
        "y": 200,
        "wires": [
            [
                "67502278.2c3254"
            ],
            [
                "8d0fc388.5f83f8"
            ],
            [
                "1a979012.481e"
            ]
        ]
    },
    {
        "id": "fc82eb85.f3f1b8",
        "type": "hubitat mode",
        "z": "b67db659.3919c",
        "name": "Mode",
        "server": "a22e0ea9.276dc8",
        "sendEvent": true,
        "x": 130,
        "y": 200,
        "wires": [
            [
                "9e89461b.0cca5"
            ]
        ]
    },
    {
        "id": "d46b2593.544e98",
        "type": "comment",
        "z": "b67db659.3919c",
        "name": "Set the desired dewpoint (flow.Td) based on Mode",
        "info": "",
        "x": 250,
        "y": 100,
        "wires": []
    },
    {
        "id": "a22e0ea9.276dc8",
        "type": "hubitat config",
        "name": "HubitatM",
        "usetls": false,
        "host": "192.168.1.46",
        "port": "80",
        "appId": "1522",
        "nodeRedServer": "http://192.168.1.4:1880",
        "webhookPath": "/hubitat/webhook",
        "autoRefresh": true,
        "useWebsocket": false,
        "colorEnabled": true,
        "color": "#5dd049"
    },
    {
        "id": "40144fb8.a1c1e",
        "type": "mqtt-broker",
        "name": "",
        "broker": "127.0.0.1",
        "port": "1883",
        "tls": "",
        "clientid": "",
        "usetls": false,
        "compatmode": false,
        "keepalive": "15",
        "cleansession": true,
        "birthTopic": "",
        "birthQos": "0",
        "birthRetain": "false",
        "birthPayload": "",
        "closeTopic": "",
        "closeRetain": "false",
        "closePayload": "",
        "willTopic": "",
        "willQos": "0",
        "willRetain": "false",
        "willPayload": ""
    },
    {
        "id": "662851c4.3ccad",
        "type": "hubitat config",
        "name": "HubitatS",
        "usetls": false,
        "host": "192.168.1.36",
        "port": "80",
        "appId": "4489",
        "nodeRedServer": "http://192.168.1.4:1880",
        "webhookPath": "/hubitat/webhook2",
        "autoRefresh": true,
        "useWebsocket": false,
        "colorEnabled": true,
        "color": "#51b8f0"
    }
]
2 Likes

Good grief.

Well, stuff happens. I felt bad for him too. Retired electrical engineer from California negotiating a tiny backstreet in New Orleans that his GPS misdirected him to.

1 Like

Good attitude!

1 Like

Well, I made a friend. Seriously, being upset wasn’t going to fix anything.

4 Likes

FWIW...I can confirm the obvious...an 80 degree bedroom with 70 deg. dewpoint is indeed "quite uncomfortable" as proposed by Mr. Epstein's chart. The windows have been closed and AC has been turned on per wife's request. Closer to 78 degrees and 60 degree dewpoint now and much more pleasant. I'm watching the calculated dewpoint but not using it for control until I have more than one humidity sensor.

Sorry to hear about your fence but at least you made a new friend!

2 Likes

Total nube question:
I installed the app but I have no idea how to use it.

After installing and configuring the app, the result is a new Virtual Temperature Sensor that contains the dewpoint computed from any temperature and humidity sensor.

Do the following:

Step 1 - Navigate to the "Apps" page, then click on "Add User App":

A new popup window will present all of the User Apps you have installed, including the Virtual Dewpoint Sensor.

Step 2 - Click on the Virtual Dewpoint Sensor tile:

Screen Shot 2021-06-24 at 8.13.04 AM

You will then be presented with the app configuration panel:

Step 3 - Make the selections and entries as desired, then click "Done". A new Virtual Temperature Sensor device will then be created, named as entered. The dewpoint computation will take place at the selected calculation update interval.

Hope this helps.

4 Likes

Thank you!

1 Like

Working perfectly!

069d5214-31d4-41aa-b31b-fa0b9a466fc3_360x203

3 Likes

So I live in East Texas, where I have the weather conditions you've described, and I've been experimenting, and I haven't been able to make dew point quite work for me.

Do you use dew point for HVAC control at night, while you're in bed? That's the time that seems to be the roughest for us to pin down, and I wonder if it's because being in bed under sheets changes the effective atmosphere I'm experiencing.

Do you have something you've been happy with for nighttime sleeping area HVAC control?

You mentioned targeting dew points in the 55-57 deg F range, but I've found myself uncomfortable at temperatures in the low 70s that had dew points around 47 or 48 deg F.

Nota Bene: I'm using the dew point calculation built in to the Ecowitt driver. It seems to work right as far as I can tell, but I'm confused enough by my results I'm trying to examine everything I think I know.

Yup 24/7 during the summer.

That would be uncomfortably "cold" or "dry" to me. I guess it is whatever one is used to.

1 Like

Thanks for getting back to me so quickly!

I'll have to keep experimenting, I guess.

I just had a thought - your Ecowitt is reporting an outdoor dew-point, correct? My thermostat control is based on a calculated indoor dew-point.

I have a couple of Ecowitt sensors, several of which are located indoors. It is the dew point calculated by the driver of those indoor sensors that I control on.

Does that answer the question? I'm still ignorant enough of this I wouldn't know if there were some sort of "Outdoor dew-point calculation" that were different from an "indoor dew-point calculation."

Thanks!

1 Like

I think so. Do your sensors report temperature and relative humidity (for each sensor)? If your post those numbers, I'll do a quick dew-point calc and see if the number I get matches the number you have.

I'm just a little flummoxed that a dew-point of 47-50 feels uncomfortable. It certainly is possible (after all, everything is subjective), but I want to eliminate all other possibilities. Would also help if you have temp/rel. humidity numbers from any non-Ecowitt sensors.

1 Like

I mentioned this in another thread but you can buy this inexpensive but fairly accurate (within +/- 1%) hygrometer:

I am using it to test and tweak HE & my Konke Humidity sensors but it seems like a good thing for this purpose as well.

2 Likes