leeyuentuen / localtuya

local handling for Tuya devices
GNU General Public License v3.0
72 stars 17 forks source link

Enhancement - Simple Zigbee Aubess Smart Scene Switch #63

Open TheLoneKiwi opened 1 year ago

TheLoneKiwi commented 1 year ago

Product Page https://vi.aliexpress.com/item/1005003683832210.html?spm=a2g0o.order_list.order_list_main.10.21191802dEimRr&gatewayAdapt=glo2vnm

Add a custom state "IDLE" if switch sends the same state a second time

Issue: This Scene Switch has 3 states per button single_click, double_click and long_press when setup as a switch in Local Tuya the switch is always on which I expect. Raw state displays the last action done with the button example single_click.

With the current state of the code it means you can not use the same button a second time. What I mean by this: On the scene switch if you click the button once it sends the full update but still updates the one with the updated state. Received event event_status_updated from gateway with data {'1': 'single_click', '2': 'double_click', '3': 'single_click', '4': 'single_click', '10': 100}

As this code currently checks that status is not the same it skips any update if you do the same option a second time. What I have had to do is add a state "IDLE" if the value is the same. This way I can setup automations per option. Example Button1 is setup to toggle a light.

I do not understand well enough how all the components work so unsure of the best method to actually add this in correctly. I have provided the code changes I did below which does work but may cause issues with other products.

Code changes made to counter this issue: (This is just a simple hack to get it working don't judge too hard :))

Switch.Py

"""Initialize the Tuya switch."""
        super().__init__(device, config_entry, switchid, _LOGGER, **kwargs)
        self._state = None 
        self.laststate = "Unknown" # Added a last state
        _LOGGER.debug("Initialized switch [%s]", self.name)

def status_updated(self):
        """Device status was updated."""
        state = self.dps(self._dp_id)
        if state is not None:
            if state == self.laststate and self.laststate != "IDLE":
                self._state = "IDLE"
            else:
                self._state = state
            self.laststate = self._state

Common.py `

    def _update_handler(status):
        self.debug("Update entity state when status was updated.")
        update = False
        if status is None:
            self._status = {}
            update = True
        elif self._status != status and str(self._dp_id) in status:
            self._status = status.copy()
            update = True
        elif self._status == status and self.dps(self._dp_id) == "single_click" or self.dps(self._dp_id) == "long_press" or self.dps(self._dp_id) == "double_click" or "IDLE" in status: # added a if statement to check for one of the 4 options it might be then tell it to update
            self.debug("Updating now")
            update = True

        if update:
            self.status_updated()
            self.schedule_update_ha_state()

`

Device Specification from Tuya cloud API { "result": { "category": "wxkg", "functions": [], "status": [ { "code": "switch_mode1", "lang_config": { "click": "single click", "double_click": "", "press": "long press" }, "name": "Button1", "type": "Enum", "values": "{\"range\":[\"click\",\"double_click\",\"press\"]}" }, { "code": "switch_mode2", "lang_config": { "click": "single click", "double_click": "double click", "press": "long press" }, "name": "Button2", "type": "Enum", "values": "{\"range\":[\"click\",\"double_click\",\"press\"]}" }, { "code": "switch_mode3", "lang_config": { "click": "single click", "double_click": "double click", "press": "long press" }, "name": "Button3", "type": "Enum", "values": "{\"range\":[\"click\",\"double_click\",\"press\"]}" }, { "code": "switch_mode4", "lang_config": { "click": "", "double_click": "double click", "press": "long press" }, "name": "Button4", "type": "Enum", "values": "{\"range\":[\"click\",\"double_click\",\"press\"]}" }, { "code": "battery_percentage", "lang_config": { "unit": "%" }, "name": "Battery", "type": "Integer", "values": "{\"unit\":\"%\",\"min\":0,\"max\":100,\"scale\":0,\"step\":1}" } ] }, "success": true, "t": 1683329805229, "tid": "b243d1c0eb9d11ed9b28425442ef4a7b" }

TheLoneKiwi commented 1 year ago

On any update it sends the status for every button so this will not work.

thewan056 commented 1 year ago

separate single click, double click and long press as three individual switches with on and off modes. when a user presses one of the three types, the switch turns on ie: user single click, the single click switch turns on and so on. right after it turns on, switch it back off, either directly in local tuya itself or through an automation made by the user (this is why it needs to be a switch, so that we can manipulate its state via automation). this way, we can create automations that react only when the switch "turns on". we can ignore the off part since other button presses will turn them off.

edit: I have quite a few versions of these smart scene switches, with one button(zigbee), two button(zigbee and wifi), three button(bluetooth) and 4 button types(zigbee) so maybe i can test them out when someone figures it out. note that my wifi version has double click disabled in the smartlife/tuya app, only single click and long press can be used, possibly due to latency of wifi that it cannot properly and reliably detect double clicks.