Actions déclarées
La moitié sortante d'une source de données : des actions typées qu'elle peut renvoyer, désactivées tant qu'un administrateur ne les a pas activées
Une source de données est entrante par défaut. Elle peut aussi déclarer des actions : des opérations nommées et versionnées qu'elle peut renvoyer vers le système qu'elle lit, par exemple une commande de véhicule. Une action n'existe que si le manifeste la déclare. Sans déclaration, il n'y a aucun chemin sortant, quoi que la connexion puisse physiquement envoyer.
Déclarer une action n'accorde rien :
- Désactivée tant qu'elle n'est pas activée. Un administrateur de l'organisation active chaque
action déclarée, et l'activation porte sur cette définition exacte (
declaredActionDigest). Une version, une mise à niveau ou une migration qui modifie la définition laisse la nouvelle désactivée jusqu'à ce qu'elle soit activée à nouveau. - Demandée uniquement par la passerelle. Une demande est l'opération de plateforme
action.tasking.dispatch. La passerelle refuse une action que la source installée ne déclare pas, et le noyau refuse une action qui n'est pas activée, avant toute préparation. - Approbation par demande lorsqu'elle est déclarée. Avec
requiresApproval: true, chaque demande est mise en attente jusqu'à ce qu'une personne approuve cette demande précise. L'approbateur doit être administrateur de l'organisation et ne peut pas être le demandeur. Pendant l'attente, la passerelle répondapproval_awaiting, avec l'identifiant de l'approbation et son échéance. Cette réponse est un refus, pas une panne : ne la relancez pas. Une demande refusée ou expirée répondapproval_deniedouapproval_expired.
En déclarer une
import { MAVLINK_SET_MESSAGE_INTERVAL_OPERATION } from "@scrydon/sdk-authoring/data-sources";
import type { DataSourceAction } from "@scrydon/sdk-authoring/data-sources/manifest";
const setMessageInterval = {
id: "set-message-interval",
displayName: "Set GLOBAL_POSITION_INT report interval",
capability: "invoke",
operation: { name: MAVLINK_SET_MESSAGE_INTERVAL_OPERATION, version: 1 },
target: { param: "vehicle" },
params: {
vehicle: { type: "string", required: true, maxLength: 64 },
// … chaque entrée de l'action, typée et bornée
},
preconditions: [],
requiresControlAuthority: false,
classification: "internal",
expirySeconds: 30,
retry: "once-within-grant",
correlation: "acknowledgement",
verification: { kind: "none" },
cancellable: false,
requiresApproval: true,
} satisfies DataSourceAction;Chaque choix qui touche à la sécurité est explicite ; aucun n'a de valeur par défaut.
expirySeconds vaut au plus 300. Il borne à la fois le temps qu'une demande admise peut attendre
sa répartition et la durée de vie de son autorisation. Une source déclare au plus 32 actions, et defineDataSource()
refuse des actions sur une source de type code. L'exemple complet du drone se trouve dans
apps/docs/examples/mavlink-drone/manifest.ts.
En demander une
Une demande à action.tasking.dispatch nomme la source installée, la version de celle-ci que
l'appelant vise, l'action et ses entrées :
| Champ | Ce que c'est |
|---|---|
sourceId | La clé de la source installée : <definitionId>, ou <definitionId>--<slug> pour une instance supplémentaire. |
sourceVersion | La version de descripteur de la source installée, sha256: suivi de 64 chiffres hexadécimaux. |
actionId, operationVersion | L'id de l'action déclarée et son operation.version. |
parameters | Les entrées, vérifiées par rapport aux params déclarés. Toute autre entrée est refusée. |
idempotencyKey | Obligatoire. Une nouvelle tentative avec la même clé obtient la même réponse. |
L'appelant fournit sourceVersion ; la passerelle ne la complète pas. Il s'agit de
dataSourceDescriptorVersion(manifest) de @scrydon/sdk-authoring/data-sources, calculée sur le
manifeste avec lequel la source a été installée. Elle lie la demande à la définition que l'appelant
vise : dès que la source est mise à niveau ou redéployée avec un autre manifeste, l'ancienne version
ne correspond plus, et la passerelle refuse la demande comme source_not_installed au lieu
d'exécuter une définition que l'appelant n'a jamais examinée. Calculez-la à nouveau à partir du
nouveau manifeste.
Aucune lecture ne renvoie encore cette version : un appelant la calcule à partir du manifeste qu'il a installé.
Où une action est envoyée
Toute action part vers la destination simulée de la plateforme, à une exception près. Une action n'est envoyée sur une vraie liaison MAVLink que si toutes les conditions suivantes sont réunies :
- Son
operation.nameestMAVLINK_SET_MESSAGE_INTERVAL_OPERATION. SET_MESSAGE_INTERVAL ne change que la télémétrie qu'un véhicule diffuse, et c'est la seule commande qui puisse jamais être envoyée sur une liaison. - La source installée est une liaison MAVLink épinglée à
MAVLINK_EXTENDED_DIALECT_DIGEST, le dialecte qui porte COMMAND_LONG et COMMAND_ACK. Sur une liaison épinglée à un autre dialecte, la demande est refusée (DECLARED_ACTION_LINK_DIALECT_LACKS_COMMANDS) ; elle n'est jamais simulée en silence. - Le déploiement a activé l'émission sur liaison (
ACTION_LINK_EGRESS_ENABLED, désactivée par défaut). Jusque-là, la demande reste en file d'attente, et expire sans envoiexpirySecondsaprès son admission.
La commande est signée avec la clé propre à la liaison, cloisonnée au réplica qui détient la liaison au moment de l'envoi, et corrélée au COMMAND_ACK du véhicule.
Ce qu'une action rapporte
| État | Signification |
|---|---|
| Queued | Admise et en attente du répartiteur. Si elle n'est pas répartie dans les expirySeconds qui suivent son admission, elle se termine Expired et n'est jamais envoyée. |
| Dispatching | Confiée au répartiteur sous une autorisation de courte durée. |
| Expired | Refusée avant l'envoi, par exemple parce que l'autorisation était périmée ou que la liaison avait changé de réplica. Rien n'a été envoyé. |
| Sent | Confiée au canal ; pas encore de réponse. Pour une action déclarée correlation: "none", rien ne répond jamais : Sent est son état final. |
| Accepted / In progress | La destination en a accusé réception. Elle n'est jamais renvoyée après un accusé de réception. Si aucune réponse finale ne suit dans les cinq minutes qui suivent son dernier signalement, elle se termine en Outcome unknown. |
| Completed / Rejected | La réponse finale de la destination. |
| Outcome unknown | Elle a peut-être été envoyée, mais aucune réponse n'est arrivée après une nouvelle tentative, aucune réponse finale n'a suivi un accusé de réception dans les cinq minutes, ou le répartiteur s'est arrêté avant de le signaler. |
Un résultat inconnu bloque la cible. Tant qu'une action sur une cible est Outcome unknown,
aucune action ultérieure sur cette cible à la même destination n'est répartie. Le même nom de cible
sur une autre liaison désigne un autre véhicule et n'est pas bloqué. Un administrateur de l'organisation lève
ce blocage avec action.outbound.reconcile, en consignant ce qui a été observé (réussite ou échec).
Consigner « toujours inconnu » laisse l'action, et le blocage, en l'état.