From eacce0b6c7752d1d1d248b1df6705958508ee7c5 Mon Sep 17 00:00:00 2001 From: Aritz Herrero Date: Wed, 23 Dec 2020 01:27:01 +0100 Subject: [PATCH] Restructure the project for PyPi - Move some files and fix some minor issues - Add setup.py for PyPi - Add README - Add .gitignore - Add unittest test First release - v1.0.0 --- .gitignore | 8 ++ README.md | 93 +++++++++++++++++++ setup.py | 26 ++++++ test.py | 26 ------ __init__.py => tests/__init__.py | 0 tests/test.py | 55 +++++++++++ trionesControl/__init__.py | 0 .../trionesControl.py | 4 +- 8 files changed, 184 insertions(+), 28 deletions(-) create mode 100644 .gitignore create mode 100644 README.md create mode 100644 setup.py delete mode 100644 test.py rename __init__.py => tests/__init__.py (100%) create mode 100644 tests/test.py create mode 100644 trionesControl/__init__.py rename trionesControl.py => trionesControl/trionesControl.py (96%) diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..dd59796 --- /dev/null +++ b/.gitignore @@ -0,0 +1,8 @@ +venv +__pycache__ +.vscode +dist/ +*.py[co] +*.egg-info/ +*.egg +build/ \ No newline at end of file diff --git a/README.md b/README.md new file mode 100644 index 0000000..e22993c --- /dev/null +++ b/README.md @@ -0,0 +1,93 @@ +# trionesControl + +This module implements the triones protocol reverse engineered by [madhead](https://github.com/madhead) with python, offering a programmatic way to control these kind of lights without needing the app on your phone. To learn more about the protocol, please read the following specification: + +* [madhead - saberlight/protocols/Triones/protocol.md](https://github.com/madhead/saberlight/blob/master/protocols/Triones/protocol.md) + +## Requirements + +This package only works on Linux, it uses pygatt and depends on blueZ. + +The package has been tested in python 3 (3.8.5) but it may work on previous versions, even python 2.7, as long as [pygatt requirements](https://github.com/peplin/pygatt#requirements) are met. + +## Installation + +Install ``trionesControl`` with pip from PyPI: + + pip install trionesControl + +This will install all the dependencies used by this package and ``pexpect``, an optional ``pygatt`` needed to use it's BlueZ backend. + +## Documentation + +### Connexion handling + +* ``connect(MAC)``: Connect to the device with the mac address specified. + +* ``disconnect(device)``: Disconnects from the specified device. + +### LED Control + +* ``powerOn(device)``: Powers on the device, the LEDs will turn on. + +* ``powerOff(device)``: Powers off the device, the LEDs will turn off. + +* ``setRGB(r: int, g: int, b: int, device)``: Sets the LED color configuration of the device to the r, g and b colors. (0-255) + +* ``setWhite(intensity: int, device)``: Sets the device's LED to white with the specified intensiy. (0-255) + +* ``setBuiltIn(mode: int, speed: int, device)``: Activates the selected predefined built-in mode at the selected speed (0-255). The built modes go from 37 to 56. + +## Example use + +The unittest code available in [tests/test.py](https://github.com/Aritzherrero4/python-trionesControl/blob/master/tests/test.py) can be used as a sample to use the available functions of the package. You can test your bulb / LED strip by using the following code too. + +### Connect and power on the device + +```python +import time +import trionesControl.trionesControl as tc + +#Change the mac address to the one of your bulb or LED strip +device = tc.connect('00:00:00:00:00:00') +tc.powerOn(device) +``` + +### Change colors + +```python +# RGB mode +tc.setRGB(100,100,100, device) +time.sleep(1) +tc.setRGB(255, 255, 255, device) +time.sleep(1) +tc.setRGB(255,0,0, device) +time.sleep(1) +tc.setRGB(0,255,0, device) + +#White mode +time.sleep(10) +tc.setWhite(255, device) +``` + +### Built-in modes + +```python +#Change built-in modes (37-56) +time.sleep(10) +tc.setBuiltIn(37, 1) +tc.time(10) +``` + +### Power off and disconnect + +```python +tc.powerOff(device) +tc.disconnect(device) +``` + +## Licence + +MIT Licence - Copyright 2020 Aritz Herrero + +For more information, check [LICENCE](https://github.com/Aritzherrero4/python-trionesControl/blob/master/LICENSE) file. diff --git a/setup.py b/setup.py new file mode 100644 index 0000000..bbf14c8 --- /dev/null +++ b/setup.py @@ -0,0 +1,26 @@ +import setuptools + +with open("README.md", "r") as fh: + long_description = fh.read() + +setuptools.setup( + name="trionesControl", + version="1.0.0", + author="Aritz Herrero", + description="Simple python package to control smart lights using the Triones porotocol", + long_description=long_description, + long_description_content_type="text/markdown", + url="https://github.com/Aritzherrero4/python-trionesControl", + license="MIT", + packages=setuptools.find_packages(exclude=("tests",)), + classifiers=[ + "Intended Audience :: Developers", + "Programming Language :: Python :: 3", + "Programming Language :: Python :: 3.7", + "Programming Language :: Python :: 3.8", + "License :: OSI Approved :: MIT License", + "Operating System :: POSIX :: Linux", + ], + install_requires=["pygatt", "pexpect"], + python_requires='>=3.6' +) \ No newline at end of file diff --git a/test.py b/test.py deleted file mode 100644 index 5e6dbd9..0000000 --- a/test.py +++ /dev/null @@ -1,26 +0,0 @@ -import time -import trionesControl as tc - -device = tc.connect('00:00:00:00:00:00') -chars = device.discover_characteristics() -tc.powerOn(device) -tc.setRGB(100,100,100, device) -time.sleep(1) -tc.setRGB(255, 255, 255, device) -time.sleep(1) -tc.setRGB(255,0,0, device) -time.sleep(1) -tc.setRGB(0,255,0, device) -time.sleep(1) -tc.setRGB(0,0,255, device) -time.sleep(1) -tc.setRGB(0,0,255, device) -time.sleep(1) -tc.setRGB(150,0,150, device) -time.sleep(10) -tc.setWhite(255, device) -time.sleep(10) -tc.setBuiltIn(37, 1) -tc.time(10) -tc.powerOff(device) -tc.disconnect(device) diff --git a/__init__.py b/tests/__init__.py similarity index 100% rename from __init__.py rename to tests/__init__.py diff --git a/tests/test.py b/tests/test.py new file mode 100644 index 0000000..09a86d5 --- /dev/null +++ b/tests/test.py @@ -0,0 +1,55 @@ +import time +from trionesControl import trionesControl as tc +import logging +import unittest + +#Set the MAC address of the lights before executing +device = tc.connect('00:00:00:00:00:00') +chars = device.discover_characteristics() + + +log = logging.getLogger(__name__) +logging.basicConfig(level=20) + +class fullTestCase(unittest.TestCase): + def powerOn(self): + tc.powerOn(device) + + def colorChange(self): + tc.setRGB(100,100,100, device) + time.sleep(1) + tc.setRGB(255, 255, 255, device) + time.sleep(1) + tc.setRGB(255,0,0, device) + time.sleep(1) + tc.setRGB(0,255,0, device) + time.sleep(1) + tc.setRGB(0,0,255, device) + time.sleep(1) + tc.setRGB(0,0,255, device) + time.sleep(1) + tc.setRGB(150,0,150, device) + time.sleep(2) + + def setWhite(self): + tc.setWhite(255, device) + time.sleep(10) + + def builtIn(self): + tc.setBuiltIn(37, 1, device) + time.sleep(10) + + def powerOff(self): + time.sleep(10) + tc.powerOff(device) + tc.disconnect(device) + + def testLights(self): + self.powerOn() + self.colorChange() + self.setWhite() + self.builtIn() + self.powerOff() + +if __name__ == '__main__': + unittest.main() \ No newline at end of file diff --git a/trionesControl/__init__.py b/trionesControl/__init__.py new file mode 100644 index 0000000..e69de29 diff --git a/trionesControl.py b/trionesControl/trionesControl.py similarity index 96% rename from trionesControl.py rename to trionesControl/trionesControl.py index 60369bb..3b8e81e 100644 --- a/trionesControl.py +++ b/trionesControl/trionesControl.py @@ -33,7 +33,7 @@ def powerOff(device): log.info("Device powered off") def setRGB(r: int, g: int, b: int, device): - # Values for color shoud be between 0 and 255 + # Values for color should be between 0 and 255 if r > 255: r = 255 if r < 0: r= 0 if g > 255: g = 255 @@ -71,7 +71,7 @@ def setWhite(intensity: int, device): device.char_write_handle(0x0009, payload) except pygatt.exceptions.NotConnectedError: raise pygatt.exceptions.NotConnectedError("Device nor connected!") - log.info("White color set -- Intensiti %d", intensity) + log.info("White color set -- Intensity: %d", intensity) def setBuiltIn(mode: int, speed: int, device): if mode<37 | mode > 56: