Skip to content

Hysteresis

cflurin edited this page Oct 23, 2018 · 15 revisions

Hysteresis is often used to control a device (heating/cooling) depending on an input value (temperature). It avoids multiple switching when the value is swinging.

For Example let's say the setpoint is 20 °C and the hysteresis is 1 °C so just set setpoint_high=20.5 and setpoint_low=19.5. The outputs greater_high and less_low can be defined as required.

hysteresis-7 3

Configuration

{
    "currentState": "undefined",
    "states": {
        "undefined": {
            "cross_high": "high",
            "cross_low": "low",
            "inter": "deadband"
        },
        "high": {
            "cross_low": "low",
            "inter": "deadband"
        },
        "low": {
            "cross_high": "high",
            "inter": "deadband"
        },
        "deadband": {
            "cross_high": "high",
            "cross_low": "low"
        }
    },
    "data": {
        "setpoint_high": 20.5,
        "setpoint_low": 19.5,
        "greater_high": "off",
        "less_low":  "on"
    },
    "methods": {
        "setpoint_high": {
            "name": "setData"
        },
        "setpoint_low": {
            "name": "setData"
        },
        "onBeforeTransition": [
            "if (!msg.topic) msg.topic = 'evaluade';"
        ],
        "evaluade": [
            "if(msg.payload > sm.data.setpoint_high)",
            "   resume('cross_high', msg);",
            "else if (msg.payload < sm.data.setpoint_low)",
            "   resume('cross_low', msg);",
            "else {",
            "   resume('inter', msg);",
            "}",
            "output = false;"
        ],
        "cross_high": [
            "msg.payload = sm.data.greater_high;",
            "sm.fill = 'yellow';"
        ],
        "cross_low": [
            "msg.payload = sm.data.less_low;",
            "sm.fill = 'green';"
        ],
        "inter": [
            "sm.fill = 'grey';",
            "output = false;"
        ],
        "status": {
            "fill": {
                "get": "sm.fill;"
            },
            "shape": "dot",
            "text": {
                "get": "sm.currentState;"
            }
        }
    }
}

Flow

[{"id":"2c1c0a35.5a1916","type":"inject","z":"cb099c1f.9ea6b","name":"","topic":"","payload":"20","payloadType":"num","repeat":"","crontab":"","once":false,"onceDelay":0.1,"x":110,"y":4100,"wires":[["6d37d36f.bf012c"]]},{"id":"c66bfc3a.eff6e","type":"inject","z":"cb099c1f.9ea6b","name":"","topic":"","payload":"21.5","payloadType":"num","repeat":"","crontab":"","once":false,"onceDelay":0.1,"x":110,"y":4060,"wires":[["6d37d36f.bf012c"]]},{"id":"7523d449.76039c","type":"inject","z":"cb099c1f.9ea6b","name":"","topic":"","payload":"19.2","payloadType":"num","repeat":"","crontab":"","once":false,"onceDelay":0.1,"x":110,"y":4140,"wires":[["6d37d36f.bf012c"]]},{"id":"d192dee0.b4794","type":"debug","z":"cb099c1f.9ea6b","name":"","active":true,"tosidebar":true,"console":false,"tostatus":true,"complete":"payload","x":530,"y":4020,"wires":[]},{"id":"4b82e590.19df3c","type":"inject","z":"cb099c1f.9ea6b","name":"","topic":"setpoint_high","payload":"21","payloadType":"num","repeat":"","crontab":"","once":false,"onceDelay":0.1,"x":140,"y":3920,"wires":[["6d37d36f.bf012c"]]},{"id":"4b4819b2.cd4ca8","type":"inject","z":"cb099c1f.9ea6b","name":"","topic":"setpoint_low","payload":"19.5","payloadType":"num","repeat":"","crontab":"","once":false,"onceDelay":0.1,"x":140,"y":3960,"wires":[["6d37d36f.bf012c"]]},{"id":"da23046.09a25f8","type":"inject","z":"cb099c1f.9ea6b","name":"","topic":"setpoint_low","payload":"19","payloadType":"num","repeat":"","crontab":"","once":false,"onceDelay":0.1,"x":140,"y":4000,"wires":[["6d37d36f.bf012c"]]},{"id":"6d37d36f.bf012c","type":"dsm","z":"cb099c1f.9ea6b","name":"hysteresis","sm_config":"{\n    \"currentState\": \"undefined\",\n    \"states\": {\n        \"undefined\": {\n            \"cross_high\": \"high\",\n            \"cross_low\": \"low\",\n            \"inter\": \"deadband\"\n        },\n        \"high\": {\n            \"cross_low\": \"low\",\n            \"inter\": \"deadband\"\n        },\n        \"low\": {\n            \"cross_high\": \"high\",\n            \"inter\": \"deadband\"\n        },\n        \"deadband\": {\n            \"cross_high\": \"high\",\n            \"cross_low\": \"low\"\n        }\n    },\n    \"data\": {\n        \"setpoint_high\": 20.5,\n        \"setpoint_low\": 19.5,\n        \"greater_high\": \"off\",\n        \"less_low\":  \"on\"\n    },\n    \"methods\": {\n        \"setpoint_high\": {\n            \"name\": \"setData\"\n        },\n        \"setpoint_low\": {\n            \"name\": \"setData\"\n        },\n        \"onBeforeTransition\": [\n            \"if (!msg.topic) msg.topic = 'evaluade';\"\n        ],\n        \"evaluade\": [\n            \"if(msg.payload > sm.data.setpoint_high)\",\n            \"   resume('cross_high', msg);\",\n            \"else if (msg.payload < sm.data.setpoint_low)\",\n            \"   resume('cross_low', msg);\",\n            \"else {\",\n            \"   resume('inter', msg);\",\n            \"}\",\n            \"output = false;\"\n        ],\n        \"cross_high\": [\n            \"msg.payload = sm.data.greater_high;\",\n            \"sm.fill = 'yellow';\"\n        ],\n        \"cross_low\": [\n            \"msg.payload = sm.data.less_low;\",\n            \"sm.fill = 'green';\"\n        ],\n        \"inter\": [\n            \"sm.fill = 'grey';\",\n            \"output = false;\"\n        ],\n        \"status\": {\n            \"fill\": {\n                \"get\": \"sm.fill;\"\n            },\n            \"shape\": \"dot\",\n            \"text\": {\n                \"get\": \"sm.currentState;\"\n            }\n        }\n    }\n}","x":370,"y":4020,"wires":[["d192dee0.b4794"]]}]
Clone this wiki locally