Koenkk / zigbee2mqtt

Zigbee 🐝 to MQTT bridge 🌉, get rid of your proprietary Zigbee bridges 🔨
https://www.zigbee2mqtt.io
GNU General Public License v3.0
11.77k stars 1.64k forks source link

TS0601_thermostat calibration does not support negative values #4590

Closed henrikwils closed 3 years ago

henrikwils commented 3 years ago

What happened

TS0601_thermostat calibration does not support negative values

What did you expect to happen

Setting negative value to calibrate in negative direction.

How to reproduce it (minimal and precise)

Trying to set calibration with i.e.:

topic: zigbee2mqtt/FRIENDLY_NAME/set/local_temperature_calibration payload: -6.0

The set temperature responds as if it was a positive value. Checking the confirmation MQTT message, shows that the value is indeed positive.

Received 9:59:49 PM QoS: 0 Payload: auto_lock: MANUAL away_preset_days: 1 away_preset_temperature: 15 boost_time: 300 child_lock: UNLOCKED comfort_temperature: 20 current_heating_setpoint: '22.5' eco_temperature: 15 force: normal holidays:

Debug info

Zigbee2MQTT version: 1.15.0 Adapter hardware: CC26X2R1 Adapter firmware version: 20191106

artem-sedykh commented 3 years ago

I will add an error log: Publish 'set' 'local_temperature_calibration' to 'tvr_test' failed: 'RangeError [ERR_OUT_OF_RANGE]: Command 0xbc33acfffe571ef9/1 manuSpecificTuyaDimmer.setData({"status":0,"transid":196,"dp":556,"fn":0,"data":[4,0,0,0,-10]}, {"timeout":10000,"disableResponse":false,"disableRecovery":false,"disableDefaultResponse":true,"direction":0,"srcEndpoint":null,"reservedBits":0,"manufacturerCode":null,"transactionSequenceNumber":null}) failed (The value of "value" is out of range. It must be >= 0 and <= 255. Received -10)' Zigbee2MQTT:debug 2020-10-11 14:24:11: RangeError [ERR_OUT_OF_RANGE]: The value of "value" is out of range. It must be >= 0 and <= 255. Received -10 at writeU_Int8 (internal/buffer.js:729:11) at Buffer.writeUInt8 (internal/buffer.js:739:10) at BuffaloZcl.writeUInt8 (/app/node_modules/zigbee-herdsman/dist/buffalo/buffalo.js:30:21) at BuffaloZcl.writeListUInt8 (/app/node_modules/zigbee-herdsman/dist/buffalo/buffalo.js:157:18) at BuffaloZcl.write (/app/node_modules/zigbee-herdsman/dist/buffalo/buffalo.js:247:18) at BuffaloZcl.write (/app/node_modules/zigbee-herdsman/dist/zcl/buffaloZcl.js:303:26) at ZclFrame.writePayloadCluster (/app/node_modules/zigbee-herdsman/dist/zcl/zclFrame.js:144:21) at ZclFrame.toBuffer (/app/node_modules/zigbee-herdsman/dist/zcl/zclFrame.js:74:18) at ZStackAdapter.<anonymous> (/app/node_modules/zigbee-herdsman/dist/adapter/z-stack/adapter/zStackAdapter.js:307:163) at Generator.next (<anonymous>)

danieledwardgeorgehitchcock commented 3 years ago

I am pretty sure that the temperature calibration parameter should be set at the actual temperature of the room rather than an offset thereof. This way, the sensor automatically calculates the offset be it positive, or negative.

henrikwils commented 3 years ago

I was pretty sure about that as well, but it DOESN'T WORK THAT WAY! If you set that temperature, it just adds it to the current measured value. Otherwise, I wouldn't have spent hours trying to figure it out, and never made this bug report.

danieledwardgeorgehitchcock commented 3 years ago

Apologies for trying to help - you did not mention in your OP, anything about trying this approach hence, my suggestion. At least people now know to rule it out of their diagnoses and prevent further abrupt replies!

I was pretty sure about that as well, but it DOESN'T WORK THAT WAY! If you set that temperature, it just adds it to the current measured value. Otherwise, I wouldn't have spent hours trying to figure it out, and never made this bug report.

henrikwils commented 3 years ago

It looks like you even have it - Why don't you try it to see what you get? Could be there are different models that behave differently? I know I have one thermostat, that doesn't play well with Z2M at all.

bkupidura commented 3 years ago

@henrikwils indeed looks like its offset, not target temperature. Looks like valve is working in 0-100 degrees range (at least in Celsius).

So if thermostat is showing current temp as ex. 25, and you want to change it to 20, just send 94 (100-25+20-1). Im not sure if this is expected (im almost sure that its not :)). But, looks like it works.

insipiens commented 3 years ago

@henrikwils This was mentioned in #3821

A small change to your code should solve it in the toZigbee.js file located here: /opt/zigbee2mqtt/node_modules/zigbee-herdsman-converters/converters/toZigbee.js

add the line: if (value < 0) value = 4096 + value;

    moes_thermostat_calibration: {
        key: ['local_temperature_calibration'],
        convertSet: async (entity, key, value, meta) => {
            if (value < 0) value = 4096 + value;
            const payloadValue = utils.convertDecimalValueTo2ByteHexArray(value);
            sendTuyaCommand(entity, 539, 0, [4, 0, 0, ...payloadValue]);
        },
    },

if 4096 doesn't work try 128

If that fails raise a question in #3821 someone there will have solved it.

github-actions[bot] commented 3 years ago

This issue is stale because it has been open 30 days with no activity. Remove stale label or comment or this will be closed in 7 days

Quapcio commented 3 years ago

couple minutes ago I managed to set negative value of local temperature compensation you shuld set value for 256 - [negative value to set]

-1 -> 255 -9 -> 247

it looks like the variable use unsigned char instead of signed char but it's more complicated, bebause fractional numers are accepted resulting in negitive numer rounded to 0.5 degree.

Quapcio commented 3 years ago

maybe rather (256 + [negtive number to set]) % 256 to be more precise...

un1te commented 3 years ago

I found new solution for calibration. I noticed that if thermostat already has calibration value ayou need to calibrate it calibration always worn. So need first to set calibration to 128 (=0) the delay several seconds, then set new value.

It works fine for me now

so my automation is:

- alias: Calibrate thermostat child
  trigger:
    - platform: state
      entity_id: sensor.temp_child_temperature
  action:
    - service: mqtt.publish
      data:
        topic: 'zigbee2mqtt/thermo_child/set/local_temperature_calibration'
        payload: 128
    - delay: '00:00:03'
    - service: mqtt.publish
      data_template:
        topic: 'zigbee2mqtt/thermo_child/set/local_temperature_calibration'
        payload_template: >-
          {% if states('sensor.temp_child_temperature')|float - state_attr('climate.thermo_child_climate', 'current_temperature')|float >= 0.5 %}
            {{ 128 + (states('sensor.temp_child_temperature')|float - state_attr('climate.thermo_child_climate', 'current_temperature')|float) | round (1) }}
          {% elif states('sensor.temp_child_temperature')|float - state_attr('climate.thermo_child_climate', 'current_temperature')|float <= (-0.5) %}
            {{ 128 - (state_attr('climate.thermo_child_climate', 'current_temperature')|float - states('sensor.temp_child_temperature')|float) | round (1)}}
          {% endif %}
avdept commented 2 years ago

I was able to set negative values via z2m UI. Just had to use arrows next to input field to set it below 0

Stooovie commented 7 months ago

Could we get a larger offset than +- 3C? Mine is off by 5C (lower than actual). Clicking the +- buttons nor manual entry work.