Simple Flow read humidity and turn fan on and off

I am trying something that should be very easy to accomplish, but I am stymied. I am using a nodeMCU and a DHT-22 temperature and humidity sensor (really there are 3, one indoors, one outdoors and one in a separate room). I use MQTT to send the temperature/humidity to a raspberrry pi. I have 3 fans and a louver that are controlled via WiFi. I want a simple node that will look at whether the fans are on, and if so, if the humidity is lower than a set point, send a command to turn the fans off. Similarly, if the fans are off, but the humidity rises above the set point, then turn them on. I will have a buffer to prevent hysteresis too. I just cannot seem to set the variables and do the unbelievably simple math to determine whether to send the off or on commands.

I have a flow, but it is probably overly complicated for this aspect of the job. Any simple to implement ideas?

I use an MQTT topic of "indoor_humidity_topic" and try to set a global variable of "GV_Indoor_Humidity" in an Edit Function Node:

    flow.get("GV_Indoor_Humidity");
    global.set("GV_Indoor_Humidity", msg.payload);
   return msg;

In a different node connected to a node that is active only if the fans are on, I am trying this code:

 var inHumid = flow.get("GV_Indoor_Humidity");
 if ("GV_Indoor_Humidity" <= 60){
msg.payload = false;
 }
return msg;

I also have a question about the edit function node. There is some sort of message in the upper righthand corner of the OnMessage tab, that I cannot see. I suspect it is some sort of a debug message, but so far that is a mystery to me too.

Suggestions would be greatly appreciated.

It may be of some help if you post your flow

Welcome to the forum @Greg

node-red-contrib-hysteresis will do it all for you.

1 Like

The code is too long to load. There must be a better way.

What code is too long to load?

Oh I see, you mean that the flows file is too big to paste here. You can just select the nodes of interest and use the menu Export to export them, and paste it here.

Yes, use node-red-contrib-hysteresis. There is no need to use any context, just feed the MQTT node straight into the hysteresis node after configuring it appropriately.

The humidity flow itself. If I export the flow and try to insert it into the response, I exceed the cap. I get this error message: Body is limited to 32000 characters and my post is 62000.

See the comment i posted at the same time as you did.

[
    {
        "id": "b72ef9e2307657a1",
        "type": "wemo lookup",
        "z": "1e6d0cc92960bc78",
        "name": "Pool Room Fan 1",
        "device": "bfd6a225d63965d7",
        "label": "Pool Room Fan 1",
        "x": 230,
        "y": 920,
        "wires": [
            [
                "9edfd69563d57081",
                "140ba1978e4bead7"
            ]
        ]
    },
    {
        "id": "82604fbed3287434",
        "type": "mqtt in",
        "z": "1e6d0cc92960bc78",
        "name": "",
        "topic": "indoor_humidity_topic",
        "qos": "2",
        "datatype": "auto-detect",
        "broker": "c6bf5d021264d8e1",
        "nl": false,
        "rap": true,
        "rh": 0,
        "inputs": 0,
        "x": 180,
        "y": 280,
        "wires": [
            [
                "0eec4248f657dcab",
                "3a58ae216556eea4",
                "58d4a8a9310540b8",
                "fc0b23b51621a17c"
            ]
        ]
    },
    {
        "id": "bfd6a225d63965d7",
        "type": "wemo-dev",
        "device": "221711K130078F",
        "name": "Pool Room Fan 1"
    },
    {
        "id": "c6bf5d021264d8e1",
        "type": "mqtt-broker",
        "name": "",
        "broker": "192.168.50.168",
        "port": "1883",
        "clientid": "",
        "autoConnect": true,
        "usetls": false,
        "protocolVersion": "4",
        "keepalive": "60",
        "cleansession": true,
        "autoUnsubscribe": true,
        "birthTopic": "",
        "birthQos": "1",
        "birthRetain": "true",
        "birthPayload": "",
        "birthMsg": {},
        "closeTopic": "",
        "closeQos": "0",
        "closeRetain": "false",
        "closePayload": "",
        "closeMsg": {},
        "willTopic": "",
        "willQos": "0",
        "willRetain": "false",
        "willPayload": "",
        "willMsg": {},
        "userProps": "",
        "sessionExpiry": ""
    }
]

This is part. Not too sure I got all I wanted to copy.

Let's try this. Here is the MQTT information flow:

[
    {
        "id": "82604fbed3287434",
        "type": "mqtt in",
        "z": "1e6d0cc92960bc78",
        "name": "",
        "topic": "indoor_humidity_topic",
        "qos": "2",
        "datatype": "auto-detect",
        "broker": "c6bf5d021264d8e1",
        "nl": false,
        "rap": true,
        "rh": 0,
        "inputs": 0,
        "x": 180,
        "y": 280,
        "wires": [
            [
                "0eec4248f657dcab",
                "3a58ae216556eea4",
                "58d4a8a9310540b8",
                "fc0b23b51621a17c"
            ]
        ]
    },
    {
        "id": "0eec4248f657dcab",
        "type": "ui_gauge",
        "z": "1e6d0cc92960bc78",
        "name": "",
        "group": "570d12a99fb5ce3d",
        "order": 2,
        "width": 0,
        "height": 0,
        "gtype": "gage",
        "title": "Pool Room Humidity ",
        "label": "% RH",
        "format": "{{value}}% RH",
        "min": 0,
        "max": "100",
        "colors": [
            "#00b500",
            "#e6e600",
            "#ca3838"
        ],
        "seg1": "50",
        "seg2": "55",
        "diff": false,
        "className": "",
        "x": 740,
        "y": 280,
        "wires": []
    },
    {
        "id": "3a58ae216556eea4",
        "type": "ui_chart",
        "z": "1e6d0cc92960bc78",
        "name": "",
        "group": "570d12a99fb5ce3d",
        "order": 4,
        "width": 0,
        "height": 0,
        "label": "Pool Room Humidity",
        "chartType": "line",
        "legend": "false",
        "xformat": "HH:mm:ss",
        "interpolate": "linear",
        "nodata": "",
        "dot": false,
        "ymin": "",
        "ymax": "",
        "removeOlder": 1,
        "removeOlderPoints": "",
        "removeOlderUnit": "3600",
        "cutout": 0,
        "useOneColor": false,
        "useUTC": false,
        "colors": [
            "#1f77b4",
            "#aec7e8",
            "#ff7f0e",
            "#2ca02c",
            "#98df8a",
            "#d62728",
            "#ff9896",
            "#9467bd",
            "#c5b0d5"
        ],
        "outputs": 1,
        "useDifferentColor": false,
        "className": "",
        "x": 740,
        "y": 320,
        "wires": [
            []
        ]
    },
    {
        "id": "58d4a8a9310540b8",
        "type": "debug",
        "z": "1e6d0cc92960bc78",
        "name": "debug 23",
        "active": false,
        "tosidebar": true,
        "console": false,
        "tostatus": false,
        "complete": "payload",
        "targetType": "msg",
        "statusVal": "",
        "statusType": "auto",
        "x": 380,
        "y": 320,
        "wires": []
    },
    {
        "id": "fc0b23b51621a17c",
        "type": "function",
        "z": "1e6d0cc92960bc78",
        "name": "InHumidy",
        "func": "flow.get(\"GV_Indoor_Humidity\");\nglobal.set(\"GV_Indoor_Humidity\", msg.payload);\nreturn msg;",
        "outputs": 1,
        "timeout": "",
        "noerr": 0,
        "initialize": "",
        "finalize": "",
        "libs": [],
        "x": 480,
        "y": 240,
        "wires": [
            [
                "1455c49c127a59e4"
            ]
        ]
    },
    {
        "id": "1455c49c127a59e4",
        "type": "debug",
        "z": "1e6d0cc92960bc78",
        "name": "debug 29",
        "active": false,
        "tosidebar": true,
        "console": false,
        "tostatus": false,
        "complete": "true",
        "targetType": "full",
        "statusVal": "",
        "statusType": "auto",
        "x": 660,
        "y": 240,
        "wires": []
    },
    {
        "id": "c6bf5d021264d8e1",
        "type": "mqtt-broker",
        "name": "",
        "broker": "192.168.50.168",
        "port": "1883",
        "clientid": "",
        "autoConnect": true,
        "usetls": false,
        "protocolVersion": "4",
        "keepalive": "60",
        "cleansession": true,
        "autoUnsubscribe": true,
        "birthTopic": "",
        "birthQos": "1",
        "birthRetain": "true",
        "birthPayload": "",
        "birthMsg": {},
        "closeTopic": "",
        "closeQos": "0",
        "closeRetain": "false",
        "closePayload": "",
        "closeMsg": {},
        "willTopic": "",
        "willQos": "0",
        "willRetain": "false",
        "willPayload": "",
        "willMsg": {},
        "userProps": "",
        "sessionExpiry": ""
    },
    {
        "id": "570d12a99fb5ce3d",
        "type": "ui_group",
        "name": "Pool Room Temp",
        "tab": "08c882008efdc3a0",
        "order": 1,
        "disp": true,
        "width": "6",
        "collapse": false,
        "className": ""
    },
    {
        "id": "08c882008efdc3a0",
        "type": "ui_tab",
        "name": "Pool Room Humidity Control",
        "icon": "dashboard",
        "order": 1,
        "disabled": false,
        "hidden": false
    }
]

Here's the fan switch portion:

[
    {
        "id": "6540e7f23b4ae0b2",
        "type": "wemo out",
        "z": "1e6d0cc92960bc78",
        "name": "Pool Room Fan 1",
        "device": "bfd6a225d63965d7",
        "label": "Pool Room Fan 1",
        "x": 1630,
        "y": 920,
        "wires": []
    },
    {
        "id": "500876ca113e5507",
        "type": "ui_switch",
        "z": "1e6d0cc92960bc78",
        "name": "",
        "label": "Fan 1",
        "tooltip": "",
        "group": "3ed3bb30fdd765cd",
        "order": 1,
        "width": 0,
        "height": 0,
        "passthru": true,
        "decouple": "false",
        "topic": "topic",
        "topicType": "msg",
        "style": "",
        "onvalue": "true",
        "onvalueType": "bool",
        "onicon": "",
        "oncolor": "",
        "offvalue": "false",
        "offvalueType": "bool",
        "officon": "",
        "offcolor": "",
        "animate": false,
        "className": "",
        "x": 910,
        "y": 920,
        "wires": [
            [
                "2fcdb2ec9e50ca08"
            ]
        ]
    },
    {
        "id": "b72ef9e2307657a1",
        "type": "wemo lookup",
        "z": "1e6d0cc92960bc78",
        "name": "Pool Room Fan 1",
        "device": "bfd6a225d63965d7",
        "label": "Pool Room Fan 1",
        "x": 230,
        "y": 920,
        "wires": [
            [
                "9edfd69563d57081",
                "140ba1978e4bead7"
            ]
        ]
    },
    {
        "id": "8b38cbfce1c3f285",
        "type": "inject",
        "z": "1e6d0cc92960bc78",
        "name": "",
        "props": [
            {
                "p": "payload"
            },
            {
                "p": "topic",
                "vt": "str"
            }
        ],
        "repeat": "60",
        "crontab": "",
        "once": true,
        "onceDelay": 0.1,
        "topic": "",
        "payload": "",
        "payloadType": "date",
        "x": 150,
        "y": 840,
        "wires": [
            [
                "b72ef9e2307657a1",
                "ead27030f0a3aee3",
                "b83c08d391b95fcc",
                "49d031a420fffb35"
            ]
        ]
    },
    {
        "id": "ce328da973733581",
        "type": "function",
        "z": "1e6d0cc92960bc78",
        "name": "indoor humidity not high",
        "func": "var inHumid = flow.get(\"GV_Indoor_Humidity\");\n\nif (\"GV_Indoor_Humidity\" <= 60){\n    msg.payload = false;\n}\n\nreturn msg;",
        "outputs": 1,
        "timeout": "",
        "noerr": 1,
        "initialize": "",
        "finalize": "",
        "libs": [],
        "x": 1150,
        "y": 840,
        "wires": [
            [
                "4af10bb7b8727642",
                "a5648d47b89335fe"
            ]
        ]
    },
    {
        "id": "4af10bb7b8727642",
        "type": "debug",
        "z": "1e6d0cc92960bc78",
        "name": "debug 10",
        "active": true,
        "tosidebar": true,
        "console": false,
        "tostatus": false,
        "complete": "true",
        "targetType": "full",
        "statusVal": "",
        "statusType": "auto",
        "x": 1400,
        "y": 860,
        "wires": []
    },
    {
        "id": "9edfd69563d57081",
        "type": "json",
        "z": "1e6d0cc92960bc78",
        "name": "",
        "property": "payload",
        "action": "",
        "pretty": false,
        "x": 410,
        "y": 920,
        "wires": [
            [
                "1c79b920373b1c54"
            ]
        ]
    },
    {
        "id": "1c79b920373b1c54",
        "type": "switch",
        "z": "1e6d0cc92960bc78",
        "name": "",
        "property": "payload",
        "propertyType": "msg",
        "rules": [
            {
                "t": "eq",
                "v": "{\"state\":1}",
                "vt": "str"
            },
            {
                "t": "else"
            }
        ],
        "checkall": "true",
        "repair": false,
        "outputs": 2,
        "x": 550,
        "y": 920,
        "wires": [
            [
                "c864f724bd0cdf27"
            ],
            [
                "997581e0458e2a92"
            ]
        ]
    },
    {
        "id": "c864f724bd0cdf27",
        "type": "change",
        "z": "1e6d0cc92960bc78",
        "name": "",
        "rules": [
            {
                "t": "set",
                "p": "payload",
                "pt": "msg",
                "to": "true",
                "tot": "bool"
            },
            {
                "t": "set",
                "p": "topic",
                "pt": "msg",
                "to": "on",
                "tot": "str"
            }
        ],
        "action": "",
        "property": "",
        "from": "",
        "to": "",
        "reg": false,
        "x": 720,
        "y": 900,
        "wires": [
            [
                "500876ca113e5507"
            ]
        ]
    },
    {
        "id": "997581e0458e2a92",
        "type": "change",
        "z": "1e6d0cc92960bc78",
        "name": "",
        "rules": [
            {
                "t": "set",
                "p": "payload",
                "pt": "msg",
                "to": "false",
                "tot": "bool"
            },
            {
                "t": "set",
                "p": "topic",
                "pt": "msg",
                "to": "off",
                "tot": "str"
            }
        ],
        "action": "",
        "property": "",
        "from": "",
        "to": "",
        "reg": false,
        "x": 720,
        "y": 940,
        "wires": [
            [
                "500876ca113e5507"
            ]
        ]
    },
    {
        "id": "2fcdb2ec9e50ca08",
        "type": "switch",
        "z": "1e6d0cc92960bc78",
        "name": "",
        "property": "payload",
        "propertyType": "msg",
        "rules": [
            {
                "t": "true"
            },
            {
                "t": "false"
            }
        ],
        "checkall": "true",
        "repair": false,
        "outputs": 2,
        "x": 1050,
        "y": 920,
        "wires": [
            [
                "d6722ca3346dbe12"
            ],
            [
                "a5648d47b89335fe"
            ]
        ]
    },
    {
        "id": "a5648d47b89335fe",
        "type": "change",
        "z": "1e6d0cc92960bc78",
        "name": "Close",
        "rules": [
            {
                "t": "set",
                "p": "payload",
                "pt": "msg",
                "to": "false",
                "tot": "bool"
            },
            {
                "t": "set",
                "p": "state",
                "pt": "msg",
                "to": "0",
                "tot": "str"
            }
        ],
        "action": "",
        "property": "",
        "from": "",
        "to": "",
        "reg": false,
        "x": 1230,
        "y": 940,
        "wires": [
            [
                "ee188d6c9a437a97",
                "fda93e578cd0560c"
            ]
        ]
    },
    {
        "id": "d6722ca3346dbe12",
        "type": "change",
        "z": "1e6d0cc92960bc78",
        "name": "Open",
        "rules": [
            {
                "t": "set",
                "p": "payload",
                "pt": "msg",
                "to": "true",
                "tot": "bool"
            },
            {
                "t": "set",
                "p": "state",
                "pt": "msg",
                "to": "1",
                "tot": "num"
            }
        ],
        "action": "",
        "property": "",
        "from": "",
        "to": "",
        "reg": false,
        "x": 1230,
        "y": 900,
        "wires": [
            [
                "ce328da973733581",
                "83077f0312b8bd5b"
            ]
        ]
    },
    {
        "id": "ee188d6c9a437a97",
        "type": "json",
        "z": "1e6d0cc92960bc78",
        "name": "",
        "property": "payload",
        "action": "",
        "pretty": false,
        "x": 1430,
        "y": 920,
        "wires": [
            [
                "6540e7f23b4ae0b2",
                "f1be88e6eaf3f46b"
            ]
        ]
    },
    {
        "id": "140ba1978e4bead7",
        "type": "debug",
        "z": "1e6d0cc92960bc78",
        "name": "debug 27",
        "active": false,
        "tosidebar": true,
        "console": false,
        "tostatus": false,
        "complete": "true",
        "targetType": "full",
        "statusVal": "",
        "statusType": "auto",
        "x": 480,
        "y": 820,
        "wires": []
    },
    {
        "id": "83077f0312b8bd5b",
        "type": "debug",
        "z": "1e6d0cc92960bc78",
        "name": "debug 30",
        "active": true,
        "tosidebar": true,
        "console": false,
        "tostatus": false,
        "complete": "false",
        "statusVal": "",
        "statusType": "auto",
        "x": 1400,
        "y": 820,
        "wires": []
    },
    {
        "id": "fda93e578cd0560c",
        "type": "debug",
        "z": "1e6d0cc92960bc78",
        "name": "debug 31",
        "active": true,
        "tosidebar": true,
        "console": false,
        "tostatus": false,
        "complete": "false",
        "statusVal": "",
        "statusType": "auto",
        "x": 1640,
        "y": 800,
        "wires": []
    },
    {
        "id": "f1be88e6eaf3f46b",
        "type": "debug",
        "z": "1e6d0cc92960bc78",
        "name": "debug 32",
        "active": true,
        "tosidebar": true,
        "console": false,
        "tostatus": false,
        "complete": "topic",
        "targetType": "msg",
        "statusVal": "",
        "statusType": "auto",
        "x": 1600,
        "y": 860,
        "wires": []
    },
    {
        "id": "bfd6a225d63965d7",
        "type": "wemo-dev",
        "device": "221711K130078F",
        "name": "Pool Room Fan 1"
    },
    {
        "id": "3ed3bb30fdd765cd",
        "type": "ui_group",
        "name": "Switches",
        "tab": "08c882008efdc3a0",
        "order": 4,
        "disp": true,
        "width": "6",
        "collapse": false,
        "className": ""
    },
    {
        "id": "08c882008efdc3a0",
        "type": "ui_tab",
        "name": "Pool Room Humidity Control",
        "icon": "dashboard",
        "order": 1,
        "disabled": false,
        "hidden": false
    }
]

Here is a simple flow I use for a similar use case, hopefully it gives you some ideas.

[
    {
        "id": "16c488f8.628e17",
        "type": "group",
        "z": "a4fbc7a7.c855f8",
        "style": {
            "stroke": "#999999",
            "stroke-opacity": "1",
            "fill": "none",
            "fill-opacity": "1",
            "label": true,
            "label-position": "nw",
            "color": "#a4a4a4"
        },
        "nodes": [
            "ba2465c5.bc0708",
            "a2b7a836.37ee88",
            "d2fd02af.15f2e",
            "c519ff2.19cd1",
            "9f2943b3.f24e",
            "c7fde95f7e44f1a8",
            "91c15097.84dae",
            "0c443fbe5c722386"
        ],
        "x": 34,
        "y": 19,
        "w": 1252,
        "h": 162
    },
    {
        "id": "ba2465c5.bc0708",
        "type": "comment",
        "z": "a4fbc7a7.c855f8",
        "g": "16c488f8.628e17",
        "name": "Fan for Humidity",
        "info": "",
        "x": 140,
        "y": 60,
        "wires": []
    },
    {
        "id": "a2b7a836.37ee88",
        "type": "switch",
        "z": "a4fbc7a7.c855f8",
        "g": "16c488f8.628e17",
        "name": "Humidity Check",
        "property": "payload",
        "propertyType": "msg",
        "rules": [
            {
                "t": "gte",
                "v": "60",
                "vt": "num"
            },
            {
                "t": "else"
            }
        ],
        "checkall": "false",
        "repair": false,
        "outputs": 2,
        "x": 460,
        "y": 120,
        "wires": [
            [
                "c519ff2.19cd1"
            ],
            [
                "9f2943b3.f24e"
            ]
        ]
    },
    {
        "id": "d2fd02af.15f2e",
        "type": "rbe",
        "z": "a4fbc7a7.c855f8",
        "g": "16c488f8.628e17",
        "name": "",
        "func": "rbe",
        "gap": "",
        "start": "",
        "inout": "out",
        "property": "payload",
        "x": 1045,
        "y": 120,
        "wires": [
            [
                "0c443fbe5c722386"
            ]
        ],
        "l": false
    },
    {
        "id": "c519ff2.19cd1",
        "type": "change",
        "z": "a4fbc7a7.c855f8",
        "g": "16c488f8.628e17",
        "name": "High Humidity",
        "rules": [
            {
                "t": "set",
                "p": "hControl",
                "pt": "global",
                "to": "true",
                "tot": "bool"
            },
            {
                "t": "delete",
                "p": "payload",
                "pt": "msg"
            },
            {
                "t": "set",
                "p": "payload.state",
                "pt": "msg",
                "to": "true",
                "tot": "bool"
            }
        ],
        "action": "",
        "property": "",
        "from": "",
        "to": "",
        "reg": false,
        "x": 720,
        "y": 100,
        "wires": [
            [
                "d2fd02af.15f2e"
            ]
        ]
    },
    {
        "id": "9f2943b3.f24e",
        "type": "change",
        "z": "a4fbc7a7.c855f8",
        "g": "16c488f8.628e17",
        "name": "Low Humidity",
        "rules": [
            {
                "t": "set",
                "p": "hControl",
                "pt": "global",
                "to": "false",
                "tot": "bool"
            },
            {
                "t": "delete",
                "p": "payload",
                "pt": "msg"
            },
            {
                "t": "set",
                "p": "payload.state",
                "pt": "msg",
                "to": "false",
                "tot": "bool"
            }
        ],
        "action": "",
        "property": "",
        "from": "",
        "to": "",
        "reg": false,
        "x": 720,
        "y": 140,
        "wires": [
            [
                "91c15097.84dae"
            ]
        ]
    },
    {
        "id": "c7fde95f7e44f1a8",
        "type": "link in",
        "z": "a4fbc7a7.c855f8",
        "g": "16c488f8.628e17",
        "name": "[Up Bath] Humidity",
        "links": [
            "7fb519088c6d8cc8"
        ],
        "x": 250,
        "y": 120,
        "wires": [
            [
                "a2b7a836.37ee88"
            ]
        ],
        "l": true
    },
    {
        "id": "91c15097.84dae",
        "type": "switch",
        "z": "a4fbc7a7.c855f8",
        "g": "16c488f8.628e17",
        "name": "Fan Status",
        "property": "fanStatus",
        "propertyType": "flow",
        "rules": [
            {
                "t": "true"
            }
        ],
        "checkall": "false",
        "repair": false,
        "outputs": 1,
        "x": 910,
        "y": 140,
        "wires": [
            [
                "d2fd02af.15f2e"
            ]
        ]
    },
    {
        "id": "0c443fbe5c722386",
        "type": "link out",
        "z": "a4fbc7a7.c855f8",
        "g": "16c488f8.628e17",
        "name": "[Up Bath] Fan",
        "mode": "link",
        "links": [
            "9c6773131e16a876"
        ],
        "x": 1180,
        "y": 120,
        "wires": [],
        "l": true
    }
]

Thanks for this. I probably need more basic help than this.

I currently have one flow that takes humidity and temperature (via MQTT) and displays it on my dashboard. I have a separate flow that reads whether the fans (WiFi devices) are on or off and displays that with an operable switch on my dashboard. If I switch it on the flow turns on the fan and if I switch it off, it turns off the fan. The next step is to read the humidity and turn the fan on or off if the humidity exceeds the set point or is below the set point (with a buffer to prevent hysteresis). I need to figure out how to have the automatic turn on and off control the fans while still being able to override the automatic nature by using the dashboard switch.

This forum is hard for me to use since I cannot upload the entire flow (it's too big) and I cannot upload a picture of the flows. So we are stuck with my description of what is happening.

For that, what I would do is add a global variable to your fan switch output "global.fanOverride" and set it to "true" using a Change node when you use the dashboard switch (not sure what logic you want to use to flip it back to "false" but build that out as well, maybe a timer node). Then in the simple flow I gave you just add a switch node (like I did with fanStatus) at the start of that flow to see if it is "false" to allow the flow to proceed.

As far as your comment about too big of a flow. I think you can tell by mine but I use an object-based approach to make my system scalable and easy to update. For example, I originally was using OpenHab for all my Zwave work and used MQTT as a communication bus between that and NodeRed so I just built a single tab for MQTT that took care of pulling status changes and control, then used the Link nodes to send/receive the various messages as needed. Later I switched to Zwave.js nodes and was able to just rebuild a new Zwave tab to take over the physical device interface.

The advantage is I don't have any real large single flows, just a bunch of smaller flows that connect together which also makes it easier to not build repeat flows, I can just call them one off as needed using callback nodes.

I hope that helps.

Ah yes. Thanks. I haven't tried to do this in modules. Probably would be better. I actually have a sensor in the room, one outside, and one in a mechanical room. I have 3 separately controlled fans, plus a separately controlled louver to make it easier to let fresh air in from the outside. The room has a pool and spa. My focus so far has been just one sensor and one fan, but I will need to scale up. I had been using OpenHAB, but that system seemed a bit opaque to me, so I am shifting to node red.

There are lots of issues so far, but I'll work on them once I get the basic functionality fixed with one sensor and one fan. (issues like my sensors send date and time information sometimes rather than temp and humidity - I can fix this by reflashing the 8266, but that seems a bit kludgy.

I will use a tab for the sensor monitor aspect and a separate one for the fan switches.

I'm trying this for the key flow. But It all seems to be switching between 1 or 2 and true and false. There must be a better way.

[
    {
        "id": "2eeeddd13d4671d5",
        "type": "switch",
        "z": "1e6d0cc92960bc78",
        "name": "",
        "property": "payload",
        "propertyType": "msg",
        "rules": [
            {
                "t": "gte",
                "v": "60",
                "vt": "num"
            },
            {
                "t": "else"
            }
        ],
        "checkall": "true",
        "repair": false,
        "outputs": 2,
        "x": 1050,
        "y": 520,
        "wires": [
            [
                "1fcfbf905b118476"
            ],
            [
                "70322e807598abfc"
            ]
        ]
    },
    {
        "id": "1fcfbf905b118476",
        "type": "change",
        "z": "1e6d0cc92960bc78",
        "name": "High Humidity",
        "rules": [
            {
                "t": "set",
                "p": "topic",
                "pt": "msg",
                "to": "true",
                "tot": "bool"
            },
            {
                "t": "delete",
                "p": "payload",
                "pt": "msg"
            },
            {
                "t": "set",
                "p": "payload.state",
                "pt": "msg",
                "to": "true",
                "tot": "bool"
            },
            {
                "t": "set",
                "p": "state",
                "pt": "msg",
                "to": "1",
                "tot": "num"
            }
        ],
        "action": "",
        "property": "",
        "from": "",
        "to": "",
        "reg": false,
        "x": 1220,
        "y": 480,
        "wires": [
            [
                "2a283fe2a66b26e8"
            ]
        ]
    },
    {
        "id": "70322e807598abfc",
        "type": "change",
        "z": "1e6d0cc92960bc78",
        "name": "Low Humidity",
        "rules": [
            {
                "t": "set",
                "p": "topic",
                "pt": "msg",
                "to": "false",
                "tot": "bool"
            },
            {
                "t": "delete",
                "p": "payload",
                "pt": "msg"
            },
            {
                "t": "set",
                "p": "payload.state",
                "pt": "msg",
                "to": "false",
                "tot": "bool"
            },
            {
                "t": "set",
                "p": "state",
                "pt": "msg",
                "to": "2",
                "tot": "num"
            }
        ],
        "action": "",
        "property": "",
        "from": "",
        "to": "",
        "reg": false,
        "x": 1220,
        "y": 560,
        "wires": [
            [
                "2a283fe2a66b26e8"
            ]
        ]
    },
    {
        "id": "2a283fe2a66b26e8",
        "type": "json",
        "z": "1e6d0cc92960bc78",
        "name": "",
        "property": "payload",
        "action": "",
        "pretty": false,
        "x": 1410,
        "y": 520,
        "wires": [
            [
                "f32a3407b2078768"
            ]
        ]
    },
    {
        "id": "f32a3407b2078768",
        "type": "wemo out",
        "z": "1e6d0cc92960bc78",
        "name": "Pool Room Fan 1",
        "device": "bfd6a225d63965d7",
        "label": "Pool Room Fan 1",
        "x": 1590,
        "y": 520,
        "wires": []
    },
    {
        "id": "be08956c157be950",
        "type": "link in",
        "z": "1e6d0cc92960bc78",
        "name": "link in 1",
        "links": [
            "b41f051f986e2444"
        ],
        "x": 925,
        "y": 520,
        "wires": [
            [
                "2eeeddd13d4671d5"
            ]
        ]
    },
    {
        "id": "bfd6a225d63965d7",
        "type": "wemo-dev",
        "device": "221711K130078F",
        "name": "Pool Room Fan 1"
    }
]

So to test your flows, put in input and full object debug nodes, then you can test the scenarios. What I get when I run this is if humidity is => 60 you generate a State as 1 and if <60 State as 2.

I don't know the Wemo nodes but when I look at the docs on them it looks like all you need to do is set msg.payload to one of these three for on/off. A State of 2 won't do anything

String : on/off
Integer : 1/0
Boolean : true/false

So I'd get rid of your json node, and make y.our change node just set msg.payload to your preferred approach (on/off, 1/0 or boolean). So something like this:

[
    {
        "id": "2eeeddd13d4671d5",
        "type": "switch",
        "z": "1c2bd26ac38f5273",
        "name": "",
        "property": "payload",
        "propertyType": "msg",
        "rules": [
            {
                "t": "gte",
                "v": "60",
                "vt": "num"
            },
            {
                "t": "else"
            }
        ],
        "checkall": "true",
        "repair": false,
        "outputs": 2,
        "x": 270,
        "y": 280,
        "wires": [
            [
                "1fcfbf905b118476"
            ],
            [
                "70322e807598abfc"
            ]
        ]
    },
    {
        "id": "1fcfbf905b118476",
        "type": "change",
        "z": "1c2bd26ac38f5273",
        "name": "High Humidity",
        "rules": [
            {
                "t": "set",
                "p": "payload",
                "pt": "msg",
                "to": "true",
                "tot": "bool"
            }
        ],
        "action": "",
        "property": "",
        "from": "",
        "to": "",
        "reg": false,
        "x": 440,
        "y": 240,
        "wires": [
            [
                "10e5c29de3ca5ee1",
                "701df4ed474ce246"
            ]
        ]
    },
    {
        "id": "70322e807598abfc",
        "type": "change",
        "z": "1c2bd26ac38f5273",
        "name": "Low Humidity",
        "rules": [
            {
                "t": "set",
                "p": "payload",
                "pt": "msg",
                "to": "false",
                "tot": "bool"
            }
        ],
        "action": "",
        "property": "",
        "from": "",
        "to": "",
        "reg": false,
        "x": 440,
        "y": 320,
        "wires": [
            [
                "082469c1fc13f9e3",
                "701df4ed474ce246"
            ]
        ]
    },
    {
        "id": "10e5c29de3ca5ee1",
        "type": "debug",
        "z": "1c2bd26ac38f5273",
        "name": "Hi",
        "active": true,
        "tosidebar": true,
        "console": false,
        "tostatus": false,
        "complete": "true",
        "targetType": "full",
        "statusVal": "",
        "statusType": "auto",
        "x": 690,
        "y": 160,
        "wires": []
    },
    {
        "id": "082469c1fc13f9e3",
        "type": "debug",
        "z": "1c2bd26ac38f5273",
        "name": "Lo",
        "active": true,
        "tosidebar": true,
        "console": false,
        "tostatus": false,
        "complete": "true",
        "targetType": "full",
        "statusVal": "",
        "statusType": "auto",
        "x": 650,
        "y": 360,
        "wires": []
    },
    {
        "id": "701df4ed474ce246",
        "type": "debug",
        "z": "1c2bd26ac38f5273",
        "name": "Out",
        "active": true,
        "tosidebar": true,
        "console": false,
        "tostatus": false,
        "complete": "true",
        "targetType": "full",
        "statusVal": "",
        "statusType": "auto",
        "x": 670,
        "y": 280,
        "wires": []
    },
    {
        "id": "c58a84e8f59a1c6a",
        "type": "inject",
        "z": "1c2bd26ac38f5273",
        "name": "60",
        "props": [
            {
                "p": "payload"
            },
            {
                "p": "topic",
                "vt": "str"
            }
        ],
        "repeat": "",
        "crontab": "",
        "once": false,
        "onceDelay": 0.1,
        "topic": "",
        "payload": "60",
        "payloadType": "num",
        "x": 110,
        "y": 160,
        "wires": [
            [
                "2eeeddd13d4671d5"
            ]
        ]
    },
    {
        "id": "7c21b74a70d17f91",
        "type": "inject",
        "z": "1c2bd26ac38f5273",
        "name": "40",
        "props": [
            {
                "p": "payload"
            },
            {
                "p": "topic",
                "vt": "str"
            }
        ],
        "repeat": "",
        "crontab": "",
        "once": false,
        "onceDelay": 0.1,
        "topic": "",
        "payload": "40",
        "payloadType": "num",
        "x": 130,
        "y": 300,
        "wires": [
            [
                "2eeeddd13d4671d5"
            ]
        ]
    }
]

If you aren't fully comfortable with the whole json msg object, I'd spend some time going through the Node-Red docs since that is such a fundamental piece of how this system works. For most of my uses, it's simple msg.topic and msg.payroll that do all the work. I do use other key pairs for very specific use cases (sensors providing multiple outputs, or to pass control variables through a flow).

I hope I'm steering you down the right path and this helps

Thanks. I'll look this over and follow-up with the results. And yes, I am not really a programmer so the Json stuff seems like a complication to avoid if possible.

Unfortunately you can't since that is the fundamental way of moving data through the nodes. I'd spend some time on this page and the videos to help you understand.
https://nodered.org/docs/user-guide/messages

Well, your suggestions worked:

[
    {
        "id": "2eeeddd13d4671d5",
        "type": "switch",
        "z": "1e6d0cc92960bc78",
        "name": "",
        "property": "payload",
        "propertyType": "msg",
        "rules": [
            {
                "t": "gte",
                "v": "60",
                "vt": "num"
            },
            {
                "t": "else"
            }
        ],
        "checkall": "true",
        "repair": false,
        "outputs": 2,
        "x": 1050,
        "y": 520,
        "wires": [
            [
                "1fcfbf905b118476"
            ],
            [
                "70322e807598abfc"
            ]
        ]
    },
    {
        "id": "1fcfbf905b118476",
        "type": "change",
        "z": "1e6d0cc92960bc78",
        "name": "High Humidity",
        "rules": [
            {
                "t": "set",
                "p": "topic",
                "pt": "msg",
                "to": "true",
                "tot": "bool"
            }
        ],
        "action": "",
        "property": "",
        "from": "",
        "to": "",
        "reg": false,
        "x": 1220,
        "y": 500,
        "wires": [
            [
                "7ae86abb7697789b"
            ]
        ]
    },
    {
        "id": "70322e807598abfc",
        "type": "change",
        "z": "1e6d0cc92960bc78",
        "name": "Low Humidity",
        "rules": [
            {
                "t": "set",
                "p": "topic",
                "pt": "msg",
                "to": "false",
                "tot": "bool"
            }
        ],
        "action": "",
        "property": "",
        "from": "",
        "to": "",
        "reg": false,
        "x": 1220,
        "y": 540,
        "wires": [
            [
                "b05ea8ecc624195f"
            ]
        ]
    },
    {
        "id": "f32a3407b2078768",
        "type": "wemo out",
        "z": "1e6d0cc92960bc78",
        "name": "Pool Room Fan 1",
        "device": "bfd6a225d63965d7",
        "label": "Pool Room Fan 1",
        "x": 1690,
        "y": 460,
        "wires": []
    },
    {
        "id": "be08956c157be950",
        "type": "link in",
        "z": "1e6d0cc92960bc78",
        "name": "link in 1",
        "links": [
            "b41f051f986e2444"
        ],
        "x": 925,
        "y": 520,
        "wires": [
            [
                "2eeeddd13d4671d5"
            ]
        ]
    },
    {
        "id": "7ae86abb7697789b",
        "type": "change",
        "z": "1e6d0cc92960bc78",
        "name": "Open",
        "rules": [
            {
                "t": "set",
                "p": "payload",
                "pt": "msg",
                "to": "true",
                "tot": "bool"
            },
            {
                "t": "set",
                "p": "state",
                "pt": "msg",
                "to": "1",
                "tot": "num"
            }
        ],
        "action": "",
        "property": "",
        "from": "",
        "to": "",
        "reg": false,
        "x": 1390,
        "y": 500,
        "wires": [
            [
                "f32a3407b2078768",
                "3a9febb0e9ca2276",
                "d4ed82629ff3c161"
            ]
        ]
    },
    {
        "id": "b05ea8ecc624195f",
        "type": "change",
        "z": "1e6d0cc92960bc78",
        "name": "Close",
        "rules": [
            {
                "t": "set",
                "p": "payload",
                "pt": "msg",
                "to": "false",
                "tot": "bool"
            },
            {
                "t": "set",
                "p": "state",
                "pt": "msg",
                "to": "0",
                "tot": "str"
            }
        ],
        "action": "",
        "property": "",
        "from": "",
        "to": "",
        "reg": false,
        "x": 1390,
        "y": 540,
        "wires": [
            [
                "f32a3407b2078768",
                "3a9febb0e9ca2276",
                "d4ed82629ff3c161"
            ]
        ]
    },
    {
        "id": "3a9febb0e9ca2276",
        "type": "wemo out",
        "z": "1e6d0cc92960bc78",
        "name": "Pool Room Fan 2",
        "device": "d4f9812e6c3f7583",
        "label": "WeMo Light Switch",
        "x": 1690,
        "y": 540,
        "wires": []
    },
    {
        "id": "d4ed82629ff3c161",
        "type": "wemo out",
        "z": "1e6d0cc92960bc78",
        "name": "",
        "device": "fce126f7ce7b57b9",
        "label": "Pool Room Fan 3",
        "x": 1690,
        "y": 620,
        "wires": []
    },
    {
        "id": "bfd6a225d63965d7",
        "type": "wemo-dev",
        "device": "221711K130078F",
        "name": "Pool Room Fan 1"
    },
    {
        "id": "d4f9812e6c3f7583",
        "type": "wemo-dev",
        "device": "221817K130072A",
        "name": "WeMo Light Switch"
    },
    {
        "id": "fce126f7ce7b57b9",
        "type": "wemo-dev",
        "device": "221816K130029F",
        "name": "Pool Room Fan 3"
    }
]

I did elect to simplify a smidge. You are right. What I really need is some sort of a primer on all this. Next step, setting up control over the louvers. I will post a follow-up in a while.

1 Like