diff options
| author | Luke Hoersten <[email protected]> | 2026-06-14 21:00:21 -0500 |
|---|---|---|
| committer | Luke Hoersten <[email protected]> | 2026-06-14 21:00:21 -0500 |
| commit | 086398dde1deeb79af8d1db01a5197e668a5d561 (patch) | |
| tree | f98cc1202b8fb1322829c81979c7278857a8bf6d | |
| parent | a2489d2caabf6050b8ce197cfc85eebfa07fffd8 (diff) | |
scrypted: persist display_name across script reloads + prefer it over v.name
The script-reload re-discovery passed `name: nativeId` to
onDeviceDiscovered, which Scrypted honored by renaming the existing
"kitchen" device to its vp_xxx nativeId. The subsequent registerViewport
fallback then saw a non-empty `v.name` (the nativeId) and used it as the
viewport name when POSTing /config, sending the firmware /config with
viewport="vp_mqek8i55_3z3s" instead of "kitchen".
Fix two things:
1. start()'s re-discovery now passes the persisted display_name (set on
createDevice + every Settings save) as the device's `name`, so the
user-chosen kitchen name survives script reloads.
2. registerViewport now prefers storage's display_name over v.name —
the storage value is the authoritative one, v.name is just a render
that can briefly drift to the nativeId during reload.
| -rw-r--r-- | scrypted/scrypted-viewport.ts | 20 |
1 files changed, 13 insertions, 7 deletions
diff --git a/scrypted/scrypted-viewport.ts b/scrypted/scrypted-viewport.ts index 3a95a69..69ccd70 100644 --- a/scrypted/scrypted-viewport.ts +++ b/scrypted/scrypted-viewport.ts @@ -274,10 +274,15 @@ class ScryptedViewportProvider extends ScryptedDeviceBase // event subscription happen at plugin load. for (const nativeId of this.childIds) { try { + // Use the persisted display_name as the canonical device + // name so a script reload doesn't reset it to the nativeId. + // First-time provision falls back to the nativeId. + const displayName = + deviceManager.getDeviceStorage(nativeId).getItem("display_name") || nativeId; await deviceManager.onDeviceDiscovered({ providerNativeId: this.nativeId, nativeId, - name: nativeId, // overridden by Scrypted from its existing record + name: displayName, type: ScryptedDeviceType.SmartDisplay, interfaces: [ScryptedInterface.Settings], }); @@ -434,12 +439,13 @@ class ScryptedViewportProvider extends ScryptedDeviceBase } private async registerViewport(v: Viewport) { - // Guard against transient empty names. Scrypted occasionally hands - // us a Viewport whose `.name` hasn't resolved yet (race between - // device-record load and event delivery); POSTing /config with an - // empty viewport just gets a 400 from the firmware. Fall back to - // the stored display name from storage if it's there, else skip. - const name = (v.name && v.name.trim()) || v.storage.getItem("display_name") || ""; + // display_name is the canonical user-facing name (written on + // createDevice and on every Settings save). v.name is just a + // render of it from the Scrypted device record and can briefly + // drift to the nativeId on script reload, so prefer the storage + // value as the source of truth. + const stored = v.storage.getItem("display_name"); + const name = (stored && stored.trim()) || (v.name && v.name.trim()) || ""; if (!name) { this.console.warn(`register skipped — empty name on ${v.nativeId}; will retry on next event`); return; |
