smartHomeHub / SmartIR

Integration for Home Assistant to control climate, TV and fan devices via IR/RF controllers (Broadlink, Xiaomi, MQTT, LOOKin, ESPHome)
MIT License
2.02k stars 997 forks source link

Support toggle climate device #573

Open eyalcha opened 3 years ago

eyalcha commented 3 years ago

HI,

Not sure if there is already support /solution for my case, but I didn't find ...

I have an aircondition device which doesn't have sepearte on / off commands. No issue to turn off the device. I have off command in the code file. The issue is with the turn on command. To turn on I actually need to send two commands. First to turn on and then send second command (mode temperature fan). Note that all the temperature commands cannt include the on command because if they wer, each up down temperature will toggle device power state.

The solution that I found was to add a pre mode command and send it each time the mode is changed (mode depended). Is there other option to handle this case without changing teh code? If not, is it possible to add support for that?

  async def async_set_hvac_mode(self, hvac_mode):
        """Set operation mode."""
        _LOGGER.debug(f"async_set_hvac_mode hvac_mode:{hvac_mode}")
        self._hvac_mode = hvac_mode

        if not hvac_mode == HVAC_MODE_OFF:
            self._last_on_operation = hvac_mode

        # Pre mode command
        if not hvac_mode == HVAC_MODE_OFF:
            pre_mode = f"pre_{hvac_mode}"
            _LOGGER.debug(f"Send {pre_mode}")
            if pre_mode in self._commands:
                await self._controller.send(self._commands[pre_mode])
                await asyncio.sleep(self._delay)

        await self.send_command()
        await self.async_update_ha_state()

Example of command:

  "commands":{
    "off":"JgC+AGKCICFBPiEfQR8hHx8hIR8fISFAHiEgIB8gPyEfIR8hIh8hHx4hIh8eIR8hHyEfIR8hISAeICIfIR8gP0EfY4IeIT9AICA/ISIfHiEfISIfIT8eIR8hHyE/ICAgHyEiHx4hIh8eIR8hHyEhHx8hHyEfIR8hIR8eIR9BQh9jgR4hP0EfIT8gHyEiHyEfIR8eQSEfHyEfIUEgICAgICAfIR8iHR8hHyEfIR8hIh8eISEgICAeIR8hID9BH4IADQUAAAAAAAAAAAA=",
    "pre_heat":"JgC+AGKCICFBPiEfQR8hHx8hIR8fISFAHiEgIB8gPyEfIR8hIh8hHx4hIh8eIR8hHyEfIR8hISAeICIfIR8gP0EfY4IeIT9AICA/ISIfHiEfISIfIT8eIR8hHyE/ICAgHyEiHx4hIh8eIR8hHyEhHx8hHyEfIR8hIR8eIR9BQh9jgR4hP0EfIT8gHyEiHyEfIR8eQSEfHyEfIUEgICAgICAfIR8iHR8hHyEfIR8hIh8eISEgICAeIR8hID9BH4IADQUAAAAAAAAAAAA=",
    "cool":{
      "auto":{
        "16":"JgDEAGVhISAhHiI+Ih4iHkEeIx0jHiEeIh4iHyEeIT9BICAhHyAhHiEfIR4hHyIeIh4iHiIeIR8hICAgICAfICE/QR9jYCIfICAhPiIeIR9BHiMdIh8hHiIeISAhHiE/QSAhHiEfIh0iHiIfISAgHiEgIR4hHyIeIh4iHiIeIR8hPkIeZGAhICAgID8hHyEfQh0iHiEgIR4iHyEeIR8hQEEeIR8hHiIfIR4iHiIfIR4iHyEeISAhHiIeIh0iHyEfIT5BIYEADQUAAAA=",
smartHomeHub commented 3 years ago

Yes, just rename the pre_heat key to on

eyalcha commented 3 years ago

Yes, just rename the pre_heat key to on

I saw the "on" option, but as I understand, it will called each time send command is called, so when I just change temperature, the on command will be sent and the aircondition will toggle state ...

    async def send_command(self):
        async with self._temp_lock:
            try:
                self._on_by_remote = False
                operation_mode = self._hvac_mode
                fan_mode = self._current_fan_mode
                swing_mode = self._current_swing_mode
                target_temperature = '{0:g}'.format(self._target_temperature)

                if operation_mode.lower() == HVAC_MODE_OFF:
                    await self._controller.send(self._commands['off'])
                    return

                if 'on' in self._commands:
                    await self._controller.send(self._commands['on'])
                    await asyncio.sleep(self._delay)
vassilis-panos commented 3 years ago

No, there is no way.

eyalcha commented 3 years ago

No, there is no way.

@vassilis-panos The code I've attached (Pre mode command) handle this case. Maybe there is a bteer way to add it to the official release.

vassilis-panos commented 3 years ago

Is there a reason why you need a different pre-code for each mode?

eyalcha commented 3 years ago

@vassilis-panos

I assume single pre command (which should turn on the device) is enough but if the pre command sends also the HVAC mode, it will be better to send the correct mode and not to rely on the immediate second command to set the mode correctly.

SamTheGeek commented 3 years ago

I also have this issue — I use a Fujitsu AR-REG1U-controlled heat pump (code 1284 in SmartIR). Once the device is powered off, it cannot be powered on from Home Assistant. However, the Broadlink App can send a power-on command by itself.

Perhaps the power-on command could be sent when toggling mode if the state is currently set to off?

mshuflin commented 3 years ago

I have the same issue with my Daikin FTN-P. It seems like it needs home assistant to send the power on command (along with the temperature or mode command) only when the state is off, otherwise, send only the temperature or mode.

mshuflin commented 3 years ago

@eyalcha your solution worked for me. I know that it is not the case for everyone, but, @vassilis-panos, perhaps it could be implemented as a configurable option?

async def async_set_hvac_mode(self, hvac_mode):
      """Set operation mode."""
      _LOGGER.debug(f"async_set_hvac_mode hvac_mode:{hvac_mode}")
      self._hvac_mode = hvac_mode

      if not hvac_mode == HVAC_MODE_OFF:
          self._last_on_operation = hvac_mode

      # Pre mode command
      if not hvac_mode == HVAC_MODE_OFF:
          pre_mode = f"pre_{hvac_mode}"
          _LOGGER.debug(f"Send {pre_mode}")
          if pre_mode in self._commands:
              await self._controller.send(self._commands[pre_mode])
              await asyncio.sleep(self._delay)

      await self.send_command()
      await self.async_update_ha_state()
stale[bot] commented 3 years ago

This issue has been automatically marked as stale because it has not had recent activity. It will be closed if no further activity occurs. Thank you for your contributions.

mshuflin commented 3 years ago

Still valid

Spirituss commented 3 years ago

Hello, I have similar issue. When I send command 'off' in case Panasonic was off, it turns in on. Nevertheless, SmatrIR has power on sensor. Why does it send the command while power sensor has 'off' status?

jpf4e commented 3 years ago

I also have a similar issue with my Hisense AC. Smart IR should detect the state change from "off" to any other state and run the on command before the new state's command.

jpf4e commented 3 years ago

Something like this fixes it for my Hisense AC:

async def async_set_hvac_mode(self, hvac_mode):
      """Set operation mode."""
      _LOGGER.debug(f"async_set_hvac_mode hvac_mode:{hvac_mode}")

      if not hvac_mode == HVAC_MODE_OFF:
          self._last_on_operation = hvac_mode

      # Pre mode command
      if not hvac_mode == HVAC_MODE_OFF and self._hvac_mode == HVAC_MODE_OFF:
          pre_mode = f"pre_{hvac_mode}"
          _LOGGER.debug(f"Send {pre_mode}")
          if pre_mode in self._commands:
              await self._controller.send(self._commands[pre_mode])
              await asyncio.sleep(self._delay)

      self._hvac_mode = hvac_mode

      await self.send_command()
      await self.async_update_ha_state()
Spirituss commented 3 years ago

Something like this fixes it for my Hisense AC:

Due to incorrect work of SmartIR at the moment I have to realise the same logic via HA script. I appreciate such fixes into the component.

stephenchew commented 3 years ago

Yeah I have a similar issue where my air-conditioner has no idempotent on/off button, the state is kept in the unit itself instead. It's a newer model of Daikin anyway.

Similar to a TV remote, the power button on the remote will send a "power" signal, and it toggles the air-conditioner on/off based on the previous state (stored in the unit).

Inspired by @eyalcha modification above, I made the necessary modification which fits my unit:


def __init__(self, hass, config, device_data):
    # initialisation of other variables...
    # ...
    self._previous_hvac_mode = HVAC_MODE_OFF

async def async_set_hvac_mode(self, hvac_mode):
    """Set operation mode."""
    self._previous_hvac_mode = self._hvac_mode
    self._hvac_mode = hvac_mode

    if not hvac_mode == HVAC_MODE_OFF:
        self._last_on_operation = hvac_mode

    # Pre mode command
    # Taken from https://github.com/smartHomeHub/SmartIR/issues/573
    # modified to a generic `on_once` for all non-off operation
    if not hvac_mode == HVAC_MODE_OFF:  # don't run if about to turn off
        if self._previous_hvac_mode == HVAC_MODE_OFF:  # only if it's previously off
            if 'on_once' in self._commands:
                await self._controller.send(self._commands['on_once'])
                await asyncio.sleep(self._delay)

    # End pre mode

    await self.send_command()
    await self.async_update_ha_state()

Add the attribute on_once in the config file

"commands": {
  "off": "JgCWAAABQwABQgABRAABQ5lRDQsOHQ4dDQwNHQ4LDAwNCwwMDh0NCw0LDgsNHgwMDQsMDA4KDgoNDA0eDR4MDA0LDCALDA0LDQsOCw0dDQwNCwwMDQsOCg0LDh0OCwwMDQsMDA0LDgoNDA0eDQsMDA0eDQsMHwwfDAwOCg4dDQsNDAwfDQsNHgwfDQsNCw0LDgsNAAKcmQANBQ==",
  "on_once": "JgCWAAABQwABQgABRAABQ5lRDQsOHQ4dDQwNHQ4LDAwNCwwMDh0NCw0LDgsNHgwMDQsMDA4KDgoNDA0eDR4MDA0LDCALDA0LDQsOCw0dDQwNCwwMDQsOCg0LDh0OCwwMDQsMDA0LDgoNDA0eDQsMDA0eDQsMHwwfDAwOCg4dDQsNDAwfDQsNHgwfDQsNCw0LDgsNAAKcmQANBQ==",
  "cool": {
    "low": {
      "16": "JgCWAAABQwABQgABRQABQZpRDA0LHw0eDA0MHwwMDAwMDAsOCx8NDAsNCw0MDAwMDB8MDAwfDR4MDQsNCw0MHg0MDB4NDAwMDA0LDQsgCwwNDAwMDAwMDAwNCyALDQsNCw0LDQwMDA0LDA0eDA0MDAweDQwMHg4dDQwMHw0MCw0LDQsfDQwMHg0MDAwMDQsfDQwLAAKdmQANBQ==",

_** Things to take note: on_once command is effectively the 'power' command, which toggle the power state of the appliance._

How it behaves:

Scenario 1 GIVEN current state is Off WHEN changing HVAC mode to either cooling, heating or fan THEN it'll fire the on_once command to turn on the appliance before sending the respective command

Scenario 2 GIVEN current state is not off (e.g. cooling, heating or fan) WHEN changing HVAC mode to either cooling, heating or fan THEN it will only fire the respective command without triggering the on_once command

Scenario 3 GIVEN current state is not off (e.g. cooling, heating or fan) WHEN changing HVAC mode to off THEN it will only fire off command to turn the appliance off

⚠️ Edge cases - The state of the appliance is out of sync with the remote

Scenario 4 GIVEN the remote shows that it's cooling but the appliance is actually off WHEN pressing off button on the remote THEN it should send off command to turn on the appliance (because off command is effectively a power command) WHEN pressing off button for the second time THEN it should send off command again to turn off the appliance AND both the states are now in sync

Scenario 5 GIVEN the remote shows that it's off but the appliance is actually on (cooling, heating or fan) WHEN pressing off button on the remote THEN it should send off command to turn off the appliance AND both the states are now in sync


To me this is quite a common design that most manufacturers employ when they make a remote, so I really wish this could be incorporated into SmartIR.

stale[bot] commented 3 years ago

This issue has been automatically marked as stale because it has not had recent activity. It will be closed if no further activity occurs. Thank you for your contributions.

Spirituss commented 3 years ago

The problem has not been solved yet. For example, Panasonic air conditioners work incorrectly because have the same command for both POWER ON and POWER OFF action.

mshuflin commented 3 years ago

I also still have this problem

On Fri, Sep 3, 2021, 5:00 PM Spirituss @.***> wrote:

The problem has not been solved yet. For example, Panasonic air conditioners work incorrectly because have the same command for both POWER ON and POWER OFF action.

— You are receiving this because you commented. Reply to this email directly, view it on GitHub https://github.com/smartHomeHub/SmartIR/issues/573#issuecomment-912379829, or unsubscribe https://github.com/notifications/unsubscribe-auth/AM336IEKHUOFK2KODUSUYTLUACFDNANCNFSM4WXDZCSQ . Triage notifications on the go with GitHub Mobile for iOS https://apps.apple.com/app/apple-store/id1477376905?ct=notification-email&mt=8&pt=524675 or Android https://play.google.com/store/apps/details?id=com.github.android&referrer=utm_campaign%3Dnotification-email%26utm_medium%3Demail%26utm_source%3Dgithub.

Paul-Vdp commented 2 years ago

So have I ...

matteo-vannucchi commented 2 years ago

I have the same problem with a pellet stove, which works perfectly with SmartIR except for the latter always sends on command with every mode change. The on_once solution from @step-chew looks perfect for my case, too

Dgomezj commented 2 years ago

Hi, In the meantime this is not added to the official release, is there any way to include the code made by @step-chew in my local installation?

matteo-vannucchi commented 2 years ago

Hi, In the meantime this is not added to the official release, is there any way to include the code made by @step-chew in my local installation?

Hi, if you know how to, you should modify the file climate.py in the custom_compnents/smartir folder of your HA config, adding the lines from @step-chew's reply

Dgomezj commented 2 years ago

Thanks a lot @matteo-vannucchi. I've seen the file and I think is pretty easy to modify. I'll give it a try.

Dgomezj commented 2 years ago

I've added the code to my instalation and it works like a charm. Thanks @step-chew for the code and thanks @matteo-vannucchi for the guidance.

It would be very nice to have this in the official release.

stale[bot] commented 2 years ago

This issue has been automatically marked as stale because it has not had recent activity. It will be closed if no further activity occurs. Thank you for your contributions.

mshuflin commented 2 years ago

Still an issue

On Sat, Apr 16, 2022, 6:45 PM stale[bot] @.***> wrote:

This issue has been automatically marked as stale because it has not had recent activity. It will be closed if no further activity occurs. Thank you for your contributions.

— Reply to this email directly, view it on GitHub https://github.com/smartHomeHub/SmartIR/issues/573#issuecomment-1100635505, or unsubscribe https://github.com/notifications/unsubscribe-auth/AM336IHMRRA5VWZZTTZJTPTVFKK6JANCNFSM4WXDZCSQ . You are receiving this because you commented.Message ID: @.***>

stale[bot] commented 2 years ago

This issue has been automatically marked as stale because it has not had recent activity. It will be closed if no further activity occurs. Thank you for your contributions.

mshuflin commented 2 years ago

Still an issue

On Sat, Aug 13, 2022, 6:34 PM stale[bot] @.***> wrote:

This issue has been automatically marked as stale because it has not had recent activity. It will be closed if no further activity occurs. Thank you for your contributions.

— Reply to this email directly, view it on GitHub https://github.com/smartHomeHub/SmartIR/issues/573#issuecomment-1214134903, or unsubscribe https://github.com/notifications/unsubscribe-auth/AM336ICE3TOWM346LVWZJKDVY5233ANCNFSM4WXDZCSQ . You are receiving this because you commented.Message ID: @.***>

HVPereira commented 1 year ago

I have this issue too!

madjetey commented 1 year ago

@stephenchew's method isn't working with Daikin. Power on_once & Power off commands work but also give the error:

Failed to call service climate/set_hvac_mode. object NoneType can't be used in 'await' expression

Other commands don't work at all: temp, fan speed & swing