Repository navigation
Releases: jandado/smartbox
Releases · jandado/smartbox
Release list
2.7.0
2.7.0
Highlights
- New per-user websocket transport (
ws_user):WsUserSocketSession— one connection serves every device of the account, replacing the N per-devicesocket_iosessions that suffer the backend's missing pings (theServer has stopped communicating85-second cycle). Server-side proxy PINGs supervise the session; the server cuts the socket exactly at the access token's 4 h expiry (close code 1006) and the reconnect with a fresh token is mandatory and part of the steady state. check_ws_user_support()probe +WsUserUnsupportedErrorand the fallback doctrine: only deterministic handshake rejections signal "endpoint unsupported"; transient trouble is retried and never demotes.UpdateManagergains aws_user_socket=kwarg so availability tracking and writes route through whichever transport is active.- Shared retry/backoff helpers for the REST side.
- CLI: authentication options resolve from
SMARTBOX_*environment variables and a.envfile (searched upward from the working directory; precedence command line > shell >.env). - README rewritten: library usage, every CLI command documented,
.envsection, websocket transports section.
Fixes
.envparsing follows python-dotenv semantics: an inline#starts a comment only when it is preceded by whitespace and lies outside quotes, and quoted values unquote cleanly even when a trailing comment follows. Previously inline comments silently became part of the value (corrupting credentials written in the conventional quoted style).
Breaking
UpdateManager.socket_sessionreturnsNoneinws_usermode (previously always aSocketSession); use the newws_user_socketaccessor to distinguish modes.
Internal
UpdateManager: the four identicalsubscribe_to_node_*bodies share one_subscribe_to_node_keyimplementation; public API unchanged (contract tests).- Socket tests for namespace callbacks, websocket cleanup, SIGINT handling and cancellation during connect; coverage floor raised to 95% (
socket.pyno longer excluded); ruff and mypy run overtests/in CI.
2.6.2
smartbox v2.6.2
Port round of upstream PR #64 (improvements/fix_bugs, 19 commits). Every commit was audited intent-level against this tree — full per-commit verdicts and evidence in ajtudela-pr-64-audit.md. Ten commits were independently fixed by the 2.6.x round; of the remainder, seven were ported, one declined by decision, one is upstream-only.
Bug fixes
set_node_setupcan no longer wipe undeclared setup keys on the device (upstream5618aa3). The setup endpoint requires the whole configuration to be re-posted; the read-modify-write GET is now always raw, so keys the setup models do not declare (e.g.counter_offseton pmo nodes) survive every write. Completed withextra="allow"onDefaultNodeSetup/PmoSetup: typed (raw_response=False) reads keep unknown keys and round-trip losslessly.- Common exception root (upstream
62efcf8):InvalidAuthError,APIUnavailableErrorandResellerNotExistErrornow derive fromSmartboxError— oneexcept SmartboxErrorcatches every library failure.APIUnavailableErrorkeeps itsaiohttp.ClientConnectionErrorbase for backwards compatibility; the data-path 403 →SmartboxErrormapping is kept deliberately. - CLI: unknown
-d/-nvalues raiseclick.BadParameterwith aparam_hint(exit code 2, usage line rendered, offending option named) instead of a generic error; malformed wire node payloads stay runtime errors (upstream6ad2014).
Build & docs
- Core dependencies bounded to their current major:
aiohttp>=3,<4,pydantic>=2,<3,python-socketio>=5,<6(upstreamda3bb9c). .vscode/settings.json: pylint/flake8 editor settings replaced with the ruff formatter/code-actions setup (upstreama78bc3a).- CODEOWNERS co-owner and README badge reflow adopted from upstream (upstream
2ec1ef0). - README staleness fixes: duplicate empty
Installationheading removed,--basic-auth-credslong option corrected, Python floor>=3.14.2,tox -e py314, basic-auth pointer moved toapi-notes.md.
Tests
test_all_resellers(real HTTP calls to twelve reseller servers) moved behind anetworkmarker, deselected by default; run on demand withpytest -m network. Sessions in it are closed (upstream0bef64c).
Deliberately not ported
- The catch-all
DefaultNodeStatusfallback (upstream6d592bf): typed mode (raw_response=False) keeps rejecting sparse payloads withSmartboxValidationErrorand the offending wire payload attached — the documented bare{"sync_status": "lost"}dead-node frame is first-class in that design, and silently-Nonefields would hide firmware drift. Rationale in the audit doc.
Full changes since 2.6.1: see the 2.6.2 section of the CHANGELOG.
2.6.1
Release notes 2.6.1
Features
- Node availability tracking on
UpdateManager:subscribe_to_node_availability/get_node_availabilityreport each node as Available/Unavailable from its status/setup frames. A bare{"sync_status": "lost"}frame arms a uniform 6 s grace timer (configurable viaunavailable_delay, matching the vendor app's unreachable window); any ok frame reports Available again. - Write-confirmation tracking:
expect_write_confirmation(knobwrite_confirm_timeout, 6 s) opens a window after each accepted write. If no ok frame arrives, a one-shot discriminating GET decides whether the write was applied (node alive) or silently dropped (node unreachable) — writes to unreachable nodes are ACKed OK with no device ack. Frame taps register lazily and are shared by both features; each enables them independently.
Improvements
SmartboxValidationErrornow carries the offending wire payload as.payload, so callers can inspect the actual shape (e.g. distinguish a documented dead-node status frame from other drift).
Both features are backed by live probes from 2026-09-26/30 (api-notes.md, "Node reachability").