src.nth.io/

summaryrefslogtreecommitdiff
path: root/scrypted/scrypted-viewport.ts
diff options
context:
space:
mode:
authorLuke Hoersten <[email protected]>2026-06-14 21:00:21 -0500
committerLuke Hoersten <[email protected]>2026-06-14 21:00:21 -0500
commit086398dde1deeb79af8d1db01a5197e668a5d561 (patch)
treef98cc1202b8fb1322829c81979c7278857a8bf6d /scrypted/scrypted-viewport.ts
parenta2489d2caabf6050b8ce197cfc85eebfa07fffd8 (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.
Diffstat (limited to 'scrypted/scrypted-viewport.ts')
-rw-r--r--scrypted/scrypted-viewport.ts20
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;