OpenZWave / open-zwave

a C++ library to control Z-Wave Networks via a USB Z-Wave Controller.
http://www.openzwave.net/
GNU Lesser General Public License v3.0
1.05k stars 918 forks source link

Use supervision to set thermostat setpoint #2584

Closed markruys closed 2 years ago

markruys commented 3 years ago

[ I messed up #2525, so I created a new PR ]

Some devices like the Fibaro FGT001 Heat Controller won't accept a ThermostatSetpointCmd_Get right immediate after a ThermostatSetpointCmd_Set. The device returns instead:

0x22 = COMMAND_CLASS_APPLICATION_STATUS (See 4.2.2 Application Busy Command in SDS13782 Z-Wave Management Command Class Specification.pdf) 0x01 = APPLICATION_BUSY 0x01 = "Try again in Wait Time seconds" 0x02 = two seconds...

One solution would be to retry the ThermostatSetpointCmd_Get after 2 seconds. A more efficient approach is to encapsulate the ThermostatSetpointCmd_Set with a supervision CC. This was proposed in issue #1971 and is implemented in this PR. It works like this:

2021-02-13 16:46:12.338 Info, Node019, Value::Set - COMMAND_CLASS_THERMOSTAT_SETPOINT - Heating 1 - 1 - 1 - 20
2021-02-13 16:46:12.338 Detail, Node019, Queuing (Send) MultiChannel Encapsulated (instance=1): Supervisioned: ThermostatSetpointCmd_Set (Node=19): 0x01, 0x14, 0x00, 0x13, 0x13, 0x0d, 0x60, 0x0d, 0x01, 0x01, 0x6c, 0x01, 0x83, 0x05, 0x43, 0x01, 0x01, 0x01, 0x14, 0x25, 0x8b, 0x98
2021-02-13 16:46:12.338 Info, Node019, Sending (Send) message (Callback ID=0x8b, Expected Reply=0x13) - MultiChannel Encapsulated (instance=1): Supervisioned: ThermostatSetpointCmd_Set (Node=19): 0x01, 0x14, 0x00, 0x13, 0x13, 0x0d, 0x60, 0x0d, 0x01, 0x01, 0x6c, 0x01, 0x83, 0x05, 0x43, 0x01, 0x01, 0x01, 0x14, 0x25, 0x8b, 0x98
2021-02-13 16:46:12.338 Info, Node019, Encrypted Flag is 0
2021-02-13 16:46:12.353 Detail, Node019,   Received: 0x01, 0x04, 0x01, 0x13, 0x01, 0xe8
2021-02-13 16:46:12.353 Detail, Node019,   ZW_SEND_DATA delivered to Z-Wave stack
2021-02-13 16:46:13.654 Detail, Node019,   Received: 0x01, 0x07, 0x00, 0x13, 0x8b, 0x00, 0x00, 0x83, 0xe3
2021-02-13 16:46:13.654 Detail, Node019,   ZW_SEND_DATA Request with callback ID 0x8b received (expected 0x8b)
2021-02-13 16:46:13.654 Info, Node019, Request RTT 1316 Average Request RTT 991
2021-02-13 16:46:13.654 Detail, Node019,   Expected callbackId was received
2021-02-13 16:46:13.654 Detail, Node019,   Expected reply was received
2021-02-13 16:46:13.655 Detail, Node019,   Message transaction complete
2021-02-13 16:46:13.655 Detail, Node019, Removing current message
2021-02-13 16:46:13.777 Detail, Node019,   Received: 0x01, 0x0f, 0x00, 0x04, 0x00, 0x13, 0x09, 0x60, 0x0d, 0x01, 0x01, 0x6c, 0x02, 0x03, 0xff, 0x00, 0x11
2021-02-13 16:46:13.777 Info, Node019, Received a MultiChannelEncap from node 19, endpoint 1 for Command Class COMMAND_CLASS_SUPERVISION
2021-02-13 16:46:13.777 Info, Node019, Received SupervisionReport: session 3, COMMAND_CLASS_THERMOSTAT_SETPOINT index 1, status SUCCESS, duration 0 sec, more status updates 0
2021-02-13 16:46:13.777 Detail, Node019, Value Updated: old value=22, new value=20, type=decimal
2021-02-13 16:46:13.778 Detail, Node019, Changes to this value are not verified
2021-02-13 16:46:13.778 Info, Node019, Confirmed thermostat setpoint index 1 to 20C
2021-02-13 16:46:13.778 Detail, Node019, Notification: ValueChanged CC: COMMAND_CLASS_THERMOSTAT_SETPOINT Instance: 1 Index: 1

The implementation supports up to 6 concurrent supervision sessions per node.

nebuohyrrah commented 3 years ago

Works like a charm.

Allow multiple concurrent supervisor requests for a single node (multiple nodes should work)

Only the last request is processed by the 'supervisionSucess' function, which normally should be correct. If the changed setpoints were on different indexes then it is possible a value is not changed after getting the supervision succes rapport.

I have tried to do the same for the ThermostatMode as it has the same issue. This works as well, but there is a problem with the "manufacturer specific / manual valve control" mode in the valuelist. I don't know if this is a known bug.

Offtopic: I see you added the settings for firmware v4.7. Does it report the temperature of the external sensor without polling with the new firmware? Other reasons to upgrade? I believe I have still v4.0.

markruys commented 3 years ago

Offtopic, here is changelog of firmware 4.7 for Heat Controller from HC3:

markruys commented 3 years ago

@nebuohyrrah, I implemented up to 6 concurrent supervision sessions per node, addressing your request. The number 6 is actually quiet random, but I guess it will work for most (all?) devices. Alternative implementation would be to lift this limitation, but add an expiration stamp to the administration. But it looks to me that would be overkill.

@Fishwaldo, I think this PR is good enough to be merged.

duco-lebens commented 3 years ago

If you have 10 x FGT001's in your home, they for sure need some sort of supervision, something the current stable build 2021.1 of Domoticz lacks. Mark's additional Z-Wave Supervision class gets the lot in control; no more 'retry later' nonsense.

This one should be merged (no pressure).

nebuohyrrah commented 3 years ago

I agree. That is why I created a fork and compiled OpenZwave with the supervision CC myself. I even added the supervision CC for the thermostat mode, as I got the same 'retry later' error there. This is running quite well for several weeks now. In Domoticz I disabled the need for polling the thermostat setpoint values since I only need the temperature and the battery level is polled once every 30 poll intervalls. This reduces the number of polls by ~90% and increases battery life by a good amount.

@markruys I forgot to mention a bug in supervision.cpp --> the bracket in line 125 should be after the 'return'. Otherwise if the supervision id is in the 2nd iteration, it will hit the return before it can access it.

markruys commented 2 years ago

@markruys I forgot to mention a bug in supervision.cpp --> the bracket in line 125 should be after the 'return'. Otherwise if the supervision id is in the 2nd iteration, it will hit the return before it can access it.

I don't think so @nebuohyrrah. The Supervision::HandleSupervisionReport() is handling a single report for a specific session. The loop at lines 101 to 103 trie to find this session. If it does, it should stop searching and return (line 127). Whether we can expect more update in coming messages (line 122) has nothing to do with it. But maybe I'm missing your point?

nebuohyrrah commented 2 years ago

Maybe I mixed things up myself by accident. I have also included the supervision command class for the thermostat mode CC, switch binary CC and switch multilevel CC. (see https://github.com/nebuohyrrah/open-zwave)

It has been running several weeks now and I am very pleased with it. It seems an improvement over the standard set/get method, especially for window blinds or dimmers that don't have the new setting directly. It's too bad that it can't be incorporated in the official master branch yet.