crankyoldgit / IRremoteESP8266

Infrared remote library for ESP8266/ESP32: send and receive infrared signals with multiple protocols. Based on: https://github.com/shirriff/Arduino-IRremote/
GNU Lesser General Public License v2.1
3k stars 833 forks source link

Samsung AC - "Clean" automatically gets toggled by the AC unit #2006

Closed bogd closed 1 year ago

bogd commented 1 year ago

Version/revision of the library used

The one included in Tasmota 12.5.0

Describe the bug

"Clean" is set as a toggle as per issue #1676 , but this does not handle the fact that "clean" is automatically set to "off" by the AC unit once a cleaning cycle is completed.

To Reproduce

For a while now, I have had to work around "clean" being a toggle by using a higher-level component (I am using Tasmota_IRHVAC to control my AC unit, and they implemented a "toggle_list" in their code in order to fix this issue - see here for the details).

As you can imagine, I was originally glad to see that clean is now a toggle at the IR library level. However, this causes a different problem...

On my AC unit, the "clean" setting is automatically turned off once a cleaning cycle is completed. As a result, the unit state becomes different than the one stored in Tasmota (and IRRemoteESP8266), making it difficult to activate a clean cycle on subsequent power ons.

Example (starting from a unit with clean: off, IRRemoteESP8266 also has an internal state of clean:off):

  1. Turn on unit. Unit clean is off, IRRemote clean is off
  2. Turn "clean" on. IRRemote clean is now on (different from before, so the IR bit gets toggled in the sent signal), unit clean becomes on
  3. Turn unit off. Unit starts the clean cycle. IRRemote clean is on, unit clean is on
  4. Unit finishes the clean cycle, and turns off the "clean" setting. Unit clean is off, but IRRemote still remembers "clean" as "on". This is where the problem starts.
  5. Next power on. Unit clean is off, IRRemote clean is on.
  6. I try to turn "clean" on, by sending a new message with "clean: on". IRRemote sees that the internal state has not changed, so it does not set the bit in the IR signal. Unit clean remains "off".
  7. On the next power off, no clean cycle is performed.
  8. Even worse, on all subsequent power cycles, I start over at step 5. So no cleaning cycle ever again :)

I could probably fix this by toggling the setting (for example, sending "clean = !prev_clean" in step 6). This would fix the issue, but it would lead to continuous inconsistency between the unit state and the state stored in IRRemoteESP8266.

A better solution would be a way to change the internal state without causing an IR signal to be sent. I do not know whether this should be done at the library (IRRemoteESP8266) level, or in the higher-level component (tasmota_irhvac). That is why I am asking in both places.

The corresponding issue for tasmota_irhvac is here.

Thank you!

Expected behaviour

Need a way to keep the IRRemoteESP8266 state in sync with the unit state, even when the unit internally toggles the setting.

Output of raw data from [IRrecvDumpV2.ino]

Not really relevant - the problem is in the logic, not in the IR signal.

What brand/model IR demodulator are you using?

N/A

Circuit diagram and hardware used (if applicable)

N/A

I have followed the steps in the [Troubleshooting Guide]

Has this library/code previously worked as expected for you?

Yes, up to the changes in #1676 . But again, I am not saying those changes are bad - they actually make sense, and I was happy to see them! It is just that they introduce an additional issue, and I am not sure what the best way to fix it would be.

Other useful information

This library has been absolutely invaluable for me so far. Just had to say this somewhere, and I found no better place for it :)

crankyoldgit commented 1 year ago

What you're describing is really beyond the scope of the library. We aim to provide the ability to send every kind of message we can to an A/C, but the library can't/won't provide complete emulation of a remote for an A/C. e.g. Some A/C messages contain a clock/time part of the message. On a real remote, there is a microcontroller than constantly adjusts the time so it is correct for the A/C, so when a message is sent, it's 14:37; then a minute later if the remote is pressed; it sends 14:38 etc. We don't provide that level of automation. That is something that is expected to be done by what ever program someone writes that uses our library.

We do our best to emulate where we can, the intended operation of a remote (e.g. Toggle Controls) but a value that changes over time. e.g. Clocks, cleaning state, timers, Sensor temps, etc. are strictly in the realm of the program using this library (or at an even higher level), not the library itself.

Basically, this library offers a programmer the tools to write a full emulation or what ever they want, by sending the messages to the A/C for them. We can't add automatic features without it potentially affecting someone elses use of the library. By keeping this simple, predicatable, & low-level we offer the greatest possible use cases for developers/programmers/users.

I suspect the Tasmota folk will give you a similar response. You're asking for a higher-level feature than what they are offering via their api/service. For instance, this is something that should be done by your home automation system. e.g. Assuming the "clean" operation takes 15 mins, and you want to perform a "clean". Your home automation system should set/toggle/what-ever the "clean" setting; cause the message to be sent; then 15 mins later, reset/change/toggle/etc the "clean" setting. Optionally sending the new message, if that is what is required etc.

Note: Tasmota uses our generic A/C API/interface (IRac class) which doesn't offer details/full control of an A/C. If you're wanting to do full/better emulation, you're much better off using the full-control IRSamsungAc class.

Hopefully I've explained it well, and I'm assuming understanding your question/problem/predicament correctly. Please let me know if I've got it wrong.

bogd commented 1 year ago

You are correct, and I will admit I half expected this answer. And yes, I do expect Tasmota to be similar - but at the same time, I need a way to change the internal state of the system without causing a new IR signal to be sent. And I could do that if only one of the components in the chain ( HomeAssistant, the tasmota_irhvac custom component, tasmota, or IRRemoteESP8266 ) would allow me to change the internal state without sending an IR signal.

In this particular case, I need a way to do exactly this: "Your home automation system should set/toggle/what-ever the "clean" setting; cause the message to be sent; then 15 mins later, reset/change/toggle/etc the "clean" setting". WITHOUT sending an IR signal.

And I thought that was not possible - but looking at the links you posted (thank you!!), it appears that the library supports this (or at least IRSamsungAC seems to support it, via .setClean() - not sure what the equivalent method is for setting state in IRac). I will just need to bug (pun not intended) the authors of the custom integration (tasmota_irhvac) to actually allow this on that level. I am not sure it is possible (the entity actually using the library is Tasmota, and I am not sure Tasmota exposes any way of changing the internal state of IRRemote), but I will keep trying.

For now, I will close this. Thank you so much for the very detailed reply! And once again, a big thank you for all the work you are doing on this library - it has helped me more times than I can count!!

crankyoldgit commented 1 year ago

if only one of the components in the chain ( HomeAssistant, the tasmota_irhvac custom component, tasmota, or IRRemoteESP8266 ) would allow me to change the internal state without sending an IR signal.

To correct the record, IRRemoteESP8266 does allow that, both via the IRac and IRSamsungAc classes/interfaces. :-)

IRSamsungAC seems to support it, via .setClean() - not sure what the equivalent method is for setting state in IRac)

IRac uses the clean attribute to control the Clean function in Samsung A/Cs. See: https://github.com/crankyoldgit/IRremoteESP8266/blob/80821751269b07bcf0385da75e8404792b8fd317/src/IRac.cpp#L2235 & https://github.com/crankyoldgit/IRremoteESP8266/blob/80821751269b07bcf0385da75e8404792b8fd317/src/IRac.cpp#L2265

The IRac class/object does allow changing of attributes without sending a message. e.g.

IRac my_ac(GPIO_PIN);
...
my_ac.next.clean = true;  // Set the internal state of my IRac object's clean setting to On, but don't actually send it.
...
// Now that I'm ready, send the desired state to the A/C.
my_ac.sendAc();

However, I suspect the way Tasmota is using it, they are not using or exposing that approach, and to be honest, 99.99% of the use cases are catered for using the simpler interface they use.

You would need to convince them to add an option to update the internal AC state in IRac and then NOT request a send.

bogd commented 1 year ago

Once again, a big thank you!!

After you posted your reply, you got me thinking about where this could be implemented. So I went digging through Tasmota's documentation (it's not much, but it's been helpful in the past :) ). And lo and behold, that option actually exists:

"StateMode":
SendOnly (default)
StoreOnly
SendStore

Even though I cannot test this right now, I do believe this is the solution to my problem. And if I can get the authors of tasmota_irhvac to allow me to control the setting via the custom component, it will be even better! :)

I trully appreciate your responses. This was not really an issue with IRRemoteESP8266, and as a result I had already closed the issue. Yet you answered with plenty of details (and even working code samples!), and that put me on the right track towards a solution. A level of support I have rarely seen even with commercial software :)

Thank you once again!