Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
7 changes: 3 additions & 4 deletions .github/workflows/pylint.yml → .github/workflows/ruff.yml
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
name: Pylint
name: RuffLint

on: [push]

Expand All @@ -17,8 +17,7 @@ jobs:
- name: Install dependencies
run: |
python -m pip install --upgrade pip
pip install pylint
pip install -r requirements.txt
pip install ruff
- name: Analyzing the code with pylint
run: |
pylint --recursive y -E tinytuya/
ruff check --output-format=github .
2 changes: 2 additions & 0 deletions examples/cloud_ir.py
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,8 @@

#tinytuya.set_debug()

DEVICEID = "01234567891234567890"

# Set this to the actual blaster device, not a virtual remote
device_id = DEVICEID

Expand Down
3 changes: 3 additions & 0 deletions examples/cloud_rgb_bulb.py
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,9 @@
import colorsys
import time


DEVICEID = "01234567891234567890"

# Set these values for your device
id = DEVICEID
cmd_code = 'colour_data_v2' # look at c.getstatus(id) to see what code should be used
Expand Down
4 changes: 4 additions & 0 deletions examples/getstatus.py
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,10 @@
import tinytuya
import time

DEVICEID = "01234567891234567890"
DEVICEIP = "10.0.1.99"
DEVICEKEY = "0123456789abcdef"

# Connect to the device - replace with real values
d=tinytuya.OutletDevice(DEVICEID, DEVICEIP, DEVICEKEY)
d.set_version(3.3)
Expand Down
4 changes: 4 additions & 0 deletions examples/send_raw_dps.py
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,10 @@
"""
import tinytuya

DEVICEID = "01234567891234567890"
DEVICEIP = "10.0.1.99"
DEVICEKEY = "0123456789abcdef"

# Connect to the device - replace with real values
d=tinytuya.OutletDevice(DEVICEID, DEVICEIP, DEVICEKEY)
d.set_version(3.3)
Expand Down
161 changes: 160 additions & 1 deletion pyproject.toml
Copy link
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

BTW, it was always on my list to get this done. Thank you!! 🙏 :)

Original file line number Diff line number Diff line change
@@ -1,2 +1,161 @@
[project]
name = "tinytuya"
dynamic = ["version", "readme"]
authors = [
{ name = "Jason Cox", email = "[email protected]" },
]
description = "Python module to interface with Tuya WiFi smart devices"
classifiers = [
"Programming Language :: Python :: 3",
"License :: OSI Approved :: MIT License",
"Operating System :: OS Independent",
]

dependencies = [
"colorama",
"requests",
]

requires-python = ">= 3.8"
Copy link
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think this is fine. This aligns to end of life with python version (https://devguide.python.org/versions/)

@uzlonewolf thoughts?


[project.optional-dependencies]
cryptography = ["cryptography>=3.1"]
pycryptodome = ["pycryptodome"]
pyaes = ["pyaes"]
pycrypto = ["pycrypto"]

Copy link
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We had added the logic to setup.py for some small IoT devices/platforms that couldn't use some of these. I believe the intent was to allow the user to install one that did and the tinytuya iinstall would continue without insisting on cryptography. Yeah, I don't think it worked well. I do wonder how this would change that use case, if at all.

[project.urls]
Homepage = "https://github.com/jasonacox/tinytuya"
Repository = "https://github.com/jasonacox/tinytuya"

[project.scripts]
tinytuya = "tinytuya.__main__:dummy"

[build-system]
requires = ["setuptools", "colorama", "requests", "cryptography"]
requires = ["setuptools"]
build-backend = "setuptools.build_meta"

[tool.setuptools.dynamic]
version = {attr = "tinytuya.core.core.__version__"}
readme = {file = ["README.md"], content-type = "text/markdown"}

[tool.setuptools.packages.find]
exclude = ["sandbox"]

[dependency-groups]
dev = [
"ruff>=0.9.2",
]


[tool.ruff]
include = [
"pyproject.toml",
"tinytuya/**/*.py",
"Contrib/**/*.py",
"server/**/*.py",
"examples/**/*.py",
"tools/**/*.py",
]

[tool.ruff.lint]
extend-select = [
"D419", # empty-docstring
"W291", # trailing-whitespace
"PLC0414", # useless-import-alias
"PLC2401", # non-ascii-name
"PLC3002", # unnecessary-direct-lambda-call
"PLE0101", # return-in-init
"F706", # return-outside-function
"F704", # yield-outside-function
"PLE0115", # nonlocal-and-global
"PLE0116", # continue-in-finally
"PLE0117", # nonlocal-without-binding
"PLE0241", # duplicate-bases
"PLE0302", # unexpected-special-method-signature
"PLE0604", # invalid-all-object
"PLE0605", # invalid-all-format
"PLE0643", # potential-index-error
"PLE0704", # misplaced-bare-raise
"PLE1142", # await-outside-async
"PLE1205", # logging-too-many-args
"PLE1206", # logging-too-few-args
"PLE1307", # bad-string-format-type
"PLE1310", # bad-str-strip-call
"PLE1507", # invalid-envvar-value
"PLE1519", # singledispatch-method
"PLE1520", # singledispatchmethod-function
"PLE2502", # bidirectional-unicode
"PLE2510", # invalid-character-backspace
"PLE2512", # invalid-character-sub
"PLE2513", # invalid-character-esc
"PLE2514", # invalid-character-nul
"PLE2515", # invalid-character-zero-width-space
"PLR0124", # comparison-with-itself
"PLR0206", # property-with-parameters
"PLR1704", # redefined-argument-from-local
"PLR1711", # useless-return
"C416", # unnecessary-comprehension
"PLR1736", # unnecessary-list-index-lookup
"PLW0120", # useless-else-on-loop
"PLW0127", # self-assigning-variable
"PLW0128", # redeclared-assigned-name
"PLW0129", # assert-on-string-literal
"B033", # duplicate-value
"PLW0131", # named-expr-without-context
"PLW0211", # bad-staticmethod-argument
"PLW0245", # super-without-brackets
"PLW0406", # import-self
"PLW0602", # global-variable-not-assigned
"PLW0603", # global-statement
"PLW0604", # global-at-module-level
"F401", # unused-import
"PLW0711", # binary-op-exception
"PLW1501", # bad-open-mode
"PLW1508", # invalid-envvar-default
"PLW1509", # subprocess-popen-preexec-fn
"PLW2101", # useless-with-lock
"PLW3301", # nested-min-max
]

ignore = [
"E501", # line-too-long
"F401", # imported but unused
"UP004", # useless-object-inheritance
"PLR0911", # too-many-return-statements
"PLR0912", # too-many-branches
"PLR0913", # too-many-arguments
"PLR0914", # too-many-locals
"PLR0915", # too-many-statements
"PLR1702", # too-many-nested-blocks
"F841", # unused-variable
"E722", # bare-except
"PLW1514", # unspecified-encoding

"E701", # Multiple statements on one line (colon)
"E721", # Use `is` and `is not` for type comparisons, or `isinstance()` for isinstance checks
"F405", # undefined-local-with-import-star-usage
"F403", # undefined-local-with-import-star
"E741", # ambiguous-variable-name
"E711", # none-comparison
"E712", # true-false-comparison
]

[tool.ruff.lint.per-file-ignores]
# this is grandfathering in some existing errors,
# we may want to remove these in the future
"tools/**/*.py" = [
"F821", # undefined-name
"PLR1704",
"PLW0602",
]
"server/**/*.py" = [
"W291",
"PLW0602",
"PLW0603",
]
"examples/**/*.py" = [
"PLW0602",
"PLW0603",
"W291",
]
1 change: 0 additions & 1 deletion server/server.py
Original file line number Diff line number Diff line change
Expand Up @@ -61,7 +61,6 @@

import tinytuya
from tinytuya import scanner
import os

BUILD = "p13"

Expand Down
5 changes: 0 additions & 5 deletions setup.cfg

This file was deleted.

50 changes: 2 additions & 48 deletions setup.py
Original file line number Diff line number Diff line change
@@ -1,50 +1,4 @@
import setuptools
from pkg_resources import DistributionNotFound, get_distribution

from tinytuya import __version__

with open("README.md", "r") as fh:
long_description = fh.read()

INSTALL_REQUIRES = [
'requests', # Used for Setup Wizard - Tuya IoT Platform calls
'colorama', # Makes ANSI escape character sequences work under MS Windows.
#'netifaces', # Used for device discovery, mainly required on multi-interface machines
]

CHOOSE_CRYPTO_LIB = [
'cryptography', # pyca/cryptography - https://cryptography.io/en/latest/
'pycryptodome', # PyCryptodome - https://pycryptodome.readthedocs.io/en/latest/
'pyaes', # pyaes - https://github.com/ricmoo/pyaes
'pycrypto', # PyCrypto - https://www.pycrypto.org/
]

pref_lib = CHOOSE_CRYPTO_LIB[0]
for cryptolib in CHOOSE_CRYPTO_LIB:
try:
get_distribution(cryptolib)
pref_lib = cryptolib
break
except DistributionNotFound:
pass

INSTALL_REQUIRES.append( pref_lib )

setuptools.setup(
name="tinytuya",
version=__version__,
author="Jason Cox",
author_email="[email protected]",
description="Python module to interface with Tuya WiFi smart devices",
long_description=long_description,
long_description_content_type="text/markdown",
url='https://github.com/jasonacox/tinytuya',
packages=setuptools.find_packages(exclude=("sandbox",)),
install_requires=INSTALL_REQUIRES,
entry_points={"console_scripts": ["tinytuya=tinytuya.__main__:dummy"]},
classifiers=[
"Programming Language :: Python :: 3",
"License :: OSI Approved :: MIT License",
"Operating System :: OS Independent",
],
)
setuptools.setup()

2 changes: 1 addition & 1 deletion tinytuya/Cloud.py
Original file line number Diff line number Diff line change
Expand Up @@ -397,7 +397,7 @@ def getdevices(self, verbose=False, oldlist=[], include_map=False):
"""
Return dictionary of all devices.

Args:
Args:
verbose - Returns raw JSON data from Tuya Cloud
oldlist - List of devices from previous run
include_map - Include the DPS mapping in the device list
Expand Down
6 changes: 3 additions & 3 deletions tinytuya/Contrib/ColorfulX7Device.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@
# -*- coding: utf-8 -*-
"""
Python module to interface with Tuya Colorful-X7:
Tuya Smart WiFi Zigbee BT Colorful X7 LED Music Controller SP107E
Tuya Smart WiFi Zigbee BT Colorful X7 LED Music Controller SP107E
Matrix 1024 Pixels LED Panel Light Music Spectrum Controller

Author: Ahmed Chehaibi (https://github.com/CheAhMeD)
Expand All @@ -17,7 +17,7 @@
switch_off() # turns off the device
switch_on() # turns on the device
set_mode(mode) # sets the mode to white | colour | scene | music | screen
set_color(r, g, b) # sets the colour
set_color(r, g, b) # sets the colour
set_countdown(value) # sets the countdown timer value (max 86400)
set_segments_number(number) # sets the number of segments in led strip|matrix (1 to 64)
set_leds_PerSegment(number) # sets the number of leds per segment in led strip|matrix (1 to 150)
Expand Down Expand Up @@ -316,7 +316,7 @@ def set_led_brand(self, brand):

def set_screen_mode(self, mode):
'''
Screen Mode:
Screen Mode:
Like Music mode but for matrix display
choose between 30 available matrix modes
modes don't have a name they are represented by numbers
Expand Down
10 changes: 5 additions & 5 deletions tinytuya/Contrib/DoorbellDevice.py
Original file line number Diff line number Diff line change
Expand Up @@ -5,11 +5,11 @@

Author: JonesMeUp
Tested: LSC-Bell 8S(AKV300_8M)
Note: Without hack the device can't be used offline.
Note: Without hack the device can't be used offline.
With hack the DoorbellDevice is useless.

For more information see https://github.com/jasonacox/tinytuya
https://github.com/jasonacox/tinytuya/issues/162
https://github.com/jasonacox/tinytuya/issues/162

Offline Device
This DoorbellDevice works only if the device is online. Most stay
Expand Down Expand Up @@ -86,7 +86,7 @@ def set_volume(self, vol=10, nowait=False):
if vol < 3:
vol = 3 # Nothing to hear below 3
if vol > 10:
vol = 10
vol = 10
self.set_value(160, int(vol), nowait)

def set_motion_area(self, x=0,y=0,xlen=50, ylen=100, nowait=False):
Expand All @@ -99,10 +99,10 @@ def set_motion_area(self, x=0,y=0,xlen=50, ylen=100, nowait=False):
if ylen < 0: ylen = 0
if xlen > 100: xlen = 100
if ylen > 100: ylen = 100
if x+xlen >100:
if x+xlen >100:
x = 25
xlen = 75
if y+ylen >100:
if y+ylen >100:
y = 25
ylen = 75
data = '{"num":1,"region0":{"x":'+str(x)+',"y":'+str(y)+',"xlen":'+str(xlen)+',"ylen":'+str(ylen)+'}}'
Expand Down
2 changes: 1 addition & 1 deletion tinytuya/Contrib/PresenceDetectorDevice.py
Original file line number Diff line number Diff line change
Expand Up @@ -50,7 +50,7 @@ def status(self):
return status
dps = status[self.DPS_KEY]
retry = 5
while(retry > 0 and not self.PRESENCE_KEY in dps):
while(retry > 0 and self.PRESENCE_KEY not in dps):
retry = retry - 1
status = super().status()
dps = status[self.DPS_KEY]
Expand Down
2 changes: 1 addition & 1 deletion tinytuya/Contrib/WiFiDualMeterDevice.py
Original file line number Diff line number Diff line change
Expand Up @@ -122,7 +122,7 @@ def get_value(self, dps_code, status_data=None):
scale = 1
try:
unit = self.dps_data[dps_code]['unit']
except KeyError:
except KeyError:
unit = ""
val = status_data['dps'][dps_code]
if isinstance(val, int):
Expand Down
1 change: 1 addition & 0 deletions tinytuya/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -97,3 +97,4 @@
from .CoverDevice import CoverDevice
from .BulbDevice import BulbDevice
from .Cloud import Cloud

Loading
Loading