mirror of
https://github.com/maziggy/bambuddy.git
synced 2026-10-09 15:35:39 +02:00
chore(cloud): clarify access-token hint and document the MakerWorld cookie path for China-region accounts (#1396)
Reporter wintsa123 (China-region user, bambulab.cn) couldn't log into Bambuddy. Looked like a code bug; turned out the code is fine and only the docs were wrong. What's already there (no change needed): - PR #1013 (April) added the China region selector to the token-login flow and routes validation to api.bambulab.cn instead of api.bambulab.com. The selector is in the form (frontend/src/pages/ProfilesPage.tsx:204-205) and the backend dispatch is in backend/app/services/bambu_cloud.py:15 + backend/app/api/routes/cloud.py:174. What was wrong: - The in-app `accessTokenHint` said "Paste your Bambu Lab access token (from Bambu Studio)" in all 8 locales. Bambu Studio never exposed the token in any UI, and the profile page on bambulab.com that used to show it has been removed. The hint was pointing users at sources that don't exist. - For China-region accounts the email / password flow is fundamentally unusable because those accounts are bound to phone numbers, not email — token login is the only working path. The hint didn't say so, so reporters kept trying email login first and getting confused. - The wiki's "Access Token Login" section in features/cloud-profiles.md only described the dead profile-page method and a Python-script alternative that only works against the global API. No mention of the China-region selector and no mention of the MakerWorld-cookie method that actually works today. What this change does: - Rewrites `accessTokenHint` in all 8 locales (en, de, fr, it, ja, pt-BR, zh-CN, zh-TW) to state that China-region accounts must use the token path and point at the wiki for the cookie retrieval procedure. zh-CN and zh-TW translations were written for the audience that actually needs this. - Rewrites the wiki's Access Token Login section: adds a "Region: China must use token login" callout, replaces the dead profile-page guidance with the MakerWorld cookie method (both makerworld.com and makerworld.com.cn, with the browser DevTools steps), keeps the Python-script alternative explicitly scoped to global-region accounts, and warns that the cookie value is sensitive and shouldn't be pasted into screenshots or threads. No backend changes. Once a user has the token + Region: China selected, the existing flow works.
This commit is contained in:
@@ -4,6 +4,9 @@ All notable changes to Bambuddy will be documented in this file.
|
||||
|
||||
## [0.2.5b1] - Unreleased
|
||||
|
||||
### Changed
|
||||
- **Cloud login: corrected the access-token hint to reflect that Bambu Lab no longer surfaces the token in any UI, and called out the China-region constraint explicitly (#1396)** — Reporter wintsa123 filed that China-region users can't log into Bambuddy. The code path itself is fine: PR #1013 (April) already added the China-region selector to the login form and routes token validation to `api.bambulab.cn`. The actual gap was documentation. The old in-app `accessTokenHint` said "Paste your Bambu Lab access token (from Bambu Studio)" — but Bambu Studio never exposed the token in any UI, and the profile page on `bambulab.com` that used to show it is gone. For China-region accounts the email/password flow is fundamentally unusable because those accounts are bound to phone numbers, not email — token login is the only path, and the hint didn't say so. Updated `accessTokenHint` in all 8 locales (en/de/fr/it/ja/pt-BR/zh-CN/zh-TW) to state that China accounts must use this path and point at the wiki for the MakerWorld-cookie retrieval procedure. Wiki page `features/cloud-profiles.md` also rewritten under "Access Token Login": adds a "Region: China must use token login" note, replaces the dead "from Bambu Studio" guidance with the working MakerWorld-cookie method (browser DevTools → Application → Cookies → `token`), keeps the Python-script alternative for global-region accounts, and flags that the cookie value is sensitive. No backend changes — the token-validation endpoint accepts both `global` and `china` regions and routes to the right API host already.
|
||||
|
||||
### Fixed
|
||||
- **Virtual Printer (queue / immediate / review modes): AMS data flickered or disappeared in BambuStudio between pushalls on P1S/A1 targets (#1387)** — Reporter vmhomelab ran a Print Queue VP against a P1S, opened BambuStudio, and saw the External Spool only — no AMS. Toggling Auto-Dispatch (which triggers a VP restart) made AMS briefly appear, then it reverted to defaults. Proxy Mode worked fine. The earlier #1371 sticky-keys fix only handled one of two Bambu firmware incremental-push shapes: it preserved cached AMS when the incoming push *omitted* the `ams` key entirely (H2D's common incremental shape). The reporter's P1S firmware (01.09.01.00) instead sends incrementals with the `ams` key present but the inner `ams.ams` array stripped — `{ams_status: 1, humidity: 2}` instead of `{ams: [...], ams_status: 1}`. To the previous sticky-keys check that read as "key present, leave new state alone," so the bridge cache got overwritten with the stripped blob; the slicer's next 1 Hz read saw `ams` with no unit list and fell back to the "no AMS" default render. Toggling Auto-Dispatch restarted the VP and got a fresh pushall in; the next P1S incremental stripped it again. (H2D rarely hits this — its incrementals typically don't carry `ams` at all, so #1371 alone was enough there. The reporter's same-VP-architecture pinging both an H2D and a P1S would observe the H2D works while the P1S doesn't, which is exactly the split that surfaced this.) Fix is a deep-merge applied to the `ams` key inside the bridge cache, mirroring the structure Bambuddy itself already does in `bambu_mqtt.py::_handle_ams_data` (which is why Bambuddy's own AMS display stays coherent on the same firmware): scalar fields like `ams_status` and `humidity` take the new value, but the `ams.ams` array is merged unit-by-unit on `id`, each unit's `tray` array is merged tray-by-tray on `id`, and units / trays the incremental doesn't mention survive intact from the cached full state. A tray-targeted incremental during a print like `{ams: [{id: 0, tray: [{id: 0, state: 11}]}]}` now updates that one tray's state without nuking the other three trays' tray_type/tray_color. Helper added as `_merge_ams_dict` in `backend/app/services/virtual_printer/mqtt_bridge.py` next to `_ip_to_uint32_le`, called from the existing sticky-keys block. Three new regression tests under `TestPushStatusCache` in `backend/tests/unit/test_vp_mqtt_bridge.py` cover the status-only partial (the reporter's exact reproduction), the multi-AMS unit-level merge, and the multi-tray merge. The existing `test_incoming_ams_update_replaces_cached_ams` still passes — fresh full updates still take effect, the merge only protects the cache from stripped incrementals. 32 tests total in that file, all green. Verified the cross-subnet topology from the report (printer / Bambuddy / slicer each on a different /24) is incidental: the symptom is the same regardless of subnet once the partial-shape arrives; the latency just makes the "empty cache when slicer first connects" race more visible. ProxyMode is unaffected because Proxy is raw byte-forwarding rather than a cached-as-base mirror — it never had this class of bug.
|
||||
- **Quick Stats showed Filament Cost = 0 and empty Time Accuracy on pre-upgrade data after the 0.2.4.1 stats rewrite (#1390)** — Reporter IndividualGhost1905 upgraded to 0.2.4.1 (which shipped the per-event aggregation rewrite from #1378) and saw the Stats page split between consistent values (Total Prints / Print Time / Filament Used / Energy / Success Rate matched the archive list) and zero-or-empty ones (Filament Cost, Time Accuracy). Inconsistency was a migration gap: #1378 added six columns to `print_log_entries` — `archive_id`, `cost`, `energy_kwh`, `energy_cost`, `failure_reason`, `created_by_id` — but **didn't backfill any of them**. So every pre-upgrade log entry kept NULL on all six. The new Quick Stats query sums `PrintLogEntry.cost` (gets 0 for legacy data); the time-accuracy query joins `PrintArchive ON archive_id` (drops every legacy run from the average). Counts and per-row fields that already existed pre-#1378 (`status`, `duration_seconds`, `filament_used_grams`) kept working — which is why some panels looked right and others didn't. Fix is a two-step backfill in `run_migrations` next to the existing column-add block (DML, runs inside `begin_nested()` not `_safe_execute` since the latter is documented "DDL only"): step 1 links each orphan log entry to its archive via `print_name + printer_id` (highest archive `id` wins on tiebreak — newest matches the overwrite-then-stop shape that pre-#1378 reprints left behind); step 2 copies `archive.cost / energy_kwh / energy_cost` onto the latest matching log entry per archive, **but only for archives where no log entry yet carries a cost**. That second clause is the idempotency anchor and also the double-count guard for users running this migration after #1378 has already written cost-bearing rows for new runs — those archives are left untouched. Earlier reprints stay NULL, matching the "first/latest writes, rest stay NULL" convention #1378 introduced. Sum across the legacy reprint chain reproduces sum-of-archive-cost exactly, so the Quick Stats Filament Cost column matches the pre-upgrade total instead of dropping to zero. SQL is plain ANSI — correlated UPDATE with `LIMIT 1` in the SET subquery, `WHERE id IN (SELECT MAX(id) ... GROUP BY archive_id HAVING SUM(CASE WHEN cost IS NOT NULL THEN 1 ELSE 0 END) = 0)` — verified end-to-end on both SQLite (4 unit tests in `test_print_log_backfill_migration.py`) and `postgres:16-alpine + asyncpg` (live container reproduction). For the other widgets the reporter listed (Printer Stats, Filament Trends, By Material, Success by Material, Color Distribution) — those still iterate the archives list on the frontend rather than calling /stats, so they read consistent pre-upgrade data and aren't part of this fix; the inconsistency the reporter saw between Quick Stats and those widgets resolves itself once the backfill brings Quick Stats in line.
|
||||
|
||||
@@ -2860,7 +2860,7 @@ export default {
|
||||
checkEmail: 'Prüfen Sie Ihre E-Mail ({{email}}) für einen 6-stelligen Code',
|
||||
enterTotpHint: 'Geben Sie den 6-stelligen Code aus Ihrer Authenticator-App ein',
|
||||
accessToken: 'Zugriffstoken',
|
||||
accessTokenHint: 'Fügen Sie Ihr Bambu Lab Zugriffstoken ein (aus Bambu Studio)',
|
||||
accessTokenHint: 'Fügen Sie Ihr Bambu-Cloud-Zugriffstoken ein. Konten der Region China müssen diesen Weg nutzen (telefonnummerngebunden — kein E-Mail-Login). Im Wiki steht, wie Sie das Token aus den MakerWorld-Cookies auslesen.',
|
||||
back: 'Zurück',
|
||||
loginButton: 'Anmelden',
|
||||
verifyButton: 'Bestätigen',
|
||||
|
||||
@@ -2863,7 +2863,7 @@ export default {
|
||||
checkEmail: 'Check your email ({{email}}) for a 6-digit code',
|
||||
enterTotpHint: 'Enter the 6-digit code from your authenticator app',
|
||||
accessToken: 'Access Token',
|
||||
accessTokenHint: 'Paste your Bambu Lab access token (from Bambu Studio)',
|
||||
accessTokenHint: 'Paste your Bambu Cloud access token. China-region accounts must use this path (phone-bound — email login unavailable). See the wiki for how to retrieve the token from MakerWorld cookies.',
|
||||
back: 'Back',
|
||||
loginButton: 'Login',
|
||||
verifyButton: 'Verify',
|
||||
|
||||
@@ -2849,7 +2849,7 @@ export default {
|
||||
checkEmail: 'Code envoyé à {{email}}',
|
||||
enterTotpHint: 'Entrez le code 2FA',
|
||||
accessToken: 'Jeton d\'accès (Access Token)',
|
||||
accessTokenHint: 'Collez le jeton (depuis Bambu Studio)',
|
||||
accessTokenHint: 'Collez votre jeton Bambu Cloud. Les comptes de la région Chine doivent passer par ici (liés à un numéro de téléphone — pas de connexion par e-mail). Le wiki explique comment récupérer le jeton depuis les cookies MakerWorld.',
|
||||
back: 'Retour',
|
||||
loginButton: 'Connexion',
|
||||
verifyButton: 'Vérifier',
|
||||
|
||||
@@ -2848,7 +2848,7 @@ export default {
|
||||
checkEmail: 'Controlla la tua email ({{email}}) per un codice a 6 cifre',
|
||||
enterTotpHint: 'Inserisci il codice a 6 cifre dalla tua app autenticatore',
|
||||
accessToken: 'Token di accesso',
|
||||
accessTokenHint: 'Incolla il tuo access token Bambu Lab (da Bambu Studio)',
|
||||
accessTokenHint: 'Incolla il tuo access token Bambu Cloud. Gli account della regione Cina devono usare questa via (vincolati al numero di telefono — login via e-mail non disponibile). Il wiki spiega come recuperare il token dai cookie di MakerWorld.',
|
||||
back: 'Indietro',
|
||||
loginButton: 'Accedi',
|
||||
verifyButton: 'Verifica',
|
||||
|
||||
@@ -2860,7 +2860,7 @@ export default {
|
||||
checkEmail: 'メール ({{email}}) に届いた6桁のコードを入力してください',
|
||||
enterTotpHint: '認証アプリの6桁のコードを入力してください',
|
||||
accessToken: 'アクセストークン',
|
||||
accessTokenHint: 'Bambu Labのアクセストークンを貼り付け(Bambu Studioから取得)',
|
||||
accessTokenHint: 'Bambu Cloud のアクセストークンを貼り付けてください。中国リージョンのアカウントはこの方法のみ利用可能です(電話番号認証のためメールログイン不可)。トークンの取得方法は MakerWorld の Cookie から(Wiki を参照)。',
|
||||
back: '戻る',
|
||||
loginButton: 'ログイン',
|
||||
verifyButton: '認証',
|
||||
|
||||
@@ -2848,7 +2848,7 @@ export default {
|
||||
checkEmail: 'Verifique seu email ({{email}}) para um código de 6 dígitos',
|
||||
enterTotpHint: 'Digite o código de 6 dígitos do seu aplicativo autenticador',
|
||||
accessToken: 'Token de Acesso',
|
||||
accessTokenHint: 'Cole seu token de acesso Bambu Lab (do Bambu Studio)',
|
||||
accessTokenHint: 'Cole seu token de acesso da Bambu Cloud. Contas da região China precisam usar este caminho (vinculadas ao celular — login por e-mail indisponível). Veja no wiki como obter o token dos cookies do MakerWorld.',
|
||||
back: 'Voltar',
|
||||
loginButton: 'Entrar',
|
||||
verifyButton: 'Verificar',
|
||||
|
||||
@@ -2848,7 +2848,7 @@ export default {
|
||||
checkEmail: '检查您的邮箱 ({{email}}) 获取 6 位验证码',
|
||||
enterTotpHint: '输入验证器应用中的 6 位代码',
|
||||
accessToken: '访问令牌',
|
||||
accessTokenHint: '粘贴您的拓竹访问令牌(来自 Bambu Studio)',
|
||||
accessTokenHint: '粘贴您的拓竹云访问令牌。中国大陆账号(绑定手机号、无邮箱登录)只能使用此方式登录。可从 MakerWorld 浏览器 Cookie 中获取令牌,详见 Wiki。',
|
||||
back: '返回',
|
||||
loginButton: '登录',
|
||||
verifyButton: '验证',
|
||||
|
||||
@@ -2848,7 +2848,7 @@ export default {
|
||||
checkEmail: '檢查您的信箱 ({{email}}) 獲取 6 位驗證碼',
|
||||
enterTotpHint: '輸入驗證器 App 中的 6 位驗證碼',
|
||||
accessToken: '存取權杖',
|
||||
accessTokenHint: '貼上您的拓竹存取權杖(來自 Bambu Studio)',
|
||||
accessTokenHint: '貼上您的拓竹雲端存取權杖。中國大陸帳號(綁定手機號碼、無 Email 登入)僅能使用此方式登入。可從 MakerWorld 瀏覽器 Cookie 取得權杖,詳見 Wiki。',
|
||||
back: '返回',
|
||||
loginButton: '登入',
|
||||
verifyButton: '驗證',
|
||||
|
||||
Reference in New Issue
Block a user