Versatile Thermostat: a full feature thermostat (energy, door/window, presence, motion, preset, ... management)

I will probably improve this feature as describe here: [Feature Request] - Change the way the temporal filter works for TRV commands · Issue #1072 · jmcollin78/versatile_thermostat · GitHub

This would be very helpful. I fully agree with whats mentioned in the github-issue. A certain loop-avoidance makes sense, but a forced 10s delay seems rather drastic. Improvements here would be very welcome. In the meantime, I’ll do some ugly hacking and manually set it to 0.

The preview release with this improvement is v8.0.0. This is a beta but it works great, I will release soon.

1 Like

Don’t know if I’m wrong but I’m pretty sure that this worked before updating Versatile Thermostat.
With the latest version I can no longer select “heat/cool” mode through versitile themostat even though the underlying HVAC support it.

Anyone else with the same issue?

Hi @jmcollin, thanks for the great work. I have been using VTHERM for the last year and it works great. Having said that, I was a bit reluctant about updating to version 8.X (as the release log shows quite a few changes were made and I would not like to mess with the thermostats when temps outside are around 0).

The question I have is: how stable is the newest version? I am using Sonoff ZBTRV. Can anyone using those share some experience with the current version? Does it seem safe to update the integration?

Hi All,

I have a query… is there any way i can use Node-Red to monitor if a particular V-Therm is calling on the central configuration firing up the boiler?.. If so can i have this trigger a helper input_booleen?. I’m trying to have a readout to determing what poticular thermostat has triggered the boiler.

A quick run down of what i have setup, I have several Sonoff SNZB-02P, Sonoff TRVZB… I have a Central configuration setup to trigger a boiler relay.
The SNZB-02P & Sonoff TRVZB are all tied together through VTherms for each room.

— EDIT 01 —
I Beleve i have found a solution using the ( Call For Boiler ) Entity.

Node-Red JSON
[
    {
        "id": "1734410157d4d130",
        "type": "server-state-changed",
        "z": "a5574c37c05ee714",
        "g": "8b1d76b8df90e4b6",
        "name": "Watch Boiler Active Sensor",
        "server": "13912b6009076c18",
        "version": 6,
        "outputs": 1,
        "exposeAsEntityConfig": "",
        "entities": {
            "entity": [
                "sensor.nb_device_active_for_boiler"
            ],
            "substring": [],
            "regex": []
        },
        "outputInitially": false,
        "stateType": "str",
        "ifState": "",
        "ifStateType": "str",
        "outputOnlyOnStateChange": false,
        "for": "0",
        "forType": "num",
        "forUnits": "minutes",
        "ignorePrevStateNull": false,
        "ignorePrevStateUnknown": false,
        "ignorePrevStateUnavailable": false,
        "ignoreCurrentStateUnknown": false,
        "ignoreCurrentStateUnavailable": false,
        "outputProperties": [
            {
                "property": "payload",
                "propertyType": "msg",
                "value": "string",
                "valueType": "entityState"
            },
            {
                "property": "data",
                "propertyType": "msg",
                "value": "",
                "valueType": "eventData"
            },
            {
                "property": "topic",
                "propertyType": "msg",
                "value": "$entity.entity_id",
                "valueType": "jsonata"
            }
        ],
        "x": 210,
        "y": 640,
        "wires": [
            [
                "57019f88bdbae6f8"
            ]
        ]
    },
    {
        "id": "57019f88bdbae6f8",
        "type": "switch",
        "z": "a5574c37c05ee714",
        "g": "8b1d76b8df90e4b6",
        "name": "Check All Active Device IDs",
        "property": "data.new_state.attributes.active_device_ids",
        "propertyType": "msg",
        "rules": [
            {
                "t": "cont",
                "v": "number.ID1",
                "vt": "str"
            },
            {
                "t": "cont",
                "v": "number.ID2",
                "vt": "str"
            },
            {
                "t": "cont",
                "v": "number.ID3",
                "vt": "str"
            },
            {
                "t": "cont",
                "v": "number.ID3.1",
                "vt": "str"
            },
            {
                "t": "cont",
                "v": "number.ID4",
                "vt": "str"
            },
            {
                "t": "cont",
                "v": "number.ID5",
                "vt": "str"
            },
            {
                "t": "else"
            }
        ],
        "checkall": "true",
        "repair": false,
        "outputs": 7,
        "x": 480,
        "y": 640,
        "wires": [
            [
                "428ff10ef2f40dfb"
            ],
            [
                "9cd40f9df5d42836"
            ],
            [
                "db28a01720898ade"
            ],
            [
                "db28a01720898ade"
            ],
            [
                "5de915dcde6219b4"
            ],
            [
                "f9f85b119ecf101b"
            ],
            [
                "acb4514eeae4f287"
            ]
        ]
    },
    {
        "id": "428ff10ef2f40dfb",
        "type": "api-call-service",
        "z": "a5574c37c05ee714",
        "g": "8b1d76b8df90e4b6",
        "name": "BL1: ON",
        "server": "13912b6009076c18",
        "version": 7,
        "debugenabled": false,
        "action": "input_boolean.turn_on",
        "floorId": [],
        "areaId": [],
        "deviceId": [],
        "entityId": [
            "input_boolean.bl1_vtherm"
        ],
        "labelId": [],
        "data": "",
        "dataType": "jsonata",
        "mergeContext": "",
        "mustacheAltTags": false,
        "outputProperties": [],
        "blockInputOverrides": false,
        "domain": "input_boolean",
        "service": "turn_on",
        "x": 740,
        "y": 500,
        "wires": [
            []
        ]
    },
    {
        "id": "5de915dcde6219b4",
        "type": "api-call-service",
        "z": "a5574c37c05ee714",
        "g": "8b1d76b8df90e4b6",
        "name": "BL4: ON",
        "server": "13912b6009076c18",
        "version": 7,
        "debugenabled": false,
        "action": "input_boolean.turn_on",
        "floorId": [],
        "areaId": [],
        "deviceId": [],
        "entityId": [
            "input_boolean.bl4_vtherm"
        ],
        "labelId": [],
        "data": "",
        "dataType": "jsonata",
        "mergeContext": "",
        "mustacheAltTags": false,
        "outputProperties": [],
        "blockInputOverrides": false,
        "domain": "input_boolean",
        "service": "turn_on",
        "x": 740,
        "y": 680,
        "wires": [
            []
        ]
    },
    {
        "id": "acb4514eeae4f287",
        "type": "api-call-service",
        "z": "a5574c37c05ee714",
        "g": "8b1d76b8df90e4b6",
        "name": "BL: OFF",
        "server": "",
        "version": 7,
        "debugenabled": false,
        "action": "",
        "floorId": [],
        "areaId": [],
        "deviceId": [],
        "entityId": [
            "BL1: OFF",
            "BL2: OFF",
            "BL3: OFF",
            "BL4: OFF",
            "BL5: OFF"
        ],
        "labelId": [],
        "data": "",
        "dataType": "jsonata",
        "mergeContext": "",
        "mustacheAltTags": false,
        "outputProperties": [],
        "blockInputOverrides": false,
        "domain": "input_boolean",
        "service": "turn_off",
        "x": 740,
        "y": 820,
        "wires": [
            []
        ]
    },
    {
        "id": "9cd40f9df5d42836",
        "type": "api-call-service",
        "z": "a5574c37c05ee714",
        "g": "8b1d76b8df90e4b6",
        "name": "BL2: ON",
        "server": "13912b6009076c18",
        "version": 7,
        "debugenabled": false,
        "action": "input_boolean.turn_on",
        "floorId": [],
        "areaId": [],
        "deviceId": [],
        "entityId": [
            "input_boolean.bl2_vtherm"
        ],
        "labelId": [],
        "data": "",
        "dataType": "jsonata",
        "mergeContext": "",
        "mustacheAltTags": false,
        "outputProperties": [],
        "blockInputOverrides": false,
        "domain": "input_boolean",
        "service": "turn_on",
        "x": 740,
        "y": 560,
        "wires": [
            []
        ]
    },
    {
        "id": "db28a01720898ade",
        "type": "api-call-service",
        "z": "a5574c37c05ee714",
        "g": "8b1d76b8df90e4b6",
        "name": "BL3: ON",
        "server": "13912b6009076c18",
        "version": 7,
        "debugenabled": false,
        "action": "input_boolean.turn_on",
        "floorId": [],
        "areaId": [],
        "deviceId": [],
        "entityId": [
            "input_boolean.bl3_vtherm"
        ],
        "labelId": [],
        "data": "",
        "dataType": "jsonata",
        "mergeContext": "",
        "mustacheAltTags": false,
        "outputProperties": [],
        "blockInputOverrides": false,
        "domain": "input_boolean",
        "service": "turn_on",
        "x": 740,
        "y": 620,
        "wires": [
            []
        ]
    },
    {
        "id": "f9f85b119ecf101b",
        "type": "api-call-service",
        "z": "a5574c37c05ee714",
        "g": "8b1d76b8df90e4b6",
        "name": "BL5: ON",
        "server": "13912b6009076c18",
        "version": 7,
        "debugenabled": false,
        "action": "input_boolean.turn_on",
        "floorId": [],
        "areaId": [],
        "deviceId": [],
        "entityId": [
            "input_boolean.bl5_vtherm"
        ],
        "labelId": [],
        "data": "",
        "dataType": "jsonata",
        "mergeContext": "",
        "mustacheAltTags": false,
        "outputProperties": [],
        "blockInputOverrides": false,
        "domain": "input_boolean",
        "service": "turn_on",
        "x": 740,
        "y": 740,
        "wires": [
            []
        ]
    },
    {
        "id": "acc3c06f0e031227",
        "type": "comment",
        "z": "a5574c37c05ee714",
        "g": "8b1d76b8df90e4b6",
        "name": "Boiler Activation Check ( Who )",
        "info": "",
        "x": 230,
        "y": 500,
        "wires": []
    },
    {
        "id": "13912b6009076c18",
        "type": "server",
        "name": "HA SERVER",
        "addon": true,
        "rejectUnauthorizedCerts": true,
        "ha_boolean": [],
        "connectionDelay": false,
        "cacheJson": false,
        "heartbeat": true,
        "heartbeatInterval": "10",
        "statusSeparator": "",
        "enableGlobalContextStore": false
    },
    {
        "id": "248f5f8b2222fc1e",
        "type": "global-config",
        "env": [],
        "modules": {
            "node-red-contrib-home-assistant-websocket": "0.80.3"
        }
    }
]

Kind Regars
Mr. S. J. Dorrington

For an over_climate entry for a Sonoff TRV with direct valve regulation, is the min regulation threshold percentage set as a whole number or a decimal? E.g. I want there to be a min 10% difference, do I enter 10, or 0.1?