Skip to Content

Chapitre 4.3 — Le modèle de données CMI

⏱️ TL;DR — Entre l’ouverture et la fermeture de session, ton SCO lit et écrit un ensemble de champs standardisés : le modèle de données CMI. Chaque champ a un nom en notation pointée (cmi.core.lesson_status, cmi.completion_status…), un type attendu, et un droit d’accès : certains sont en lecture seule (l’identité de l’apprenant, fournie par le LMS), d’autres en écriture (le statut, le score), quelques-uns en écriture seule (la durée de session). On accède à tout par deux méthodes seulement : GetValue(elt) pour lire, SetValue(elt, val) pour écrire. Le vocabulaire change entre 1.2 et 2004 — c’est la source d’erreur n°1 quand on porte un contenu d’une version à l’autre. Ce chapitre te donne les éléments clés des deux versions et leurs droits d’accès.

🎯 Objectifs

  • Comprendre la structure cmi.* en notation pointée et la notion de collection (cmi.objectives.n.*).
  • Lire et écrire avec GetValue / SetValue (et leurs préfixes LMS en 1.2).
  • Connaître les éléments clés de SCORM 1.2 et de SCORM 2004, avec leurs droits d’accès.
  • Ne plus confondre cmi.core.lesson_status (1.2) et le couple cmi.completion_status + cmi.success_status (2004).

Un dictionnaire à notation pointée

Le modèle CMI est un dictionnaire de champs nommés hiérarchiquement. Le préfixe est toujours cmi ; le reste décrit la donnée : cmi.core.score.raw = « le score brut, dans le sous-ensemble core ». Tout se lit et s’écrit avec deux verbes :

// SCORM 1.2 : méthodes préfixées LMS const nom = api.LMSGetValue("cmi.core.student_name"); // lecture api.LMSSetValue("cmi.core.score.raw", "85"); // écriture // SCORM 2004 : mêmes verbes sans le préfixe LMS const nom2 = api.GetValue("cmi.learner_name"); api.SetValue("cmi.score.raw", "85");

Trois principes valent pour tout le modèle :

  • Les valeurs sont des chaînes. SetValue attend une string. "85", pas 85 ; "completed", pas un booléen. Le LMS validera le type logique (nombre, vocabulaire fermé…) mais l’échange se fait en texte.
  • Certains champs sont des collections indexées. cmi.objectives.n.id, cmi.interactions.n.result : le n est un indice (0, 1, 2…). On lit le nombre d’éléments via un champ _count et on écrit en incrémentant l’indice.
  • Chaque champ a un droit d’accès. Lecture seule (RO), lecture-écriture (RW), ou écriture seule (WO). Écrire un RO ou lire un WO échoue avec une erreur dédiée (chapitre 4.5).

⚠️ Piège — Écrire dans un champ en lecture seule, typiquement cmi.core.student_name. C’est le LMS qui te donne l’identité de l’apprenant ; tu la lis, tu ne la poses pas. Un SetValue dessus renvoie false et pose l’erreur « element is read only ». Même logique inverse pour cmi.core.session_time (écriture seule) : tu l’écris, tu ne le relis pas.

Les éléments clés de SCORM 1.2

Sous-ensemble cmi.core pour l’essentiel de l’exécution, plus quelques champs hors core.

Élément (SCORM 1.2)AccèsRôle
cmi.core.student_idROIdentifiant de l’apprenant (fourni par le LMS).
cmi.core.student_nameRONom de l’apprenant.
cmi.core.lesson_statusRWLe statut : passed, completed, failed, incomplete, browsed, not attempted.
cmi.core.score.rawRWScore brut (souvent 0–100).
cmi.core.score.minRWBorne basse du score.
cmi.core.score.maxRWBorne haute du score.
cmi.core.lesson_locationRWSignet : où reprendre (page, écran…).
cmi.core.entryROContexte d’entrée : première fois vs reprise.
cmi.core.exitWOComment on quitte : suspend, logout, time-out, "".
cmi.core.session_timeWODurée de cette session (format HHHH:MM:SS.SS).
cmi.core.total_timeROTemps cumulé sur toutes les sessions.
cmi.suspend_dataRWMémoire libre du SCO (max 4096 caractères).
cmi.launch_dataRODonnées de lancement définies dans le manifeste.
cmi.objectives.n.*RWSous-objectifs (id, statut, score).

Le champ pivot, c’est cmi.core.lesson_status : en SCORM 1.2, un seul champ porte à la fois la complétion et la réussite. C’est simple, mais ambigu — on ne peut pas dire « terminé mais échoué » proprement. SCORM 2004 corrige exactement ce point.

Les éléments clés de SCORM 2004

Le modèle 2004 sépare la complétion (a-t-on parcouru ?) de la réussite (a-t-on réussi ?), abandonne le sous-ensemble core, et enrichit le score et les interactions.

Élément (SCORM 2004)AccèsRôle
cmi.learner_idROIdentifiant de l’apprenant (équivaut à student_id).
cmi.learner_nameRONom de l’apprenant.
cmi.completion_statusRWComplétion : completed, incomplete, not attempted, unknown.
cmi.success_statusRWRéussite : passed, failed, unknown.
cmi.score.scaledRWScore normalisé de -1 à 1 (le plus important en 2004).
cmi.score.rawRWScore brut.
cmi.score.min / cmi.score.maxRWBornes du score brut.
cmi.progress_measureRWAvancement de 0 à 1 (barre de progression).
cmi.locationRWSignet de reprise (équivaut à lesson_location).
cmi.entryROContexte d’entrée (première fois vs reprise).
cmi.exitWOSortie : suspend, normal, time-out, logout, "".
cmi.session_timeWODurée de session au format ISO 8601 (ex. PT30M).
cmi.suspend_dataRWMémoire libre du SCO (max 64000 caractères).
cmi.interactions.n.*RWDétail des interactions (questions/réponses).
cmi.objectives.n.*RWObjectifs (id, statut, score, mesure).
adl.nav.requestWODemande de navigation (continue, previous… — Partie 5).

Deux différences à graver :

  1. Un seul statut (1.2) vs deux (2004). cmi.core.lesson_status porte tout en 1.2 ; en 2004 tu poses cmi.completion_status ET cmi.success_status séparément. C’est le sujet du chapitre 4.4.
  2. Le score de référence change. En 1.2, on raisonne cmi.core.score.raw (0–100). En 2004, le champ canonique est cmi.score.scaled, un ratio de -1 à 1 (0,85 pour 85 %). On peut poser les deux, mais c’est le scaled qui pilote souvent les règles.

💡 Réflexe — Ne jamais porter un SCO 1.2 vers 2004 par un simple copier-coller. Les noms changent (cmi.core.lesson_statuscmi.completion_status/cmi.success_status ; cmi.core.score.rawcmi.score.raw + cmi.score.scaled ; cmi.core.lesson_locationcmi.location). Passe par une couche d’abstraction (comme les adaptateurs setValue() du chapitre 4.2) qui traduit selon la version détectée.

🔌 Côté intégration — Le format de la durée de session piège souvent : HHHH:MM:SS.SS en 1.2, ISO 8601 en 2004 (PT1H30M). Un SCO qui envoie une durée au mauvais format se voit rejeter la valeur par un LMS strict — la session passe, mais le temps affiché est faux ou nul. Vérifie toujours le format attendu par la version que tu cibles.

Lire l’identité, écrire le résultat

Le schéma mental le plus utile : le LMS te prête l’identité et le contexte (champs RO), tu lui rends le résultat (champs RW/WO).

// SCORM 1.2 — ce que je LIS (le LMS me le donne) const id = api.LMSGetValue("cmi.core.student_id"); const nom = api.LMSGetValue("cmi.core.student_name"); const repr = api.LMSGetValue("cmi.core.entry"); // "ab-initio" = 1re fois, "resume" = reprise // ... ce que j'ÉCRIS (je rends le résultat) api.LMSSetValue("cmi.core.lesson_status", "completed"); api.LMSSetValue("cmi.core.score.raw", "85"); api.LMSSetValue("cmi.core.score.min", "0"); api.LMSSetValue("cmi.core.score.max", "100"); api.LMSCommit("");

Tenter l’inverse — écrire student_name, ou lire session_time — n’a pas de sens et déclenche une erreur. Respecter les droits d’accès, c’est déjà éliminer une famille entière de bugs.

🧭 Sur FormaCampus — En inspectant le module fautif, on confirme que l’API répond bien à LMSGetValue("cmi.core.student_name") (l’apprenant est identifié) et que l’écriture du score fonctionne. Le modèle de données est donc accessible. Le problème n’est pas « le SCO ne sait pas parler CMI » : c’est quelle valeur de cmi.core.lesson_status il pose, et quand il clôt. On resserre le diagnostic sur le statut — chapitre 4.4.

📚 La spec — Le modèle CMI complet (noms d’éléments, types, vocabulaires fermés, droits d’accès) est le cœur du livre RTE de chaque version SCORM, publié par ADL (adlnet.gov). Les tableaux ci-dessus en donnent les éléments les plus utilisés au quotidien ; pour la liste exhaustive (dont cmi.comments, cmi.student_preference, le détail des interactions…), se reporter à la spec de la version ciblée.

✏️ Exercices

Exercice 1 — Traduire un SCO 1.2 en 2004. Voici trois lignes d’un SCO 1.2 :

api.LMSSetValue("cmi.core.lesson_status", "passed"); api.LMSSetValue("cmi.core.score.raw", "82"); api.LMSSetValue("cmi.core.lesson_location", "ecran-7");

Écris l’équivalent SCORM 2004 correct.

✅ Solution

// "passed" en 1.2 sous-entend à la fois terminé ET réussi : // en 2004 on sépare les deux. api.SetValue("cmi.completion_status", "completed"); api.SetValue("cmi.success_status", "passed"); // Score : on pose le brut ET le scaled (canonique en 2004). api.SetValue("cmi.score.raw", "82"); api.SetValue("cmi.score.scaled", "0.82"); // ratio -1..1 // Le signet change de nom. api.SetValue("cmi.location", "ecran-7");

Le piège classique : garder cmi.core.lesson_status (inexistant en 2004) ou oublier le scaled. La séparation complétion/réussite est le point de bascule 1.2 → 2004.

Exercice 2 — Droit d’accès. Un dev veut « personnaliser l’accueil » avec le prénom, alors il écrit :

api.LMSSetValue("cmi.core.student_name", "Bonjour Léa");

Pourquoi est-ce faux, et que faire à la place ?

✅ Solution

cmi.core.student_name est en lecture seule (RO) : c’est le LMS qui fournit le nom. Un SetValue dessus renvoie false et pose l’erreur « element is read only » (code 403 en 1.2). Pour afficher un accueil personnalisé, il faut lire la valeur, pas l’écrire :

const nom = api.LMSGetValue("cmi.core.student_name"); // ex. "Martin, Léa" document.querySelector("#accueil").textContent = `Bonjour ${nom}`;

🧠 Quiz de révision

1. Avec quelles méthodes lit-on et écrit-on le modèle CMI ?

GetValue(elt) pour lire, SetValue(elt, val) pour écrire — préfixées LMS en SCORM 1.2 (LMSGetValue, LMSSetValue). Deux verbes couvrent tout le modèle. Les valeurs échangées sont des chaînes.

2. Quelle est la grande différence de statut entre 1.2 et 2004 ?

SCORM 1.2 a un seul champ, cmi.core.lesson_status, qui mélange complétion et réussite. SCORM 2004 sépare en deux : cmi.completion_status (parcouru ?) et cmi.success_status (réussi ?).

3. Quel est le score « canonique » en SCORM 2004 et quelle est sa plage ?

cmi.score.scaled, un ratio de -1 à 1 (0,85 = 85 %). On peut aussi poser cmi.score.raw/min/max, mais le scaled est souvent celui qui pilote les règles.

4. Que se passe-t-il si on écrit dans cmi.core.student_name ?

Échec : ce champ est en lecture seule. SetValue renvoie false et pose une erreur « read only » (code 403 en 1.2). L’identité est fournie par le LMS ; on la lit.

5. Comment porter proprement un contenu de 1.2 vers 2004 ?

Via une couche d’abstraction qui traduit les noms selon la version détectée : cmi.core.lesson_statuscmi.completion_status/cmi.success_status, cmi.core.score.rawcmi.score.raw + cmi.score.scaled, cmi.core.lesson_locationcmi.location, formats de durée différents… Jamais un simple copier-coller.


Chapitre suivant : 4.4 — Statut, score & suspend_data — le trio qui décide si ta complétion remonte, si ton score compte, et si la reprise fonctionne.

Last updated on