Conversation
- Added troubleshooting notes in README for battery-powered device limitations and polling warnings. - Enhanced scanner output to clarify when no IP is found, indicating potential battery-powered or offline status. - Updated wizard to provide hints for "permission deny" errors, suggesting users check their Tuya IoT subscription. - Bump version to 1.17.7.
There was a problem hiding this comment.
Pull request overview
v1.17.7 focuses on UX improvements across the setup wizard, network scanner output, CLI ergonomics, and documentation to better guide users through common failure modes (battery/offline devices, cloud permission errors, and shell-escaping pitfalls for local keys).
Changes:
- Wizard: add a targeted hint for “permission deny” / code 1010 Tuya Cloud errors.
- Scanner/README/RELEASE: improve messaging + troubleshooting guidance around battery-powered/offline devices and polling frequency.
- CLI: prompt for missing
--keyand validate local key length with clearer error tips.
Reviewed changes
Copilot reviewed 6 out of 6 changed files in this pull request and generated 3 comments.
Show a summary per file
| File | Description |
|---|---|
tinytuya/wizard.py |
Adds a “permission deny / 1010” hint when cloud calls fail. |
tinytuya/scanner.py |
Updates “no IP” status line to be more descriptive. |
tinytuya/core/core.py |
Bumps version tuple to 1.17.7. |
tinytuya/__main__.py |
Improves CLI --key handling (prompt + length validation + usage tips). |
RELEASE.md |
Adds release notes for v1.17.7. |
README.md |
Adds troubleshooting notes on battery devices and polling rates. |
Comments suppressed due to low confidence (3)
tinytuya/scanner.py:1845
- This new message says "Battery-powered or offline", but the PR description/release notes say the scanner should also clearly indicate that local control is not supported when there is no IP. Consider updating the message here to include that local control isn't possible without an IP (and possibly that the device may be sleeping).
print(" %s[%-25.25s] %sNo IP found - Battery-powered or offline%s" %
(term.subbold, name, term.alertdim, term.normal))
tinytuya/wizard.py:196
- The 1010 detection uses a broad substring match (
'1010' in str(err)), which can produce false positives if other codes/messages contain that sequence. Since Cloud errors appear to be formatted like "Code 1010" (see Cloud.py), consider matching more specifically (e.g., checking for "code 1010" case-insensitively) or extracting the numeric code when available.
if 'permission' in str(err).lower() or '1010' in str(err):
print(bold + 'Hint: ' + dim + 'This may indicate your Tuya IoT subscription has expired.')
tinytuya/wizard.py:216
- This same hint logic is duplicated in multiple error branches. Consider factoring it into a small helper (or a local function) so future changes to the hint text/conditions only need to be made once.
if 'permission' in str(err).lower() or '1010' in str(err):
print(bold + 'Hint: ' + dim + 'This may indicate your Tuya IoT subscription has expired.')
print(' Visit https://iot.tuya.com to check and renew your IoT Core service.')
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
- Strip leading/trailing whitespace from keys from all sources (--key, devices.json, prompt) before length validation, preventing false failures from copy-paste artifacts - Guard interactive key prompt with sys.stdin.isatty(); non-interactive contexts (cron, CI, piped input) now exit with a clear error instead of blocking indefinitely - Switch key prompt from input() to getpass.getpass() so the key is not echoed to the terminal or captured in screen recordings/logs; prompt text notes that input is hidden
|
At some point I would like to add something like the "monitor" example to make it easier for people with devices that only send updates asynchronously to figure that out (i.e. #673). Call it |
|
I love that idea! # using devices.json
tinytuya monitor --name "Kitchen Light"
# direct
tinytuya monitor --id $DEVICE_ID --key $KEY --ip $IP --version $VER |
|
I felt __main__ was starting to grow a bit too big and so I moved all the CLI functions into a new file, cli.py. I also reworked the argpase config a bit and moved the CLI commands up into the main I kinda want to add keyboard-interactive DP set commands now but that's going to have to wait for next time 😆 |
|
Oh yeah, either |
|
The fact that all the old commands use |
I thought the same. I'm glad you added the option for both formats... honors the old API but accomodates the more modern --. |
|
I thought about merging this separate from documentation, but since the doc changes are simple, it is probably good to combine under same version. Let me know if you agree. |
|
Sounds good to me. |
v1.17.7 - UX Improvements
on,off,set,get): Improved handling of device local keys that contain special shell characters ($,#,=,:,!) - re: #688:--keyis omitted and the key is not found indevices.json, the CLI now prompts interactively for the key. Input at a terminal prompt bypasses shell interpretation entirely, so no quoting or escaping is needed.