Documentazione

Crea un’app che appartiene a uno schermo

Usa l’SDK browser iniettato per controllo playlist, eventi applicazione, diagnostica e stato persistente chiave/valore.

Guarda come viene costruito

Film / Crea un’app kiosk con l’SDK

3:07

Un visitatore che tocca un chiosco di check-in nella hall sotto un muro di benvenuto

Claude Code scrive un kiosk check-in lobby contro window.screenrig: waitUntilActive(), ready(), kv.get() e emitConfirmed(). Il tocco di un visitatore raggiunge l’agente, che risponde sul muro di benvenuto. Capitoli e trascrizione →

Il runtime è già nell’app

app pack e app upload prendono una directory statica già costruita con una radice index.html. Il pacchettizzatore inietta _screenrig/runtime.js e aggiunge il suo tag script a quel documento. L’applicazione in esecuzione riceve window.screenrig senza passaggi di build e senza dipendenze npm: non c’è nulla da installare, importare o configurare.

Ogni versione immutabile dell’applicazione viene eseguita su una propria origine isolata sotto apps.screenrig.ai. L’id dell’applicazione sopravvive alla versione, quindi i dati chiave/valore scritti da una versione restano disponibili anche per la successiva.

La superficie window.screenrig

Tre proprietà in sola lettura, dieci metodi, un namespace kv di altri cinque e un namespace device per il display, la presenza, i tasti fisici, il sensore di luce, lo stato della rete e il feedback aptico. Leggi prima readyState e controlla capabilities prima di chiamare un metodo che una data attivazione potrebbe non avere.

Ogni metodo risponde a una domanda diversa, quindi inizia da ciò che vuoi fare:

Per fare questoChiamata
Attendere che il Player attivi questa paginascreenrig.waitUntilActive()
Indica che l’applicazione è attiva e sullo schermoscreenrig.ready()
Termina il turno di questa applicazione su una pagina di avanzamento applicazionescreenrig.nextPage()
Comunicare al Player che questa pagina non ha nulla da mostrare in questo momentoscreenrig.skip(reason)
Comunica all’agente che qualcosa è successoscreenrig.emit(code)
Il backend ha registrato quell’eventoscreenrig.emitConfirmed(code)
Lascia una diagnostica per il Player e il runtime da raccoglierescreenrig.log(...)
Leggi lo stato live dell’applicazionescreenrig.kv.get(), screenrig.kv.list()
Scrivi stato applicazione livescreenrig.kv.set(), screenrig.kv.delete()
Aggiorna al momento del cambiamento dello stato dell’applicazione livescreenrig.kv.onChange()
Reagire a un cambiamento di dimensione o capacitàscreenrig.onResize(), screenrig.onCapabilities()
Attenuare, oscurare o riattivare il displayscreenrig.device.display.set()
Sapere che qualcuno si è avvicinato allo schermoscreenrig.device.onPresence()
Prendere il controllo dei tasti volume fisiciscreenrig.device.onKey()
Sapere il livello di luce ambientalescreenrig.device.onLight()
Sapere che il dispositivo è andato online o offlinescreenrig.device.onNetwork()
Riprodurre un impulso apticoscreenrig.device.vibrate()
Rimuovere i listener quando l’applicazione ha finito con il runtimescreenrig.destroy()

screenrig.readyState#

Se il runtime iniettato è collegato. Ogni documento inizia inert e diventa active quando arrivano handshake e contesto del Player; una pagina non ancora su schermo resta inert. Aspetta active con screenrig.waitUntilActive(); non considerare inert al caricamento come “fuori screenRIG”. Su failed, o quando window.screenrig manca, mostra il tuo contenuto e salta la superficie sottostante, così la stessa build funziona anche fuori screenRIG. Mentre inert, ready(), log(), emit(), emitConfirmed(), nextPage(), skip() e kv leggono e scrivono lanciando o rifiutando con codice inert; kv.onChange può essere registrato in qualsiasi momento.

Tipo
"inert" | "active" | "failed"

screenrig.context#

Dove viene eseguito questo documento.

CampoTipoNote
application_idstringL’ID app_ da app upload. Il key/value store gli appartiene.
release_idstringLa release immutabile che serve questa origine.
primitive_idstringIl primitivo che questo documento riempie nella pagina corrente.
viewport{ width, height }La superficie in cui il Player esegue il rendering.
primitive{ width, height }Il rettangolo che questo documento occupa all’interno di quella viewport.
capabilitiesobjectGli stessi booleani di screenrig.capabilities.
screen_idstringa, opzionalePresente quando il runtime sa quale schermo sta riproducendo.

context è descrizione, non materiale di richiesta. Nulla in esso è destinato a essere firmato, inoltrato o inviato a screenRIG; i metodi seguenti portano ciò che il runtime richiede.

I parametri di avvio non fanno parte di context: una playlist può dare a un'applicazione params (vedi Token dello schermo negli indirizzi iframe e nei parametri dell'applicazione), e il Player aggiunge ciascuno all'indirizzo della pagina come parametro di query dopo ticket. Leggili da location.search, ad esempio new URLSearchParams(location.search).get("kiosk"). Sono suggerimenti, non credenziali, e chiunque possa aprire la pagina può inviare qualsiasi valore, quindi trattali come input non attendibile; context.screen_id resta il modo per sapere quale schermo sta riproducendo. I Player Qt, Android, Apple e Windows caricano un'applicazione dal pacchetto locale, che non ha un indirizzo di avvio, e non le passano parametri.

screenrig.capabilities#

Dieci booleani che indicano quali metodi gated faranno qualcosa per questa attivazione. Le chiavi sono puntate, quindi leggile con la notazione a parentesi quadre.

SegnalaCancelli
page.advancescreenrig.nextPage()
page.skipscreenrig.skip()
kv.readscreenrig.kv.get(), screenrig.kv.list() e screenrig.kv.onChange()
kv.writescreenrig.kv.set() e screenrig.kv.delete()
device.displayscreenrig.device.display.get(), .set() e screenrig.device.onDisplay()
device.presencescreenrig.device.onPresence()
device.keysscreenrig.device.onKey()
device.lightscreenrig.device.onLight()
device.networkscreenrig.device.onNetwork()
device.hapticsscreenrig.device.vibrate()
if (window.screenrig.capabilities["kv.write"]) {
  saveButton.hidden = false;
}

Iscriviti con onCapabilities invece di leggere i flag una volta all’avvio.

Tipo
oggetto di booleani

screenrig.waitUntilActive(timeoutMs)#

Chiamalo per primo, prima di qualsiasi altro metodo, e rendi la tua UI mentre attende. Si risolve quando il Player ha attivato questa pagina, o subito se il runtime è già active, e non dichiara l’applicazione resa. Rifiuta con activation_timeout dopo timeoutMs (default 10000, massimo 300000); una pagina in attesa può semplicemente attendere di nuovo. Avvia l’audio dopo la risoluzione, perché il Player carica un’applicazione prima che la sua pagina compaia: uno schermo il cui browser consente la riproduzione automatica lo avvia subito, mentre su uno il cui browser la rifiuta play() viene rifiutato con NotAllowedError; intercetta l’errore e riproduci senza audio.

const sr = window.screenrig;
async function start() {
  render(); // the UI works with or without screenRIG
  if (!sr) return;
  for (;;) {
    try { await sr.waitUntilActive(60000); break; }
    catch (err) { if (err.code !== "activation_timeout") return; }
  }
  await sr.ready();
  // From here: emit, emitConfirmed, log, kv, nextPage.
}
start();

Controlla readyState === "active" prima di una chiamata SDK da un gestore eventi, timer o catch, e metti in coda l’input che arriva prima. Un log() da un gestore che gira mentre inert lancia un’eccezione, che può terminare l’avvio prima che venga inviato un evento.

Restituisce
Promise<void>

screenrig.ready()#

Chiamalo dopo che waitUntilActive() si risolve e prima di dipendere da context, kv o nextPage, una volta che l’applicazione ha ciò che serve per essere sullo schermo. Se chiamato durante inert, genera un errore.

await window.screenrig.waitUntilActive();
await window.screenrig.ready();
Restituisce
Promise<void>

screenrig.nextPage()#

Chiamalo solo su una pagina di avanzamento applicazione dove questa primitiva è il controller, quando l’applicazione ha finito il suo turno. È one-shot: un’attivazione ottiene un avanzamento.

window.screenrig.nextPage();

Il metodo è per una pagina il cui advance.mode è application, dove questa primitiva è il controller:

{
  "advance": { "mode": "application", "max_ms": 60000 },
  "primitives": [
    {
      "id": "app",
      "primitive": "application",
      "release_id": "rel_01EXAMPLERELEASE000000000",
      "rect": { "x": 0, "y": 0, "width": 1920, "height": 1080 },
      "layer": 0,
      "content_fit": "fill",
      "controller": true
    }
  ]
}

Esattamente una primitiva in quella pagina contiene controller: true e deve essere una primitiva applicativa. max_ms nella pagina avanza i limiti dell’oggetto turno.

Richiede
capabilities["page.advance"]
Restituisce
Promise<void>

screenrig.skip(reason)#

Chiamalo al posto di ready() quando l’applicazione non ha nulla da mostrare in questo momento. Lo schermo passa subito oltre con la normale transizione della pagina e questa apparizione non conta alcuna riproduzione. È una decisione presa all’avvio: chiamalo entro dieci secondi dall’attivazione e prima di ready().

await window.screenrig.waitUntilActive();
const events = await loadToday();
if (events.length === 0) {
  await window.screenrig.skip("no events today");
} else {
  render(events);
  await window.screenrig.ready();
}

Il controller della pagina, o l’applicazione da sola sulla sua pagina, ha la capacità, su una pagina senza immagini né video. Il metodo rifiuta con capability_denied senza di essa, con skip_after_ready dopo che ready() è stato chiamato e con not_supported su un Player che non lo supporta. Rifiuta con forbidden quando il Player mantiene la pagina: l’operatore la trattiene, il display è spento, nessun’altra pagina può essere riprodotta o anche tutte le altre pagine sono state saltate. Mostra allora il tuo contenuto di ripiego e chiama ready(). Una playlist di riquadri che saltano tutti mostra l’ultimo per tutta la sua durata invece di girare in ciclo. Il reason facoltativo (al massimo 64 caratteri) compare nel log del Player del progetto come player.application_skipped. skip() è incluso nel runtime che app pack e app upload iniettano, quindi reimpacchetta una release per darle il metodo.

Richiede
capabilities["page.skip"]
Restituisce
Promise<void>

screenrig.emit(code)#

Usalo quando l’agente deve sapere che qualcosa è successo: una pagina ha completato un passaggio, un modulo kiosk è stato inviato, l’applicazione ha dimostrato di essere eseguita. Questo è un evento applicativo nominato, che arriva nel registro eventi del progetto dove l’agente lo osserva con la CLI inclusa events list o events follow. Un codice, nessun corpo messaggio.

log non è un sostituto. Una diagnostica non è un evento applicativo e un agente che legge il registro eventi non lo vedrà.

window.screenrig.emit("menu.rendered");

I metodi SDK emit() ed emitConfirmed() aggiungono record application.event la cui risorsa è lo schermo. Leggili con --type application.event, aggiungendo facoltativamente --screen-id. I campi restituiti details.primitive_id e details.code identificano la primitiva emittente e l’azione denominata. --app-id seleziona gli eventi della risorsa applicazione, delle release e delle voci K/V, quindi esclude questi eventi dello schermo.

screenrig events list --type application.event --screen-id scr_SCREEN
ParametroTipoNote
codestringSanificato a [A-Za-z0-9._-], massimo 64 caratteri.
Restituisce
void

screenrig.emitConfirmed(code)#

Usalo quando l’applicazione deve sapere che l’evento è arrivato: un ordine kiosk è stato effettuato, un modulo inviato, una visita terminata. Invia lo stesso evento applicativo nominato di emit, e la sua promessa si risolve solo quando il Player conferma che il backend ha accettato l’evento.

Rifiuta con il problema backend quando l’evento è rifiutato, e con ack_timeout dopo 10 secondi senza risposta. Non riprovare automaticamente dopo timeout: il backend potrebbe aver già accettato l’evento. Una ricevuta prova che l’evento è nel log eventi progetto, non che qualcosa abbia ancora agito su di esso.

Le ricevute funzionano su ogni Player che esegue applicazioni.

await window.screenrig.emitConfirmed("order.placed");
ParametroTipoNote
codestringSanificato a [A-Za-z0-9._-], massimo 64 caratteri.
Restituisce
Promise<void>

screenrig.log({ level, code, message })#

Usalo per la diagnostica: il debug, info, warn e error sono testi che il Player e il runtime raccolgono mentre l’applicazione è sullo schermo. I log del runtime iniettato passano tramite questo metodo stesso. Il logging è limitato: 32 righe per client e al massimo 2048 byte per messaggio. Registra ciò che serve per il debug, non una riga per frame.

Non usare log quando intendi emit. Gli agenti non trattano le righe di log come eventi applicativi, quindi tutto ciò su cui l’agente deve agire appartiene a un codice emit.

window.screenrig.log({
  level: "warn",
  code: "menu.stale",
  message: "Falling back to the cached menu."
});
CampoTipoNote
levelstringdebug, info, warn o error.
codestringSanificato a [A-Za-z0-9._-], massimo 64 caratteri.
messagestringAl massimo 2048 byte.
Restituisce
void

screenrig.onResize(handler)#

Iscriviti quando il layout può cambiare sotto di te invece di leggere context una volta. Il gestore riceve { viewport, primitive }, gli stessi due oggetti che porta context, e la chiamata restituisce la funzione che termina l’iscrizione.

const stopResize = window.screenrig.onResize(function (size) {
  render(size.viewport, size.primitive);
});

stopResize();
Restituisce
funzione unsubscribe

screenrig.onCapabilities(handler)#

Iscriviti quando le capacità concesse possono cambiare invece di decidere una volta all’avvio. Leggi screenrig.capabilities dentro il gestore per i booleani correnti e abilita o nascondi i controlli interessati; la chiamata restituisce la funzione che termina l’iscrizione.

const stopCapabilities = window.screenrig.onCapabilities(function () {
  saveButton.hidden = !window.screenrig.capabilities["kv.write"];
});
Restituisce
funzione unsubscribe

screenrig.destroy()#

Rimuovi i listener quando l’applicazione ha finito con il runtime. Un’applicazione che gira per tutto il suo turno e lascia che il Player sostituisca il documento non deve chiamarla.

Restituisce
void

screenrig.kv#

Il key/value store dell’applicazione, per lo stato live dell’app che sopravvive a un’attivazione. Cinque metodi propri: get, list, set, delete e onChange. Vedi il key/value store sotto.

Tipo
namespace

Il database chiave/valore

Usa lo store per lo stato live dell’applicazione: il menu che l’applicazione rende, il testo che un operatore ha modificato stamattina, un contatore lasciato dall’ultima attivazione. Leggilo con kv.get e kv.list, scrivilo con kv.set e kv.delete, e ricevi notifiche di ogni modifica con kv.onChange.

Il negozio appartiene all’id applicazione in context.application_id, non a una release, quindi una voce sopravvive al prossimo app upload. I valori sono byte, quindi testo, JSON e piccoli binari fanno il round-trip. Le letture necessitano kv.read e le scritture kv.write; controlla la flag prima di chiamare.

Il negozio e la sua spinta di modifica girano su ogni lettore che esegue applicazioni: l’app web Player (PWA), Android, Amazon Signage Stick, macOS, Windows, Linux, Raspberry Pi, LG webOS Signage, BrightSign e Samsung Smart Signage (Tizen). Apple TV, iPhone e iPad non eseguono applicazioni; vedi supporto primitiva per piattaforma.

screenrig.kv.get(key)#

Leggi lo stato live dell’applicazione. Attendi la promessa.

const entry = await window.screenrig.kv.get("menu");
Richiede
capabilities["kv.read"]
Restituisce
promessa

screenrig.kv.list()#

Leggi lo stato live dell’applicazione quando non conosci ancora le chiavi: questo elenca le chiavi memorizzate dall’applicazione. Attendi la promessa.

const keys = await window.screenrig.kv.list();
Richiede
capabilities["kv.read"]
Restituisce
promessa

screenrig.kv.set(key, value, options)#

Scrivi stato live dell’applicazione. value è una stringa o un Uint8Array; options è opzionale.

await window.screenrig.kv.set("menu", JSON.stringify(menu), {
  contentType: "application/json"
});

await window.screenrig.kv.set("badge.png", pngBytes, {
  contentType: "image/png"
});
ParametroTipoObbligatorioNote
keystringsìVedi chiavi.
valuestringa o Uint8ArraysìI byte da memorizzare.
options.contentTypestringnoPredefinito a text/plain per una stringa e application/octet-stream per un Uint8Array.
options.expectedRevisionintero non negativonoScrivi solo se la voce è ancora a questa revisione.
options.idempotencyKeystringnoRitenta la stessa scrittura senza applicarla due volte.
Richiede
capabilities["kv.write"]
Restituisce
promessa

screenrig.kv.delete(key, expectedRevision, options)#

Scrivi stato live dell’applicazione rimuovendo una voce. expectedRevision è opzionale: omettilo per eliminare la voce corrente, o forniscilo per rifiutare modifiche concorrenti.

await window.screenrig.kv.delete("menu");
ParametroTipoObbligatorioNote
keystringsìVedi chiavi.
expectedRevisionintero non negativonoLa revisione a cui era l’elemento quando l’hai letta.
options.idempotencyKeystringnoRitenta la stessa eliminazione senza applicarla due volte.
Richiede
capabilities["kv.write"]
Restituisce
promessa

screenrig.kv.onChange(handler)#

Aggiorna lo stato live dell’applicazione al cambiamento invece di interrogarlo. Il gestore si attiva ogni volta che una chiave di questa applicazione cambia, chiunque l’abbia modificata: l’agente con kv set, un sistema esterno tramite un webhook chiave/valore, o questa applicazione su qualsiasi schermo. Riceve quale chiave è cambiata, non il valore, quindi leggi il nuovo valore con kv.get. La chiamata restituisce la funzione che termina l’iscrizione.

const sr = window.screenrig;

async function showMenu() {
  render(await sr.kv.get("menu"));
}

const stopChanges = sr.kv.onChange(function (change) {
  if (change.key === "menu" && !change.deleted) showMenu();
});

await sr.waitUntilActive();
await sr.ready();
await showMenu();

Iscriviti prima della prima lettura, così una modifica che arriva mentre leggi non viene persa; un gestore registrato prima dell’attivazione parte una volta che la pagina è attiva. Chiama stopChanges() per terminare l’iscrizione.

Una modifica raggiunge ogni schermo la cui playlist posiziona questa app entro secondi. Diverse scritture rapide a una chiave possono arrivare come una modifica che porta la revisione più recente, quindi considera una modifica come “leggi di nuovo questa chiave”, non come un conteggio di scritture. Una modifica è un segnale, non una storia: leggi ciò che serve all’avvio dell’app, poi segui le modifiche.

CampoTipoNote
keystringLa chiave modificata.
revisionintero, opzionaleLa nuova revisione della voce. Assente quando deleted è true.
deletedbooleantrue quando la chiave è stata eliminata.
Richiede
capabilities["kv.read"]; senza di esso il gestore non viene mai eseguito
Restituisce
funzione unsubscribe

Chiavi

Una chiave è da 1 a 256 byte UTF-8. Il limite è in byte, non in caratteri, quindi una chiave con caratteri multi-byte lo raggiunge prima di quanto suggerisca la sua lunghezza. Una chiave non deve iniziare con _screenrig/; quel prefisso appartiene al runtime iniettato.

Revisioni e idempotenza

Ogni voce ha una revisione. Facoltativamente passa expectedRevision a screenrig.kv.set o screenrig.kv.delete per scrivere solo se la voce è ancora alla revisione letta. Una revisione obsoleta significa che qualcun altro ha scritto prima: rileggi la voce, riapplica la modifica e riprova.

idempotencyKey copre l’altra metà. Una scrittura che può essere ritentata dopo una risposta persa può portare la stessa chiave a ogni tentativo, e lo store la applica una volta.

Lo stesso store dalla CLI

L’agente può accedere a queste voci dall’esterno del browser con i comandi kv del CLI incluso contro l’id app_ da app upload. Questa è la vista dell’operatore del negozio. Non sostituisce i cinque metodi sopra: un’applicazione modifica i propri dati tramite screenrig.kv nel browser, mentre è sullo schermo. Una modifica scritta dall’agente raggiunge l’applicazione in esecuzione tramite kv.onChange.

Invia dati da un altro sistema

Un webhook chiave/valore è un URL che scrive una chiave di questa applicazione. Forniscilo a qualsiasi cosa possa inviare una richiesta HTTP POST, come un punto vendita, uno script di foglio di calcolo, un cron job o curl, e ogni post sostituisce il valore di quella chiave. Ogni schermo che esegue l’applicazione ne viene informato tramite kv.onChange in pochi secondi, senza nuove release e senza agente in mezzo.

L’agente ne crea uno per una chiave con il CLI incluso e ti fornisce il suo URL e segreto:

screenrig kv webhook create menu --app-id app_01EXAMPLEAPP00000000000 --description "Point of sale menu feed"

La risposta include il url del webhook e il suo secret (srkw_…). Il segreto è mostrato solo alla creazione del webhook e alla rotazione del segreto, quindi inseriscilo subito nel sistema di invio. L’URL non è segreto; il segreto sì.

Il mittente invia il nuovo valore come corpo grezzo della richiesta, con il segreto nell’header Authorization:

curl https://api.screenrig.ai/api/applications/app_01EXAMPLEAPP00000000000/kv-webhooks/kvw_01EXAMPLEWEBHOOK00000/write \
  -H "Authorization: Bearer $KV_WEBHOOK_SECRET" \
  -H "Content-Type: application/json" \
  --data '{"soup":"lentil","price":"6.50"}'

Un mittente che parla solo autenticazione HTTP Basic usa l’id webhook come username e il segreto come password:

curl https://api.screenrig.ai/api/applications/app_01EXAMPLEAPP00000000000/kv-webhooks/kvw_01EXAMPLEWEBHOOK00000/write \
  --user "kvw_01EXAMPLEWEBHOOK00000:$KV_WEBHOOK_SECRET" \
  -H "Content-Type: application/json" \
  --data '{"soup":"lentil","price":"6.50"}'
  • Il corpo, massimo 1 MiB, diventa il valore, e Content-Type il suo tipo di contenuto (application/octet-stream se l’header è assente). Il valore raggiunge l’applicazione browser, quindi non inviare mai una credenziale come valore.
  • Ogni post è una scrittura chiave/valore come kv set: sostituisce il valore, incrementa la revisione ed è conteggiata per l’archiviazione come qualsiasi altra scrittura.
  • La risposta è i nuovi metadati della chiave (key, revision, bytes, sha256, content_type e updated_at), mai il suo valore.
  • Aggiungi un’intestazione Idempotency-Key (da 8 a 200 caratteri) per riprovare un post in sicurezza: entro 24 ore la stessa chiave vale una volta, e la stessa chiave con un corpo o tipo contenuto diverso è rifiutata con idempotency_mismatch. Senza, ogni post è una nuova scrittura.
  • Un webhook accetta fino a 120 post al minuto; oltre la risposta è 429 con Retry-After.
  • Un segreto mancante o errato, o un webhook sconosciuto, risponde 401. Un segreto nell’URL o nella query string non è mai accettato.
  • Un’app ha fino a 20 webhook. kv webhook rotate-secret emette un nuovo segreto e quello vecchio si ferma subito; kv webhook delete ferma subito l’URL e lascia il valore della chiave al suo posto.

Anche una scheda accetta webhook: un invio costruisce il suo documento dati, così com'è o tramite una mappatura (Webhook delle schede).

Comandi webhook chiave/valore →

Il dispositivo

Un’applicazione che gestisce un pannello a muro o un chiosco può controllare lo schermo su cui gira. I flag device vanno al frame che controlla la sua pagina (il controller della pagina, o la sua unica applicazione), su un Player in grado di farlo su quel dispositivo: il Player Android concede device.display, device.keys e device.network, concede device.presence quando il dispositivo ha una fotocamera e la persona che ha configurato il dispositivo ha consentito al Player di usarla (Impostazioni di Android, App, screenRIG Player, Autorizzazioni, Fotocamera), device.light quando ha un sensore di luce e device.haptics quando ha un motore di vibrazione. I Player che non possono controllare un dispositivo lasciano a false ogni flag device. display.get(), display.set() e vibrate() rifiutano con not_supported su un Player che non li offre e con capability_denied senza il flag. onDisplay, onPresence, onKey, onLight e onNetwork possono essere registrati in qualsiasi momento e, come kv.onChange, semplicemente non vengono mai eseguiti senza il flag.

screenrig.device.display.set(state)#

Attenuare, oscurare o riattivare il display. brightness va da 0 a 1 (0 è il livello più basso della retroilluminazione, non lo spegnimento); on: false oscura il display e on: true lo riaccende. Ometti un membro per lasciarlo com’è. I tocchi raggiungono comunque l’applicazione mentre il display è scuro, quindi un tocco può riattivarlo. Una programmazione del display che lo tiene scuro prevale sull’applicazione, e il Player ripristina il display quando la pagina lascia lo schermo.

await window.screenrig.device.display.set({ brightness: 0.3 });
await window.screenrig.device.display.set({ on: false });
Si risolve con
{ on, brightness }, il display dopo la chiamata (brightness è null quando il Player non riesce a leggerlo); set({}) si limita a leggere, e brightness mantiene il suo valore mentre il display è scuro
Richiede
capabilities["device.display"]

screenrig.device.display.get()#

Lo stato attuale del display, come { on, brightness }.

Richiede
capabilities["device.display"]

screenrig.device.onDisplay(handler)#

Chiamato con { on, brightness } ogni volta che il display cambia, sia che lo abbia cambiato questa applicazione, una programmazione del display o un operatore.

Restituisce
funzione unsubscribe
Richiede
capabilities["device.display"]

screenrig.device.onPresence(handler)#

Chiamato quando il dispositivo vede qualcuno muoversi davanti allo schermo, al massimo una volta al secondo. Il Player legge la fotocamera del dispositivo e non conserva alcuna immagine: nessuna immagine viene memorizzata, registrata nel log o inviata. La fotocamera è attiva solo finché è registrato un gestore.

window.screenrig.device.onPresence(function () {
  window.screenrig.device.display.set({ on: true, brightness: 1 });
});
Restituisce
funzione unsubscribe
Richiede
capabilities["device.presence"]

screenrig.device.onKey(handler)#

Chiamato con "volume_up" o "volume_down" a ogni pressione di un tasto volume fisico, ripetizioni incluse. Finché è registrato un gestore, i tasti appartengono all’applicazione e il volume del dispositivo resta com’è.

Restituisce
funzione unsubscribe
Richiede
capabilities["device.keys"]

screenrig.device.onLight(handler)#

Chiamato con la luce ambientale in lux: la prima lettura dopo la registrazione del gestore, poi ogni volta che la luce cambia di almeno il 10% o attraversa 1 lux, al massimo una volta al secondo. Il dispositivo deve avere un sensore di luce.

window.screenrig.device.onLight(function (lux) {
  document.body.classList.toggle("dim-room", lux < 10);
});
Restituisce
funzione unsubscribe
Richiede
capabilities["device.light"]

screenrig.device.onNetwork(handler)#

Chiamato con true o false ogni volta che il dispositivo ottiene o perde la connettività internet convalidata dal sistema, e subito con lo stato corrente quando viene registrato il primo gestore.

window.screenrig.device.onNetwork(function (online) {
  offlineBadge.hidden = online;
});
Restituisce
funzione unsubscribe
Richiede
capabilities["device.network"]

screenrig.device.vibrate(ms)#

Riproduci un impulso aptico. ms è un numero intero di millisecondi da 1 a 200 e il valore predefinito è 12. La promessa si risolve senza valore non appena il Player ha avviato la vibrazione, e viene rifiutata con invalid_request, senza inviare nulla, per qualsiasi altro ms.

await window.screenrig.device.vibrate();
await window.screenrig.device.vibrate(40);
Si risolve con
nessun valore
Richiede
capabilities["device.haptics"]

Raggiungere i dispositivi nella rete dello schermo

Un’applicazione può recuperare dati da indirizzi http:// e ws:// oltre che https://, così può comunicare con un dispositivo o un server sulla rete stessa dello schermo, come un controller a http://192.168.1.20. I Player Android, Linux e Raspberry Pi, Windows e macOS lo consentono. Su un browser in modalità kiosk che esegue l’app web del Player, il proprietario del browser lo consente con un criterio aziendale: vedi Applicazioni sulla rete locale. Il server che chiami risponde a CORS per l’origine dell’applicazione; su macOS le richieste di un’applicazione riportano Origin: null, quindi su macOS il CORS del server consente quell’origine.

Un motore del browser blocca <img src="http://…"> in una pagina sicura, quindi carica le immagini da un indirizzo http:// con fetch() e URL.createObjectURL().

const response = await fetch("http://192.168.1.20/snapshot.jpg");
image.src = URL.createObjectURL(await response.blob());

Costruisci e posiziona l’app