### Setup Virtual Environment for Development Source: https://github.com/webdjoe/pyvesync/blob/dev/README.md Provides bash commands for setting up a Python virtual environment, which is crucial for isolating project dependencies. It includes checking the Python version, creating a virtual environment, and activating it on Linux systems, essential for development and testing. ```bash mkdir python_test && cd python_test # Check Python version is 3.11 or higher python3 --version # or python --version or python3.8 --version # Create a new venv python3 -m venv pyvesync-venv # Activate the venv on linux source pyvesync-venv/bin/activate ``` -------------------------------- ### Install frida-tools in a Python Virtual Environment Source: https://github.com/webdjoe/pyvesync/blob/dev/docs/development/capturing.md This snippet demonstrates how to create a Python virtual environment and install the frida-tools package, which is essential for interacting with Frida. ```bash python -m venv venv source venv/bin/activate # On Windows cmd use `venv\Scripts\activate` # On powershell use `venv\Scripts\Activate.ps1` pip install frida-tools ``` -------------------------------- ### Connect to Android Emulator and Start frida-server Source: https://github.com/webdjoe/pyvesync/blob/dev/docs/development/capturing.md This sequence of commands connects to the Android emulator via ADB, pushes the frida-server binary and SSL certificate to the emulator's temporary directory, and then executes the frida-server. ```bash adb connect 127.0.0.1:7555 adb root adb push cert-der.crt /data/local/tmp/ adb push frida-server /data/local/tmp/ cd /data/local/tmp chmod +x frida-server ./frida-server ``` -------------------------------- ### Install pyvesync using pip Source: https://github.com/webdjoe/pyvesync/blob/dev/README.md This snippet shows the command to install the latest version of the pyvesync library from pip. Ensure pip is up-to-date before running. ```bash pip install pyvesync ``` -------------------------------- ### Example Usage of Bypass V2 Mixin - Python Source: https://github.com/webdjoe/pyvesync/blob/dev/docs/development/index.md This example demonstrates how to use the `BypassV2Mixin` and `process_bypassv2_response` methods within a custom device class, `VSDevice`, inheriting from `VeSyncPurifier`. It shows calling `call_bypassv2_api` to get purifier status and then processing the response. ```python from pyvesync.base_devices import VeSyncPurifier from pyvesync.models.purifier_models import RequestPurifierDetails from pyvesync.utils.device_mixins import BypassV2Mixin, process_bypassv2_response class VSDevice(BypassV2Mixin, VeSyncPurifier): """VeSync Purifier device class.""" async def get_details(self) -> bool: """Get the details of the device.""" response = await self.call_bypassv2_api( payload_method="getPurifierStatus", data=update_dict ) # The process_bypassv2_response method makes the appropriate logs if error in response result = process_bypassv2_response(self, logger, 'get_details', response) ``` -------------------------------- ### Install Pyvesync from GitHub Branch Source: https://github.com/webdjoe/pyvesync/blob/dev/README.md Installs the pyvesync library from a specified Git branch. This is useful for testing unmerged changes or specific versions of the library. ```bash pip install git+https://github.com/webdjoe/pyvesync.git@BRANCHNAME ``` -------------------------------- ### Install Pyvesync from Unmerged GitHub Pull Request Source: https://github.com/webdjoe/pyvesync/blob/dev/README.md Installs a pull request that has not yet been merged into the main branch. This allows for testing specific contributions before they are officially integrated. ```bash pip install git+https://github.com/webdjoe/pyvesync.git@refs/pull/PR_NUMBER/head ``` -------------------------------- ### Access and Control Devices via DeviceContainer Source: https://github.com/webdjoe/pyvesync/blob/dev/README.md Explains how to access devices through the `manager.devices` attribute, which is a `DeviceContainer`. It shows how to get lists of specific device types (e.g., outlets, switches) and how to iterate through devices to find and control specific ones by name. This is key for device management. ```python # Acts as set with properties that return product type lists manager.devices = DeviceContainer instance manager.devices.outlets = [VeSyncOutletInstances] manager.devices.switches = [VeSyncSwitchInstances] manager.devices.fans = [VeSyncFanInstances] manager.devices.bulbs = [VeSyncBulbInstances] manager.devices.air_purifiers = [VeSyncPurifierInstances] manager.devices.humidifiers = [VeSyncHumidifierInstances] manager.devices.air_fryers = [VeSyncAirFryerInstances] managers.devices.thermostats = [VeSyncThermostatInstances] # Get device by device name dev_name = "My Device" for device in manager.devices: if device.device_name == dev_name: my_device = device device.display() # Turn on switch by switch name switch_name = "My Switch" for switch in manager.devices.switches: if switch.device_name == switch_name: await switch.turn_on() # Asynchronous ``` -------------------------------- ### Log pyvesync Debug Output to File Source: https://github.com/webdjoe/pyvesync/blob/dev/docs/index.md This example demonstrates how to log detailed debug information from pyvesync to a file. It utilizes the `VeSync` object's `debug` and `verbose` attributes, and the `log_to_file` method. This helps manage large log outputs by directing them to a file, with an option to also log to standard output. The `VeSync` class is required. ```python from pyvesync import VeSync async def main(): async with VeSync(username="EMAIL", password="PASSWORD") as manager: manager.debug = True # Enable debug logging manager.verbose = True # Enable verbose logging await manager.log_to_file("debug.log", stdout=True) # Can be an absolute or path relative to the current working directory await manager.login() await manager.get_devices() ``` -------------------------------- ### Control Wall Switches with PyVesync (Python) Source: https://context7.com/webdjoe/pyvesync/llms.txt This Python script demonstrates how to interact with wall switches managed by VeSync. It covers basic on/off toggling, brightness adjustment for dimmable switches, indicator light control, RGB backlight customization, and timer settings. Ensure you have the 'pyvesync' library installed and valid VeSync account credentials. ```python import asyncio from pyvesync import VeSync async def control_switches(): async with VeSync("user@example.com", "password") as manager: await manager.login() await manager.update() if not manager.devices.switches: print("No switches found") return switch = manager.devices.switches[0] await switch.update() # Basic on/off control await switch.turn_on() await switch.turn_off() await switch.toggle_switch(True) # Turn on print(f"Switch status: {switch.state.device_status}") # Brightness control (dimmer switches) if switch.supports_brightness: await switch.set_brightness(0) # Off/minimum await switch.set_brightness(25) # 25% await switch.set_brightness(50) # 50% await switch.set_brightness(100) # Full brightness print(f"Brightness: {switch.state.brightness}%") # Indicator light control (if supported) if switch.supports_indicator: await switch.turn_on_indicator_light() await switch.turn_off_indicator_light() print(f"Indicator status: {switch.state.indicator_light}") # RGB backlight control (if supported) if hasattr(switch, 'set_backlight_color'): # Set RGB values (0-255) await switch.set_backlight_color(red=255, green=100, blue=50) await switch.set_backlight_color(red=0, green=255, blue=0) # Green await switch.set_backlight_color(red=0, green=0, blue=255) # Blue # Timer operations await switch.set_timer(1800, action='off') # Turn off in 30 minutes await switch.get_timer() if switch.state.timer: print(f"Timer active: {switch.state.timer.action} in {switch.state.timer.remaining}s") await switch.clear_timer() # Display device information switch.display() print(f"Device model: {switch.device_type}") print(f"Connection: {switch.state.connection_status}") if __name__ == "__main__": asyncio.run(control_switches()) ``` -------------------------------- ### Access Devices by Type in Python Source: https://context7.com/webdjoe/pyvesync/llms.txt Demonstrates how to access and categorize smart devices managed by VeSync. It initializes the VeSync manager, logs in, updates device status, and then retrieves lists of devices based on their type (e.g., outlets, bulbs, air purifiers). The snippet also shows how to iterate through all devices, get a specific device by name (exact and fuzzy matching), and check for device existence by CID. Requires the pyvesync library and asyncio. ```python import asyncio from pyvesync import VeSync async def access_devices(): async with VeSync("user@example.com", "password") as manager: await manager.login() await manager.update() # Access devices by type (returns lists) outlets = manager.devices.outlets # List[VeSyncOutlet] switches = manager.devices.switches # List[VeSyncSwitch] bulbs = manager.devices.bulbs # List[VeSyncBulb] fans = manager.devices.fans # List[VeSyncFanBase] air_purifiers = manager.devices.air_purifiers # List[VeSyncPurifier] humidifiers = manager.devices.humidifiers # List[VeSyncHumidifier] air_fryers = manager.devices.air_fryers # List[VeSyncFryer] thermostats = manager.devices.thermostats # List[VeSyncThermostat] print(f"Outlets: {len(outlets)}") print(f"Bulbs: {len(bulbs)}") print(f"Air Purifiers: {len(air_purifiers)}") # Iterate all devices regardless of type for device in manager.devices: print(f"{device.device_name} ({device.device_type}): {device.state.device_status}") device.display() # Print formatted device info # Get device by name (exact match) living_room_lamp = manager.devices.get_by_name("Living Room Lamp") if living_room_lamp: await living_room_lamp.turn_on() # Get device by name with fuzzy matching (removes non-alphanumeric) device = manager.devices.get_by_name("living-room-lamp!", fuzzy=True) # Check if device exists exists = manager.devices.device_exists(cid="device_cid", sub_device_no=0) # Total device count print(f"Total devices: {len(manager.devices)}") if __name__ == "__main__": asyncio.run(access_devices()) ``` -------------------------------- ### Initialize VeSync Manager and Handle Credentials Source: https://github.com/webdjoe/pyvesync/blob/dev/README.md Demonstrates initializing the VeSync manager with username and password, and managing credentials by loading from or saving to a file, or setting them directly. It also shows how to output credentials as a JSON string. This is essential for authentication with the VeSync service. ```python import asyncio from pyvesync.vesync import VeSync async def main(): async with VeSync("user", "password") as manager: # If credentials are stored in a file, it can be loaded # the default location is ~/.vesync_token await manager.load_credentials_from_file() # or the file path can be passed await manager.load_credentials_from_file("/path/to/token_file") # Or credentials can be passed directly manager.set_credentials("your_token", "your_account_id") # No login needed # await manager.login() # To store credentials to a file after login await manager.save_credentials() # Saves to default location ~/.vesync_token # or pass a file path await manager.save_credentials("/path/to/token_file") # Output Credentials as JSON String await manager.output_credentials() await manager.update() # Acts as a set of device instances device_container = manager.devices outlets = device_container.outlets # List of outlet instances outlet = outlets[0] await outlet.update() await outlet.turn_off() outlet.display() # Iterate of entire device list for devices in device_container: device.display() if __name__ == "__main__": asyncio.run(main()) ``` -------------------------------- ### Initialize and Use VeSync Asynchronously Source: https://github.com/webdjoe/pyvesync/blob/dev/README.md Demonstrates how to initialize the VeSync library as an asynchronous context manager using aiohttp. It covers logging in, updating device states, iterating through different device types, and performing actions like turning off outlets. It also shows how to access device attributes and the last API response. ```python import asyncio import aiohttp from pyvesync.vesync import VeSync async def main(): async with VeSync( username="user", password="password", country_code="US", # Optional - country Code to select correct server session=session, # Optional - aiohttp.ClientSession time_zone="America/New_York", # Optional - Timezone, defaults to America/New_York redact=True # Optional - Redact sensitive information from logs ) as manager: # Redact mode is enabled by default, set to False to disable manager.redact = False # To print request & response content for all API calls enable verbose mode manager.verbose = True # To print logs to file manager.log_to_file("pyvesync.log") await manager.login() if not manager.enabled: print("Not logged in.") return await manager.get_devices() # Instantiates supported devices in device list, automatically called by login, only needed if you would like updates await manager.update() # Updates the state of all devices # manager.devices is a DeviceContainer object # manager.devices.outlets is a list of VeSyncOutlet objects # manager.devices.switches is a list of VeSyncSwitch objects # manager.devices.fans is a list of VeSyncFan objects # manager.devices.bulbs is a list of VeSyncBulb objects # manager.devices.humidifiers is a list of VeSyncHumid objects # manager.devices.air_purifiers is a list of VeSyncAir objects # manager.devices.air_fryers is a list of VeSyncAirFryer objects # manager.devices.thermostats is a list of VeSyncThermostat objects for outlet in manager.devices.outlets: # The outlet object contain all action methods and static device attributes await outlet.update() await outlet.turn_off() outlet.display() # Print static device information, name, type, CID, etc. # State of object held in `device.state` attribute print(outlet.state) state_json = outlet.dumps() # Returns JSON string of device state state_bytes = orjson.dumps(outlet.state) # Returns bytes of device state # to view the response information of the last API call print(outlet.last_response) # Prints a ResponseInfo object containing error code, # and other response information # Or use your own session session = aiohttp.ClientSession() async def main(): async with VeSync("user", "password", session=session): await manager.login() await manager.update() if __name__ == "__main__": asyncio.run(main()) ``` -------------------------------- ### Manage and Control Devices with VeSync Source: https://github.com/webdjoe/pyvesync/blob/dev/docs/usage.md Demonstrates how to log in, fetch devices, update their states, and perform actions like turning them on/off or toggling. It also shows how to set timers for outlets. This snippet iterates through all devices and specifically through outlets. ```python import asyncio from pyvesync import VeSync from pyvesync.const import DeviceStatus # This is a device constant StrEnum USER = "EMAIL" PASSWORD = "PASSWORD" async def main(): manager = VeSync(username=USER, password=PASSWORD) await manager.login() # Login to the VeSync account if not manager.enabled: print("Login failed") return await manager.get_devices() # Get devices await manager.update() # Update all devices for device in manager.devices: print(device) # Print the device name and type await device.update() # Update the device state, this is not required if `manager.update()` has already been called. print(device.state) # Print the device state # Turn on or off the device await device.turn_on() # Turn on the device await device.turn_off() # Turn off the device # Toggle the device state await device.toggle() # Toggle the device state for outlet in manager.devices.outlets: print(outlet) await outlet.update() # Update the outlet state this is not required if `manager.update()` has already been called. await outlet.turn_on() # Turn on the outlet await outlet.turn_off() # Turn off the outlet await outlet.toggle() # Toggle the outlet state await outlet.set_timer(10, DeviceStatus.OFF) # Set a timer to turn off the outlet in 10 seconds if __name__ == "__main__": asyncio.run(main()) ``` -------------------------------- ### Bypass V1 API Structure Source: https://github.com/webdjoe/pyvesync/blob/dev/docs/development/index.md Details the request structure for the Bypass V1 API, used for older devices, with examples for general and bypass-specific calls. ```APIDOC ## Bypass V1 API Request Structure Used for older devices, this API typically uses `POST` requests to `/cloud/v1/deviceManaged/`. ### General Request Structure (e.g., `/cloud/v1/deviceManaged/deviceDetail`) ```json { "method": "deviceDetail", "acceptLanguage": "en_US", "appVersion": "1.0.0", "phoneBrand": "Android", "phoneOS": "Android 10", "accountID": "1234567890", "cid": "deviceCID", "configModule": "configModule", "debugMode": false, "traceId": 1234567890, "timeZone": "America/New_York", "token": "abcdefg1234567", "userCountryCode": "+1", "uuid": 1234567890, "configModel": "configModule", "deviceId": "deviceCID" } ``` Additional keys like `"status": "on"` can be included. No nested dictionaries are used. ### Bypass Method Request Structure (e.g., `/cloud/v1/deviceManaged/bypass`) ```json { "method": "bypass", "acceptLanguage": "en_US", "appVersion": "1.0.0", "phoneBrand": "Android", "phoneOS": "Android 10", "accountID": "1234567890", "cid": "deviceCID", "configModule": "configModule", "debugMode": false, "traceId": 1234567890, "timeZone": "America/New_York", "token": "abcdefg1234567", "userCountryCode": "+1", "uuid": 1234567890, "configModel": "configModule", "deviceId": "deviceCID", "jsonCmd": { "getLightStatus": "get" } } ``` ``` -------------------------------- ### Initialize and Login with VeSync Source: https://github.com/webdjoe/pyvesync/blob/dev/docs/usage.md Initializes the VeSync object, logs into the account, and retrieves device information. This is the primary entry point for interacting with the library asynchronously. It requires valid username and password credentials. ```python import asyncio from pyvesync import VeSync async def main(): # Create a new VeSync object async with VeSync(username="EMAIL", password="PASSWORD") as manager: # To enable debugging manager.debug = True # Login to the VeSync account await manager.login() # Check if logged in assert manager.enabled # Get devices await manager.get_devices() # Update all devices await manager.update() # OR Iterate through devices and update individually for device in manager.outlets: await device.update() if __name__ == "__main__": asyncio.run(main()) ``` -------------------------------- ### Activate Virtual Environment Scripts Source: https://github.com/webdjoe/pyvesync/blob/dev/README.md Scripts to activate the pyvesync virtual environment on PowerShell and Command Prompt. These scripts are essential for using the installed pyvesync package. ```powershell pyvesync-venv\Scripts\activate.ps1 ``` ```bat pyvesync-venv\Scripts\activate.bat ``` -------------------------------- ### Define Mock Method Responses for Devices using Python Source: https://github.com/webdjoe/pyvesync/blob/dev/src/tests/README.md This snippet demonstrates how to define mock responses for device methods, particularly for scenarios like setting status. It shows the creation of a `METHOD_RESPONSES` dictionary, deep copying `FunctionResponses` for each device type, and defining specific response functions (e.g., `valceno_set_status_response`) that can dynamically generate responses based on input arguments. This allows for detailed testing of device interactions. ```python METHOD_RESPONSES = {k: deepcopy(FunctionResponses) for k in BULBS} def valceno_set_status_response(kwargs=None): default_resp = { "traceId": Defaults.trace_id, "code": 0, "msg": "request success", "result": { "traceId": Defaults.trace_id, "code": 0, "result": { "enabled": "on", "colorMode": "hsv", "brightness": Defaults.brightness, "colorTemp": Defaults.color_temp, "hue": Defaults.color.hsv.hue*27.7778, "saturation": Defaults.color.hsv.saturation*100, "value": Defaults.color.hsv.value } } } if kwargs is not None and isinstance(kwargs, dict): if kwargs.get('hue') is not None: default_resp['result']['result']['hue'] = kwargs['hue'] * 27.7778 if kwargs.get('saturation') is not None: default_resp['result']['result']['saturation'] = kwargs['saturation'] * 100 if kwargs.get('value') is not None: default_resp['result']['result']['value'] = kwargs['value'] return default_resp, 200 XYD0001_RESP = { 'set_brightness': valceno_set_status_response, 'set_color_temp': valceno_set_status_response, 'set_hsv': valceno_set_status_response, 'set_rgb': valceno_set_status_response, } METHOD_RESPONSES['XYD0001'].update(XYD0001_RESP) ``` -------------------------------- ### Instantiate and Use VeSync Manager Source: https://github.com/webdjoe/pyvesync/blob/dev/docs/index.md This code demonstrates how to instantiate the VeSync manager object, log in, retrieve and update device states, and iterate through devices. It requires the `pyvesync` and `asyncio` libraries. The manager is used as an asynchronous context manager. ```python import asyncio from pyvesync import VeSync # To enable debug logging: import logging vs_logger = logging.getLogger("pyvesync") vs_logger.setLevel(logging.DEBUG) async def main(): async with VeSync( username="user", password="password", country_code="US", # Optional - country Code to select correct server session=session, # Optional - aiohttp.ClientSession time_zone="America/New_York", # Optional - Timezone, defaults to America/New_York redact=True # Optional - Redact sensitive information from logs ) as manager: # VeSync object is now instantiated await manager.login() # Check if logged in assert manager.enabled # Debug and Redact are optional arguments manager.redact = True # Get devices await manager.get_devices() # Device objects are now instantiated, but do not have state await manager.update() # Pulls in state and updates all devices # Or iterate through devices and update individually for device in manager.outlets: await device.update() # Or update a product type of devices: for outlet in manager.devices.outlets: await outlet.update() if __name__ == "__main__": asyncio.run(main()) ``` -------------------------------- ### Basic pyvesync Usage Source: https://github.com/webdjoe/pyvesync/blob/dev/README.md Demonstrates the fundamental usage of the pyvesync library, including initializing the VeSync manager, logging in, updating device status, and interacting with individual devices like outlets. It utilizes Python's asyncio for asynchronous operations. ```python import asyncio from pyvesync import VeSync from pyvesync.logs import VeSyncLoginError # VeSync is an asynchronous context manager # VeSync(username, password, redact=True, session=None) async def main(): async with VeSync("user", "password") as manager: await manager.login() await manager.update() # Acts as a set of device instances device_container = manager.devices outlets = device_container.outlets # List of outlet instances outlet = outlets[0] await outlet.update() await outlet.turn_off() outlet.display() # Iterate of entire device list for devices in device_container: device.display() if __name__ == "__main__": asyncio.run(main()) ``` -------------------------------- ### Accessing Device Information in pyvesync Source: https://github.com/webdjoe/pyvesync/blob/dev/docs/index.md This snippet demonstrates how to access and retrieve information about devices managed by the pyvesync library. It iterates through the `manager.outlets` list to access individual outlet devices and prints their properties like `device_name`, `device_type`, `sub_device_no`, and `state`. It also shows how to get the `last_response` object for a device. ```python for devices in manager.outlets: print(outlet) print(outlet.device_name) print(outlet.device_type) print(outlet.sub_device_no) print(outlet.state) ``` ```python # Get the last response information print(outlet.last_response) # ResponseInfo( # error_name="SUCCESS", # error_type=SUCCESS, # StrEnum from ErrorTypes class # message="Success", # critical_error=False, # operational_error=False, # device_online=True, # ) ``` -------------------------------- ### Initialize and Login with VeSync Manager (Python) Source: https://context7.com/webdjoe/pyvesync/llms.txt Initializes the VeSync manager, logs in using provided credentials, discovers devices, and updates their states. It handles authentication errors and provides basic device information. Requires aiohttp for asynchronous operations. ```python import asyncio from pyvesync import VeSync from pyvesync.utils.errors import VeSyncLoginError, VeSyncRateLimitError async def main(): # Initialize with credentials (context manager handles session lifecycle) async with VeSync( username="user@example.com", password="your_password", country_code="US", # US or EU, auto-detects region time_zone="America/New_York", # Optional, defaults to America/New_York redact=True # Redact sensitive info from logs ) as manager: # Authenticate with VeSync API try: await manager.login() except VeSyncLoginError as e: print(f"Login failed: {e}") return # Check if login successful if not manager.enabled: print("Authentication failed") return # Discover and instantiate all devices await manager.get_devices() # Update state of all devices await manager.update() print(f"Found {len(manager.devices)} devices") print(f"Token: {manager.token[:20]}...") print(f"Account ID: {manager.account_id}") if __name__ == "__main__": asyncio.run(main()) ``` -------------------------------- ### Build Device List Response using Python Source: https://github.com/webdjoe/pyvesync/blob/dev/src/tests/README.md The `call_json.py` script defines how to construct the `get_devices()` response, including the full device list and individual device items. It utilizes the `DeviceList` class and the `device_list_response` method to filter devices by type and the `device_list_item` method to format individual device data. Default configuration values are sourced from the `Defaults` class in `utils.py`. ```python from utils import FunctionResponses from copy import deepcopy device_types = ['dev1', 'dev2'] # defaultdict with default value - ({"code": 0, "msg": None}, 200) method_response = FunctionResponses # Use deepcopy to build the device response dictionary used to test the get_details() method device_responses = {dev_type: deepcopy(method_response) for dev_type in device_types} # Define response for specific device & method # All response must be tuples with (json response, 200) device_responses['dev1']['special_method'] = ({'response': 'special response', 'msg': 'special method'}, 200) # The default factory can be change for a single device type since deepcopy is used. device_responses['dev2'].default_factory = lambda: ({'new_code': 0, 'msg': 'success', {'payload': {}}}, 200) ``` -------------------------------- ### Control Humidifiers - Python Source: https://context7.com/webdjoe/pyvesync/llms.txt This Python script demonstrates how to connect to and control a humidifier using the pyvesync library. It covers power operations, mode settings, humidity targeting, mist level adjustments, and other device-specific features. Ensure you have the pyvesync library installed and valid VSync account credentials. ```python import asyncio from pyvesync import VeSync async def control_humidifiers(): async with VeSync("user@example.com", "password") as manager: await manager.login() await manager.update() if not manager.devices.humidifiers: print("No humidifiers found") return humidifier = manager.devices.humidifiers[0] await humidifier.update() # Power control await humidifier.turn_on() await humidifier.turn_off() # Mode control await humidifier.set_auto_mode() # Automatic humidity control await humidifier.set_manual_mode() # Manual mist level control await humidifier.set_sleep_mode() # Quiet operation # Some models support humidity mode if hasattr(humidifier, 'set_humidity_mode'): await humidifier.set_humidity_mode() print(f"Current mode: {humidifier.state.mode}") # Target humidity (auto/humidity mode) await humidifier.set_humidity(50) # Set target to 50% await humidifier.set_humidity(60) # Set target to 60% print(f"Target humidity: {humidifier.state.target_humidity}%") # Current humidity reading print(f"Current humidity: {humidifier.state.humidity}%") # Mist level control (manual mode, typically 1-9) await humidifier.set_manual_mode() await humidifier.set_mist_level(1) # Low mist await humidifier.set_mist_level(5) # Medium mist await humidifier.set_mist_level(9) # High mist print(f"Mist level: {humidifier.state.mist_level}") # Warm mist control (if supported) if hasattr(humidifier, 'set_warm_level'): await humidifier.set_warm_level(0) # Cool mist await humidifier.set_warm_level(2) # Warm mist print(f"Warm level: {humidifier.state.warm_level}") # Water status print(f"Water lacks: {humidifier.state.water_lacks}") # True if water low # Display control if humidifier.supports_display: await humidifier.turn_off_display() await humidifier.turn_on_display() # Nightlight control (if supported) if humidifier.supports_nightlight: await humidifier.turn_on_nightlight() await humidifier.turn_off_nightlight() # Automatic shutoff when water empty if hasattr(humidifier, 'set_auto_stop'): await humidifier.set_auto_stop(True) # Display device info humidifier.display() if __name__ == "__main__": asyncio.run(control_humidifiers()) ``` -------------------------------- ### Save and Load VeSync Credentials (Python) Source: https://context7.com/webdjoe/pyvesync/llms.txt Demonstrates how to save and load authentication credentials for the VeSync manager, either to a default location or a custom file path. This avoids repeated logins by persisting tokens and account information. It also shows how to set credentials directly. ```python import asyncio from pyvesync import VeSync async def save_credentials_example(): async with VeSync("user@example.com", "password") as manager: await manager.login() # Save credentials to default location (~/.vesync_auth) await manager.save_credentials() # Or save to custom path await manager.save_credentials("/path/to/token_file.json") # Output credentials as JSON string creds_json = manager.output_credentials_json() print(creds_json) async def load_credentials_example(): async with VeSync("user@example.com", "password") as manager: # Load from default location await manager.load_credentials_from_file() # Or load from custom path # await manager.load_credentials_from_file("/path/to/token_file.json") # Or set credentials directly # manager.set_credentials( # token="your_token", # account_id="your_account_id", # country_code="US", # region="US" # ) # No login() needed if credentials valid await manager.update() for device in manager.devices: print(f"{device.device_name}: {device.state.device_status}") if __name__ == "__main__": asyncio.run(save_credentials_example()) ``` -------------------------------- ### Asynchronous VeSync Operations with aiohttp Source: https://github.com/webdjoe/pyvesync/blob/dev/docs/pyvesync3.md Demonstrates how to use the pyvesync.VeSync class as an asynchronous context manager for managing devices. It includes logging in, retrieving devices, updating their states, and performing actions like turning outlets on/off. The example also shows how to access device state, last API responses, and convert state to JSON or bytes. ```python import asyncio import aiohttp from pyvesync.vesync import VeSync async def main(): async with VeSync("user", "password", country_code="US") as manager: await manager.login() # Still returns true if not manager.enabled: print("Not logged in.") return await manager.get_devices() # Instantiates supported devices in device list await manager.update() # Updates the state of all devices for outlet in manager.devices.outlets: # The outlet object contain all action methods and static device attributes await outlet.update() await outlet.turn_off() outlet.display() # Print static device information, name, type, CID, etc. # State of object held in `device.state` attribute print(outlet.state) state_json = outlet.dumps() # Returns JSON string of device state state_bytes = orjson.dumps(outlet.state) # Returns bytes of device state # to view the response information of the last API call print(outlet.last_response) # Prints a ResponseInfo object containing error code, # and other response information # Or use your own session session = aiohttp.ClientSession() async def main(): async with VeSync("user", "password", session=session): await manager.login() await manager.update() if __name__ == "__main__": asyncio.run(main()) ``` -------------------------------- ### Manage pyvesync Authentication Credentials Source: https://github.com/webdjoe/pyvesync/blob/dev/docs/index.md This Python code illustrates how to handle authentication with the pyvesync library. It covers logging in with username and password, saving and loading credentials from a file, setting credentials directly, and outputting them as JSON or a dictionary. The `VeSync` class is essential for these operations. Note that username and password are required for initial login as tokens can expire. ```python from pyvesync import VeSync async def main(): async with VeSync(username="EMAIL", password="PASSWORD") as manager: await manager.login() # Login with username and password if not manager.enabled: print("Login failed") return # Save credentials to file await manager.save_credentials("/path/to/token_file") # Will save to user's home directory as .vesync_token if no path is provided # Load credentials from file await manager.load_credentials_from_file("/path/to/token_file") # Calling with no argument will load the .vesync_token file from user's home directory and then the current working directory. # Or set credentials directly creds = { "token": "your_token", "account_id": "your_account_id", "country_code": "US" # Optional "region": "US" # Optional } manager.set_credentials(**creds) # Output credentials as JSON string await manager.output_credentials_json() # or as a dictionary await manager.output_credentials_dict() # No login needed if token is valid # await manager.login() ``` -------------------------------- ### Control Smart Bulbs with PyVesync Source: https://context7.com/webdjoe/pyvesync/llms.txt This Python script demonstrates how to control smart bulbs using the pyvesync library. It covers authentication, device updates, power management, brightness adjustment, color temperature settings, and both RGB and HSV color mode control. Ensure you have the pyvesync library installed and valid VeSync account credentials. ```python import asyncio from pyvesync import VeSync async def control_bulbs(): async with VeSync("user@example.com", "password") as manager: await manager.login() await manager.update() if not manager.devices.bulbs: print("No bulbs found") return bulb = manager.devices.bulbs[0] await bulb.update() # Power control await bulb.turn_on() await bulb.turn_off() # Brightness control (0-100) if bulb.supports_brightness: await bulb.set_brightness(75) print(f"Brightness: {bulb.state.brightness}%") await bulb.set_brightness(100) # Full brightness await bulb.set_brightness(10) # Dim # Color temperature (if supported) if bulb.supports_color_temp: await bulb.set_color_temp(50) # Warm to cool scale print(f"Color temp: {bulb.state.color_temp}") # RGB color control (if supported) if bulb.supports_rgb: # Set RGB color (red, green, blue: 0-255) await bulb.set_rgb(255, 0, 0) # Red await bulb.set_rgb(0, 255, 0) # Green await bulb.set_rgb(255, 100, 0) # Orange await bulb.set_rgb(128, 0, 128) # Purple print(f"Color mode: {bulb.state.color_mode}") print(f"RGB: ({bulb.state.color.red}, {bulb.state.color.green}, {bulb.state.color.blue})") # HSV color control (if supported) if bulb.supports_rgb: # Set HSV (hue: 0-360, saturation: 0-100, value: 0-100) await bulb.set_hsv(hue=120, saturation=100, value=100) # Green await bulb.set_hsv(hue=240, saturation=100, value=100) # Blue if bulb.state.color: print(f"HSV: ({bulb.state.color.hue}, {bulb.state.color.saturation}, {bulb.state.color.value})") # Display device info bulb.display() # Check supported features print(f"Supports brightness: {bulb.supports_brightness}") print(f"Supports color temp: {bulb.supports_color_temp}") print(f"Supports RGB: {bulb.supports_rgb}") if __name__ == "__main__": asyncio.run(control_bulbs()) ``` -------------------------------- ### Serialize Device State to JSON, Dict, and Binary with Python Source: https://context7.com/webdjoe/pyvesync/llms.txt Export device state as JSON, dictionary, or binary format for storage, logging, or integration. This function logs into VeSync, updates device information, and demonstrates how to get and display device status, power, voltage, and other attributes. It also shows how to save the full device state including static attributes to local files in JSON format. ```python import asyncio import json from pyvesync import VeSync async def state_serialization(): async with VeSync("user@example.com", "password") as manager: await manager.login() await manager.update() if not manager.devices.outlets: print("No outlets found") return outlet = manager.devices.outlets[0] await outlet.update() # Display formatted device info to console outlet.display() # Output: # Device Name: Living Room Outlet # Model: ESW15-USA # Type: wifi-switch-1.3 # Status: on # Power: 125.5W # Voltage: 120.1V # etc. # Export state as dictionary state_dict = outlet.state.to_dict() print(json.dumps(state_dict, indent=2)) # { # "device_status": "on", # "connection_status": "online", # "power": 125.5, # "voltage": 120.1, # "current": 1.045, # "energy": 2.34, # ... # } # Export state as JSON string state_json = outlet.state.to_json(indent=True) print(state_json) # Export state as bytes (using orjson) state_bytes = outlet.state.to_jsonb() print(f"Serialized size: {len(state_bytes)} bytes") # Export full device info including static attributes device_json = outlet.to_json(state=True, indent=True) device_dict = outlet.to_dict(state=True) # Example: Save state to file with open("outlet_state.json", "w") as f: f.write(outlet.to_json(state=True, indent=True)) # Example: Save all device states all_devices_state = [] for device in manager.devices: all_devices_state.append({ "name": device.device_name, "type": device.device_type, "state": device.state.to_dict() }) with open("all_devices.json", "w") as f: json.dump(all_devices_state, f, indent=2) print(f"Saved state for {len(all_devices_state)} devices") if __name__ == "__main__": asyncio.run(state_serialization()) ``` -------------------------------- ### Manual VeSync Context Management Source: https://github.com/webdjoe/pyvesync/blob/dev/README.md Illustrates how to manually enter and exit the asynchronous context manager for the VeSync class when automatic handling via `async with` is not preferred. This method requires explicit calls to `__aenter__` and `__aexit__`. ```python manager = VeSync(user, password) await manager.__aenter__() ... await manager.__aexit__(None, None, None) ``` -------------------------------- ### Outputting Device and State Data to Dictionaries in Python Source: https://github.com/webdjoe/pyvesync/blob/dev/docs/index.md Illustrates how to convert device and state attributes into a Python dictionary using the `to_dict()` method, which is useful for logging and debugging. It shows how to access specific attributes like 'device_name' and 'device_status' from the resulting dictionary. ```python device = manager.outlets[0] dev_dict = device.to_dict(state=True) # Dictionary of device and state attributes dev_dict["device_name"] # Get the device name from the dictionary dev_dict["device_status"] # Returns device status as a StrEnum ``` -------------------------------- ### Accessing Device State Attributes in Python Source: https://github.com/webdjoe/pyvesync/blob/dev/docs/index.md Demonstrates how to retrieve device status, connection status, and voltage from a device's state object. It utilizes StrEnum for representing states like ON/OFF and ONLINE/OFFLINE. ```python print(outlet.state.device_status) DeviceStatus.ON # StrEnum representing the "on" state print(outlet.state.connection_status) ConnectionStatus.ONLINE # StrEnum representing the "online" state print(outlet.state.voltage) 120.0 # Voltage of the device ``` -------------------------------- ### Run frida script with VeSync application Source: https://github.com/webdjoe/pyvesync/blob/dev/docs/development/capturing.md This command initiates the frida script to attach to the VeSync application (com.etekcity.vesyncplatform) on a connected USB device (-U). It utilizes a shared frida script for handling SSL unpinning. ```bash frida -U --codeshare akabe1/frida-multiple-unpinning -f com.etekcity.vesyncplatform ``` -------------------------------- ### Manage VeSync Credentials and Devices Source: https://github.com/webdjoe/pyvesync/blob/dev/docs/index.md This snippet shows how to manage VeSync credentials, including loading from and saving to files, setting credentials directly, and then interacting with devices. It utilizes the asynchronous context manager pattern and requires `pyvesync` and `asyncio`. ```python import asyncio from pyvesync import VeSync # VeSync is an asynchronous context manager # VeSync(username, password, redact=True, session=None) async def main(): async with VeSync("user", "password") as manager: # If credentials are stored in a file, it can be loaded # the default location is ~/.vesync_token await manager.load_credentials_from_file() # or the file path can be passed await manager.load_credentials_from_file("/path/to/token_file") # Or credentials can be passed directly manager.set_credentials("your_token", "your_account_id") # No login needed # await manager.login() # To store credentials to a file after login await manager.save_credentials() # Saves to default location ~/.vesync_token # or pass a file path await manager.save_credentials("/path/to/token_file") # Output Credentials as JSON String await manager.output_credentials() await manager.update() # Acts as a set of device instances device_container = manager.devices outlets = device_container.outlets # List of outlet instances outlet = outlets[0] await outlet.update() await outlet.turn_off() outlet.display() # Iterate of entire device list for devices in device_container: device.display() if __name__ == "__main__": asyncio.run(main()) ```