Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[Bug]: Climate sets HVACAction.HEATING with euristic set up also when the flame in the device is not shown #502

Closed
3 tasks
andeb91 opened this issue Jan 21, 2025 · 25 comments
Labels
bug Something isn't working

Comments

@andeb91
Copy link

andeb91 commented Jan 21, 2025

LocalTuya Version

2025.1.1

Home Assistant Version

2025.1.3

Environment

  • Does the device work using the Home Assistant Tuya Cloud component?
  • Is this device connected to another local integration, including Home Assistant and any other tools?
  • The devices are within the same HA subnet, and they get discovered automatically when I add them

What happened?

With euristic option checked, climate sets HVACAction.HEATING also when the flame in the device is not shown. In the past versions, the action perfectly followed the flame.

Steps to reproduce.

I have already the devices added. If I set the target temperature 0.5°C more than the actual temperature the climate sets HVACAction.HEATING as action but the device doesn't show the flame icon.

Relevant log output

Diagnostics information.

No response

@andeb91 andeb91 added the bug Something isn't working label Jan 21, 2025
xZetsubou added a commit that referenced this issue Jan 21, 2025
related #502

---------

Co-authored-by: Bander <46300268+xZetsubou@users.noreply.github.com>
@xZetsubou xZetsubou added the master/next-release Fixed in master branch, Will be ready in the next release label Jan 21, 2025
@mmxxmm
Copy link

mmxxmm commented Jan 22, 2025

My heater shows the flame on the device when current temperature drops below the target temperature - 1 and the flame disappears when current temperature raises over target temperature. Is it the same as yours? It has the current temperature precision 0.1 and target temperature precision 1.

@andeb91
Copy link
Author

andeb91 commented Jan 22, 2025

@xZetsubou I've tried the branch but it continues not working as expected.

@mmxxmm yes, more or less is the same, except for the precisions, both 0.5

@mmxxmm
Copy link

mmxxmm commented Jan 22, 2025

I think the reason for the device to turn on the heater when the current temperature drops below the target temperature - target precision (for me it's 1 degree) is because it avoids frequently turn on/off the heater.

@mmxxmm
Copy link

mmxxmm commented Jan 22, 2025

@andeb91 You can observe your device to see when the flame icon shows. If your target and current temperature precision is both 0.5 degree and you set your target temperature 0.5 more than the current temperature the icon still doesn't show, Maybe you can try set the target temperature 1 degree more than current? The temperature difference to turn on the heater maybe more than 0.5.

@andeb91
Copy link
Author

andeb91 commented Jan 22, 2025

@mmxxmm I can try doing this.
in the meanwhile I fixed keeping the previous HVACAction in the LocalTuyaClimate class. I introduced the variable in the class and used it in the hvac_action() function
if hvac_mode == HVACMode.HEAT: if current_temperature < precision_target_diff: hvac_action = HVACAction.HEATING if precision_current_diff > target_temperature: hvac_action = HVACAction.IDLE if ( current_temperature == precision_target_diff and (previous_hvac_action := self._previous_hvac_action) is not None ): if previous_hvac_action == HVACAction.HEATING: hvac_action = HVACAction.HEATING if previous_hvac_action == HVACAction.IDLE: hvac_action = HVACAction.IDLE

and added at the end of this function

self._previous_hvac_action = hvac_action

@xZetsubou
Copy link
Owner

I haven't made any changes related to this feature nor I actually fully understand yet especially precision diff part, I know kinda how it works? can you post your device diagnostics

You mentioned this were working for you fine? if so which version you meant because as I mentioned no changes made into this.

Also I would be happy if you guys explained this for me more because from what I understand from code, this feature works as:

  • If target temp > current temp = it's heating
  • if target temp < current temp = it's idle?
  • what if it's equal? then it should remain to the last state.

There is a test you may want to do in line 353 add elif instead of if

                # if precision_current_diff > target_temperature:
                #    hvac_action = HVACAction.IDLE

                elif precision_current_diff > target_temperature:
                    hvac_action = HVACAction.IDLE

@mmxxmm
Copy link

mmxxmm commented Jan 23, 2025

I haven't made any changes related to this feature nor I actually fully understand yet especially precision diff part, I know kinda how it works? can you post your device diagnostics

You mentioned this were working for you fine? if so which version you meant because as I mentioned no changes made into this.

Also I would be happy if you guys explained this for me more because from what I understand from code, this feature works as:

  • If target temp > current temp = it's heating
  • if target temp < current temp = it's idle?
  • what if it's equal? then it should remain to the last state.

There is a test you may want to do in line 353 add elif instead of if

            # if precision_current_diff > target_temperature:
            #    hvac_action = HVACAction.IDLE

            elif precision_current_diff > target_temperature:
                hvac_action = HVACAction.IDLE

On my heater device it works as follow:

  • If target temp - 1 > current temp = it's heating
  • if target temp < current temp = it's idle

My device has a current temperature precision of 0.1 degree and target temperature precision of 1 degree.
The reason behind this is it avoids frequently turn on/off the heater.

The device will show a flame icon when it's heating, but will not report this state to any DPs. so we need to set the HVACAction based on the the current/target temperature of the device(so-called heuristic).

@xZetsubou
Copy link
Owner

Currently this feature function according to your config with 0.1 precision, and assuming both current/target temp is 20.

  • target minus precision (20 - 0.1) 19.9 > current temp raw 20 = heating no?
  • target raw 20 > current plus precision (20 + 0.1) 20.1 = idle no?

This should be heating icon "in HA at least" unless you are talking about flame icon on the device it self and this device start heating when current temperature below target by at least 1

Keep in mind this feature uses only current temp precision for both current/target.

Again can you post your device diagnostics so I can see the values of your DPS :)

note: the target precision and precision are used to scale the value of the target DP and current DP, however it seems precision is used for heuristic as well

@mmxxmm
Copy link

mmxxmm commented Jan 23, 2025

I think the heating icon (HVAC Action) on HA should be consistent with the heating status(flame icon) on the device it self.
On my device it starts heating when current temperature below target by at least 1, and goes to idle when current temperature >=target. For me the target precision is 1 so I change line 347 to
precision_target_diff = target_temperature - self._precision_target
to get it work.

I'm not sure if other devices have different logic.

Please look into the device diagnostics
ufh.json

The following are the DP Specs from Tuya cloud platform.
[
{
"dpId": 16,
"dpName": "Set temperature"
},
{
"dpId": 1,
"dpName": "Switch"
},
{
"dpId": 2,
"dpName": "Mode"
},
{
"dpId": 24,
"dpName": "Current temperature"
},
{
"dpId": 40,
"dpName": "Child lock"
},
{
"dpId": 30,
"dpName": "Weekly procedure (working day)"
},
{
"dpId": 31,
"dpName": "Working day setting"
}
]

@xZetsubou
Copy link
Owner

xZetsubou commented Jan 23, 2025

Was this intentional to have both self._precision to be fair this logic looks weird to me :) it's not like having self._precision_target or self._precision would makes any difference here your because these two are using to scale factor the temperature not for heuristic feature and somehow it used there? for me both of them doesn't makes sense :) and having 0.5 or 1 as diff.

To be clear from your device DP data it seems the values of Current/Target temperature are Integer not Float this might be why it didn't works for you at start.

can you test this code block paste from line 342

        if (
            self._config.get(CONF_HEURISTIC_ACTION)
            and (target_temperature := self._target_temperature) is not None
            and (current_temperature := self._current_temperature) is not None
        ):
            precision = 0.5 if isinstance(current_temperature, float) else 1
            precision_target_diff = target_temperature - precision
            precision_current_diff = current_temperature + precision

            if hvac_mode == HVACMode.HEAT:
                if current_temperature < precision_target_diff:
                    hvac_action = HVACAction.HEATING
                if precision_current_diff > target_temperature:
                    hvac_action = HVACAction.IDLE
            if hvac_mode == HVACMode.COOL:
                if current_temperature > precision_target_diff:
                    hvac_action = HVACAction.COOLING
                if precision_current_diff < target_temperature:
                    hvac_action = HVACAction.IDLE
            if hvac_mode == HVACMode.HEAT_COOL:
                if current_temperature < precision_target_diff:
                    hvac_action = HVACAction.HEATING
                if current_temperature == precision_target_diff:
                    hvac_action = HVACAction.IDLE
                if precision_current_diff > target_temperature:
                    hvac_action = HVACAction.COOLING
            if hvac_mode == HVACMode.DRY:
                hvac_action = HVACAction.DRYING
            if hvac_mode == HVACMode.FAN_ONLY:
                hvac_action = HVACAction.FAN

@andeb91 andeb91 closed this as completed Jan 23, 2025
@andeb91
Copy link
Author

andeb91 commented Jan 23, 2025

I haven't made any changes related to this feature nor I actually fully understand yet especially precision diff part, I know kinda how it works? can you post your device diagnostics

You mentioned this were working for you fine? if so which version you meant because as I mentioned no changes made into this.

Also I would be happy if you guys explained this for me more because from what I understand from code, this feature works as:

  • If target temp > current temp = it's heating
  • if target temp < current temp = it's idle?
  • what if it's equal? then it should remain to the last state.

There is a test you may want to do in line 353 add elif instead of if

            # if precision_current_diff > target_temperature:
            #    hvac_action = HVACAction.IDLE

            elif precision_current_diff > target_temperature:
                hvac_action = HVACAction.IDLE

My thermostates (but I think more or less all thermostates), to avoid frequent on/off of the heater, work with an hysteresis, so:

  • start heating when the current temperature is 1 degree less of target temperature (if target temperature is 20°, they start heating when current temperature is 19°)
  • stop heating when current temperature is equal to target temperature (if target temperature is 20°, they stop heating when current temperature is 20°)
  • for middle temperatures they keep the previous state (if current temperature is 19.5°, if previous temperature was 20° [so they weren't heating] they keep not heating, but if previous temperature was 19° [so they were heating] they keep heating)

@mmxxmm precision_target and precision values are used to scale correctly the values from the device DP data (to be more clear, in my case I have both precisions equal to 0.5 and in DP data current_temperature and target_temperature (both integers) I always receive numbers that are twice the real value and I have to use precision values to scale them correctly (I set a target temperature in the thermostat equal to 20 and I read in the DP data 40)

The device will show a flame icon when it's heating, but will not report this state to any DPs. so we need to set the HVACAction based on the the current/target temperature of the device(so-called heuristic).

For me it is not only an aesthetic question because I use home assistant (accordingly with 5 different thermostates) to turn on and off my heat pump but every single thermostat open/close the valve for the related room heating system.

@andeb91 andeb91 reopened this Jan 23, 2025
@mmxxmm
Copy link

mmxxmm commented Jan 23, 2025

@andeb91 It seems your thermostats works the same as mine, except the precisions. I also use one thermostat per room to control the valve for the water heating pipelines for each room. So I think we should introduce the previous_hvac_action as you did and ignore the precision staff like the following:

if (
            self._config.get(CONF_HEURISTIC_ACTION)
            and (target_temperature := self._target_temperature) is not None
            and (current_temperature := self._current_temperature) is not None
        ):
            if hvac_mode == HVACMode.HEAT:
                if current_temperature < target_temperature - 1:
                    hvac_action = HVACAction.HEATING
                elif current_temperature >= target_temperature:
                    hvac_action = HVACAction.IDLE
                else:
                    hvac_action = self._previous_hvac_action
            if hvac_mode == HVACMode.COOL:
                if current_temperature > target_temperature + 1:
                    hvac_action = HVACAction.COOLING
                if current_temperature <= target_temperature:
                    hvac_action = HVACAction.IDLE
            if hvac_mode == HVACMode.HEAT_COOL:
                if current_temperature < target_temperature - 1:
                    hvac_action = HVACAction.HEATING
                if current_temperature == target_temperature:
                    hvac_action = HVACAction.IDLE
                if current_temperature > target_temperature:
                    hvac_action = HVACAction.COOLING
            if hvac_mode == HVACMode.DRY:
                hvac_action = HVACAction.DRYING
            if hvac_mode == HVACMode.FAN_ONLY:
                hvac_action = HVACAction.FAN
           self._previous_hvac_action = hvac_action

@xZetsubou
Copy link
Owner

xZetsubou commented Jan 23, 2025

@andeb91 I know how now it works and again still not sure why It uses precision to calculate that. the current method does exactly as you said.

You know what I think I may know what breaking this logic, can you remove the code above line 342
this one below remove it it should exists above CONF_HEURISTIC_ACTION check

        if not self._conf_hvac_action_dp:
            if hvac_mode == HVACMode.COOL:
                hvac_action = HVACAction.COOLING
            if hvac_mode == HVACMode.HEAT:
                hvac_action = HVACAction.HEATING
            if hvac_mode == HVACMode.DRY:
                hvac_action = HVACAction.DRYING
            if hvac_mode == HVACMode.FAN_ONLY:
                hvac_action = HVACAction.FAN

@mmxxmm
Copy link

mmxxmm commented Jan 23, 2025

@andeb91 The original code in https://github.com/rospogrigio/localtuya/blob/master/custom_components/localtuya/climate.py is

     if self._current_temperature < (
                         self._target_temperature - self._precision
                     ):
                         self._hvac_action = HVACAction.HEATING

in your case self._precision = 0.5, but you said it starts heating when the current temperature is 1 degree less of target temperature.
It's not consistent with how the device works.

@xZetsubou
Copy link
Owner

xZetsubou commented Jan 23, 2025

Yes using precision doesn't matter to be fair any number from 0.1 to 1 would works.

Now why did this works for @andeb91 and probably for other uses before and would works for @mmxxmm as well it's because the device reports the current temperature on whole numbers which means it will always be 20 until it drops by 1 then it will reports 19 so this means the diff for 0.1, 0.5, 1 are the same and will use last ACTION until current temperature drops by 1

@mmxxmm
Copy link

mmxxmm commented Jan 24, 2025

Yes using precision doesn't matter to be fair any number from 0.1 to 1 would works.

Now why did this works for @andeb91 and probably for other uses before and would works for @mmxxmm as well it's because the device reports the current temperature on whole numbers which means it will always be 20 until it drops by 1 then it will reports 19 so this means the diff for 0.1, 0.5, 1 are the same and will use last ACTION until current temperature drops by 1

@xZetsubou The current temperature variable is not always whole numbers. in the status_updated event:

if self.has_config(CONF_CURRENT_TEMPERATURE_DP) and (
            current_dp_temp := self.dp_value(CONF_CURRENT_TEMPERATURE_DP)
        ):
            self._current_temperature = current_dp_temp * self._precision

In my posted device diagnostics the reported value is 168 and precision is 0.1, 168*0.1=16.8. It can be float numbers.

@xZetsubou
Copy link
Owner

I think your issue is due to the fact the target is scaled 1 and current is scaled 0.1 I assumes the feature made with both of them has the same scale in mind., I wonder if your device @mmxxmm round it to 17 or does it shows 16.8.

either way what If we refactored this to this and took 1 difference instead since this function.

        if (
            (self._config.get(CONF_HEURISTIC_ACTION) or not self._conf_hvac_action_dp)
            and (target_temperature := self._target_temperature) is not None
            and (current_temperature := self._current_temperature) is not None
        ):
            # This function assumes that action changes if target is "1" different from current.
            target_current_diff = current_temperature - target_temperature
            device_react_diff = 1

            if hvac_mode == HVACMode.HEAT:
                if target_current_diff > device_react_diff:
                    hvac_action = HVACAction.HEATING
                elif target_current_diff < device_react_diff:
                    hvac_action = HVACAction.IDLE
            elif hvac_mode == HVACMode.COOL:
                if target_current_diff > device_react_diff:
                    hvac_action = HVACAction.COOLING
                elif target_current_diff < device_react_diff:
                    hvac_action = HVACAction.IDLE
            elif hvac_mode == HVACMode.HEAT_COOL:
                if current_temperature < device_react_diff:
                    hvac_action = HVACAction.HEATING
                elif target_current_diff > device_react_diff:
                    hvac_action = HVACAction.COOLING
                elif current_temperature == target_temperature:
                    hvac_action = HVACAction.IDLE
            elif hvac_mode == HVACMode.DRY:
                hvac_action = HVACAction.DRYING
            elif hvac_mode == HVACMode.FAN_ONLY:
                hvac_action = HVACAction.FAN

@andeb91
Copy link
Author

andeb91 commented Jan 24, 2025

@andeb91 The original code in https://github.com/rospogrigio/localtuya/blob/master/custom_components/localtuya/climate.py is

     if self._current_temperature < (
                         self._target_temperature - self._precision
                     ):
                         self._hvac_action = HVACAction.HEATING

in your case self._precision = 0.5, but you said it starts heating when the current temperature is 1 degree less of target temperature. It's not consistent with how the device works.

Sorry for the late reply but I was out for work.

@mmxxmm I don't remember which version of the old local_tuya component I had, because when something works fine, I don't always update it as soon as a new version is released. Maybe it was a one or two years old version....

@xZetsubou I tried your code below but it continues not working for my thermostats. My precision is 0.5 for both temperatures (current and target)

I think your issue is due to the fact the target is scaled 1 and current is scaled 0.1 I assumes the feature made with both of them has the same scale in mind., I wonder if your device @mmxxmm round it to 17 or does it shows 16.8.

either way what If we refactored this to this and took 1 difference instead since this function.

    if (
        (self._config.get(CONF_HEURISTIC_ACTION) or not self._conf_hvac_action_dp)
        and (target_temperature := self._target_temperature) is not None
        and (current_temperature := self._current_temperature) is not None
    ):
        # This function assumes that action changes if target is "1" different from current.
        target_current_diff = current_temperature - target_temperature
        device_react_diff = 1

        if hvac_mode == HVACMode.HEAT:
            if target_current_diff > device_react_diff:
                hvac_action = HVACAction.HEATING
            elif target_current_diff < device_react_diff:
                hvac_action = HVACAction.IDLE
        elif hvac_mode == HVACMode.COOL:
            if target_current_diff > device_react_diff:
                hvac_action = HVACAction.COOLING
            elif target_current_diff < device_react_diff:
                hvac_action = HVACAction.IDLE
        elif hvac_mode == HVACMode.HEAT_COOL:
            if current_temperature < device_react_diff:
                hvac_action = HVACAction.HEATING
            elif target_current_diff > device_react_diff:
                hvac_action = HVACAction.COOLING
            elif current_temperature == target_temperature:
                hvac_action = HVACAction.IDLE
        elif hvac_mode == HVACMode.DRY:
            hvac_action = HVACAction.DRYING
        elif hvac_mode == HVACMode.FAN_ONLY:
            hvac_action = HVACAction.FAN

It is not working because I'm pretty sure you exchange the temperature in

        target_current_diff = current_temperature - target_temperature

By the way also if you correct this into

        target_current_diff = target_temperature - current_temperature

It is not working as expected surely for the middle temperatures. I give you an example to try to be clear:

Imagine to have a target_temperature = 20°
In the room there is a current_temperature of 18° and the heater is on; it heats and the temperature increases to 18.5°, then 19°, the 19.5° until it reaches 20° (target_temperature) and the heater turns to off.
Then time passes and the temperature starts decreasing and passes from 20° to 19.5° but for the hysteresis of 1° the heater continues being off until the temperature decreases more and reaches 19° and finally the heater turns on.

For my opinion the best things is to introduce also the device_react_diff in climate configuration (as the other parameters and to complain with other thermostats that can have different hysterisis values) and then use the previous_hvac_action in this way:

  • if current_temperature >= target_temperature -> hvac_action = HVACAction.IDLE
  • elif current_temperature <= target_temperature - device_react_diff -> hvac_action = HVACAction.HEATING
  • else -> hvac_action = previous_hvac_action

then using the same logic it is possible also to fix for HVACMode.COOL and HVACMode.HEAT_COOL

I never wrote a ha custom component but if I can help you in some way, please let me know.

@mmxxmm
Copy link

mmxxmm commented Jan 24, 2025

I think your issue is due to the fact the target is scaled 1 and current is scaled 0.1 I assumes the feature made with both of them has the same scale in mind., I wonder if your device @mmxxmm round it to 17 or does it shows 16.8.

either way what If we refactored this to this and took 1 difference instead since this function.

    if (
        (self._config.get(CONF_HEURISTIC_ACTION) or not self._conf_hvac_action_dp)
        and (target_temperature := self._target_temperature) is not None
        and (current_temperature := self._current_temperature) is not None
    ):
        # This function assumes that action changes if target is "1" different from current.
        target_current_diff = current_temperature - target_temperature
        device_react_diff = 1

        if hvac_mode == HVACMode.HEAT:
            if target_current_diff > device_react_diff:
                hvac_action = HVACAction.HEATING
            elif target_current_diff < device_react_diff:
                hvac_action = HVACAction.IDLE
        elif hvac_mode == HVACMode.COOL:
            if target_current_diff > device_react_diff:
                hvac_action = HVACAction.COOLING
            elif target_current_diff < device_react_diff:
                hvac_action = HVACAction.IDLE
        elif hvac_mode == HVACMode.HEAT_COOL:
            if current_temperature < device_react_diff:
                hvac_action = HVACAction.HEATING
            elif target_current_diff > device_react_diff:
                hvac_action = HVACAction.COOLING
            elif current_temperature == target_temperature:
                hvac_action = HVACAction.IDLE
        elif hvac_mode == HVACMode.DRY:
            hvac_action = HVACAction.DRYING
        elif hvac_mode == HVACMode.FAN_ONLY:
            hvac_action = HVACAction.FAN

My device shows 16.8 on screen. The above code will not work. target_current_diff = current_temperature - target_temperature, If current_temperature < target_temperature it will return negative value therefore will not set hvac_action = HVACAction.HEATING and IDLE state cannot be simply be determined using the target_current_diff, for example current_temperature = 18.9 , target temperature = 20, the difference is 1.1. The heater turned on , after a while the temperature raised to 19.2 which the difference is now 0.8, but the heater will keep working until the current_temperature >= target_temperature. so we should probably change state like this

           if hvac_mode == HVACMode.HEAT:
                if current_temperature < target_temperature - 1:
                    hvac_action = HVACAction.HEATING
                elif current_temperature >= target_temperature:
                    hvac_action = HVACAction.IDLE
                else:
                    hvac_action = self._previous_hvac_action 

@xZetsubou
Copy link
Owner

xZetsubou commented Jan 24, 2025

what's the point of this "hvac_action = self._previous_hvac_action" to be clear both condition fails it will stays on the previous HVAC action since it did not changed! however this #502 (comment) were breaking the logic of previous HVAC action so removing that should fix!

with your code current_temperature < target_temperature - 1 means if current is 19 and target is 20 will stay idle even tho it should be heating no? it should be <= instead unless device react when it actually lower then 1 not equal.

I made fixes to this it should handle other modes as well.

        if (
            (self._config.get(CONF_HEURISTIC_ACTION) or not self._conf_hvac_action_dp)
            and (target_temperature := self._target_temperature) is not None
            and (current_temperature := self._current_temperature) is not None
        ):
            # This function assumes that action changes if target is "1" different from current.
            target_react_diff = target_temperature - 1

            if hvac_mode == HVACMode.HEAT:
                if current_temperature <= target_react_diff:
                    hvac_action = HVACAction.HEATING
                elif current_temperature >= target_temperature:
                    hvac_action = HVACAction.IDLE
            elif hvac_mode == HVACMode.COOL:
                if current_temperature <= target_react_diff:
                    hvac_action = HVACAction.COOLING
                elif current_temperature >= target_temperature:
                    hvac_action = HVACAction.IDLE
            elif hvac_mode == HVACMode.HEAT_COOL:
                if current_temperature <= target_react_diff:
                    hvac_action = HVACAction.HEATING
                elif current_temperature > target_temperature:
                    hvac_action = HVACAction.COOLING
                elif current_temperature == target_temperature:
                    hvac_action = HVACAction.IDLE
            elif hvac_mode == HVACMode.DRY:
                hvac_action = HVACAction.DRYING
            elif hvac_mode == HVACMode.FAN_ONLY:
                hvac_action = HVACAction.FAN
Tests

Test current 20 to 19

        ----------------------------------------------------
        target_react_diff is: 19
        current_temperature: 20
        target_temperature: 20
        Action results: idle
        ----------------------------------------------------
        

        ----------------------------------------------------
        target_react_diff is: 19
        current_temperature: 19.9
        target_temperature: 20
        Action results: idle
        ----------------------------------------------------
        

        ----------------------------------------------------
        target_react_diff is: 19
        current_temperature: 19.8
        target_temperature: 20
        Action results: idle
        ----------------------------------------------------
        

        ----------------------------------------------------
        target_react_diff is: 19
        current_temperature: 19.7
        target_temperature: 20
        Action results: idle
        ----------------------------------------------------
        

        ----------------------------------------------------
        target_react_diff is: 19
        current_temperature: 19.6
        target_temperature: 20
        Action results: idle
        ----------------------------------------------------
        

        ----------------------------------------------------
        target_react_diff is: 19
        current_temperature: 19.5
        target_temperature: 20
        Action results: idle
        ----------------------------------------------------
        

        ----------------------------------------------------
        target_react_diff is: 19
        current_temperature: 19.4
        target_temperature: 20
        Action results: idle
        ----------------------------------------------------
        

        ----------------------------------------------------
        target_react_diff is: 19
        current_temperature: 19.3
        target_temperature: 20
        Action results: idle
        ----------------------------------------------------
        

        ----------------------------------------------------
        target_react_diff is: 19
        current_temperature: 19.2
        target_temperature: 20
        Action results: idle
        ----------------------------------------------------
        

        ----------------------------------------------------
        target_react_diff is: 19
        current_temperature: 19.1
        target_temperature: 20
        Action results: idle
        ----------------------------------------------------
        

        ----------------------------------------------------
        target_react_diff is: 19
        current_temperature: 19.0
        target_temperature: 20
        Action results: heating
        ----------------------------------------------------
        

Test Current went 19 to 20

        ----------------------------------------------------
        target_react_diff is: 19
        current_temperature: 19
        target_temperature: 20
        Action results: heating
        ----------------------------------------------------
        

        ----------------------------------------------------
        target_react_diff is: 19
        current_temperature: 19.1
        target_temperature: 20
        Action results: heating
        ----------------------------------------------------
        

        ----------------------------------------------------
        target_react_diff is: 19
        current_temperature: 19.2
        target_temperature: 20
        Action results: heating
        ----------------------------------------------------
        

        ----------------------------------------------------
        target_react_diff is: 19
        current_temperature: 19.3
        target_temperature: 20
        Action results: heating
        ----------------------------------------------------
        

        ----------------------------------------------------
        target_react_diff is: 19
        current_temperature: 19.4
        target_temperature: 20
        Action results: heating
        ----------------------------------------------------
        

        ----------------------------------------------------
        target_react_diff is: 19
        current_temperature: 19.5
        target_temperature: 20
        Action results: heating
        ----------------------------------------------------
        

        ----------------------------------------------------
        target_react_diff is: 19
        current_temperature: 19.6
        target_temperature: 20
        Action results: heating
        ----------------------------------------------------
        

        ----------------------------------------------------
        target_react_diff is: 19
        current_temperature: 19.7
        target_temperature: 20
        Action results: heating
        ----------------------------------------------------
        

        ----------------------------------------------------
        target_react_diff is: 19
        current_temperature: 19.8
        target_temperature: 20
        Action results: heating
        ----------------------------------------------------
        

        ----------------------------------------------------
        target_react_diff is: 19
        current_temperature: 19.9
        target_temperature: 20
        Action results: heating
        ----------------------------------------------------
        

        ----------------------------------------------------
        target_react_diff is: 19
        current_temperature: 20.0
        target_temperature: 20
        Action results: idle
        ----------------------------------------------------

@mmxxmm
Copy link

mmxxmm commented Jan 25, 2025

@xZetsubou You are absolutely correct. We don't need to handle not self._conf_hvac_action_dp separately. Removing that code block will make it work.
For the case current_temperature = target_react_diff the heater will still not turn on my device. only when current_temperature < target_react_diff. For the cooling case, It should be current_temperature > target_temperature + 1.
It would better if we can customize the hysteresis differential, maybe some devices' hysteresis differential is not 1 or even don't have it.

@xZetsubou
Copy link
Owner

maybe some devices' hysteresis differential

I think this related to target temperature STEP? if step is whole number 1 then for sure the device react to "1" otherwise, If it's possible to set decimal numbers then the device also do that as well. so we may use target_temperature - self.target_temperature_step instead.

@mmxxmm
Copy link

mmxxmm commented Jan 25, 2025

maybe some devices' hysteresis differential

I think this related to target temperature STEP? if step is whole number 1 then for sure the device react to "1" otherwise, If it's possible to set decimal numbers then the device also do that as well. so we may use target_temperature - self.target_temperature_step instead.

There is a Generic Thermostat Integration in HA. It has separate cold_tolerance and hot_tolerance configurations which is different from target_temp_step.

@xZetsubou
Copy link
Owner

That's a helper entity, you can create it from HA UI, For now I will assume that device action depends of temperature step.

Copy link

This issue was closed because it was resolved on the release: 2025.2.0

@github-actions github-actions bot added stale and removed master/next-release Fixed in master branch, Will be ready in the next release stale labels Jan 31, 2025
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
bug Something isn't working
Projects
None yet
Development

No branches or pull requests

3 participants