Skip to content

Commit 8454410

Browse files
committed
v2.20.0 — TigerScale header states + iOS battery, standby-aware offline, TigerPOD Standard/Mini, 12k+ catalogue
TigerScale header presence rebuilt as one glyph per scale (capped at 2), each coloured by its own state (active green / standby blue / offline red / grey none) with a per-scale hover popover; iOS-style battery pill on the glyph (% + charging bolt); standby is a first-class state with regime-aware offline detection (90 s active / 11 min screen_off); Wi-Fi coloured by connectivity; rfidReadersMax recorded on a successful read + kept at lifetime max; tare confirmed only on a 2xx now the firmware returns CORS headers; backend cloud indicator only after 3 s of real disconnection (no startup flash); containerWeight -1 renders "—"; light-theme contrast fixes on the TigerPOD modal. TigerPOD modal offers both models to print (Standard + Mini for OpenSpool). TigerTag+ reference database refreshed to 12,211 products (db_update.py). Debug-mode telemetry instrumentation for plug/unplug and wake latency.
1 parent 4183032 commit 8454410

24 files changed

Lines changed: 110500 additions & 2953 deletions

‎CHANGELOG.md‎

Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,32 @@ Versions follow [Semantic Versioning](https://semver.org/).
55

66
---
77

8+
## v2.20.0 — 2026-08-22
9+
10+
### Added
11+
12+
- **The header scale icon is now one glyph per scale (capped at two), each coloured by its own connection state.** A single aggregate icon became `renderScaleHealth`'s per-scale render: 1 scale → 1 glyph, 2+ → 2 (never more), each `.scale-glyph` carrying `scale-active` (green) / `scale-standby` (blue) / `scale-offline` (red), and muted grey when no scale is paired. A hover popover (`.scale-health-pop`, mirroring the RFID-pod popover) lists **every** scale — one row each with a matching status dot + `Scale #N` + status label — so 3+ scales still surface fully even though the glyph count is capped. The rebuild is signature-guarded (`_scaleHealthSig`) so the live-ping animation isn't restarted on every 10 s tick / snapshot — `renderer/IoT/tigerscale/index.js`, `renderer/IoT/tigerscale/tigerscale.css`, `renderer/inventory.html`. New `scaleStatusStandby` / `scaleHealthStandby` / `scaleHealthRow` i18n (9 locales).
13+
- **Standby is a first-class connection state.** `scaleConnState` returns `active` / `standby` / `offline`; a screen-off scale (`power_state === "screen_off"`, firmware ≥ 3.6.0) with a heartbeat inside the standby window shows **blue "standby"** rather than offline. Offline detection is regime-aware — `SCALE_ONLINE_ACTIVE_MS` 90 s (30 s cadence) vs `SCALE_ONLINE_STANDBY_MS` 11 min (5 min cadence) — so a fully-awake scale with its backlight off is never shown disconnected; a genuinely silent scale still flips to offline once its heartbeat ages past the window (needed because a scale that dies in standby keeps its last `screen_off` forever) — `renderer/IoT/tigerscale/index.js`.
14+
- **Battery on the header scale glyph — an iOS-style pill.** Coloured outline + terminal nub, proportional fill, and the value inside: reads `XX%` while discharging and `XX` + a charging bolt while charging. Colour precedence **charging (green) → low < 20 % (red) → neutral**; `battery_present === false` shows no gauge, and `battery_percent` null is treated as "no cell" (≠ 0) — `renderer/IoT/tigerscale/index.js`, `renderer/IoT/tigerscale/tigerscale.css`.
15+
- **The TigerPOD modal offers both Pod models to print.** Two buttons — **Standard** and **Mini (OpenSpool)** — each opening its own MakerWorld model. The badge now opens the modal whether a reader is connected or not — `renderer/inventory.html`, `renderer/inventory.js`, `renderer/css/60-modals.css`. New `tigerPodPrintCta` / `tigerPodPrintNormalBtn` / `tigerPodPrintMiniBtn` / `tigerPodOwnLabel` / `tigerPodOwnSub` i18n (9 locales).
16+
- **TigerTag+ reference database refreshed to 12 211 products.** `db_update.py` re-synced every reference JSON from the live API — `assets/db/tigertag/id_catalog.json` + `last_update.json` (and the id_* datasets).
17+
18+
### Changed
19+
20+
- **The scale Wi-Fi indicator follows connectivity, not raw RSSI.** It was a red single bar for a perfectly working link because the thresholds were router-adjacent (excellent ≥ -50 dBm). Colour is now green while online / muted while offline (matching the scale's own screen, which is green whenever connected), with realistic bar-count thresholds; the exact dBm + quality label stay in the tooltip — `renderer/IoT/tigerscale/index.js`, `renderer/IoT/tigerscale/tigerscale.css`.
21+
- **`rfidReadersMax` (TigerPOD reader count) is recorded on a successful read, not a bare connect,** and kept at the lifetime max — seeded from the persisted value at login so a fresh session (counter reset to 0) can no longer write a lower count over a stored 2 — `renderer/IoT/tigerscale/index.js`.
22+
- **The backend "cloud" indicator only appears on a real network problem.** Hidden while all is well, and shown only after **3 s of continuous disconnection** (offline / serving from cache) — suppressing the flash at startup while the cloud is still connecting. The Firestore-metadata logic and hover ping are unchanged — `renderer/inventory.html`, `renderer/inventory.js`.
23+
- **The tare button reads the response now that the firmware returns CORS headers.** It shows success only on a 2xx and an error state otherwise, instead of adding the "success" class before the fetch and swallowing the error (which reported success even when the scale was unreachable) — `renderer/IoT/tigerscale/index.js`, `renderer/IoT/tigerscale/tigerscale.css`.
24+
- **Debug-mode telemetry instrumentation** in the scales Firestore subscription: a timestamped log of every `power_state` / `power_source` / `is_charging` transition (with `from_cache`) plus a `snapshot → render` timing, to measure plug/unplug and wake latency — `renderer/IoT/tigerscale/index.js`.
25+
26+
### Fixed
27+
28+
- **A scale in standby was wrongly marked offline after 90 s.** Since firmware 3.6.0 a screen-off scale heartbeats every 5 min, but the flat 90 s threshold treated all scales alike — it now uses the standby window (see Added) — `renderer/IoT/tigerscale/index.js`.
29+
- **`containerWeight` of `-1` (unknown, per the firmware contract) rendered as "-1 g".** Weights are now guarded `> 0`, so an unknown container/net weight shows "—" — `renderer/IoT/tigerscale/index.js`.
30+
- **Light-theme contrast in the TigerPOD modal.** The title and badges on the fixed purple header, and the numerals in the orange feature circles, used theme ink tokens that turn dark in light mode → unreadable; they are forced to white/light — `renderer/css/60-modals.css`.
31+
32+
---
33+
834
## v2.19.1 — 2026-08-19
935

1036
### Fixed

‎FEATURES.md‎

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
# Tiger Studio Manager — Feature Catalogue
22

3-
Tiger Studio Manager is the Electron desktop companion to the TigerTag ecosystem: a filament-inventory manager built around RFID/NFC-tagged spools ("TigerTag" chips), a fully-digital "TigerData" tier (and its catalogue-identified "TigerData+" rung), live 3D-printer integration across six brands, physical storage/rack management, a Firebase-backed social layer (friends, shareable wishlists, public profiles), and companion hardware (TD1S color sensor, TigerScale, TigerPOD dual-reader stand). This document catalogues every **shipped** feature, grouped by domain, current as of **v2.19.1**. Per-version release detail lives in `CHANGELOG.md`; forward-looking / in-progress work lives in `ROADMAP.md`.
3+
Tiger Studio Manager is the Electron desktop companion to the TigerTag ecosystem: a filament-inventory manager built around RFID/NFC-tagged spools ("TigerTag" chips), a fully-digital "TigerData" tier (and its catalogue-identified "TigerData+" rung), live 3D-printer integration across six brands, physical storage/rack management, a Firebase-backed social layer (friends, shareable wishlists, public profiles), and companion hardware (TD1S color sensor, TigerScale, TigerPOD dual-reader stand). This document catalogues every **shipped** feature, grouped by domain, current as of **v2.20.0**. Per-version release detail lives in `CHANGELOG.md`; forward-looking / in-progress work lives in `ROADMAP.md`.
44

55
---
66

@@ -195,8 +195,8 @@ Live integrations across six brands, each with real-time temperatures, per-slot
195195

196196
- **ACR122U NFC reader** (USB, via `nfc-pcsc`) — plug-and-scan auto-open of the matching spool, with hot-plug detection on Windows (v1.0+; hot-plug fix v1.10.28-era).
197197
- **TD1S** color/TD sensor — auto-detect on USB plug, live viewer, unified color+TD scanning modal with multi-slot (1–3 colour) support, edit-pencil swatch UI (v1.3+; unified modal v1.8.0).
198-
- **TigerScale** — WebSocket heartbeat presence (`users/{uid}/scales/{mac}`), live gradient card matching the mobile app: 56 px weight display, send-status badge (`idle → scanning → stable → send → success`), filament mini-panel pushed from firmware, twin-UID 2-reader grid, hold-to-confirm TARE (v1.5.0). Onboarding card for users without a scale, rebuilt around the **V3** machine — lit product shot with a generation badge, six icon-led capability rows, and two destinations: the firmware on GitHub and the printable body on MakerWorld (v2.19.0).
199-
- **TigerPOD** dual-reader stand — dedicated modal with product video/imagery, MakerWorld STL download, dual-chip simultaneous encode ("Dual Link"), auto-opens when a chip action needs a reader that isn't connected (v1.8.0; redesigns v1.8.2, v2.9.0 hero video); ownership + reader-count telemetry signal (`hasPod`, `rfidReadersMax`) (v2.9.0).
198+
- **TigerScale** — WebSocket heartbeat presence (`users/{uid}/scales/{mac}`), live gradient card matching the mobile app: 56 px weight display, send-status badge (`idle → scanning → stable → send → success`), filament mini-panel pushed from firmware, twin-UID 2-reader grid, hold-to-confirm TARE (v1.5.0). Onboarding card for users without a scale, rebuilt around the **V3** machine — lit product shot with a generation badge, six icon-led capability rows, and two destinations: the firmware on GitHub and the printable body on MakerWorld (v2.19.0). Header presence rebuilt as **one glyph per scale** (capped at two), each coloured by its own state — **active** (green) / **standby** (blue) / **offline** (red) / grey when none — with a per-scale hover popover, an **iOS-style battery pill** (charge % + charging bolt) on the glyph, a distinct **standby** state with regime-aware offline detection (90 s active / 11 min screen-off, so a screen-off scale isn't shown disconnected), Wi-Fi coloured by connectivity, and a TARE confirmed only on a real 2xx response (v2.20.0).
199+
- **TigerPOD** dual-reader stand — dedicated modal with product video/imagery, MakerWorld STL download, dual-chip simultaneous encode ("Dual Link"), auto-opens when a chip action needs a reader that isn't connected (v1.8.0; redesigns v1.8.2, v2.9.0 hero video); ownership + reader-count telemetry signal (`hasPod`, `rfidReadersMax`) (v2.9.0); the modal now offers **both Pod models** to print — Standard and Mini (for OpenSpool) — each with its own MakerWorld download (v2.20.0).
200200
- **USB scale (Dymo M-series)** live weighing — plug a Dymo USB HID scale and spool weights fill themselves in: a chip on the reader (POD mode) saves the weight silently, or an open spool card offers an inline confirm; live grams appear in the spool's weight panel with an "asleep — tap to wake" hint when the scale powers down (v2.14.0).
201201

202202
## RFID / NFC & tags

‎ROADMAP.md‎

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1397,6 +1397,12 @@ No commitment, no ETA. Listed roughly by likely impact.
13971397
13981398
Lower priority but worth noting.
13991399
1400+
- **Rename the GitHub repo `TigerTag-Studio-Manager` → `Tiger-Studio-Manager`** — it is the last place still carrying "TigerTag": the product is already `Tiger Studio Manager` and so are the binaries (`Tiger-Studio-Manager-Setup-<version>.exe`). **Effort**: S. **Risk**: low, with one trap.
1401+
- **Auto-update survives it.** `build.publish` (`owner` + `repo`) is baked into each build's `app-update.yml`, so every already-installed app keeps asking for the OLD name forever. It works because GitHub keeps a permanent redirect — repo *and* release-asset URLs — and electron-updater follows redirects. There is no `setFeedURL` anywhere in `main.js`, so nothing else to reroute. The `appId` (`io.tigertag.inventory`) and `productName` are independent of the repo, so installs upgrade in place: no duplicate app, no lost accounts or inventory.
1402+
- **The trap**: that redirect dies the day anything re-occupies the name `TigerTag-Studio-Manager` in the org — and every pre-rename install then stops updating, *silently*. After the rename that name is burnt; never reuse it.
1403+
- **Verify, don't assume.** A broken updater produces no complaints, just users frozen on an old version. Keep a pre-rename build installed, rename, publish the next version, and confirm the old build actually offers it.
1404+
- **Order matters**: rename on GitHub FIRST, then ship the code changes — pointing `package.json` at a repo that does not exist yet would break the *next* build's publish.
1405+
- **What to change** (5 code references + docs): `package.json` `build.publish.repo` (the only one that affects the updater), `main.js` (app "website" link), `renderer/inventory.js` ×2 (sidebar GitHub button + sign-in screen), `scripts/extract-changelog.mjs` ×2 (the "Full changelog" footer of every release note), then `README.md`, `TRADEMARK.md`, `llms.txt`. The CI needs nothing — the workflows use `github.repository`. Outside this repo: `CLAUDE.local.md`, and the repo links in TigerSystem-Docs, TigerTag_Hub and TigerTag_Firebase_Integration.
14001406
- **Migrate to Firebase v9 modular SDK** — the current app uses the v8 compat bundle (`firebase-app-compat.js` etc.) which calls `eval()` internally. This forces `unsafe-eval` in any Content-Security-Policy, triggering an Electron security warning in dev. Migrating to the v9 modular API (`import { getAuth } from 'firebase/auth'`) eliminates `eval()` usage entirely → a proper restrictive CSP becomes possible → warning disappears. **Effort**: L. **Risk**: medium (v8 `firebase.auth()` / `firebase.firestore()` call style changes significantly to functional API). Has no user-visible impact; purely a dev-quality and security hardening item.
14011407
- **Modularize `inventory.js`** — split the 12k-line IIFE into ES modules (auth, inventory, racks, snapmaker, friends, ui-helpers, …). XL effort, medium risk (every cross-file dep needs an import). Discussed but parked because the CODEMAP gives most of the navigation benefit at zero risk.
14021408
- **TypeScript port** — only worth it after modularization. Would catch a real class of bugs (type mismatches in Firestore schemas, plural-object inconsistencies the i18n hook now catches manually). XL.

‎WORKLOG.md‎

Lines changed: 15 additions & 28 deletions
Original file line numberDiff line numberDiff line change
@@ -1,38 +1,25 @@
1-
# Worklog — v2.19.1 (in progress)
1+
# Worklog — v2.20.0
22

33
## Added
4+
- Header scale icon = one glyph per scale (capped at 2), coloured by its own state (active green / standby blue / offline red / grey none) + hover popover listing every scale with a status dot — `renderer/IoT/tigerscale/*`, `renderer/inventory.html`.
5+
- Standby as a first-class state (blue) with regime-aware offline detection (90 s active / 11 min screen_off).
6+
- iOS-style battery pill on the scale glyph (fill + value inside + charging bolt; charging→low→neutral).
7+
- TigerPOD modal: two print buttons — Standard + Mini (OpenSpool).
8+
- TigerTag+ reference DB refreshed to 12 211 products (`db_update.py` → `assets/db/tigertag/*`).
49

510
## Changed
11+
- Scale Wi-Fi = connectivity colour (green online) + realistic bar thresholds; dBm in tooltip.
12+
- `rfidReadersMax` recorded on a successful read + kept at lifetime max (seeded at login).
13+
- Backend cloud indicator hidden unless offline > 3 s (kills the startup flash).
14+
- Tare button confirms success only on a 2xx (firmware CORS open); error state otherwise.
15+
- Debug-mode telemetry instrumentation (power transitions + snapshot→render timing).
616

717
## Fixed
8-
- Snapmaker printer side card showed "0m" next to the clock on a running print while the table
9-
showed the real 21m — the card printed `printDuration`, which is the time ELAPSED, not remaining.
10-
Moonraker sends no remaining time, so the card now reads the same normalised job the table does
11-
(slicer estimate − elapsed, else extrapolated from progress) via a new `ctx.getPrinterJob`, and
12-
shows "—" rather than a wrong "0m" while there is nothing to derive from yet —
13-
`renderer/printers/snapmaker/cards.js`, `renderer/printers/context.js`, `renderer/inventory.js`
14-
- Bambu Lab printer side card showed "0m" remaining on a running print while the table column
15-
showed the real figure. `mc_remaining_time` is reported in MINUTES, but the card fed it straight
16-
into a seconds formatter, so a 32-minute job floored to 0. The table was right because it goes
17-
through `_getPrinterJob`, which converts. `PROTOCOL.md` documented the field as seconds — the
18-
source of the mistake — and is corrected with the observed value — `renderer/printers/bambulab/cards.js`,
19-
`renderer/printers/bambulab/PROTOCOL.md`
20-
- Dependency refresh — 18 advisories (1 critical, 17 high) down to 0, entirely within the existing
21-
semver ranges: `package.json` is untouched, only the lockfile was stale. Covers the reported
22-
**CVE-2026-54673** / GHSA-p2f4-r6v6-j797 (`builder-util-runtime` 9.5.1 → 9.7.0 — electron-updater
23-
leaked `Authorization` / `PRIVATE-TOKEN` headers across a cross-origin redirect; `electron-updater`
24-
is a runtime dependency, though our update feed is a public GitHub release that carries no
25-
credentials), plus electron-builder/app-builder-lib 26.8.1 → 26.15.3 (AppImage search-path advisory),
26-
electron 41.3.0 → 41.10.6 (three advisories), and tar, undici, ws, js-yaml, tmp, form-data,
27-
ip-address. Supersedes external PR #10, which pinned a single package through `overrides` —
28-
`package-lock.json`
29-
- Six column headers in the Printers table view stayed in English in every language (Brand, Name,
30-
Model, Status, Job, Last seen) — they were hardcoded literals while their neighbours (Preview,
31-
Ends at) went through `t()`. They now reuse the existing table-header key family; switching
32-
language already re-renders this view, so they follow immediately — `renderer/inventory.js`
18+
- Standby scale wrongly marked offline after 90 s.
19+
- `containerWeight` = -1 (unknown) rendered "-1 g" → now "—".
20+
- Light-theme contrast on the TigerPOD modal (purple header text + orange badge numbers).
3321

3422
## Removed
3523

3624
## i18n
37-
- Added: `thModel`, `thStatus`, `thJob` — 9 locales (the Printers table headers; `thBrand`, `thName`
38-
and `printersLastSeen` already existed and are reused)
25+
- Added: `scaleStatusStandby`, `scaleHealthStandby`, `scaleHealthRow`, `scaleChipCharging`, `tigerPodPrintCta`, `tigerPodPrintNormalBtn`, `tigerPodPrintMiniBtn`, `tigerPodOwnLabel`, `tigerPodOwnSub` — 9 locales

0 commit comments

Comments
 (0)