pyvesync icon indicating copy to clipboard operation
pyvesync copied to clipboard

Fix WHOGPLUG toggle_switch - incorrect API method

Open Xgabi86 opened this issue 2 months ago • 1 comments

Device: GreenSun WHOGPLUG (model WHDZ03) Current behavior: Getting error code -1 "unknown_error" when toggling switch Root cause: Wrong API method in VeSyncOutletWHOGPlug.toggle_switch()

The current implementation uses:

  • Method: 'setProperty'
  • Data: {'powerSwitch_1': toggle_int}

But it should use (like VeSyncBSDOGPlug):

  • Method: 'setSwitch'
  • Data: {'id': 0, 'enabled': toggle}

This fix makes the WHOGPLUG work perfectly in Home Assistant.

Location: src/pyvesync/devices/vesyncoutlet.py, line 804 Class: VeSyncOutletWHOGPlug

The device works perfectly in the official VeSync app, confirming the API is correct.

Xgabi86 avatar Dec 06 '25 15:12 Xgabi86

Copied from #194

I also own GreenSun outlets (Model WHOGPLUG / Config_Module DM_WFBO_OTL_WHOGPLUG_UN). They are recognized in the new version, but I can’t turn them ON or OFF. The payload method that needs to be used is setSwitch, and the payload data must be {'id': 0, 'enabled': True/False}. I have already modified the code accordingly and it works.

Do you know how to distinguish between the different WHOGPLUG models? I can provide the API calls if needed.

Current method (WHOGPLUG)

    async def toggle_switch(self, toggle: bool | None = None) -> bool:
        if toggle is None:
            toggle = self.state.device_status != DeviceStatus.ON
        toggle_int = int(toggle)
        r_dict = await self.call_bypassv2_api(
            'setProperty',
            data={'powerSwitch_1': toggle_int},
            payload_update={'subDeviceNo': 0},
        )
        r = Helpers.process_dev_response(logger, 'toggle_switch', self, r_dict)
        if r is None:
            return False

        self.state.device_status = DeviceStatus.ON if toggle else DeviceStatus.OFF
        self.state.connection_status = ConnectionStatus.ONLINE
        return True

New method (WHOGPLUG)

    async def toggle_switch(self, toggle: bool | None = None) -> bool:
        if toggle is None:
            toggle = self.state.device_status != DeviceStatus.ON
        payload_data = {
            'id': 0,
            'enabled': toggle,
        }
        payload_method = 'setSwitch'
        r_dict = await self.call_bypassv2_api(payload_method, payload_data)
        r = Helpers.process_dev_response(logger, 'toggle_switch', self, r_dict)
        if r is None:
            return False

        self.state.device_status = DeviceStatus.ON if toggle else DeviceStatus.OFF
        self.state.connection_status = ConnectionStatus.ONLINE
        return True

sidious38 avatar Dec 14 '25 12:12 sidious38