From a772faecbedd7b55d854d8ae0b236f21a8246720 Mon Sep 17 00:00:00 2001 From: Joe Trabulsy Date: Sun, 22 Dec 2024 22:09:10 -0500 Subject: [PATCH 1/2] Update documentation --- .gitignore | 3 ++- src/pyvesync/vesyncbulb.py | 51 ++++++++++++++++++++++++++---------- src/pyvesync/vesyncswitch.py | 37 ++++++++++++++++++++++++-- 3 files changed, 74 insertions(+), 17 deletions(-) diff --git a/.gitignore b/.gitignore index 58efc16..1ccc7fe 100644 --- a/.gitignore +++ b/.gitignore @@ -35,4 +35,5 @@ pyvesync.und mkdocs.yml requirements-docs.txt docs/ -site/ \ No newline at end of file +site/ +overrides/ \ No newline at end of file diff --git a/src/pyvesync/vesyncbulb.py b/src/pyvesync/vesyncbulb.py index 8cf7f42..8201dd2 100644 --- a/src/pyvesync/vesyncbulb.py +++ b/src/pyvesync/vesyncbulb.py @@ -16,7 +16,7 @@ Note: The bulb module is built from the `feature_dict` dictionary and used by the `vesync.object_factory` and tests to determine the class to instantiate for - each bulb model. + each bulb model. These classes should not be instantiated manually. Examples: The following example shows the structure of the `feature_dict` dictionary: @@ -48,6 +48,8 @@ NUMERIC_T = Optional[Union[int, float, str]] +# --8<-- [start:feature_dict] + feature_dict: dict = { 'ESL100': { @@ -75,10 +77,11 @@ } } +# --8<-- [end:feature_dict] bulb_modules: dict = {k: v['module'] for k, v in feature_dict.items()} -__all__: list = list(bulb_modules.values()) + ['bulb_modules'] +__all__: list = list(bulb_modules.values()) + ["bulb_modules", "VeSyncBulb"] def pct_to_kelvin(pct: float, max_k: int = 6500, min_k: int = 2700) -> float: @@ -91,7 +94,8 @@ class VeSyncBulb(VeSyncBaseDevice): Abstract base class to provide methods for controlling and getting details of VeSync bulbs. Inherits from - [`VeSyncBaseDevice`][pyvesync.vesyncbasedevice.VeSyncBaseDevice]. + [`VeSyncBaseDevice`][pyvesync.vesyncbasedevice.VeSyncBaseDevice]. This class + should not be used directly for devices, but rather subclassed for each. Attributes: brightness (int): Brightness of bulb (0-100). @@ -539,7 +543,26 @@ def display(self) -> None: print(f'{line[0]:.<30} {line[1]} {line[2]}') def displayJSON(self) -> str: - """Return bulb device info in JSON format.""" + """Return bulb device info in JSON format. + + Returns: + str: JSON formatted string of bulb details. + + Example: + ```json + { + "deviceName": "Bulb", + "deviceStatus": "on", + "connectionStatus": "online", + "Brightness": "100%", + "WhiteTemperaturePct": "100%", + "WhiteTemperatureKelvin": "6500K", + "ColorHSV": "{"hue": 0, "saturation": 0, "value": 0}", + "ColorRGB": "{"red": 0, "green": 0, "blue": 0}", + "ColorMode": "hsv" + } + ``` + """ sup = super().displayJSON() sup_val = json.loads(sup) if self.connection_status == 'online': @@ -595,17 +618,16 @@ class VeSyncBulbESL100MC(VeSyncBulb): two named tuple attributes - `hsv` & `rgb`. See [pyvesync.helpers.Color][]. Notes: - The `self.details` dictionary is structured as follows: + The details dictionary contains the device information retreived by the + `update()` method: ```python - >>> self.details - { - 'brightness': 0, - 'colorMode': 'color', - 'red': 0, - 'green': 0, - 'blue': 0 + details = { + 'brightness': 50, + 'colorMode': 'rgb', + 'color' : Color(red=0, green=0, blue=0) } ``` + See pyvesync.helpers.Color for more information on the Color dataclass. """ def __init__(self, details: dict[str, str | list], manager: VeSync) -> None: @@ -613,7 +635,7 @@ def __init__(self, details: dict[str, str | list], manager: VeSync) -> None: Args: details (dict): Dictionary of bulb state details. - manager (VeSync): Manager class used to make API calls + manager (VeSync): Manager class used to make API calls. """ super().__init__(details, manager) self.details: dict = {} @@ -811,7 +833,8 @@ def toggle(self, status: str) -> bool: class VeSyncBulbESL100(VeSyncBulb): """Object to hold VeSync ESL100 light bulb. - This bulb only has the dimmable feature. + This bulb only has the dimmable feature. Inherits from pyvesync.vesyncbulb.VeSyncBulb + and pyvesync.vesyncbasedevice.VeSyncBaseDevice. Attributes: details (dict): Dictionary of bulb state details. diff --git a/src/pyvesync/vesyncswitch.py b/src/pyvesync/vesyncswitch.py index af06fc0..b356424 100644 --- a/src/pyvesync/vesyncswitch.py +++ b/src/pyvesync/vesyncswitch.py @@ -1,4 +1,24 @@ -"""Classes for VeSync Switch Devices.""" +"""Classes for VeSync Switch Devices. + +This module provides classes for VeSync Switch Devices: + + 1. VeSyncSwitch: Abstract Base class for VeSync Switch Devices. + 2. VeSyncWallSwitch: Class for VeSync Wall Switch Devices ESWL01 and ESWL03. + 3. VeSyncDimmerSwitch: Class for VeSync Dimmer Switch Devices ESWD16. + + +Attributes: + feature_dict (dict): Dictionary of switch models and their supported features. + Defines the class to use for each switch model and the list of features + switch_modules (dict): Dictionary of switch models as keys and their associated classes + as string values. + +Note: + The switch device is built from the `feature_dict` dictionary and used by the + `vesync.object_factory` during initial call to pyvesync.vesync.update() and + determines the class to instantiate for each switch model. These classes should + not be instantiated manually. +""" import logging import json @@ -10,6 +30,8 @@ logger = logging.getLogger(__name__) +# --8<-- [start:feature_dict] + feature_dict: Dict[str, Dict[str, Union[list, str]]] = { 'ESWL01': { 'module': 'VeSyncWallSwitch', @@ -25,6 +47,8 @@ } } +# --8<-- [end:feature_dict] + switch_modules: dict = {k: v['module'] for k, v in feature_dict.items()} @@ -32,7 +56,16 @@ class VeSyncSwitch(VeSyncBaseDevice): - """Etekcity Switch Base Class.""" + """Etekcity Switch Base Class. + + Abstract Base Class for Etekcity Switch Devices, inherting from + pyvesync.vesyncbasedevice.VeSyncBaseDevice. Should not be instantiated directly, + subclassed by VeSyncWallSwitch and VeSyncDimmerSwitch. + + Attributes: + features (list): List of features supported by the switch device. + details (dict): Dictionary of switch device details. + """ __metaclasss__ = ABCMeta From 72cdfe83a135562b6557593870feadbd8ad8f2ae Mon Sep 17 00:00:00 2001 From: Joe Trabulsy Date: Mon, 23 Dec 2024 00:06:05 -0500 Subject: [PATCH 2/2] Bump version & docs --- CONTRIBUTING.md | 12 +++++++----- setup.py | 2 +- src/pyvesync/vesyncswitch.py | 4 ++-- tox.ini | 1 + 4 files changed, 11 insertions(+), 8 deletions(-) diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md index 82373da..f6b13f1 100644 --- a/CONTRIBUTING.md +++ b/CONTRIBUTING.md @@ -1,4 +1,6 @@ -# Setting up the Development Environment +# Contributing to the pyvesync Library + +## Setting up the Development Environment 1. Git clone the repository @@ -33,7 +35,7 @@ If the above steps were executed successfully, you should now have: Any change in the code will now be directly reflected and can be tested. To deactivate the python venv, simply run `deactivate`. -# Testing Python with Tox +## Testing Python with Tox Install tox, navigate to the pyvesync repository which contains the tox.ini file, and run tox as follows: @@ -48,12 +50,12 @@ tox -e lint # flake8 & pydocstrings tox -e mypy # type checkings ``` -Tests are run based off of the API calls recorded in the [api](src/tests/api) directory. Please read the [Test Readme](src/tests/README.md) for further details on the structure of the tests. +Tests are run based off of the API calls recorded in the [api](src/tests/api) directory. Please read the [Test Readme](src/tests/README.md) for further details on the structure of the tests. # Ensure new devices are Integrated in Tests -If you integrate a new device, please read the [testing README](tests/README.md) to ensure that your device is tested. +If you integrate a new device, please read the [testing README](src/tests/README.md) to ensure that your device is tested. ## Testing with pytest and Writing API to YAML @@ -85,4 +87,4 @@ If fixing an existing device where the API call was incorrect or the api has cha pytest --write_api --overwrite tox -e testenv -- --write_api --overwrite -``` +``` \ No newline at end of file diff --git a/setup.py b/setup.py index 2eadd75..ba72123 100644 --- a/setup.py +++ b/setup.py @@ -10,7 +10,7 @@ setup( name='pyvesync', - version='2.1.13', + version='2.1.14', description='pyvesync is a library to manage Etekcity\ Devices, Cosori Air Fryers and Levoit Air \ Purifiers run on the VeSync app.', diff --git a/src/pyvesync/vesyncswitch.py b/src/pyvesync/vesyncswitch.py index b356424..90315d8 100644 --- a/src/pyvesync/vesyncswitch.py +++ b/src/pyvesync/vesyncswitch.py @@ -10,8 +10,8 @@ Attributes: feature_dict (dict): Dictionary of switch models and their supported features. Defines the class to use for each switch model and the list of features - switch_modules (dict): Dictionary of switch models as keys and their associated classes - as string values. + switch_modules (dict): Dictionary of switch models as keys and their associated + classes as string values. Note: The switch device is built from the `feature_dict` dictionary and used by the diff --git a/tox.ini b/tox.ini index 163f248..5eb0268 100644 --- a/tox.ini +++ b/tox.ini @@ -26,4 +26,5 @@ ignore_errors = True deps = mypy types-requests +allowlist_externals = mypy commands = mypy src/pyvesync \ No newline at end of file