Comment fonctionne une source
- Une source, une carte. Une source désigne la carte qu’elle alimente. Une carte a au plus une source, et une organisation en compte jusqu’à 200, tous projets confondus.
- Elle s’exécute selon un calendrier. Une source de calendrier se synchronise toutes les 5 minutes, et chaque source peut être réglée entre 1 minute et 24 heures. Une source s’exécute dans les secondes qui suivent sa création ou sa modification, et
source refreshla synchronise tout de suite. - Une synchronisation en échec ne modifie jamais la carte. La carte garde son dernier bon document, et le statut de la source indique ce qui a échoué. Les échecs sont repris automatiquement, avec une attente plus longue après chacun.
- Seuls les changements sont écrits. Lorsqu’une synchronisation trouve ce que la carte contient déjà, rien n’est écrit et les écrans ne sont pas réveillés.
- Les synchronisations sont gratuites. Les documents comptent dans le stockage des données de cartes comme toute autre écriture.
- Les identifiants sont chiffrés. Une adresse qui donne accès est stockée chiffrée, n’est renvoyée que sous la forme de son schéma et de son hôte, et n’apparaît jamais dans un journal, une erreur ou le journal d’événements du projet.
- Elle garde les dernières bonnes données pendant la durée de votre choix. Quand une source ne peut pas s'actualiser, sa carte garde les dernières bonnes données pendant la période d'expiration de la source (
--stale-after, de 1 minute à 7 jours ; une source de réservations de lieu les garde 30 minutes), puis les données expirent sur chaque écran, y compris hors ligne, et les pages qui en dépendent basculent sur les pages suivantes. Sans période, les dernières bonnes données restent jusqu'à la prochaine actualisation. Voir Quand une source ne peut pas s'actualiser.
Partir d’un préréglage
Un préréglage est une source toute faite pour un service que l’on affiche souvent sur un écran. Choisissez-en un, remplissez quelques champs, ajoutez l’identifiant que le service délivre, et screenRIG construit la source et fait correspondre la réponse à la carte. Les préréglages sont des sources json, que tous les forfaits incluent.
| Préréglage | Carte | Ce qu’il faut |
|---|---|---|
slack-channel | workplace-posts, message-wall | L’ID du canal, et le jeton de bot (xoxb-…) d’une application Slack interne à votre espace de travail : sur api.slack.com/apps, ajoutez les portées channels:history et groups:history, installez l’application, puis ajoutez-la au canal |
bonusly | kudos | Un jeton d’accès Bonusly avec recognition:read, qu’un administrateur global ou technique crée sous Company, Integrations, API & Tokens |
facebook-page | social-wall | L’ID de la page, le nom à afficher, et un jeton d’accès de page avec pages_read_engagement et pages_show_list, obtenu dans l’Explorateur de l’API Graph |
instagram-business | social-wall | L’ID du compte Instagram, le nom à afficher, et le jeton d’accès de la page Facebook liée, avec instagram_basic, pages_show_list et pages_read_engagement |
google-reviews | reviews | L’ID du lieu, et une clé d’API Google Cloud avec l’API Places (New) activée |
google-travel-times | travel-times | Une adresse de départ, de une à huit destinations, en voiture ou en transport en commun, et une clé d’API Google Cloud avec l’API Routes activée |
greenhouse-jobs | now-hiring | Le jeton du tableau, tiré de boards.greenhouse.io/TOKEN. Aucun identifiant : le tableau est public |
lever-jobs | now-hiring | Le nom du site, tiré de jobs.lever.co/NAME, et la région. Aucun identifiant |
ashby-jobs | now-hiring | Le nom du tableau, tiré de jobs.ashbyhq.com/NAME. Aucun identifiant |
github-actions | build-board | Le propriétaire, le dépôt et la branche, et un jeton d’accès personnel à granularité fine avec un accès en lecture seule aux Actions de ce dépôt, créé sur github.com/settings/personal-access-tokens |
Le tableau de bord, votre agent et l’API listent les préréglages, avec l’aide et l’exemple de chaque champ et les étapes pour obtenir chaque identifiant : GET /api/source-presets les renvoie tous et GET /api/source-presets/NAME un seul (le groupe Sources de données de la référence de l’API). Créez une source à partir d’un préréglage avec preset, settings et secrets à la place de kind et config. Gardez l’identifiant dans le fichier de requête, pas sur la ligne de commande, et remplacez BOT_TOKEN par le jeton :
{
"name": "Announcements",
"preset": "slack-channel",
"target": {"card_id": "crd_CARD"},
"settings": {"channel": "C0123456789", "channel_label": "#announcements"},
"secrets": {"token": "BOT_TOKEN"}
}curl -sS https://api.screenrig.ai/api/sources/test \
-H "Authorization: Bearer $SCREENRIG_TOKEN" -H "Content-Type: application/json" -d @source.jsonPOST /api/sources/test affiche le document que la carte montrerait, indique si la carte l’accepte et ce qu’il a remarqué, et n’écrit rien. POST /api/sources enregistre le même fichier, et PATCH /api/sources/ID avec de nouveaux settings reconstruit la source à partir du préréglage.
- Votre compte, vos conditions. Un préréglage lit votre propre compte avec un identifiant que vous créez, selon les conditions du service, et la carte affiche ce que ces conditions demandent : les avis Google apparaissent avec la marque Google et le nom de chaque auteur.
- Horaire et expiration. Chaque préréglage fixe son propre intervalle et sa propre période d’expiration, par exemple une minute et 15 minutes pour Slack, ou 6 heures et 24 heures pour les avis Google. Une source peut choisir un autre intervalle, jamais plus court que le minimum de son préréglage. Quand une synchronisation échoue, la carte garde ses dernières données jusqu’à la fin de la période d’expiration, puis devient vide.
- Facturation chez le service. Chaque actualisation des avis Google est une requête Place Details sur votre projet Google Cloud, et chaque actualisation des temps de trajet Google est un élément d’itinéraire pour chaque destination : quatre destinations toutes les 15 minutes font environ 11 500 éléments par mois.
- Slack exige une application interne. Ne la distribuez pas : Slack limite à une requête par minute une application distribuée hors de son Marketplace. L’application ne lit que les canaux auxquels elle a été ajoutée, et la carte affiche les messages propres des personnes, pas les arrivées, les publications de bots ni les avis de canal.
Créer une source
Créez d’abord la carte, puis faites un aperçu, puis enregistrez.
screenrig card create --type events --file events.json
screenrig source test --kind ics --card crd_CARD \
--set 'calendars=[{"key":"lobby"}]' --set time_zone=America/Vancouver \
--secret calendar_url.lobby=@lobby.url
screenrig source create --kind ics --card crd_CARD --name "Lobby calendar" \
--set 'calendars=[{"key":"lobby"}]' --set time_zone=America/Vancouver \
--secret calendar_url.lobby=@lobby.url
screenrig source show src_SOURCEsource test récupère l’adresse, la met en forme pour la carte et vérifie le résultat auprès de la carte, sans rien enregistrer ni écrire. Il affiche le document, indique si la carte l’accepte et signale ce qu’il a remarqué en chemin. Donnez l’adresse dans un fichier (@FILE) ou sur l’entrée standard (-) pour qu’elle reste hors de l’historique de votre shell.
| Commande | Ce que ça fait |
|---|---|
source list, source show ID | Les sources du projet, avec leur statut, leurs paramètres et leurs secrets masqués |
source create | Enregistre une source et l’exécute en quelques secondes |
source update ID | Modifie le nom, la carte, les paramètres (--set KEY=VALUE, ou --settings JSON), les secrets (--secret, --unset-secret), le calendrier (--refresh 10m) ou --enable et --disable |
source test | Fait un aperçu d’une source, enregistrée ou non, sans rien écrire |
source refresh ID | Synchronise tout de suite et affiche le résultat |
source delete ID | Supprime la source; la carte garde son dernier document |
--settings prend toute la configuration de la source en JSON, @FILE ou -. L’option --config de la CLI désigne son fichier d’identifiants et n’a rien à voir avec les sources.
Quand une source ne peut pas s'actualiser
Une source écrit chaque document avec une échéance : sa période d'expiration après l'écriture, renouvelée tant que la source continue de s'actualiser. Tant que la source fonctionne, l'échéance recule sans cesse. Quand elle échoue, la carte continue d'afficher les dernières bonnes données jusqu'à l'échéance, puis les données expirent sur chaque écran, y compris hors ligne.
- Définissez la période avec
--stale-after 30msursource createousource update, de 1 minute à 7 jours et au moins le double de l'intervalle d'actualisation.--stale-after nonegarde les dernières bonnes données jusqu'à la prochaine actualisation. Une source de réservations de lieu (momentus) les garde 30 minutes sauf indication contraire ; les autres types les gardent jusqu'à la prochaine actualisation. - Basculer sur votre propre contenu. Une page dont la condition
visibility.datadésigne le document (pour une salle,momentus-room-{screen.field.room}) s'affiche tant que les données sont là et cède la place à la page suivante à leur expiration. Gardez après elle une page ordinaire, à votre image, comme repli. - Le lire.
source showindiquestale_after,data_expires_atet, une fois les données expirées alors que la source continue d'échouer,stale: true. La page Sources de données du tableau de bord montre la même chose : une source en échec est En échec, et celle dont les données ont expiré est Périmée. - Être prévenu. Une notification sur les conditions
source_failed(une actualisation a échoué) etsource_stale(les données ont expiré) envoie un courriel ou publie dans Slack, Teams, PagerDuty ou Telegram, comme pour un écran :screenrig notifications create --email owner --conditions source_failed,source_stale --hold 5. Un avis nomme la source et renvoie à sa page, disparaît quand une actualisation réussit, et--tagne correspond jamais à une source.
Statut et erreurs
Chaque source affiche son statut : quand elle a tourné pour la dernière fois, réussi pour la dernière fois et modifié la carte pour la dernière fois, quand elle tournera de nouveau, combien de synchronisations de suite ont échoué, et la dernière erreur.
| État | Sens |
|---|---|
pending | La source ne s’est pas encore exécutée |
ok | La dernière récupération a réussi et la carte a accepté le document |
error | La dernière synchronisation a échoué; la carte garde son dernier bon document |
disabled | Le calendrier est arrêté |
ok ne juge pas si les données en amont sont exactes ou à jour, ni si un écran affiche la carte.
| Code d’erreur | Ce qui s’est passé |
|---|---|
unreachable | screenRIG n’a pas pu joindre l’adresse. Utilisez une adresse http(s) publique sur le port 80 ou 443 |
timeout | L’adresse n’a pas répondu en 20 secondes |
too_large | La réponse dépasse 5 Mo |
http_status | L’adresse a répondu par une erreur HTTP. Un 404 signifie que l’adresse n’est plus la bonne |
auth_failed | L’adresse a refusé les identifiants; le prochain essai attend une heure |
not_shared | Une feuille Google n’est pas partagée : Google a répondu par une page de connexion, un 401 ou un 403. Partagez-la avec Tous les utilisateurs disposant du lien, ou publiez-la sur le web |
parse_failed | La réponse n’est pas un calendrier. Une page de connexion se lit comme une page web, pas comme un calendrier : utilisez l’adresse ICS du calendrier |
rate_limited | Le service limite les requêtes; la prochaine synchronisation attend |
mapping_failed | Le mappage n’a pas pu lire la réponse à l’endroit que nomme le message, par exemple un rows_path qui ne mène à aucun tableau |
card_data_invalid | La carte a refusé le document au chemin indiqué par le message |
target_missing | La carte a été supprimée. Pointez la source vers une autre carte |
payment_required | Le stockage du projet est plein, donc le document n’a pas été écrit |
config_invalid | Un paramètre ou un secret stocké ne peut plus être utilisé. Saisissez-le de nouveau |
internal | La synchronisation a échoué dans screenRIG et sera retentée |
La création ou la modification d’une source peut répondre source_target_taken (la carte a déjà une source), source_target_unsupported (ce type ne peut pas alimenter cette carte; la réponse liste les cartes possibles), source_secret_required (un secret manque, ou a été saisi pour une autre adresse et doit l’être de nouveau), source_limit_reached et source_busy (une synchronisation est en cours; réessayez après l’intervalle). source test répond source_test_failed avec la raison lorsque l’adresse ne peut pas être lue.
Calendriers
Une source de calendrier lit des adresses iCalendar (ICS) : l’adresse secrète que Google Agenda, Outlook, iCloud et Nextcloud donnent pour un calendrier, et tout lien webcal://. Elle alimente une carte events avec un agenda de tous les calendriers, ou une carte study-rooms avec une salle par calendrier.
| Paramètre | Sens |
|---|---|
calendars | 1 à 60 calendriers, chacun défini par {key, name, floor, capacity}. La clé se compose de lettres minuscules, de chiffres, de - et de _; le nom, l’étage et la capacité décrivent une salle |
days | Combien de jours afficher à partir d’aujourd’hui, de 1 à 31 (7 par défaut) |
time_zone | Un fuseau horaire IANA tel que America/Vancouver, utilisé pour la limite de la journée et pour les heures qu’un flux laisse sans fuseau |
private_title | Le titre affiché pour les événements privés (Private par défaut) |
include, exclude | Mots-clés qui conservent ou masquent des événements selon leur titre : voir Garder ou masquer des événements par mot-clé |
Chaque calendrier a un secret, calendar_url.KEY, qui contient son adresse.
- Les événements récurrents (règles quotidiennes, hebdomadaires, mensuelles et annuelles, exceptions, occurrences déplacées et annulées) et les fuseaux horaires sont développés sur le serveur : un événement garde son heure malgré le changement d’heure, et une carte ne répète jamais les règles du calendrier. Les noms de fuseaux horaires de Windows utilisés par Outlook sont reconnus.
- Les événements privés (
CLASS:PRIVATEouCONFIDENTIAL) n’affichent que leurs horaires, avec le titre privé et sans organisateur ni lieu. La règle couvre ceux qui sont marqués privés et ne juge pas ce que révèlent les autres événements. - Temps libre (événements marqués comme transparents ou libres) : conservé dans un agenda et exclu d’un tableau de salles, où seul le temps occupé compte. Les événements annulés sont retirés, et les événements provisoires comptent comme occupés.
- Les événements sur toute la journée s’affichent comme des dates; un événement sans fin n’affiche pas de fin.
- Avertissements. Lorsqu’un flux n’indique aucun fuseau horaire, en utilise un que screenRIG ne reconnaît pas, ou contient plus de 500 occurrences d’un événement ou plus de 5 000 événements, la synchronisation réussit et le statut affiche un avertissement.
- Plusieurs calendriers se synchronisent ensemble : si l’un échoue, toute la synchronisation échoue et l’erreur nomme le calendrier, de sorte qu’un tableau n’affiche jamais un ensemble partiel.
Garder ou masquer des événements par mot-clé
Les sources ics, microsoft365, google_calendar et momentus acceptent deux paramètres facultatifs, include et exclude, chacun une liste de 1 à 20 mots-clés de 1 à 100 caractères. Un événement est conservé quand son titre contient au moins un mot-clé include (si include est défini) et aucun des mots-clés exclude. Un mot-clé correspond à l’intérieur d’un titre sans égard à la casse ni aux accents : café et CAFE se correspondent donc.
- Titre seulement. Le lieu, l’organisateur et la description ne sont jamais comparés. Un événement sans titre est comparé comme
Untitled event. - Les événements privés sont comparés sur leur propre titre et affichent toujours le titre privé. Le titre privé lui-même n’est jamais comparé, de sorte que
exclude: ["private"]ne retire rien. - Tout ce que la source écrit lit les calendriers filtrés : la carte et chaque document de salle par clé. Un filtre retire seulement des événements, jamais un calendrier ni une salle, et les événements libres comptent comme les autres.
- Le statut compte ce qui a été écarté sous
filtered, 0 compris. Quand la fenêtre contient des événements et que les mots-clés n’en laissent aucun, la synchronisation réussit avec un avertissement qui demande de les vérifier, et la carte affiche une liste vide.source testmontre la même chose.
screenrig source create --kind ics --card crd_EVENTS --name "Public events" \
--set 'calendars=[{"key":"main"}]' --set 'include=["open house","tour"]' --set 'exclude=["cancelled"]' \
--secret calendar_url.main=@calendar.urlFeuilles, CSV et JSON
Une source sheets, csv ou json lit un tableau ou un document JSON et en tire les données d’une carte grâce à un mappage, de sorte qu’elle alimente n’importe quelle carte : un menu à partir d’une liste de prix, un tableau d’indicateurs à partir d’une feuille de mesures, un tableau à partir d’une feuille de classement. Le mappage est un modèle JSON dans les paramètres de la source. Les règles propres à la carte décident si ce que produit le mappage est accepté, et source test affiche le document et indique si la carte l’accepte; vous modifiez donc le mappage jusqu’à ce qu’elle l’accepte. Ces sources se synchronisent toutes les 5 minutes, et toutes les minutes au plus court.
screenrig source test --kind sheets --card crd_MENU --settings @menu-sheet.json
screenrig source create --kind sheets --card crd_MENU --name "Cafe menu" --settings @menu-sheet.json
screenrig source create --kind json --card crd_KPI --name "Daily numbers" \
--settings @kpi-api.json --secret token=@api.token| Paramètre | Types | Sens |
|---|---|---|
url | tout | Le lien de la feuille, ou l’adresse du fichier CSV ou du document JSON : une adresse http(s) publique sur le port 80 ou 443 |
mapping | tout | Le modèle qui produit les données de la carte. Requis |
key_template | tout | Clé facultative avec des marqueurs {screen.field.NAME}; la transformation renvoie un tableau documents de {fields,document} |
sheet | sheets | Le nom d’un onglet, pour lire un onglet autre que celui que nomme le lien |
header_row | sheets, csv | true (par défaut) quand la première ligne contient les noms des colonnes; false quand toutes les lignes sont des données, nommées Column 1, Column 2 |
key_column | sheets, csv | La colonne dont les cellules nomment les lignes, pour que le mappage puisse retrouver une ligne par son nom |
delimiter | csv | ,, ; ou tab. Par défaut, celui que la première ligne utilise le plus |
auth | csv, json | none (par défaut), bearer, header, basic, oauth2 ou token_request : voir Requêtes, connexion et pages |
header_name | csv, json | Avec auth header, l’en-tête qui porte le jeton, par exemple X-API-Key |
rows_path | json | L’emplacement du tableau de lignes dans la réponse, par exemple data.items |
key_field | json | Le membre de chaque ligne qui la nomme. Définissez-le avec rows_path |
Partager une feuille Google
Une source sheets lit la feuille par l’exportation CSV de Google. Elle n’exige aucune connexion ni aucun accès à votre compte Google, et la feuille doit être lisible par toute personne qui en a le lien.
- Dans Google Sheets, choisissez Partager, réglez Accès général sur Tous les utilisateurs disposant du lien et le rôle sur Lecteur. Pour publier plutôt, choisissez Fichier, Partager, Publier sur le web.
- Copiez le lien de la barre d’adresse du navigateur dans
url. Un lien vers un onglet garde cet onglet. Pour lire un autre onglet par son nom, définissezsheet; un lien publié n’accepte passheet. - Faites un aperçu avec
source test. La ligne d’en-tête de la feuille devient les clés de colonne que lit le mappage.
Une feuille qui n’est pas partagée répond par une page de connexion, un 401 ou un 403. Le statut est alors not_shared, et le message nomme le réglage à changer : Partager, Accès général, Tous les utilisateurs disposant du lien, Lecteur, ou Fichier, Partager, Publier sur le web. Demandez au propriétaire de la feuille de la partager. not_shared ne juge que ces trois réponses. Il ne compare pas les colonnes avec votre mappage.
Adresses avec jeton
Un fichier CSV ou un document JSON à une adresse publique n’exige aucun jeton. Pour une adresse protégée, réglez auth sur bearer (screenRIG envoie Authorization: Bearer TOKEN) ou sur header avec header_name (il envoie HEADER_NAME: TOKEN), et fournissez le jeton comme secret token :
screenrig source create --kind csv --card crd_TABLE --name "Standings" \
--settings @standings.json --secret token=@api.tokenLe jeton est stocké chiffré et n’est renvoyé que sous forme d’indice : ses quatre derniers caractères s’il en compte 12 ou plus, sinon …. Il n’est envoyé qu’à l’origine de l’adresse elle-même : le schéma, l’hôte et le port. Une redirection vers un autre site n’est pas suivie avec le jeton, et pointer la source vers une autre origine sans saisir de nouveau le jeton est refusé avec source_secret_required. Ne changer que le chemin ou la requête garde le jeton. Pour basic, OAuth 2 et les demandes de jeton, et pour une requête avec un corps, des en-têtes ou des pages, voir Requêtes, connexion et pages. header_name ne peut pas être Host, Cookie, Content-Length, Connection, Transfer-Encoding, Upgrade ni un en-tête Proxy-, ni un en-tête que screenRIG définit lui-même.
Requêtes, connexion et pages
Une source csv ou json envoie un GET à son url. Ces paramètres envoient un corps ou des en-têtes supplémentaires, ouvrent une session, lisent plus d’une page et placent la date du jour dans une requête. Chaque requête dispose de 20 secondes et une exécution complète de 60.
| Paramètre | Sens |
|---|---|
method | GET (par défaut) ou POST. Un body ou un graphql en fait un POST |
body | Un objet ou un tableau JSON, ou du texte envoyé tel quel. Au plus 16 Kio une fois ses marqueurs remplis |
body_format | json (par défaut) ou form. Un corps de formulaire est un objet de champs texte, nombre et booléen, ou un texte comme a=1&b={{today}} ; les valeurs sont encodées pour une URL |
graphql | {query, variables}, envoyé comme un POST JSON. Une réponse avec des erreurs et sans données est parse_failed ; des erreurs à côté de données sont un avertissement |
headers | Jusqu’à 8 en-têtes supplémentaires dont les valeurs ne sont pas secrètes. Authorization est refusé, tout comme n’importe quel en-tête que header_name refuse : utilisez auth ou un secret d’en-tête |
time_zone | Un fuseau IANA pour les marqueurs de date. Sans fuseau, ils sont lus en UTC et le statut liste un avertissement |
pagination | Lit plus d’une page, comme décrit ci-dessous |
format | Type json seulement : auto (par défaut), json, csv ou xml |
Un secret nommé header.NAME est envoyé comme l’en-tête NAME : une API à deux en-têtes d’identification prend donc header.X-Client-Id et header.X-Api-Key. Un secret nommé query.NAME est ajouté à l’adresse sous la forme NAME=value. Chaque sorte en accepte jusqu’à 8, les deux sont stockées chiffrées et jamais affichées, et l’aperçu affiche un secret de requête sous la forme NAME=***.
| Authentification | Paramètres et secrets |
|---|---|
none | La valeur par défaut |
bearer | Le secret token, envoyé comme Authorization: Bearer |
header | header_name et le secret token |
basic | username (sans deux-points) et le secret password, envoyés comme Authorization: Basic |
oauth2 | Informations d’identification du client : token_url, client_id, scope et audience facultatifs, token_auth (body, la valeur par défaut, ou basic) et le secret client_secret. screenRIG demande un jeton à token_url et l’envoie comme Authorization: Bearer |
token_request | Une connexion qui renvoie un jeton : token_url, token_body (un objet dont les chaînes peuvent lire les secrets stockés sous la forme {{secrets.NAME}}), token_body_format (json ou form), token_path (l’endroit de la réponse où se trouve le jeton, par exemple token.accessToken) et, facultativement, token_expires_path, token_ttl (de 60 à 86 400 secondes, 3 600 par défaut) et header_name (l’en-tête qui porte le jeton tel quel ; sans lui, Authorization: Bearer) |
screenRIG garde un jeton en mémoire, jamais en stockage, et le renouvelle une minute avant son expiration. Quand l’adresse refuse un jeton avec un 401, il en demande un nouveau une fois. Un refus à l’adresse du jeton (HTTP 400, 401 ou 403) donne auth_failed, et rien de ce que dit l’adresse du jeton n’est cité.
{
"url": "https://api.example.com/v2/orders/summary",
"method": "POST",
"body": {"from": "{{today-7d}}", "to": "{{today}}"},
"time_zone": "America/Vancouver",
"auth": "oauth2",
"token_url": "https://login.example.com/oauth/token",
"client_id": "screen-signs",
"scope": "orders.read",
"mapping": {"body": "{{body.total}} orders this week"}
}screenrig source create --kind json --card crd_BOARD --name "Orders" \
--settings @orders.json --secret client_secret=@client.secretLes marqueurs de date remplissent l’adresse, le corps et headers : {{now}} (2026-11-01T17:30:00Z), {{today}} (2026-11-01) et {{unix}} (secondes), chacun avec un décalage facultatif comme {{now-90m}}, {{now+7d}} ou {{today-1d}} (unités m, h et d ; {{today}} n’accepte que les jours). Ils sont lus dans time_zone, ou en UTC. Chaque exécution les remplit d’après l’horloge : l’exécution de demain demande donc la date de demain.
Pages. pagination est {type, max_pages}, avec max_pages de 1 à 20 (5 par défaut). Une source json définit rows_path pour que les lignes des pages se joignent en un seul tableau, et une source csv joint les lignes du tableau.
| Type | Comment la page suivante est trouvée |
|---|---|
link_header | L’adresse rel="next" dans l’en-tête Link |
next_url | path, l’endroit de la réponse qui contient l’adresse suivante (json seulement) |
cursor | param et path : le curseur va dans l’adresse sous la forme param, ou dans le corps avec "in": "body", et la lecture se termine quand le curseur est absent ou vide (json seulement) |
page | param, start (1 par défaut) et size_param avec size : le numéro de page va dans l’adresse ou, avec "in": "body", dans le corps, et la lecture se termine sur une page sans ligne ou avec moins de size |
L’adresse suivante doit rester sur l’origine de la source, de sorte qu’un secret ne la quitte jamais. Une page répétée, ou plus de pages que max_pages, met fin à la lecture avec un avertissement, et l’ensemble des pages fait au plus 5 Mo.
XML et RSS. Une réponse qui commence par <, ou format xml, est lue comme du XML. body contient l’élément racine : les attributs sont @name, le texte d’un élément qui a des enfants est #text, les éléments répétés sont des listes, et les noms gardent leur préfixe (item["media:thumbnail"]["@url"]). Un flux RSS ou Atom reçoit aussi body.items, chaque entrée avec title, link, published, summary (texte brut, jusqu’à 1 000 caractères) et image, quand l’entrée les a. Un DOCTYPE n’est jamais suivi et rien n’en est récupéré.
source test montre dans request la première requête telle qu’elle est partie : les marqueurs remplis, les secrets de requête sous la forme NAME=***, les noms des en-têtes autres que Accept et Content-Type sans leurs valeurs, le premier Kio du corps et le nombre de pages lues.
Ce que lit une source
- CSV et feuilles. CSV ordinaire : une marque d’ordre des octets, des champs entre guillemets, des guillemets doublés, des sauts de ligne entre guillemets et des fins de ligne CRLF sont tous lus. Les cellules sont rognées et les lignes sans contenu sont ignorées. Un en-tête devient une clé en minuscules, sans accents, chaque suite d’autres caractères devenant un seul
_, de sorte queSold outdevientsold_out; un en-tête vide devientcolumn_3(sa position) et un doublon_2,_3. Un fichier qui n’est pas du texte UTF-8, comme un fichier de tableur, donneparse_failed: enregistrez-le en CSV UTF-8. - JSON. Les nombres gardent leurs chiffres. Avec
rows_path, la source y cherche le tableau de lignes; un chemin qui ne mène à aucun tableau donnemapping_failedàrows_path, et un tableau vide est un tableau sans lignes. - Limites. Un tableau est lu jusqu’à 10 000 lignes et 200 colonnes. Au-delà, la synchronisation réussit et le statut affiche un avertissement qui compte les lignes ou les colonnes omises.
- Une page web à l’adresse, au lieu des données, donne
parse_failed.
Le mappage
Le mappage est un modèle JSON. Une chaîne contenant des marqueurs comme {{item.price}} est du texte, et une chaîne qui est exactement un seul marqueur garde le type de la valeur. Un chemin qui ne contient rien est vide dans un texte et fait disparaître une valeur seule, de sorte que la carte nomme alors ce qui lui manque. Ce que peut viser le début d’un chemin dépend du type :
| Type | Punto de partida | Contient |
|---|---|---|
sheets, csv | rows | Chaque ligne de données, un objet par clé de colonne |
sheets, csv | columns | [{key, name}] dans l’ordre de la feuille |
sheets, csv | by_key | Avec key_column : les lignes selon le texte rogné de la cellule de cette colonne |
json | body | Toute la réponse |
json | by_key | Avec rows_path et key_field : les lignes selon le texte, le nombre ou le booléen rogné de ce membre |
Préférez by_key à une position comme rows[2] : une ligne trouvée par sa clé reste trouvée quand quelqu’un trie la feuille ou insère une ligne au-dessus. Écrivez une clé contenant des espaces ainsi : by_key["Net sales"].value. Si deux lignes partagent une clé, la première l’emporte et le statut affiche un avertissement qui compte les doublons. Aucun avertissement ne cite une cellule.
Les cellules sont du texte; convertissez-les : {"$number": "{{item.price}}"} lit 1,234.50, $4.50, 3,50 € et 12% (ajoutez "$decimal": "," pour une virgule décimale), et {"$bool": "{{item.sold_out}}"} lit true, yes, y, 1 et x. $each parcourt une liste avec item et index dans la portée, $group avec $by regroupe les lignes dans l’ordre de première apparition avec group.key et group.items dans la portée, et $text avec $max coupe le texte. Le modèle est vérifié à l’enregistrement de la source.
Un menu tiré d’une feuille aux colonnes Section, Item, Price et Sold out regroupe les lignes par section :
{
"url": "https://docs.google.com/spreadsheets/d/SHEET_ID/edit#gid=0",
"mapping": {
"sections": {
"$group": "{{rows}}", "$by": "{{item.section}}",
"$template": {
"name": "{{group.key}}",
"items": {
"$each": "{{group.items}}",
"$template": {
"name": "{{item.item}}",
"price": { "$number": "{{item.price}}" },
"soldOut": { "$bool": "{{item.sold_out}}" }
}
}
}
}
}
}Un tableau d’indicateurs tiré d’une feuille aux colonnes Metric, Value, Unit et Change cherche chaque indicateur par son nom; trier la feuille ne déplace donc rien :
{
"url": "https://docs.google.com/spreadsheets/d/SHEET_ID/edit#gid=0",
"key_column": "Metric",
"mapping": {
"tiles": [
{ "label": "Revenue", "value": { "$number": "{{by_key.Revenue.value}}" },
"unit": "{{by_key.Revenue.unit}}", "delta": { "$number": "{{by_key.Revenue.change}}" } },
{ "label": "Orders", "value": { "$number": "{{by_key.Orders.value}}" },
"delta": { "$number": "{{by_key.Orders.change}}" } }
]
}
}Une carte de tableau liste chaque ligne :
{
"mapping": {
"rows": {
"$each": "{{rows}}", "$limit": 50,
"$template": {
"team": "{{item.team}}",
"points": { "$number": "{{item.points}}" },
"played": { "$number": "{{item.played}}" }
}
}
}
}Pour voir ce qu’une source lit, faites un test avec le mappage {"columns": "{{columns}}", "rows": "{{rows}}"}. La carte refuse ce document, et l’aperçu l’affiche quand même, avec chaque clé et chaque ligne.
ok sur l’une de ces sources signifie que l’adresse a répondu et que la carte a accepté le document produit par le mappage. Cela ne dit pas que la feuille ou la réponse contient les lignes que votre mappage attend : une colonne qui disparaît fait tomber son membre, et la carte refuse un document auquel il manque un membre obligatoire.
Valeurs calculées
Un mappage peut aussi calculer vrai ou faux et des nombres sur le serveur : une condition de page qui ne teste que l’égalité, comme visibility.data avec equals: true, peut donc suivre un nombre. Les mappages des webhooks de carte et des déclencheurs de superposition disposent des mêmes fonctions.
| Fonction | Donne | Écriture |
|---|---|---|
$gt, $gte, $lt, $lte | Vrai ou faux, en lisant les deux valeurs comme des nombres | {"$lt": ["{{body.stock}}", 5]} |
$between | Vrai quand la valeur est comprise entre les deux bornes, bornes incluses | {"$between": ["{{body.temp}}", 18, 24]} |
$eq, $ne | Les nombres par valeur (5, "5" et "5.00" correspondent), tout le reste comme texte exact, casse comprise | {"$eq": ["{{body.status}}", "open"]} |
$contains | Un texte contient un texte, sans égard à la casse, ou une liste contient une valeur | {"$contains": ["{{body.title}}", "closed"]} |
$in | La valeur figure dans une liste | {"$in": ["{{body.tier}}", ["gold", "silver"]]} |
$and, $or, $not | Combinent des conditions | {"$and": [{"$gt": ["{{body.a}}", 1]}, {"$not": {"$eq": ["{{body.s}}", "x"]}}]} |
$sum, $avg, $min, $max | Un nombre à partir d’une liste | {"$sum": "{{rows}}", "$of": "{{item.amount}}"} |
$count | Combien d’éléments, ou combien passent $where | {"$count": "{{body.queue}}", "$where": {"$gt": ["{{item.wait}}", 5]}} |
- Une comparaison qui ne peut pas être faite est fausse, avec un avertissement qui nomme l’endroit et jamais la valeur : une valeur absente, vide ou non numérique n’active donc jamais une page.
$boolest le seul lecteur qui prend une valeur absente pour faux. - Listes.
$oflit un marqueur dans chaque élément, avecitemetindexdisponibles, et$wheregarde les éléments pour lesquels une condition est vraie. Un élément vide ou non numérique est ignoré, et un avertissement les compte. Sans rien à additionner,$sumet$countvalent 0, et$avg,$minet$maxomettent leur membre. - Nombres. Une virgule décimale (
3,50,1.234,50) exige"$decimal": ",".$avgarrondit à 2 décimales, et"$round"fixe de 0 à 6.$sum,$minet$maxsont exacts.
Un indicateur de stock bas à partir d’une réponse JSON. Une page dont visibility.data désigne le document avec path /low_stock et equals true ne s’affiche que lorsque le stock est bas :
{
"sku": "{{body.sku}}",
"stock": {"$number": "{{body.stock}}"},
"low_stock": {"$lt": ["{{body.stock}}", 5]}
}À partir d’une feuille, tout produit sous son propre seuil de réapprovisionnement :
{"low_stock": {"$gt": [{"$count": "{{rows}}", "$where": {"$lt": ["{{item.stock}}", "{{item.reorder_at}}"]}}, 0]}}Documents par clé
Les sources JSON, CSV et Sheets acceptent key_template, par exemple room-{screen.field.room}. Transformez le flux en un tableau documents d’objets {"fields":{"room":"A101"},"document":{"body":"Room A101"}}. Un webhook de carte utilise --key-template avec la même sortie, ou reçoit directement l’objet englobant sans transformation.
{
"key_template": "room-{screen.field.room}",
"mapping": {
"documents": {
"$each": "{{rows}}",
"$template": {
"fields": {"room": "{{item.room}}"},
"document": {"body": "{{item.title}}"}
}
}
}
}Placez l’instance crd_ correspondante avec data: "room-{screen.field.room}"; chaque écran lit uniquement la clé formée à partir de son propre champ room. Toutes les sorties utilisent le schéma de carte de l’instance. Utilisez des instances, des transformations et des préfixes distincts pour les différents types de cartes qui lisent le même flux.
Prévisualisez avec source test. Les documents invalides, les champs manquants et les clés en double font refuser le lot avant l’écriture. Une défaillance du stockage peut laisser une partie écrite : renvoyez le même corps du webhook avec le même Idempotency-Key, ou actualisez la source. Les clés omises conservent leurs données et leur expiration précédentes; les webhooks ne définissent aucune expiration. Effacez le modèle d’un webhook avec --clear-key-template.
Conseils pour les fichiers et les feuilles
- OneDrive et SharePoint. Un lien de partage ouvre une page d’aperçu, qu’une source lit comme une page web (
parse_failed). Ajoutez?download=1au lien d’un fichier CSV, ou&download=1s’il contient déjà un?, pour que le lien renvoie le fichier lui-même. Le lien doit fonctionner sans connexion. - Retrouver des lignes par leur nom. Réglez
key_columnsur la colonne qui nomme chaque ligne, par son en-tête sans égard à la casse, et lisez une ligne sous la formeby_key.NAME.column: trier la feuille ou insérer une ligne ne change rien. Un nom qui ne correspond à aucune colonne donnemapping_failedàkey_column, et une clé répétée garde la première ligne avec un avertissement qui compte les répétitions.
Salles de réunion
Une source de salles lit des calendriers de salles de réunion et alimente une carte room, le panneau de porte d’une salle, ou une carte room-board, toutes les salles d’un bâtiment. Elle peut aussi alimenter un agenda events ou une carte study-rooms, et une adresse de calendrier (ICS) alimente les mêmes cartes.
Les cartes déterminent à l’écran, chaque seconde, si une salle est libre, occupée ou ce qui vient ensuite, à partir des réservations qu’elles détiennent : un panneau reste exact même quand son écran est hors ligne. Une source de salles ne fait que lire : une carte affiche des réservations et n’accepte aucune saisie, donc rien n’est réservé, terminé ou enregistré depuis un écran.
| Paramètre | Sens |
|---|---|
rooms | De 1 à 60 salles, chacune avec une key (lettres minuscules, chiffres, - et _), l’adresse de la salle (email pour Microsoft 365, calendar_id pour Google) et, en option, name, floor et capacity. Une carte room accepte exactement une salle |
days | Combien de jours afficher à partir d’aujourd’hui, de 1 à 31 (7 par défaut) |
time_zone | Un fuseau IANA tel que America/Los_Angeles, utilisé pour la limite des journées et pour les événements d’une journée entière. Sans fuseau, la journée commence à minuit UTC et l’état affiche un avertissement |
private_title | Le titre affiché pour les événements privés (Private par défaut) |
Boîtes aux lettres de salle Microsoft 365
Le type microsoft365 lit les boîtes aux lettres de salle d’Exchange Online avec votre propre application Microsoft Entra : l’application, son secret et ce qu’elle peut lire restent à vous. Deux paramètres de plus : tenant, l’ID du répertoire ou un domaine vérifié comme contoso.com (common, organizations et consumers sont refusés), et client_id, l’ID d’application (client) de l’application. Le secret client_secret est la valeur du secret client de l’application.
- Dans le centre d’administration Microsoft Entra, enregistrez une application à locataire unique sans URI de redirection, ajoutez un secret client (copiez sa valeur, pas son ID de secret), ajoutez l’autorisation d’application Microsoft Graph
Calendars.Readet accordez le consentement de l’administrateur. - Limitez l’application aux boîtes aux lettres de salle.
Calendars.Readatteint toutes les boîtes aux lettres de l’organisation tant qu’une stratégie d’accès aux applications ne la restreint pas. Placez les salles dans un groupe de sécurité à extension messagerie et exécutez les deux premières commandes ci-dessous dans Exchange Online PowerShell;Test-ApplicationAccessPolicyrépondGrantedpour une salle du groupe. Le RBAC Exchange pour les applications limite une application de la même façon. - Les boîtes aux lettres de salle remplacent l’objet d’une réunion par le nom de l’organisateur, sauf indication contraire. Pour afficher les titres des réunions, exécutez la troisième commande pour chaque salle.
- Faites un aperçu, puis enregistrez.
source testouvre une session, lit chaque salle et indique les salles et les réservations lues, un compte par salle et, si l’application détient aussiPlace.Read.All, combien de salles l’organisation répertorie.
# Exchange Online PowerShell
New-ApplicationAccessPolicy -AppId CLIENT_ID -PolicyScopeGroupId rooms@example.com -AccessRight RestrictAccess -Description "screenRIG room signs"
Test-ApplicationAccessPolicy -AppId CLIENT_ID -Identity boardroom@example.com
Set-CalendarProcessing -Identity boardroom@example.com -DeleteSubject $false -AddOrganizerToSubject $false
# screenRIG (source create takes the same options, plus --name)
screenrig source test --kind microsoft365 --card crd_ROOM \
--set tenant=contoso.com --set client_id=CLIENT_ID --set time_zone=America/Los_Angeles \
--set 'rooms=[{"key":"boardroom","email":"boardroom@example.com","name":"Boardroom","floor":"Level 4","capacity":12}]' \
--secret client_secret=@secret.txt- Correspondance. Les réunions privées et confidentielles affichent le titre privé et aucun organisateur. Les réunions marquées comme libres ou en télétravail, et celles que la salle a refusées, sont du temps libre; les réunions provisoires comptent comme occupées; les réunions annulées sont écartées. Les événements d’une journée entière sont des dates dans le fuseau de la salle.
- Cadence. Une source de salles se synchronise toutes les 2 minutes. L’ouverture de session dure environ une heure et est réutilisée.
- Erreurs. Le code et le texte d’erreur de Microsoft sont cités, par exemple
AADSTS7000215pour un secret client erroné, et une salle que l’application ne peut pas lire fait échouer la synchronisation et est nommée. - Une connexion à la place. Réglez
connection_idsur une connexion Microsoft du projet, dans l’un ou l’autre mode, à la place detenant,client_idetclient_secret. La source ne détient alors aucun secret et se connecte comme la connexion.
Calendriers de ressources Google Workspace
Le type google_calendar lit les calendriers de ressources et de salles avec votre propre compte de service Google. Le secret service_account_key est le fichier de clé tel que Google le délivre, et son indice est l’adresse du compte. Le paramètre facultatif subject nomme l’utilisateur au nom duquel le compte agit avec la délégation à l’échelle du domaine.
- Dans Google Cloud, activez l’API Google Agenda, créez un compte de service et téléchargez-en une clé JSON.
- Donnez au compte l’accès aux salles. Soit partagez chaque calendrier de salle avec l’adresse du compte et l’autorisation Voir tous les détails de l’événement, soit activez la délégation à l’échelle du domaine pour le compte dans la console d’administration avec la portée
https://www.googleapis.com/auth/calendar.events.readonlyet réglezsubjectsur un utilisateur qui voit les salles. - Le
calendar_idd’une salle est l’ID de calendrier de la ressource dans la console d’administration, sous Bâtiments et ressources; il se termine par@resource.calendar.google.com. Faites un aperçu avecsource test, puis enregistrez.
screenrig source test --kind google_calendar --card crd_ROOM \
--set time_zone=America/Los_Angeles \
--set 'rooms=[{"key":"boardroom","calendar_id":"CALENDAR_ID","name":"Boardroom"}]' \
--secret service_account_key=@key.json- Correspondance. Les événements privés et confidentiels affichent le titre privé et aucun organisateur. Les événements marqués comme transparents, et ceux que la salle a refusés, sont du temps libre; les événements annulés sont écartés. Les événements d’une journée entière gardent leurs dates.
- Erreurs. Le texte d’erreur de Google est cité tel quel. Un calendrier que le compte ne voit pas est nommé dans l’erreur, avec la marche à suivre pour le partager.
- Une connexion à la place. Réglez
connection_idsur une connexion Google du projet à la place deservice_account_key. Avec l’application de screenRIG, la source lit les calendriers que peut voir le compte qui l’a approuvée : ce compte doit donc voir chaque calendrier de salle que la source liste, etsubjectn’est pas permis.
Limites et confidentialité
- Une carte
roomgarde les 200 premières réservations et une carteroom-boarden garde 60 par salle. S’il y en a davantage, l’état affiche un avertissement indiquant combien ont été laissées de côté. - Le document de la carte ne contient que ce que la carte affiche, parce que chaque écran qui montre une carte en garde le document. Une carte
roomreçoit les organisateurs seulement sishowOrganizerest activé. Une carteroom-boardne reçoit jamais d’organisateurs et reçoit le titre privé à la place de chaque titre de réunion, sauf sishowTitlesest activé. Un changement de l’un ou l’autre réglage atteint la carte à la prochaine synchronisation. Une réunion privée porte le titre privé dans les deux cas. - Les messages de ces types citent le texte d’erreur que Microsoft ou Google a renvoyé, et jamais un secret.
Le système de réservation d'un lieu
Le type momentus lit les fonctions (chaque utilisation d'une salle, avec ses dates et heures) et les espaces d'une installation Momentus Enterprise, le système vendu auparavant sous les noms Ungerboeck et EBMS, avec un utilisateur d'API que votre administrateur crée dans Momentus (Menu principal, Api Users). Il alimente une carte events pour un répertoire d'événements, une carte room-board pour un hall ou un couloir, ou une carte room pour une salle, et avec un document par salle, chaque écran affiche les réservations de sa propre salle. Une salle qui change peu avant un événement s'affiche dans l'intervalle d'actualisation, une minute par défaut.
| Paramètre | Sens |
|---|---|
base_url | L'adresse https de votre serveur Web Momentus, par exemple https://momentus.example.com/prod ; l'API est lue depuis {base_url}/api/v1/... |
organization | Le code d'organisation Momentus dont les données sont lues |
api_user | L'identifiant de l'utilisateur d'API |
time_zone | Le fuseau IANA du lieu. Momentus garde des dates et heures locales : définissez-le ; sans lui, les heures sont lues en UTC et l'état affiche un avertissement |
days | Combien de jours à partir d'aujourd'hui lire, de 1 à 31 (7 par défaut) |
rooms | Liste facultative de {key, space, name?, floor?, capacity?, area?} ; space est le code d'espace Momentus. Sans elle, chaque espace que Momentus liste est une salle (clé : le code en minuscules) |
space_filter, function_filter | Expressions de recherche Momentus facultatives qui limitent les espaces ou les fonctions lus |
exclude_status_codes | Codes d'état de fonction à exclure, comme les fonctions annulées. Les codes d'état sont propres à votre lieu, il n'y a donc pas de valeur par défaut |
include, exclude | Mots-clés qui conservent ou masquent des fonctions selon le titre que la source affiche, comme pour les calendriers |
Deux secrets : api_key, l'un des GUID de clé de l'utilisateur d'API, et api_secret, son GUID secret. Les deux sont stockés scellés, ne sont jamais réaffichés et sont à saisir de nouveau si la source pointe vers un autre serveur, une autre organisation ou un autre utilisateur d'API.
screenrig source test --kind momentus --card crd_EVENTS \
--set base_url=https://momentus.example.com/prod --set organization=10 \
--set api_user=venue-api --set time_zone=America/Los_Angeles \
--set 'exclude_status_codes=["XX"]' \
--secret api_key=@key.guid --secret api_secret=@secret.guid
screenrig source create --kind momentus --card crd_EVENTS --name "Venue events" \
--settings @momentus.json --secret api_key=@key.guid --secret api_secret=@secret.guidsource test lit Momentus, met le document en forme et le vérifie auprès de la carte, puis montre les salles et les événements lus (functions, functions_other_spaces, events_KEY). Rien n'est enregistré ni écrit.
- Ce que devient une fonction. Le
Spacede la fonction choisit la salle, sonDescriptionest le titre (title_fieldpeut désigner l'une de ses descriptions alternatives) et le nom de la salle est le lieu. Une fonction sans heure de début est un événement d'une journée. Une fonction sur plusieurs dates avec des heures affiche ces heures à chaque date ; celle qui finit avant de commencer se prolonge sur la nuit. - Titres privés. Un
room-boardaffiche le titre privé sauf sishow_titlesest activé, comme pour les autres types de salles. - Erreurs. Le texte propre à Momentus n'est jamais cité, car le serveur est le vôtre :
auth_failedsignifie que l'utilisateur d'API, la clé ou le secret est incorrect ou ne peut pas lire les fonctions et les espaces,config_invalidqu'un filtre n'est pas une recherche Momentus valide, etparse_failedquebase_urla atteint une page Web et non l'API.
Une affiche pour chaque salle
Définissez room_key_prefix (par exemple momentus-room-) et la source écrit aussi un document room pour chaque salle sous ce préfixe suivi de la clé de la salle. Donnez à l'écran de chaque salle sa salle, et placez une carte room dont la clé data est le préfixe suivi du champ propre à l'écran :
screenrig screen update scr_BALLROOM --field room=ballroom-aUtilisez le type de catalogue intégré room dans cette primitive de la liste de lecture :
{"id":"door","primitive":"card","card":"room","layout":"full","content_fit":"fill","params":{"room":"{screen.field.room}"},"data":"momentus-room-{screen.field.room}"}Les primitives crd_ utilisent params et major de l’instance; omettez ces champs. Leur data facultatif sélectionne une clé de document ou un modèle de clé par écran. Le --card crd_ID de la source désigne toujours sa cible de synchronisation. Pour la page, définissez visibility.data.key à momentus-room-{screen.field.room} et ajoutez ensuite une page de repli sans condition.
Le backend remplit le champ dans le manifeste de chaque écran : une seule liste de lecture montre donc à chaque écran sa propre salle, et un écran sans champ de salle n'affiche rien pour cette carte. area_key_prefix fait de même pour un affichage de couloir : le area de chaque salle la regroupe, et une room-board des salles de cette zone est écrite sous le préfixe suivi de la clé de la zone (area_card peut valoir events). screen_field et area_field nomment les champs d'écran que la vérification ci-dessous lit (room et area par défaut).
Vérifier le mappage
screenrig source rooms src_ID (et la section Mappage des salles de la page de la source dans le tableau de bord) liste les salles que la source offre et qu'aucun écran n'affiche, ainsi que les écrans dont la salle est absente ou désigne une salle que Momentus n'a pas :
screenrig source rooms src_VENUEUn écran figure dans le rapport lorsqu'il a une valeur pour le champ, ou lorsque sa propre liste de lecture place une carte qui lit la clé. Chacun est mapped, missing (la liste de lecture lit le champ et l'écran n'en a pas) ou unknown (la valeur ne désigne aucune salle ; le rapport indique la salle probablement visée, par exemple les mêmes lettres dans une autre casse). Corrigez un écran avec screenrig screen update scr_ID --field room=ROOM_KEY. Le rapport lit les salles de la dernière bonne actualisation de la source et ne récupère rien ; une source qui liste ses rooms les connaît avant sa première actualisation.
Sécurité
Une adresse qui donne accès est un identifiant. screenRIG la stocke chiffrée, ne renvoie que son schéma et son hôte, et ne l’utilise que pour effectuer la synchronisation. Les sources lisent des adresses http(s) publiques sur le port 80 ou 443 et suivent au plus trois redirections; une adresse qui ne se résout pas vers un hôte public, une connexion refusée et un échec de négociation se lisent tous de la même façon, ce qui empêche d’utiliser une source pour explorer un réseau. Aucun message ne cite une adresse ni la réponse reçue. Les sources ne font que lire : elles n’écrivent jamais dans un calendrier.