home-assistant / core

:house_with_garden: Open source home automation that puts local control and privacy first.
https://www.home-assistant.io
Apache License 2.0
71.53k stars 29.91k forks source link

Cannot set setpoint for SRT321 #47347

Closed gsemet closed 3 years ago

gsemet commented 3 years ago

The problem

SRT321/HRT4-ZW Thermostat setpoint is well discovered and converted to climate entity but cannot set the setpoint.

What is version of Home Assistant Core has the issue?

core-2021.3.0

What was the last working version of Home Assistant Core?

No response

What type of installation are you running?

Home Assistant Supervised

Integration causing the issue

ZWave2JSMQTT

Link to integration documentation on our website

https://www.home-assistant.io/integrations/zwave_js/

Example YAML snippet

No response

Anything in the logs that might be useful for us?

Stacktrace:

Traceback (most recent call last):
  File "/usr/src/homeassistant/homeassistant/core.py", line 1504, in catch_exceptions
    await coro_or_task
  File "/usr/src/homeassistant/homeassistant/core.py", line 1523, in _execute_service
    await handler.job.target(service_call)
  File "/usr/src/homeassistant/homeassistant/helpers/entity_component.py", line 204, in handle_service
    await self.hass.helpers.service.entity_service_call(
  File "/usr/src/homeassistant/homeassistant/helpers/service.py", line 642, in entity_service_call
    future.result()  # pop exception if have
  File "/usr/src/homeassistant/homeassistant/helpers/entity.py", line 681, in async_request_call
    await coro
  File "/usr/src/homeassistant/homeassistant/helpers/service.py", line 679, in _handle_entity_call
    await result
  File "/usr/src/homeassistant/homeassistant/components/zwave_js/climate.py", line 401, in async_set_hvac_mode
    raise ValueError(
ValueError: Thermostat climate.main_heater_thermostat_main does not support setting a mode

I also see:

Traceback (most recent call last):
  File "/usr/src/homeassistant/homeassistant/helpers/entity_platform.py", line 317, in async_add_entities
    await asyncio.gather(*tasks)
  File "/usr/src/homeassistant/homeassistant/helpers/entity_platform.py", line 424, in _async_add_entity
    capabilities=entity.capability_attributes,
  File "/usr/src/homeassistant/homeassistant/components/climate/__init__.py", line 189, in capability_attributes
    self.hass, self.min_temp, self.temperature_unit, self.precision
  File "/usr/src/homeassistant/homeassistant/components/climate/__init__.py", line 498, in min_temp
    DEFAULT_MIN_TEMP, TEMP_CELSIUS, self.temperature_unit
  File "/usr/src/homeassistant/homeassistant/components/zwave_js/climate.py", line 218, in temperature_unit
    if "f" in self._unit_value.metadata.unit.lower():
AttributeError: 'NoneType' object has no attribute 'metadata'

Follow up of #46570

The zwave trace is available here.

probot-home-assistant[bot] commented 3 years ago

Hey there @home-assistant/z-wave, mind taking a look at this issue as its been labeled with an integration (zwave_js) you are listed as a codeowner for? Thanks! (message by CodeOwnersMention)

MartinHjelmare commented 3 years ago

@gsemet please create a new dump with core-2021.3.0 of your Z-Wave network and upload the dump as a text file here. I'm looking at addressing part of this issue but your old dump is not compatible anymore with our latest schema version.

Thanks!

gsemet commented 3 years ago

Here what I have:

Node 20 ```json { "nodeId": 20, "index": 0, "status": 4, "ready": true, "deviceClass": { "basic": { "key": 4, "label": "Routing Slave" }, "generic": { "key": 8, "label": "Thermostat" }, "specific": { "key": 0, "label": "Unused" }, "mandatorySupportedCCs": [], "mandatoryControlledCCs": [] }, "isListening": true, "isFrequentListening": false, "isRouting": true, "maxBaudRate": 40000, "isSecure": false, "version": 3, "isBeaming": true, "manufacturerId": 89, "productId": 1, "productType": 3, "firmwareVersion": "2.0", "name": "main_heat_actionner", "location": "kitchen", "deviceConfig": { "filename": "/opt/node_modules/@zwave-js/config/config/devices/0x0059/asr-zw.json", "manufacturerId": 89, "manufacturer": "Secure Meters (UK) Ltd.", "label": "SRT322", "description": "Thermostat Receiver", "devices": [ { "productType": "0x0003", "productId": "0x0001" } ], "firmwareVersion": { "min": "0.0", "max": "255.255" } }, "label": "SRT322", "neighbors": [ 1, 5, 10, 12, 13, 14, 15, 18, 21 ], "interviewAttempts": 1, "interviewStage": 7, "commandClasses": [ { "id": 37, "name": "Binary Switch", "version": 1, "isSecure": false }, { "id": 64, "name": "Thermostat Mode", "version": 1, "isSecure": false }, { "id": 114, "name": "Manufacturer Specific", "version": 1, "isSecure": false }, { "id": 134, "name": "Version", "version": 1, "isSecure": false } ], "endpoints": [ { "nodeId": 20, "index": 0 } ], "values": [ { "endpoint": 0, "commandClass": 37, "commandClassName": "Binary Switch", "property": "currentValue", "propertyName": "currentValue", "ccVersion": 1, "metadata": { "type": "boolean", "readable": true, "writeable": false, "label": "Current value" }, "value": false }, { "endpoint": 0, "commandClass": 37, "commandClassName": "Binary Switch", "property": "targetValue", "propertyName": "targetValue", "ccVersion": 1, "metadata": { "type": "boolean", "readable": true, "writeable": true, "label": "Target value" }, "value": false }, { "endpoint": 0, "commandClass": 64, "commandClassName": "Thermostat Mode", "property": "mode", "propertyName": "mode", "ccVersion": 1, "metadata": { "type": "number", "readable": true, "writeable": true, "min": 0, "max": 255, "states": { "0": "Off", "1": "Heat" }, "label": "Thermostat mode" }, "value": 0 }, { "endpoint": 0, "commandClass": 64, "commandClassName": "Thermostat Mode", "property": "manufacturerData", "propertyName": "manufacturerData", "ccVersion": 1, "metadata": { "type": "any", "readable": true, "writeable": true } }, { "endpoint": 0, "commandClass": 114, "commandClassName": "Manufacturer Specific", "property": "manufacturerId", "propertyName": "manufacturerId", "ccVersion": 1, "metadata": { "type": "number", "readable": true, "writeable": false, "min": 0, "max": 65535, "label": "Manufacturer ID" }, "value": 89 }, { "endpoint": 0, "commandClass": 114, "commandClassName": "Manufacturer Specific", "property": "productType", "propertyName": "productType", "ccVersion": 1, "metadata": { "type": "number", "readable": true, "writeable": false, "min": 0, "max": 65535, "label": "Product type" }, "value": 3 }, { "endpoint": 0, "commandClass": 114, "commandClassName": "Manufacturer Specific", "property": "productId", "propertyName": "productId", "ccVersion": 1, "metadata": { "type": "number", "readable": true, "writeable": false, "min": 0, "max": 65535, "label": "Product ID" }, "value": 1 }, { "endpoint": 0, "commandClass": 134, "commandClassName": "Version", "property": "libraryType", "propertyName": "libraryType", "ccVersion": 1, "metadata": { "type": "any", "readable": true, "writeable": false, "label": "Library type" }, "value": 6 }, { "endpoint": 0, "commandClass": 134, "commandClassName": "Version", "property": "protocolVersion", "propertyName": "protocolVersion", "ccVersion": 1, "metadata": { "type": "any", "readable": true, "writeable": false, "label": "Z-Wave protocol version" }, "value": "2.78" }, { "endpoint": 0, "commandClass": 134, "commandClassName": "Version", "property": "firmwareVersions", "propertyName": "firmwareVersions", "ccVersion": 1, "metadata": { "type": "any", "readable": true, "writeable": false, "label": "Z-Wave chip firmware versions" }, "value": [ "2.0" ] } ] }
MartinHjelmare commented 3 years ago

The dump above is for the SRT322. That's a different device, right?

gsemet commented 3 years ago

Not, the transmitter is the same. I don't know why its name has changed, I can not reset it. image

SECURE SRT322-5 Z‑Wave+ (Gen5) = Pack Thermostat transmitter SRT321-5 + Thermostat receiver Z-Wave+ SSR303-5

This is the pack I brought indeed, but I always saw reference to SRT321

MartinHjelmare commented 3 years ago

Ok, thanks.

Looking at the dump, there are no setpoints reported, hence the missing support for setting temperature currently. I'll open a PR to fix the attribute error for unit. It will not fix the missing setpoints of course.

@kpine do you know anything about this device?

kpine commented 3 years ago

I haven't seen this before. The first question is if this device is really supposed to have a setpoint or not. Is this just an SRT321 with an addon? I know the SRT321 supports a Heating setpoint value. If this is the same, then I would submit an issue to node-zwave-js with the interview logs, maybe the command class needs to be added manually?

gsemet commented 3 years ago

The device is the same old SRT321 that is a thermostat (and use to work as a classic climate entity on ozw). I did a patch for supporting the climate entity now it is seen but the setpoint seems to be misconfigured

gsemet commented 3 years ago

Ohhhh my mistake it is the receiver ! I’ll repost the transmitter ASAP !

kpine commented 3 years ago

OK, this is probably related to the changes to the discovery schema, as thermostat mode climate entities used to be based on Generic and Specific types. Maybe the Thermostat Mode discovery needs to require at least one setpoint value. A climate entity probably shouldn't be created for this receiver.

gsemet commented 3 years ago

Here the real thermotat transmitter SRT321

Node 19 ```json { "nodeId": 19, "index": 0, "status": 1, "ready": true, "deviceClass": { "basic": { "key": 1, "label": "Controller" }, "generic": { "key": 8, "label": "Thermostat" }, "specific": { "key": 0, "label": "Unused" }, "mandatorySupportedCCs": [], "mandatoryControlledCCs": [] }, "isListening": false, "isFrequentListening": false, "isRouting": false, "maxBaudRate": 40000, "isSecure": false, "version": 3, "isBeaming": true, "manufacturerId": 89, "productId": 3, "productType": 1, "firmwareVersion": "6.0", "name": "thermostat_main", "location": "entrance", "deviceConfig": { "filename": "/opt/node_modules/@zwave-js/config/config/devices/0x0059/hrt4-zw.json", "manufacturerId": 89, "manufacturer": "Secure Meters (UK) Ltd.", "label": "HRT4-ZW / SRT321", "description": "Battery Powered Wall Thermostat", "devices": [ { "productType": "0x0001", "productId": "0x0003" } ], "firmwareVersion": { "min": "0.0", "max": "255.255" }, "associations": {}, "paramInformation": { "_map": {} } }, "label": "HRT4-ZW / SRT321", "neighbors": [], "interviewAttempts": 1, "interviewStage": 7, "commandClasses": [ { "id": 49, "name": "Multilevel Sensor", "version": 1, "isSecure": false }, { "id": 67, "name": "Thermostat Setpoint", "version": 1, "isSecure": false }, { "id": 112, "name": "Configuration", "version": 1, "isSecure": false }, { "id": 114, "name": "Manufacturer Specific", "version": 1, "isSecure": false }, { "id": 128, "name": "Battery", "version": 1, "isSecure": false }, { "id": 132, "name": "Wake Up", "version": 1, "isSecure": false }, { "id": 133, "name": "Association", "version": 1, "isSecure": false }, { "id": 134, "name": "Version", "version": 1, "isSecure": false } ], "endpoints": [ { "nodeId": 19, "index": 0 } ], "values": [ { "endpoint": 0, "commandClass": 49, "commandClassName": "Multilevel Sensor", "property": "Air temperature", "propertyName": "Air temperature", "ccVersion": 1, "metadata": { "type": "number", "readable": true, "writeable": false, "unit": "\u00b0C", "label": "Air temperature", "ccSpecific": { "sensorType": 1, "scale": 0 } }, "value": 19.7 }, { "endpoint": 0, "commandClass": 67, "commandClassName": "Thermostat Setpoint", "property": "setpoint", "propertyKey": 1, "propertyName": "setpoint", "propertyKeyName": "Heating", "ccVersion": 1, "metadata": { "type": "number", "readable": true, "writeable": true, "unit": "\u00b0C", "ccSpecific": { "setpointType": 1 } }, "value": 17 }, { "endpoint": 0, "commandClass": 112, "commandClassName": "Configuration", "property": 1, "propertyName": "Enable Temperature Sensor", "ccVersion": 1, "metadata": { "type": "number", "readable": true, "writeable": true, "valueSize": 1, "min": 0, "max": 255, "default": 0, "format": 1, "allowManualEntry": false, "states": { "0": "Disable", "255": "Enable" }, "label": "Enable Temperature Sensor", "description": "Controls the use of the temperature sensor on the device", "isFromConfig": true }, "value": 255 }, { "endpoint": 0, "commandClass": 112, "commandClassName": "Configuration", "property": 2, "propertyName": "Temperature Scale", "ccVersion": 1, "metadata": { "type": "number", "readable": true, "writeable": true, "valueSize": 1, "min": 0, "max": 255, "default": 0, "format": 1, "allowManualEntry": false, "states": { "0": "Celsius", "255": "Fahrenheit" }, "label": "Temperature Scale", "description": "Controls the temperature sensor scale", "isFromConfig": true }, "value": 0 }, { "endpoint": 0, "commandClass": 112, "commandClassName": "Configuration", "property": 3, "propertyName": "Delta T", "ccVersion": 1, "metadata": { "type": "number", "readable": true, "writeable": true, "valueSize": 1, "min": 0, "max": 255, "default": 10, "format": 1, "allowManualEntry": true, "label": "Delta T", "description": "Defines the temperature steps of the heating control. Steps are 0.1 K", "isFromConfig": true }, "value": 10 }, { "endpoint": 0, "commandClass": 114, "commandClassName": "Manufacturer Specific", "property": "manufacturerId", "propertyName": "manufacturerId", "ccVersion": 1, "metadata": { "type": "number", "readable": true, "writeable": false, "min": 0, "max": 65535, "label": "Manufacturer ID" }, "value": 89 }, { "endpoint": 0, "commandClass": 114, "commandClassName": "Manufacturer Specific", "property": "productType", "propertyName": "productType", "ccVersion": 1, "metadata": { "type": "number", "readable": true, "writeable": false, "min": 0, "max": 65535, "label": "Product type" }, "value": 1 }, { "endpoint": 0, "commandClass": 114, "commandClassName": "Manufacturer Specific", "property": "productId", "propertyName": "productId", "ccVersion": 1, "metadata": { "type": "number", "readable": true, "writeable": false, "min": 0, "max": 65535, "label": "Product ID" }, "value": 3 }, { "endpoint": 0, "commandClass": 128, "commandClassName": "Battery", "property": "level", "propertyName": "level", "ccVersion": 1, "metadata": { "type": "number", "readable": true, "writeable": false, "min": 0, "max": 100, "unit": "%", "label": "Battery level" }, "value": 46 }, { "endpoint": 0, "commandClass": 128, "commandClassName": "Battery", "property": "isLow", "propertyName": "isLow", "ccVersion": 1, "metadata": { "type": "boolean", "readable": true, "writeable": false, "label": "Low battery level" }, "value": false }, { "endpoint": 0, "commandClass": 132, "commandClassName": "Wake Up", "property": "wakeUpInterval", "propertyName": "wakeUpInterval", "ccVersion": 1, "metadata": { "type": "number", "readable": false, "writeable": true, "min": 256, "max": 131071, "label": "Wake Up interval", "steps": 1, "default": 86400 }, "value": 86400 }, { "endpoint": 0, "commandClass": 132, "commandClassName": "Wake Up", "property": "controllerNodeId", "propertyName": "controllerNodeId", "ccVersion": 1, "metadata": { "type": "any", "readable": true, "writeable": false, "label": "Node ID of the controller" }, "value": 1 }, { "endpoint": 0, "commandClass": 134, "commandClassName": "Version", "property": "libraryType", "propertyName": "libraryType", "ccVersion": 1, "metadata": { "type": "any", "readable": true, "writeable": false, "label": "Library type" }, "value": 2 }, { "endpoint": 0, "commandClass": 134, "commandClassName": "Version", "property": "protocolVersion", "propertyName": "protocolVersion", "ccVersion": 1, "metadata": { "type": "any", "readable": true, "writeable": false, "label": "Z-Wave protocol version" }, "value": "2.78" }, { "endpoint": 0, "commandClass": 134, "commandClassName": "Version", "property": "firmwareVersions", "propertyName": "firmwareVersions", "ccVersion": 1, "metadata": { "type": "any", "readable": true, "writeable": false, "label": "Z-Wave chip firmware versions" }, "value": [ "6.0" ] } ] } ```
kpine commented 3 years ago

That one should be supported. Do you have two climate entities?

GreatAlbatross commented 3 years ago

Not sure if this helps, but I saw both my SR321 and another thermostat input device fall off after upgrading Z-Wave JS from 0.1.07 (iirc) to 0.1.10. Other attributes (temp etc.) are still relayed, but not the thermostat entity.

gsemet commented 3 years ago

I only have one climate and it displays the right temperature and setpoint value. But as soon as I try to change I see this error in the log

Traceback (most recent call last):
  File "/usr/src/homeassistant/homeassistant/core.py", line 1504, in catch_exceptions
    await coro_or_task
  File "/usr/src/homeassistant/homeassistant/core.py", line 1523, in _execute_service
    await handler.job.target(service_call)
  File "/usr/src/homeassistant/homeassistant/helpers/entity_component.py", line 204, in handle_service
    await self.hass.helpers.service.entity_service_call(
  File "/usr/src/homeassistant/homeassistant/helpers/service.py", line 642, in entity_service_call
    future.result()  # pop exception if have
  File "/usr/src/homeassistant/homeassistant/helpers/entity.py", line 681, in async_request_call
    await coro
  File "/usr/src/homeassistant/homeassistant/helpers/service.py", line 679, in _handle_entity_call
    await result
  File "/usr/src/homeassistant/homeassistant/components/zwave_js/climate.py", line 401, in async_set_hvac_mode
    raise ValueError(
ValueError: Thermostat climate.main_heater_thermostat_main does not support setting a mode
kpine commented 3 years ago

Which node ID is the climate entity associated with, 19 or 20?

gsemet commented 3 years ago

Sorry for the misunderstanding

Node 19 is the thermostat transmitter SRT321

node 20 is the receiver SSR303-5, that seems to be seen as SRT322.

kpine commented 3 years ago

Sure, I understand that part, my question is to determine which node HA is creating the climate entity for. If you go to the Devices page, you can select one of the nodes (each node is a device), and it will list the node ID plus its entities. It sounds like you only have one climate entity, so which of those nodes is it assigned to?

gsemet commented 3 years ago

Node 19 23D3C321-073A-44FC-BC87-225DC6D925B0

kpine commented 3 years ago

Not sure if this helps, but I saw both my SR321 and another thermostat input device fall off after upgrading Z-Wave JS from 0.1.07 (iirc) to 0.1.10. Other attributes (temp etc.) are still relayed, but not the thermostat entity.

@GreatAlbatross I think this is a different problem. HA 2021.2.X is not compatible with the newer versions of the server, with regards to thermostats and RGB devices. So if you upgrade the server (e.g. zwave-js addon) but stay at HA Core 2021.2.3, you won't see a thermostat.

kpine commented 3 years ago

@gsemet Can you clarify, was the thermostat working in 2021.2, and is now broken in 2021.3.0, or is this the first time you've tried it?

gsemet commented 3 years ago

Not the climate never worked on zwavejs. I just switched to zwavejs2mqtt. The climate was working on ozw.

On 2021.2.x, the thermostat SRT321 devices only added 3 entities out of 4 (see #46570), the climate was missing.

I did this patch I guess that helped the setpoint command to be translated into climate entity. Read is ok (both temperature sensor and the setpoint value) but changing the setpoint value from HA fails.

gsemet commented 3 years ago

Could it comes from this utf-8 character for the setpoint property?

    {
      "endpoint": 0,
      "commandClass": 67,
      "commandClassName": "Thermostat Setpoint",
      "property": "setpoint",
      "propertyKey": 1,
      "propertyName": "setpoint",
      "propertyKeyName": "Heating",
      "ccVersion": 1,
      "metadata": {
        "type": "number",
        "readable": true,
        "writeable": true,
        "unit": "\u00b0C",  # <===== weird character here (or it is a copy paste issue)
        "ccSpecific": {
          "setpointType": 1
        }
      },

which differs from some unit test I can see.

Looks like this condition is not met so self._unit_value is None, which lead to this exception:

  File "/usr/src/homeassistant/homeassistant/components/zwave_js/climate.py", line 218, in temperature_unit
    if "f" in self._unit_value.metadata.unit.lower():
AttributeError: 'NoneType' object has no attribute 'metadata'
gsemet commented 3 years ago

Any news for this issue ? This is still a bit annoying not to be able to change the setpoint value from HA, and I am sure it is not a big issue, just I don’t know how to help

MartinHjelmare commented 3 years ago

The AttributeError was fixed in release core-2021.3.1.

The unicode degree sign should not be a problem.

gsemet commented 3 years ago

Ok I do not have the attribute error indeed.

But still this issue:


Last logged: 07:30:00

    Error executing service: <ServiceCall climate.set_hvac_mode (c:a3cff9948165c1d4c674e142c9165749): hvac_mode=heat, entity_id=['climate.main_heater_thermostat_main']>
    Error executing service: <ServiceCall climate.set_hvac_mode (c:25f07ba8e5b75d8fc8091c70806d385c): hvac_mode=heat, entity_id=['climate.main_heater_thermostat_main']>
    Error executing service: <ServiceCall climate.set_hvac_mode (c:b43f9deb1820b0665a4450332246a216): hvac_mode=heat, entity_id=['climate.main_heater_thermostat_main']>
    Error executing service: <ServiceCall climate.set_hvac_mode (c:c949ff875ab670d468b10edfde57a6d6): hvac_mode=heat, entity_id=['climate.main_heater_thermostat_main']>
    Error executing service: <ServiceCall climate.set_hvac_mode (c:e1269a79bee09f769e7e604ab3c56f71): hvac_mode=heat, entity_id=['climate.main_heater_thermostat_main']>

Traceback (most recent call last):
  File "/usr/src/homeassistant/homeassistant/core.py", line 1504, in catch_exceptions
    await coro_or_task
  File "/usr/src/homeassistant/homeassistant/core.py", line 1523, in _execute_service
    await handler.job.target(service_call)
  File "/usr/src/homeassistant/homeassistant/helpers/entity_component.py", line 204, in handle_service
    await self.hass.helpers.service.entity_service_call(
  File "/usr/src/homeassistant/homeassistant/helpers/service.py", line 642, in entity_service_call
    future.result()  # pop exception if have
  File "/usr/src/homeassistant/homeassistant/helpers/entity.py", line 681, in async_request_call
    await coro
  File "/usr/src/homeassistant/homeassistant/helpers/service.py", line 679, in _handle_entity_call
    await result
  File "/usr/src/homeassistant/homeassistant/components/zwave_js/climate.py", line 399, in async_set_hvac_mode
    raise ValueError(
ValueError: Thermostat climate.main_heater_thermostat_main does not support setting a mode
MartinHjelmare commented 3 years ago

Why are you calling the set hvac mode service when you want to change temperature?

GreatAlbatross commented 3 years ago

I think because the set temperature attribute of the thermostat is not being made available. Similar to gsemet, I'm only getting 4 entities: HVAC, Air Temperature, Battery %, and low battery alert.

So, because the setpoint attribute isn't isolated, we're trying the next best, HVAC, which isn't compatible with the call. Edit: And trying to manually change the setpoint through HVAC does not work, I just attempted.

MartinHjelmare commented 3 years ago

To change the setpoint temperature you should call the climate.set_temperature service. Have you tried that?

MartinHjelmare commented 3 years ago

I think because the set temperature attribute of the thermostat is not being made available. Similar to gsemet, I'm only getting 4 entities: HVAC, Air Temperature, Battery %, and low battery alert.

So, because the setpoint attribute isn't isolated, we're trying the next best, HVAC, which isn't compatible with the call. Edit: And trying to manually change the setpoint through HVAC does not work, I just attempted.

When you say HVAC, what do you mean? Do you mean the climate entity?

gsemet commented 3 years ago

It is possible there is a disalignment between this line:


    # thermostats supporting setpoint only (and thus not mode)
    ZWaveDiscoverySchema(
        platform="climate",
        primary_value=ZWaveValueDiscoverySchema(
            command_class={CommandClass.THERMOSTAT_SETPOINT},
            property={"setpoint"},
            type={"number"},
        ),
        absent_values=[  # mode must not be present to prevent dupes
            ZWaveValueDiscoverySchema(
                command_class={CommandClass.THERMOSTAT_MODE},
                property={"mode"},
                type={"number"},
            ),
        ],
    ),

and this command class:


    {
      "endpoint": 0,
      "commandClass": 67,
      "commandClassName": "Thermostat Setpoint",
      "property": "setpoint",
      "propertyKey": 1,
      "propertyName": "setpoint",
      "propertyKeyName": "Heating",
      "ccVersion": 1,
      "metadata": {
        "type": "number",
        "readable": true,
        "writeable": true,
        "unit": "\u00b0C",
        "ccSpecific": {
          "setpointType": 1
        }
      },
      "value": 17
    },

or maybe because this is evaluated before (and so it thinks it a thermostat with mode (no check on absence of mode property) but fails when trying to set it) ?

    # thermostats supporting mode (and optional setpoint)
    ZWaveDiscoverySchema(
        platform="climate",
        primary_value=ZWaveValueDiscoverySchema(
            command_class={CommandClass.THERMOSTAT_MODE},
            property={"mode"},
            type={"number"},
        ),
    ),
GreatAlbatross commented 3 years ago

I think because the set temperature attribute of the thermostat is not being made available. Similar to gsemet, I'm only getting 4 entities: HVAC, Air Temperature, Battery %, and low battery alert. So, because the setpoint attribute isn't isolated, we're trying the next best, HVAC, which isn't compatible with the call. Edit: And trying to manually change the setpoint through HVAC does not work, I just attempted.

When you say HVAC, what do you mean? Do you mean the climate entity?

Yes, apologies, the one which shoes up like this: image

gsemet commented 3 years ago

I confirm calling the service climate.set_temperature works.

GreatAlbatross commented 3 years ago

I'll have to dig to see where in the logs it shows up, but for me calling against the SR321, it doesn't seem to do anything on that command. But also doesn't give an error.

gsemet commented 3 years ago

You ll have to wait for the device to awake, by default it is extremely long.

MartinHjelmare commented 3 years ago

I've now tested both provided dumps for node 19 and node 20 in unit tests, successfully. Node 19 is able to set temperature and node 20 is able to change mode (between off and heat).

Please let us know if there are any remaining issues.

gsemet commented 3 years ago

is there a version that fix this issue already ? newer than "core-2021.3.3" ?

MartinHjelmare commented 3 years ago

I've now tested my unit test on the master branch which is currently released as core-2021.3.3. That works as well.

What is it that doesn't work for you? Please describe more in detail what you are testing.

gsemet commented 3 years ago

Please see my comment here. I still get this error with core-2021.3.3. I am pretty sure it is something like the first ZWaveDiscoverySchema is matched so the device is thought to be supporting setting the "mode", so it appears with the "Operation" field in its entity UI.

kpine commented 3 years ago

Please see my comment here. I still get this error with core-2021.3.3. I am pretty sure it is something like the first ZWaveDiscoverySchema is matched so the device is thought to be supporting setting the "mode", so it appears with the "Operation" field in its entity UI.

The discovery schema for the thermostat is just deciding whether a climate entity is created or not. That schema does not match your node 19 because the node does not have the Thermostat Mode CC, so it has no effect. Whether mode is supported or not is detected when the entity is created. Again, your node does not support the Thermostat Mode CC so that self._current_mode is None.

Can you clarify what action is giving you the error? Is it the frontend or service call? Clicking the temperature arrow buttons, or what?

I don't think Preset shouldn't even be shown. That is hardcoded in zwave_js, but presets are only assigned for mode thermostats.

gsemet commented 3 years ago

Service call works. Setting using the climate widget (yes button + and -) in the front end generates this exception.

MartinHjelmare commented 3 years ago

That may just be a frontend problem for what the +/- buttons do. Are the buttons supposed to change temperature?

kpine commented 3 years ago

Yes, the buttons set the temperature individually, using the set_temperature service call (from my understanding of the frontend code). I wonder if the frontend is getting confused and the hvac mode setting is getting triggered?

I tested this on my mode-based thermostat, and clicking on the arrow sends the expected set_temperature call, with only the temperature set.

2021-03-12 10:44:17 INFO (MainThread) [homeassistant.components.zwave_js.climate] In async_set_temperature, kwargs = {'temperature': 68.0, 'entity_id': ['climate.z_wave_thermostat']}

No service calls for async_set_hvac mode are seen unless I change it.

gsemet commented 3 years ago

So, if it only comes from the UI button, how do we do to avoid calling the set_hvac_mode service when only dealing with the + or - buttons?

Can't it comes from zwave_js/climate.py#L377 ?

        if hvac_mode is not None:
            await self.async_set_hvac_mode(hvac_mode)

I feel like the information coming from the UI get a default "mode" value (here "Heating", because we see the UI shows a mode dropbox), so this test is indeed not None, so it tries to set the mode and it crashes later because if not self._current_mode: is not set (because this is not a device that can change the mode).

kpine commented 3 years ago

If I understand the frontend code correctly, when you change the temperature, the service call from the frontend doesn't specify hvac mode, it only sets the temperature:

  private _targetTemperatureChanged(ev) {
    const newVal = ev.target.value;
    this._callServiceHelper(
      this.stateObj!.attributes.temperature,
      newVal,
      "set_temperature",
      { temperature: newVal }
    );
  }

Unless the async await affects the stack trace, your trace above doesn't show async_set_temperature in the call stack, it looks like it's directly invoking async_set_hvac_mode from the service handler.

  File "/usr/src/homeassistant/homeassistant/helpers/service.py", line 679, in _handle_entity_call
    await result
  File "/usr/src/homeassistant/homeassistant/components/zwave_js/climate.py", line 399, in async_set_hvac_mode
    raise ValueError(
ValueError: Thermostat climate.main_heater_thermostat_main does not support setting a mode

If you can edit the source code (directly or via a custom component) you could confirm with some logging calls.

Based on those assumptions, I thought that the frontend might be setting the hvac mode mistakenly. I'm not sure how that would happen though. I added logging to set_hvac_mode and it was not invoked for me when only changing the temperature.

gsemet commented 3 years ago

Hello. i still think as well the frontend trigger hvac mode my mistake, because service works. I manage with the scheduler widget to change the temperature based on time, but it is a little bit annoying not to be able to change it with the widget.

Isn't something to do in order to have the widget not displaying these mode and preset that is not relevant to this device?

Screenshot 2021-03-19 at 10 55 00

Maybe this will have the widget not wanting to change mode.

gsemet commented 3 years ago

So it looks fixed in 2021.4.0. I now have the ability to change the setpoint throught the UI and service, and no exception is raised whatsoever ^^