Русский
Русский
English
Статистика
Реклама

Xapi

XAPI и IMS Caliper. Или ADL против IMS?

02.07.2020 10:04:35 | Автор: admin
image

Появление xAPI (ADL) не было неожиданным событием. Очень продолжительное время велись обсуждения TinCan'а, огромное количество открытых форумов кипели при обсуждении новой спецификации. И только после достаточного обсуждения, ADL выпустила релиз спецификации. Затем, уже после практической работы многих компаний с xApi, появилась CMI5.

И тут появилась аналогичная спецификация IMS Global Learning Consortium под названием Caliper.
Заметное сходство между xAPI и Caliper побудило разработчиков и поставщиков контента прояснить различия в реализации одной или обеих спецификаций (обе из которых в настоящее время нацелены на стандартизацию).

Оба сообщества, поддерживающие xAPI и Caliper, выразили обеспокоенность по поводу возможности экономически эффективной поддержки обеих спецификаций, что привело к запросам как к ADL, так и к IMS о том, возможно ли их согласование.



Вот краткий ответ IMS (http://personeltest.ru/aways/www.imsglobal.org/initial-xapicaliper-comparison)

a) Caliper and xAPI have very different origins. The core xAPI is to enable any type of experience and evidence tracking, both electronic and physical performance and not limited to just web-based courses (as is the case for SCORM). Caliper is the manifestation of the IMS Learning Analytics Framework and the Sensor API and Metric Profile(s) are the first two components of that framework. xAPI and Caliper are NOT equivalent. Adoption should not be one-or-the-other, instead it is a horses-for-courses decision;

b) While both xAPI (Actor/Verb/Object) and Caliper (Actor/Action/Activity) use a data model based upon a triple statement structure there are considerable differences in the detailed structure and usage of the Object and Activity definitions. However, it should be possible for each specification to make use of the others Verb/Action;


Вот краткий ответ ADL (http://personeltest.ru/aways/adlnet.gov/news/2016/07/25/adl-experience-api-and-ims-caliper-discovery-review/)

As xAPI has matured, so too has a similar specification from the IMS Global Learning Consortium called Caliper. There are notable similarities between xAPI and Caliper, which has caused adopters and vendors to clarify implementation differences of one or both specifications (both of which are now targeting standardization). Both communities supporting xAPI and Caliper have expressed concerns about being able to cost-effectively support both specs, which led to inquiries to both ADL Initiative and IMS about whether alignment of the two would be possible.


xAPI (Actor / Verb / Object) и Caliper (Actor / Action / Activity) используют модель данных, основанную на структуре тройного оператора, существуют значительные различия в подробной структуре и использовании определений Object и Activity. Видимо Actor и Verb/Action совпадают, отличаются только Object/Activity?

Я достаточно давно работаю с xAPI, но Caliper мне не был знаком. Пришлось немного изучить документацию (http://personeltest.ru/aways/www.imsglobal.org/sites/default/files/caliper/v1p1/caliper-spec-v1p1/caliper-spec-v1p1.html и www.imsglobal.org/caliper/caliperv1p0/ims-caliper-analytics-implementation-guide)

Скажу сразу, я не нашел значительных лично для меня отличий. То что называется в xAPI statement (Activites) в Caliper называется Event.



image

Я обратил внимание на наличие так называемой метрики в Caliper, но описание достаточно абстрактное, примеров практического использования мне найти не удалось.

The Caliper information model defines a number of metric profiles, each of which models a learning activity or a supporting activity that helps facilitate learning. A metric profiles raison detre is to encourage vocabulary standardization and re-use among application providers delivering complementary, albeit competing capabilities that collect learning activity data. Each profile provides a domain-specific set of terms and concepts that application designers and developers can draw upon to describe common user interactions in a consistent manner using a shared vocabulary. Annotating a reading, playing a video, taking a test, or grading an assignment submission represent a few examples of the many activities or events that Calipers metric profiles attempt to describe.

Think of each metric profile as a stand-alone, logical container, or collection of one or more Caliper events that together help describe a set of inter-related activities. Each Event type included in a metric profile place constraints on the various entities and actions that can be utilized to describe a learning activity. Vocabulary restrictions are outlined in each profile description under the following headings


На сайте IMS есть очень много красивых картинок, но они еще более усиливают ощущение того, что разница минимальна.

С точки зрения механизма авторизации и хранения (LRS), разницы практически нет, отличие JSON в xApi и JSON-LD в Caliper для меня не существенно. т.е. и в этих вопросах разницы нет.

Давайте посмотрим примеры JSON xApi и Caliper
xApi
{
actor: {
name: Sally Glider,
mbox: mailto:sally@example.com
},
verb: {
id: adlnet.gov/expapi/verbs/completed,
display: { en-US: completed }
},
object: {
id: example.com/activities/hang-gliding-test,
definition: {
type: adlnet.gov/expapi/activities/assessment,
name: { en-US: Hang Gliding Test },
description: {
en-US: The Solo Hang Gliding test, consisting of a timed flight from the peak of Mount Magazine
},
extensions: {
example.com/gliderClubId: test-435
}
}
},
result: {
completion: true,
success: true,
score: {
scaled: 0.95
},
extensions: {
example.com/flight/averagePitch: 0.05
}
},
context: {
instructor: {
name: Irene Instructor,
mbox: mailto:irene@example.com
},
contextActivities:{
parent: { id: example.com/activities/hang-gliding-class-a }
grouping: { id: example.com/activities/hang-gliding-school }
},
extensions: {
example.com/weatherConditions: rainy
}
},
timestamp: 2012-07-05T18:30:32.360Z,
stored: 2012-07-05T18:30:33.540Z,
authority: {
name: Irene Instructor,
mbox: mailto:irene@example.com
}
}


Caliper
{
sensor: example.edu/sensors/1,
sendTime: 2018-11-15T11:05:01.000Z,
dataVersion: purl.imsglobal.org/ctx/caliper/v1p1,
data: [
{
"@context": purl.imsglobal.org/ctx/caliper/v1p1,
id: example.edu/users/554433,
type: Person,
dateCreated: 2018-08-01T06:00:00.000Z,
dateModified: 2018-09-02T11:30:00.000Z
},
{
"@context": purl.imsglobal.org/ctx/caliper/v1p1,
id: example.edu/terms/201801/courses/7/sections/1/assess/1?ver=v1p0,
type: Assessment,
name: Quiz One,
items: [
{
id: example.edu/terms/201801/courses/7/sections/1/assess/1/items/1,
type: AssessmentItem
},
{
id: example.edu/terms/201801/courses/7/sections/1/assess/1/items/2,
type: AssessmentItem
},
{
id: example.edu/terms/201801/courses/7/sections/1/assess/1/items/3,
type: AssessmentItem
}
],
dateCreated: 2018-08-01T06:00:00.000Z,
dateModified: 2018-09-02T11:30:00.000Z,
datePublished: 2018-08-15T09:30:00.000Z,
dateToActivate: 2018-08-16T05:00:00.000Z,
dateToShow: 2018-08-16T05:00:00.000Z,
dateToStartOn: 2018-08-16T05:00:00.000Z,
dateToSubmit: 2018-09-28T11:59:59.000Z,
maxAttempts: 2,
maxScore: 15.0,
maxSubmits: 2,
version: 1.0
},
{
"@context": purl.imsglobal.org/ctx/caliper/v1p1,
id: example.edu,
type: SoftwareApplication,
version: v2
},
{
"@context": purl.imsglobal.org/ctx/caliper/v1p1,
id: example.edu/terms/201801/courses/7/sections/1,
type: CourseSection,
academicSession: Fall 2018,
courseNumber: CPS 435-01,
name: CPS 435 Learning Analytics, Section 01,
category: seminar,
subOrganizationOf: {
id: example.edu/terms/201801/courses/7,
type: CourseOffering,
courseNumber: CPS 435
},
dateCreated: 2018-08-01T06:00:00.000Z
},
{
"@context": purl.imsglobal.org/ctx/caliper/v1p1,
id: urn:uuid:c51570e4-f8ed-4c18-bb3a-dfe51b2cc594,
type: AssessmentEvent,
actor: example.edu/users/554433,
action: Started,
object: example.edu/terms/201801/courses/7/sections/1/assess/1?ver=v1p0,
generated: {
id: example.edu/terms/201801/courses/7/sections/1/assess/1/users/554433/attempts/1,
type: Attempt,
assignee: example.edu/users/554433,
assignable: example.edu/terms/201801/courses/7/sections/1/assess/1?ver=v1p0,
count: 1,
dateCreated: 2018-11-15T10:15:00.000Z,
startedAtTime: 2018-11-15T10:15:00.000Z
},
eventTime: 2018-11-15T10:15:00.000Z,
edApp: example.edu,
group: example.edu/terms/201801/courses/7/sections/1,
membership: {
id: example.edu/terms/201801/courses/7/sections/1/rosters/1,
type: Membership,
member: example.edu/users/554433,
organization: example.edu/terms/201801/courses/7/sections/1,
roles: [ Learner ],
status: Active,
dateCreated: 2018-08-01T06:00:00.000Z
},
session: {
id: example.edu/sessions/1f6442a482de72ea6ad134943812bff564a76259,
type: Session,
startedAtTime: 2018-11-15T10:00:00.000Z
}
},
{
"@context": purl.imsglobal.org/ctx/caliper/v1p1,
id: urn:uuid:dad88464-0c20-4a19-a1ba-ddf2f9c3ff33,
type: AssessmentEvent,
actor: example.edu/users/554433,
action: Submitted,
object: example.edu/terms/201801/courses/7/sections/1/assess/1?ver=v1p0,
generated: {
id: example.edu/terms/201801/courses/7/sections/1/assess/1/users/554433/attempts/1,
type: Attempt,
assignee: example.edu/users/554433,
assignable: example.edu/terms/201801/courses/7/sections/1/assess/1?ver=v1p0,
count: 1,
dateCreated: 2018-11-15T10:15:00.000Z,
startedAtTime: 2018-11-15T10:15:00.000Z,
endedAtTime: 2018-11-15T10:55:12.000Z,
duration: PT40M12S
},
eventTime: 2018-11-15T10:25:30.000Z,
edApp: example.edu,
group: example.edu/terms/201801/courses/7/sections/1,
membership: {
id: example.edu/terms/201801/courses/7/sections/1/rosters/1,
type: Membership,
member: example.edu/users/554433,
organization: example.edu/terms/201801/courses/7/sections/1,
roles: [Learner],
status: Active,
dateCreated: 2018-08-01T06:00:00.000Z
},
session: {
id: example.edu/sessions/1f6442a482de72ea6ad134943812bff564a76259,
type: Session,
startedAtTime: 2018-11-15T10:00:00.000Z
}
},
{
"@context": purl.imsglobal.org/ctx/caliper/v1p1,
id: urn:uuid:a50ca17f-5971-47bb-8fca-4e6e6879001d,
type: GradeEvent,
actor: {
id: example.edu/autograder,
type: SoftwareApplication,
version: v2
},
action: Graded,
object: {
id: example.edu/terms/201801/courses/7/sections/1/assess/1/users/554433/attempts/1,
type: Attempt,
assignee: example.edu/users/554433,
assignable: example.edu/terms/201801/courses/7/sections/1/assess/1?ver=v1p0,
count: 1,
dateCreated: 2018-11-15T10:15:00.000Z,
startedAtTime: 2018-11-15T10:15:00.000Z,
endedAtTime: 2018-11-15T10:55:12.000Z,
duration: PT40M12S
},
eventTime: 2018-11-15T10:57:06.000Z,
edApp: example.edu,
generated: {
id: example.edu/terms/201801/courses/7/sections/1/assess/1/users/554433/attempts/1/scores/1,
type: Score,
attempt: example.edu/terms/201801/courses/7/sections/1/assess/1/users/554433/attempts/1,
maxScore: 15.0,
scoreGiven: 10.0,
scoredBy: example.edu/autograder,
comment: auto-graded exam,
dateCreated: 2018-11-15T10:56:00.000Z
},
group: example.edu/terms/201801/courses/7/sections/1
}
]
}


Должен признать, что я не смог выявить для себя существенную разницу между этими спецификациями.

Фраза
IMS Learning Analytics Framework and the Sensor API and Metric Profile(s) are the first two components of that framework
говорит о том, что видимо стоит ожидать появление Framework. Но информации по нему я не смог найти.

Я не знаю причин по которым две уважаемые организации представили, по моему личному мнению, сходные спецификации. Предыдущая история сосуществования SCORM (ADL) и IMS CP например показывала, что стандарты могут дополнять друг друга. В этот раз я не вижу такого дополнения.

Подробнее..

XAPICMI5. Полная мощность

08.04.2021 12:19:54 | Автор: admin

Продолжим разбор спецификаций xAPI/CMI5 для хранения и анализа данных обучения персонала. В последние годы появилось достаточно большое количество статей на тему использования рассматриваемых спецификаций (например - https://levellab.ru/blog/xapi-1). Вместе с тем, существующие публикации описывают использования спецификаций, на мой взгляд, очень поверхностно. Да, я согласен с тем, что использования xAPI для отчета о просмотре курса презентации или теста является достаточно тривиальной задачей. Особенно когда нужно просто получить информацию в виде затраченного времени и оценки. В предыдущей статье http://personeltest.ru/aways/habr.com/ru/post/508882/ я уже писал, что при таком подходе, как мне кажется, использование xAPI может не дать никакого значительного преимущества.

Именно поэтому я и решил "копнуть поглубже" и показать как можно использовать спецификацию xAPI на 100% мощности, в т.ч. не только в хранении, но и в анализе данных. Кроме того, постараюсь практически объяснить разницу между xAPI и CMI5 в контексте того, как CMI5 формализует использование xAPI.

В качестве примера будем использовать имитационный тренажер для обучения персонала, например https://youtu.be/zewU3JHZCfg

Теперь давайте посмотрим отчет по форме CMI5 / xAPI. При запуске нашего ресурса (через плагин для Moodle https://moodle.org/plugins/mod_tincanlaunch или через очень удобный для проверки сервис https://cloud.scorm.com/), мы автоматически получаем запись в LRS с глаголом "http://adlnet.gov/expapi/verbs/launched". Обратите внимание, что запись выполняется не нашей с Вами программой, а сервисом, который производит запуск (например -moodle). Последние 4 записи (id, authority , stored, timestamp) формируются уже самой LRS. Также информация о регистрации (registration: "fb13ae65-d9cf-469d-8d89-e41fd61c842d"), LRS endpoint и авторизации передается непосредственно в наш ресурс, что дает возможность сделать запрос в LRS и найти запись "launched" даже, к примеру, из exe-файла. Таким образом мы можем получить информацию относительно обучаемого, команде и т.д. В принципе, мы можем и сами выполнить данную запись, если например, запускаем exe-файл без LMS системы.

Statement "launched"

{

  • actor: {

    • mbox: "mailto:scorm@lcontent.ru",

    • name: "Петров Сергей Александрович",

    • objectType: "Agent"

    },

  • verb: {

    • id: "http://adlnet.gov/expapi/verbs/launched",

    • display: {

      • en-US: "launched"

      }

    },

  • context: {

    • registration: "fb13ae65-d9cf-469d-8d89-e41fd61c842d",

    • contextActivities: {

      • parent: [

        • {

          • objectType: "Activity",

          • id: "https://lms.lcontent.ru/pluginfile.php/3678/mod_resource/content/76/T.html"

          }

        ]

      }

    },

  • object: {

    • id: "simulation://xapitest",

    • definition: {

      • name: {

        • en-US: "Пример тренажера"

        },

      • description: {

        • en-US: "Пример тренажера полное описание"

        }

      },

    • objectType: "Activity"

    },

  • id: "d7a3b941-10a8-412b-912c-50cc89017f1c",

  • authority: {

    • objectType: "Agent",

    • account: {

      • homePage: "https://lrs.lcontent.ru:443",

      • name: "maxxxxr@gmail.com"

      }

    },

  • stored: "2021-04-07T14:40:58+00:00",

  • timestamp: "2021-04-07T14:40:58+00:00"

}

Первой записью после запуска тренажера, мы обязаны (cmi5) прописать утверждение "initialized", которое указывает, что действие было начато. Обратите внимание на registration, которое совпадает с ранее приведенным launched, что позволяет связывать эти записи в единую последовательность. В данном утверждении целесообразно уже использовать расширения, например http://lcontent.ru/xapi/weatherConditions: "rainy", чтобы сообщить о погодных условиях в симуляторе или http://lcontent.ru/xapi/Device: "HTC VIVE" - для уточнения, что используется VR-шлем. Также мы используем уточнения про инструктора и про групповой режим обучения. Для использования CMI5 на данном шаге мы должны получить шаблон утверждения и в дальнейшем добавлять нужные поля уже на его основе.

Statement "initialized"

{

  • actor: {

    • mbox: "mailto:user@lcontent.ru",

    • name: "Петров Сергей Александрович",

    • objectType: "Agent"

    },

  • verb: {

    • id: "http://adlnet.gov/expapi/verbs/initialized",

    • display: {

      • en-US: "Indicates that the activity was started.",

      • ru-RU: "Указывает, что действие было начато."

      }

    },

  • object: {

    },

  • context: {

    • registration: "fb13ae65-d9cf-469d-8d89-e41fd61c842d",

    • extensions: {

      • https://w3id.org/xapi/cmi5/context/extensions/sessionid: "fb13ae65-d9cf-469d-8d89-e41fd61c842d",

      • https://w3id.org/xapi/cmi5/context/extensions/masteryscore: 0.860000014305115,

      • https://w3id.org/xapi/cmi5/context/extensions/launchurl: "https://lcontent.ru",

      • https://w3id.org/xapi/cmi5/context/extensions/launchmode: "Normal",

      • http://lcontent.ru/xapi/weatherConditions: "rainy",

      • https://w3id.org/xapi/acme/extensions/training-location: "tyumen",

      • http://lcontent.ru/xapi/Device: "HTC VIVE"

      },

    • contextActivities: {

      • category: [

        • {

          • objectType: "Activity",

          • id: "https://w3id.org/xapi/cmi5/context/categories/cmi5"

          }

        ]

      },

    • platform: "lms.lcontent.ru",

    • instructor: {

      • objectType: "Agent",

      • mbox: "mailto:MaxGammer@gmail.com",

      • name: "Anna Gammer"

      },

    • team: {

      • objectType: "Group",

      • mbox: "mailto:group@gmail.com",

      • name: "Commander ken"

      }

    },

  • authority: {

    • objectType: "Agent",

    • account: {

      • homePage: "https://lrs.lcontent.ru:443",

      • name: "maxgammer@gmail.com"

      }

    },

  • stored: "2021-04-07T09:35:50+00:00",

  • timestamp: "2021-04-07T09:35:50+00:00",

  • id: "263d5e25-c26f-46e0-8199-b59db7d11aaf"

}

completed - указывает, что субъект закончил или завершил действие в обычном режиме. Обратите внимание на записи "https://w3id.org/xapi/cmi5", они обязаны быть, если Вы хотите, чтобы данные были записаны как CMI5. Без этих записей это не будет успешно. Формат xAPI не накладывает таких ограничений.

Statement "completed"

{

  • actor: {

    • mbox: "mailto:user@lcontent.ru",

    • name: "Петров Сергей Александрович",

    • objectType: "Agent"

    },

  • verb: {

    • id: "http://adlnet.gov/expapi/verbs/completed",

    • display: {

      • en-US: "Indicates the actor finished or concluded the activity normally.",

      • ru-RU: "Указывает, что субъект закончил или завершил действие в обычном режиме."

      }

    },

  • object: {

    },

  • result: {

    • completion: true,

    • duration: "PT41S",

    • response: "Сценарий выполнен",

    • extensions: {

      • http://lcontent.ru/xapi/Total_Losses_money: 600000,

      • http://lcontent.ru/xapi/Total_Deads: 0,

      • https://w3id.org/xapi/cmi5/result/extensions/progress: 100

      }

    },

  • context: {

    • registration: "fb13ae65-d9cf-469d-8d89-e41fd61c842d",

    • extensions: {

      • https://w3id.org/xapi/cmi5/context/extensions/sessionid: "fb13ae65-d9cf-469d-8d89-e41fd61c842d",

      • https://w3id.org/xapi/cmi5/context/extensions/masteryscore: 0.860000014305115,

      • https://w3id.org/xapi/cmi5/context/extensions/launchurl: "https://lcontent.ru",

      • https://w3id.org/xapi/cmi5/context/extensions/launchmode: "Normal",

      • https://w3id.org/xapi/cmi5/context/extensions/moveon: "CompletedOrPassed",

      • http://lcontent.ru/xapi/weatherConditions: "rainy",

      • https://w3id.org/xapi/acme/extensions/training-location: "tyumen",

      • http://lcontent.ru/xapi/Device: "HTC VIVE"

      },

    • contextActivities: {

      • category: [

        • {

          • objectType: "Activity",

          • id: "https://w3id.org/xapi/cmi5/context/categories/cmi5"

          },

        • {

          • objectType: "Activity",

          • id: "https://w3id.org/xapi/cmi5/context/categories/moveon"

          }

        ]

      },

    • platform: "lms.lcontent.ru",

    • instructor: {

      • objectType: "Agent",

      • mbox: "mailto:MaxGammer@gmail.com",

      • name: "Anna Gammer"

      },

    • team: {

      • objectType: "Group",

      • mbox: "mailto:group@gmail.com",

      • name: "Commander ken"

      }

    },

  • authority: {

    • objectType: "Agent",

    • account: {

      • homePage: "https://lrs.lcontent.ru:443",

      • name: "maxgammer@gmail.com"

      }

    },

  • stored: "2021-04-07T09:35:51+00:00",

  • timestamp: "2021-04-07T09:35:51+00:00",

  • id: "f7e26b65-b9f4-4934-9988-6dcc034356ce"

}

Ну и наконец одна из нескольких записей о непосредственно "оценивании" (passed). Обратите внимание, что кроме времени и самой оценки мы используем записи для описания:

  1. Шаги обучаемого (открыл, ответил, подошел, прочитал и т.д.) с уточнением места события в модели действий персонала (обнаружение/диагностика/принятие решений и т.д.)

  2. Последствия его действий (в $, жизнях, экологии и т.д.)

  3. Параметры математической модели, представляющие интерес

  4. Параметры, заданные инструктором

  5. Комментарии инструктора

  6. Данные нейроинтерфейса и т.д.

Statement "passed"

{

  • actor: {

    • mbox: "mailto:user@lcontent.ru",

    • name: "Петров Сергей Александрович",

    • objectType: "Agent"

    },

  • verb: {

    • id: "http://adlnet.gov/expapi/verbs/passed",

    • display: {

      • en-US: "Indicates the actor completed an activity to standard.",

      • ru-RU: "Указывает, что субъект выполнил действие в соответствии со стандартными требованиями."

      }

    },

  • object: {

    },

  • result: {

    • success: true,

    • duration: "PT41S",

    • response: "Сценарий выполнен",

    • score: {

      • scaled: 0.0204081628471613,

      • raw: 1,

      • min: 0,

      • max: 49

      },

    • extensions: {

      • http://lcontent.ru/xapi/Total_Losses_money: 600000,

      • http://lcontent.ru/xapi/Total_Deads: 0,

      • https://w3id.org/xapi/cmi5/result/extensions/progress: 100

      }

    },

  • context: {

    • registration: "fb13ae65-d9cf-469d-8d89-e41fd61c842d",

    • extensions: {

      • https://w3id.org/xapi/cmi5/context/extensions/sessionid: "fb13ae65-d9cf-469d-8d89-e41fd61c842d",

      • https://w3id.org/xapi/cmi5/context/extensions/masteryscore: 0.860000014305115,

      • https://w3id.org/xapi/cmi5/context/extensions/launchurl: "https://lcontent.ru",

      • https://w3id.org/xapi/cmi5/context/extensions/launchmode: "Normal",

      • https://w3id.org/xapi/cmi5/context/extensions/moveon: "CompletedOrPassed",

      • http://lcontent.ru/xapi/weatherConditions: "rainy",

      • https://w3id.org/xapi/acme/extensions/training-location: "tyumen",

      • http://lcontent.ru/xapi/Device: "HTC VIVE"

      },

    • contextActivities: {

      • category: [

        • {

          • objectType: "Activity",

          • id: "https://w3id.org/xapi/cmi5/context/categories/cmi5"

          },

        • {

          • objectType: "Activity",

          • id: "https://w3id.org/xapi/cmi5/context/categories/moveon"

          }

        ],

      • other: [

        • {

          • id: "http://lcontent.ru/xapi/step",

          • definition: {

            • name: {

              • ru-RU: "41b7a8b9-cac2-4853-9703-74fb3825d73b"

              },

            • description: {

              • ru-RU: "Событие Стропальщик 1"

              },

            • extensions: {

              • http://lcontent.ru/step_datatime_real: "2021-04-07 14:35:27 ",

              • http://lcontent.ru/step_datatime_simulation: "2021-04-07 14:35:27 ",

              • http://lcontent.ru/step_type: "Scenario_wait_trigger",

              • http://lcontent.ru/step_completed: 1,

              • http://lcontent.ru/step_passed: 1,

              • http://lcontent.ru/step_categoty: ""

              }

            },

          • objectType: "Activity"

          },

        • {

          • id: "http://lcontent.ru/xapi/step",

          • definition: {

            • name: {

              • ru-RU: "20e06279-e2b7-4738-9fea-5836d5d2dbe8"

              },

            • description: {

              • ru-RU: "Вопрос:Укажите правильный вариант. Ответ пользователя: Нет нарушений.. Ответ неверен. Верный ответ: Нарушение. Стропальщик в момент подъема груза находится на площадке полуприцепа."

              },

            • extensions: {

              • http://lcontent.ru/step_datatime_real: "2021-04-07 14:35:30 ",

              • http://lcontent.ru/step_datatime_simulation: "2021-04-07 14:35:30 ",

              • http://lcontent.ru/step_type: "Scenario_step_question",

              • http://lcontent.ru/step_completed: 1,

              • http://lcontent.ru/step_passed: 0,

              • http://lcontent.ru/step_categoty: ""

              }

            },

          • objectType: "Activity"

          },

        • {

          • id: "http://lcontent.ru/xapi/step",

          • definition: {

            • name: {

              • ru-RU: "2ab73493-28c3-49f6-bc9a-fbf6eb56ad1c"

              },

            • description: {

              • ru-RU: "Событие 1trigg"

              },

            • extensions: {

              • http://lcontent.ru/step_datatime_real: "2021-04-07 14:35:24 ",

              • http://lcontent.ru/step_datatime_simulation: "2021-04-07 14:35:24 ",

              • http://lcontent.ru/step_type: "Scenario_wait_trigger",

              • http://lcontent.ru/step_completed: 1,

              • http://lcontent.ru/step_passed: 1,

              • http://lcontent.ru/step_categoty: ""

              }

            },

          • objectType: "Activity"

          },

        • {

          • id: "http://lcontent.ru/xapi/step",

          • definition: {

            • name: {

              • ru-RU: "9d1feb96-a948-4c39-a880-567a169b7df9"

              },

            • description: {

              • ru-RU: "Вопрос:Укажите правильный вариант. Ответ пользователя: Нарушение. Стропальщик не использует багор-оттяжку при сопровождении груза, поднятого на высоту более 1-го метра над землей (груз на месте складирования направляет руками, высота груза на уровне плеч стропальщика). Ответ верен."

              },

            • extensions: {

              • http://lcontent.ru/step_datatime_real: "2021-04-07 14:35:25 ",

              • http://lcontent.ru/step_datatime_simulation: "2021-04-07 14:35:25 ",

              • http://lcontent.ru/step_type: "Scenario_step_question",

              • http://lcontent.ru/step_completed: 1,

              • http://lcontent.ru/step_passed: 1,

              • http://lcontent.ru/step_categoty: ""

              }

            },

          • objectType: "Activity"

          },

        • {

          • id: "http://lcontent.ru/xapi/step",

          • definition: {

            • name: {

              • ru-RU: "813a8565-3c31-4ec3-9659-319651522851"

              },

            • description: {

              • ru-RU: "Показан текст Извините, У меня просто нет оттяжки и нет багра.... Я и так справлюсь."

              },

            • extensions: {

              • http://lcontent.ru/step_datatime_real: "2021-04-07 14:35:35 ",

              • http://lcontent.ru/step_datatime_simulation: "2021-04-07 14:35:35 ",

              • http://lcontent.ru/step_type: "Scenario_step_text",

              • http://lcontent.ru/step_completed: 1,

              • http://lcontent.ru/step_passed: 1,

              • http://lcontent.ru/step_categoty: ""

              }

            },

          • objectType: "Activity"

          },

        • {

          • id: "http://lcontent.ru/xapi/step",

          • definition: {

            • name: {

              • ru-RU: "7f2dc374-b564-472d-a5ab-2eac29bfe11f"

              },

            • description: {

              • ru-RU: "Показан текст Добро пожаловать в компьютерный имитационный тренажер, позволяющий отрабатывать навыки выявления опасных условий и действий при производстве работ повышенной опасности. Вы находитесь на производственном объекте . Ваша задача выявить все нарушения при производстве грузоподъемных работ. Нарушения также могут быть связаны с неправильным оформлением или отсутствием необходимой документации. В любой момент, Вы можете выйти из тренажера, нажав кнопку с флагом в правом верхнем углу экрана. Будет представлен отчет о результатах, а в режиме экзамена отчет сохранится в виде текстового файла на рабочем столе. Дата проведения проверки 3 сентября 2020. Для передвижения используйте клавиши WSAD. Для поворота головы нажмите правую клавишу мыши и перемещайте мышь в нужном направлении. Для изменения высоты используйте клавиши в нижнем правом углу экрана. Для увеличения используйте клавишу Q. Необходимо нажать на объект, предмет, работника и указать имеется нарушение или нет. Желаем приятного обучения. "

              },

            • extensions: {

              • http://lcontent.ru/step_datatime_real: "2021-04-07 14:35:35 ",

              • http://lcontent.ru/step_datatime_simulation: "2021-04-07 14:35:35 ",

              • http://lcontent.ru/step_type: "Scenario_step_text",

              • http://lcontent.ru/step_completed: 1,

              • http://lcontent.ru/step_passed: 1,

              • http://lcontent.ru/step_categoty: ""

              }

            },

          • objectType: "Activity"

          },

        • {

          • id: "http://lcontent.ru/xapi/step",

          • definition: {

            • name: {

              • ru-RU: "5ed064b0-aae2-4b67-a2c6-8492af0ab1fe"

              },

            • description: {

              • ru-RU: "Событие ОбъектыНаПлатформе"

              },

            • extensions: {

              • http://lcontent.ru/step_datatime_real: "2021-04-07 14:35:44 ",

              • http://lcontent.ru/step_datatime_simulation: "2021-04-07 14:35:44 ",

              • http://lcontent.ru/step_type: "Scenario_wait_trigger",

              • http://lcontent.ru/step_completed: 1,

              • http://lcontent.ru/step_passed: 1,

              • http://lcontent.ru/step_categoty: ""

              }

            },

          • objectType: "Activity"

          },

        • {

          • id: "http://lcontent.ru/xapi/step",

          • definition: {

            • name: {

              • ru-RU: "edf64367-855b-42b7-9181-a7b5ac32c23a"

              },

            • description: {

              • ru-RU: "Вопрос:Укажите правильный вариант. Ответ пользователя: Нарушение незначительно. Ответ неверен. Верный ответ: Нарушение. Груз на поворотной платформе"

              },

            • extensions: {

              • http://lcontent.ru/step_datatime_real: "2021-04-07 14:35:46 ",

              • http://lcontent.ru/step_datatime_simulation: "2021-04-07 14:35:46 ",

              • http://lcontent.ru/step_type: "Scenario_step_question",

              • http://lcontent.ru/step_completed: 1,

              • http://lcontent.ru/step_passed: 0,

              • http://lcontent.ru/step_categoty: ""

              }

            },

          • objectType: "Activity"

          },

        • {

          • id: "http://lcontent.ru/xapi/step",

          • definition: {

            • name: {

              • ru-RU: "91c4aa0e-5126-43bd-81e1-39cf1b60e994"

              },

            • description: {

              • ru-RU: "Выполнение в режиме экзамена"

              },

            • extensions: {

              • http://lcontent.ru/step_datatime_real: "2021-04-07 14:35:50",

              • http://lcontent.ru/step_datatime_simulation: "2021-04-07 14:35:50",

              • http://lcontent.ru/step_type: "ScenarioEditorManager",

              • http://lcontent.ru/step_completed: 1,

              • http://lcontent.ru/step_passed: 1,

              • http://lcontent.ru/step_categoty: ""

              }

            },

          • objectType: "Activity"

          },

        • {

          • id: "http://lcontent.ru/xapi/step",

          • definition: {

            • name: {

              • ru-RU: "3b2f4732-5ee5-4c10-8c2f-9012dc17163c"

              },

            • description: {

              • ru-RU: "Время выполнения: 00:00:28"

              },

            • extensions: {

              • http://lcontent.ru/step_datatime_real: "2021-04-07 14:35:50",

              • http://lcontent.ru/step_datatime_simulation: "2021-04-07 14:35:50",

              • http://lcontent.ru/step_type: "ScenarioEditorManager",

              • http://lcontent.ru/step_completed: 1,

              • http://lcontent.ru/step_passed: 1,

              • http://lcontent.ru/step_categoty: ""

              }

            },

          • objectType: "Activity"

          },

        • {

          • id: "http://lcontent.ru/xapi/step",

          • definition: {

            • name: {

              • ru-RU: "d3a31c1f-bfe1-4164-bd71-360789f59aac"

              },

            • description: {

              • ru-RU: "Возможных нарушений было замечено: 4 Из них исправлено: 1 Из них не исправлено: 3 Возможных нарушений не было замечено: 45"

              },

            • extensions: {

              • http://lcontent.ru/step_datatime_real: "2021-04-07 14:35:50",

              • http://lcontent.ru/step_datatime_simulation: "2021-04-07 14:35:50",

              • http://lcontent.ru/step_type: "ScenarioEditorManager",

              • http://lcontent.ru/step_completed: 1,

              • http://lcontent.ru/step_passed: 1,

              • http://lcontent.ru/step_categoty: ""

              }

            },

          • objectType: "Activity"

          },

        • {

          • id: "http://lcontent.ru/xapi/step",

          • definition: {

            • name: {

              • ru-RU: "bc03d881-faf3-4bff-8b37-e9850025c42a"

              },

            • description: {

              • ru-RU: "Задача :Объекты на платформе. Выполнена. "

              },

            • extensions: {

              • http://lcontent.ru/step_datatime_real: "2021-04-07 14:35:50",

              • http://lcontent.ru/step_datatime_simulation: "2021-04-07 14:35:50",

              • http://lcontent.ru/step_type: "ScenarioEditorManager",

              • http://lcontent.ru/step_completed: 1,

              • http://lcontent.ru/step_passed: 1,

              • http://lcontent.ru/step_categoty: ""

              }

            },

          • objectType: "Activity"

          },

        • {

          • id: "http://lcontent.ru/xapi/step",

          • definition: {

            • name: {

              • ru-RU: "ca1130ad-0d14-4ff7-89f9-033f929229bc"

              },

            • description: {

              • ru-RU: "Задача :Стропальщик в момент подъема груза находится на площадке полуприцепа. Выполнена. "

              },

            • extensions: {

              • http://lcontent.ru/step_datatime_real: "2021-04-07 14:35:50",

              • http://lcontent.ru/step_datatime_simulation: "2021-04-07 14:35:50",

              • http://lcontent.ru/step_type: "ScenarioEditorManager",

              • http://lcontent.ru/step_completed: 1,

              • http://lcontent.ru/step_passed: 1,

              • http://lcontent.ru/step_categoty: ""

              }

            },

          • objectType: "Activity"

          },

        • {

          • id: "http://lcontent.ru/xapi/step",

          • definition: {

            • name: {

              • ru-RU: "2d428645-f89d-4163-900b-7aede52581e3"

              },

            • description: {

              • ru-RU: "Задача :Стропальщик не использует багор-оттяжку при сопровождении груза. Выполнена. "

              },

            • extensions: {

              • http://lcontent.ru/step_datatime_real: "2021-04-07 14:35:50",

              • http://lcontent.ru/step_datatime_simulation: "2021-04-07 14:35:50",

              • http://lcontent.ru/step_type: "ScenarioEditorManager",

              • http://lcontent.ru/step_completed: 1,

              • http://lcontent.ru/step_passed: 1,

              • http://lcontent.ru/step_categoty: ""

              }

            },

          • objectType: "Activity"

          },

        • {

          • id: "http://lcontent.ru/xapi/mathmodel_value",

          • definition: {

            • name: {

              • ru-RU: "Pump1.Q"

              },

            • extensions: {

              • http://lcontent.ru/mm_dimension: "Q, m3/s",

              • http://lcontent.ru/mm_datatime_real: "2021-04-07 14:35:51 ",

              • http://lcontent.ru/mm_datatime_simulation: "2021-04-07 14:35:51 ",

              • http://lcontent.ru/mm_float_value: 56.7770004272461,

              • http://lcontent.ru/mm_str_value: ""

              }

            },

          • objectType: "Activity"

          },

        • {

          • id: "http://lcontent.ru/xapi/effects",

          • definition: {

            • name: {

              • ru-RU: "4b422c7f-e7da-46be-970f-fb4f44258dc4"

              },

            • description: {

              • ru-RU: "Нарушение не было устранено, Стропальщик в опасности."

              },

            • extensions: {

              • http://lcontent.ru/effect_ref_parent: "",

              • http://lcontent.ru/effect_datatime_real: "2021-04-07 14:35:30 ",

              • http://lcontent.ru/effect_datatime_simulation: "2021-04-07 14:35:30 ",

              • http://lcontent.ru/effect_cause: "Обучаемый обратил внимание на нарушение, но ошибся с его диагностированием",

              • http://lcontent.ru/effect_cause_full: "Место в модели поведения-Обнаружение=True, Диагностика=True, ПринятиеРешений=False, ВыполняемыеДействия=False",

              • http://lcontent.ru/effect_losses: "Нарушение не было устранено, Стропальщик в опасности.",

              • http://lcontent.ru/effect_losses_moneys: "",

              • http://lcontent.ru/effect_losses_life_health: "",

              • http://lcontent.ru/effect_losses_ecology: ""

              }

            },

          • objectType: "Activity"

          },

        • {

          • id: "http://lcontent.ru/xapi/effects",

          • definition: {

            • name: {

              • ru-RU: "ff53421f-5012-41db-93b2-2308bed78792"

              },

            • description: {

              • ru-RU: "Стропальщик использует безопасные методы и средства при выполнении работ. Угроза жизни и здоровью отсутствует."

              },

            • extensions: {

              • http://lcontent.ru/effect_ref_parent: "",

              • http://lcontent.ru/effect_datatime_real: "2021-04-07 14:35:25 ",

              • http://lcontent.ru/effect_datatime_simulation: "2021-04-07 14:35:25 ",

              • http://lcontent.ru/effect_cause: "Обучаемый обратил внимание на нарушение.",

              • http://lcontent.ru/effect_cause_full: "Место в модели поведения-Обнаружение=True, Диагностика=True, ПринятиеРешений=False, ВыполняемыеДействия=False",

              • http://lcontent.ru/effect_losses: "",

              • http://lcontent.ru/effect_losses_moneys: "",

              • http://lcontent.ru/effect_losses_life_health: "",

              • http://lcontent.ru/effect_losses_ecology: ""

              }

            },

          • objectType: "Activity"

          },

        • {

          • id: "http://lcontent.ru/xapi/effects",

          • definition: {

            • name: {

              • ru-RU: "73360673-9775-41e3-9bba-398d7b7efe5e"

              },

            • description: {

              • ru-RU: "Обучаемый обнаружил нарушение, но не верно его диагностировал."

              },

            • extensions: {

              • http://lcontent.ru/effect_ref_parent: "",

              • http://lcontent.ru/effect_datatime_real: "2021-04-07 14:35:46 ",

              • http://lcontent.ru/effect_datatime_simulation: "2021-04-07 14:35:46 ",

              • http://lcontent.ru/effect_cause: "Обучаемый обратил внимание на нарушение.",

              • http://lcontent.ru/effect_cause_full: "Место в модели поведения-Обнаружение=True, Диагностика=True, ПринятиеРешений=False, ВыполняемыеДействия=False",

              • http://lcontent.ru/effect_losses: "Обучаемый обнаружил нарушение, но не верно его диагностировал.",

              • http://lcontent.ru/effect_losses_moneys: "",

              • http://lcontent.ru/effect_losses_life_health: "",

              • http://lcontent.ru/effect_losses_ecology: ""

              }

            },

          • objectType: "Activity"

          },

        • {

          • id: "http://lcontent.ru/xapi/instructor_parameter",

          • definition: {

            • name: {

              • ru-RU: "1"

              },

            • extensions: {

              • http://lcontent.ru/instructor_parameter_name: "Pump1.Z",

              • http://lcontent.ru/instructor_parameter_dimension: "количество ступеней, шт.",

              • http://lcontent.ru/instructor_parameter_datatime_real: "2021-04-07 14:35:51 ",

              • http://lcontent.ru/instructor_parameter_datatime_simulation: "2021-04-07 14:35:51 ",

              • http://lcontent.ru/instructor_parameter_float_value: 56.7770004272461,

              • http://lcontent.ru/instructor_parameter_str_value: ""

              }

            },

          • objectType: "Activity"

          },

        • {

          • id: "http://lcontent.ru/xapi/instructor_problem",

          • definition: {

            • name: {

              • ru-RU: "1"

              },

            • extensions: {

              • http://lcontent.ru/instructor_problem_name: "Задвижка3.Клин",

              • http://lcontent.ru/instructor_problem_dimension: "да или нет",

              • http://lcontent.ru/instructor_problem_datatime_real: "2021-04-07 14:35:51 ",

              • http://lcontent.ru/instructor_problem_datatime_simulation: "2021-04-07 14:35:51 ",

              • http://lcontent.ru/instructor_problem_float_value: 0,

              • http://lcontent.ru/instructor_problem_str_value: "да"

              }

            },

          • objectType: "Activity"

          },

        • {

          • id: "http://lcontent.ru/xapi/instructor_comment",

          • definition: {

            • name: {

              • ru-RU: "1"

              },

            • extensions: {

              • http://lcontent.ru/instructor_comment_text: "Грубое нарушение техники безопасности.н",

              • http://lcontent.ru/instructor_comment_datatime_real: "2021-04-07 14:35:51 ",

              • http://lcontent.ru/instructor_comment_datatime_simulation: "2021-04-07 14:35:51 "

              }

            },

          • objectType: "Activity"

          },

        • {

          }

        ]

      },

    • platform: "lms.lcontent.ru",

    • instructor: {

      • objectType: "Agent",

      • mbox: "mailto:MaxGammer@gmail.com",

      • name: "Anna Gammer"

      },

    • team: {

      • objectType: "Group",

      • mbox: "mailto:group@gmail.com",

      • name: "Commander ken"

      }

    },

  • authority: {

    • objectType: "Agent",

    • account: {

      • homePage: "https://lrs.lcontent.ru:443",

      • name: "maxgammer@gmail.com"

      }

    },

  • stored: "2021-04-07T09:35:51+00:00",

  • timestamp: "2021-04-07T09:35:51+00:00",

  • id: "1abfd011-b0a5-442b-bc07-4087b4ac86cc"

}

terminated

{

  • actor: {

    • mbox: "mailto:user@lcontent.ru",

    • name: "Петров Сергей Александрович",

    • objectType: "Agent"

    },

  • verb: {

    • id: "http://adlnet.gov/expapi/verbs/terminated",

    • display: {

      • en-US: "Indicates the actor has completed their session normally.",

      • ru-RU: "Указывает, что субъект нормально завершил сеанс."

      }

    },

  • object: {

    },

  • result: {

    • duration: "PT41S",

    • response: "Сценарий выполнен",

    • extensions: {

      • http://lcontent.ru/xapi/Total_Losses_money: 600000,

      • http://lcontent.ru/xapi/Total_Deads: 0,

      • https://w3id.org/xapi/cmi5/result/extensions/progress: 100

      }

    },

  • context: {

    • registration: "fb13ae65-d9cf-469d-8d89-e41fd61c842d",

    • extensions: {

      • https://w3id.org/xapi/cmi5/context/extensions/sessionid: "fb13ae65-d9cf-469d-8d89-e41fd61c842d",

      • https://w3id.org/xapi/cmi5/context/extensions/masteryscore: 0.860000014305115,

      • https://w3id.org/xapi/cmi5/context/extensions/launchurl: "https://lcontent.ru",

      • https://w3id.org/xapi/cmi5/context/extensions/launchmode: "Normal",

      • https://w3id.org/xapi/cmi5/context/extensions/moveon: "CompletedOrPassed",

      • http://lcontent.ru/xapi/weatherConditions: "rainy",

      • https://w3id.org/xapi/acme/extensions/training-location: "tyumen",

      • http://lcontent.ru/xapi/Device: "HTC VIVE"

      },

    • contextActivities: {

      • category: [

        • {

          • objectType: "Activity",

          • id: "https://w3id.org/xapi/cmi5/context/categories/cmi5"

          }

        ]

      },

    • platform: "lms.lcontent.ru",

    • instructor: {

      • objectType: "Agent",

      • mbox: "mailto:MaxGammer@gmail.com",

      • name: "Anna Gammer"

      },

    • team: {

      • objectType: "Group",

      • mbox: "mailto:group@gmail.com",

      • name: "Commander ken"

      }

    },

  • authority: {

    • objectType: "Agent",

    • account: {

      • homePage: "https://lrs.lcontent.ru:443",

      • name: "maxgammer@gmail.com"

      }

    },

  • stored: "2021-04-07T09:35:52+00:00",

  • timestamp: "2021-04-07T09:35:52+00:00",

  • id: "d32fd6bf-c1b2-471d-af58-ca8754a6373b"

Ну и теперь ответим на вопрос - зачем это все нужно и что это дает?

А. Позволяет дифференцировать знания, умения и навыки, в т.ч. с учетом типа ошибок

Типы ошибокТипы ошибок

Б. Позволяет строить диаграммы последствий (см. http://personeltest.ru/aways/habr.com/ru/post/509736/)

Вероятности событий, связанных с человеческим фактором на диаграмме ETAВероятности событий, связанных с человеческим фактором на диаграмме ETAВероятности событий, связанных с человеческим фактором на диаграмме FTAВероятности событий, связанных с человеческим фактором на диаграмме FTA

В. Позволяет строить диаграммы в разрезе нужных показателей, причем в сравнении как с предыдущими попытками обучаемого, так и с оценками группы.

, ,

Г. Позволяет строить диаграммы изменения параметра математической модели (тренды) совместно с диаграммами Ганта для показа действий персонала и их взаимного влияния.

Таким образом я попытался показать некоторые возможности xAPI, обычно не затрагиваемые в других обзорах.

Все примеры доступны на сайте https://lms.lcontent.ru/course/view.php?id=84

Буду рад ответить на Ваши вопросы.

Подробнее..

Использование xAPI (Tin Can) и CMI5 в имитаторах

28.06.2020 18:15:43 | Автор: admin
image
Несмотря на то, что SCORM 2004 еще держит позиции, пора начинать поддерживать новые стандарты. Сегодня попробуем разобраться с xAPI / TinCab / CMI5. Обязательно протестируем код на официальных сайтах www.SCORM.com и www.adlnet.gov.

Итак, Tin Can API это спецификация программ в сфере дистанционного обучения, которая позволяет обучающим системам общаться между собой путём отслеживания и записи учебных занятий всех видов. Информация об учебной деятельности сохраняется в специальную базу хранилище учебных записей (англ. learning record store, LRS).

Особенности Tin Can API:

Tin Can API улучшенная версия спецификации SCORM
Tin Can API позволяет записывать любой опыт обучения, что дает нам более полную картину обучения конкретного человека
Tin Can API снимает с данных ограничения, накладываемые СДО
Tin Can API способен оказать неоценимую помощь учебным отделам, сопоставляя данные о качестве выполнения работы с учебными данными, тем самым повышая эффективность обучения.

Это теория, теперь практика.

При работе с SCORM 2000 все было относительно просто, нужно было выставить значения фиксированных переменных или получить значения фиксированных переменных.



Ну например

min = 0
max= 100
raw_score = 100
scaled = raw_score / max -- Оценка приведенная к диапазону 0..1.

ScormSetValue("cmi.score.min", ""..min); -- Минимальная оценка
ScormSetValue("cmi.score.max", ""..max); -- Максимальная оценка
ScormSetValue("cmi.score.raw", ""..raw_score); -- Полученная оценка
ScormSetValue("cmi.score.scaled", ""..scaled); -- Оценка приведенная к диапазону 0..1.

--Объем (количество) 0..1
ScormSetValue("cmi.progress_measure", "1");

ScormSetValue("cmi.success_status", "passed");
ScormSetValue("cmi.completion_status", "completed");

ScormGetValue("cmi.learner_name");
ScormGetValue("cmi.learner_id");
ScormGetValue("cmi.suspend_data");
ScormGetValue("cmi.scaled_passing_score");
ScormGetValue("cmi.completion_threshold");

print ( ScormGetValue("cmi._version"))
print ( ScormGetValue("cmi.total_time"))
print ( ScormGetValue("cmi.time_limit_action"))
print ( ScormGetValue("cmi.max_time_allowed"))

--Запись значений интеракций
ScormSetValue("cmi.interactions.0.id","Step1");
ScormSetValue("cmi.interactions.0.description", "17:14:28 Произвести аварийный останов работающих компрессорных станций")
ScormSetValue("cmi.interactions.0.result","correct");

ScormSetValue("cmi.interactions.1.id","Step2");
ScormSetValue("cmi.interactions.1.type","fill-in");
ScormSetValue("cmi.interactions.1.objectives.0.id","urn:ADL:objectiveid-0001");
ScormSetValue("cmi.interactions.1.description", "privet");
ScormSetValue("cmi.interactions.1.learner_response", "privet");
ScormSetValue("cmi.interactions.1.timestamp", "2005-10-11T09:00:30");
ScormSetValue("cmi.interactions.1.correct_responses.0.pattern", "privet");
ScormSetValue("cmi.interactions.1.weighting", "1");
--correct, incorrect, unanticipated, neutral , number 0..1
ScormSetValue("cmi.interactions.1.result","unanticipated");
ScormSetValue("cmi.interactions.1.latency", "PT0H0M5.0S");

ScormSetValue ("cmi.comments_from_learner.0.comment",q1);
ScormSetValue ("cmi.comments_from_learner.1.comment",q2);


Примерно так все и делалось Теперь на xAPI

Далее идет список тех LRS на которых я выполнял тестирование взаимодействия (необходима регистрация и получение login/pass соответственно)



Для взаимодействия с xAPI на C++ нам понадобится CURL и какая-нибудь библиотека для работы с JSON (cJSON например)

Тогда использование xAPI можно выполнять например так:

TinCanAddRecord(actor:::mbox:::mailto:mathmodel@mathmodel.com) TinCanAddRecord(actor:::name:::mathmodel)
TinCanAddRecord(actor:::objectType:::Agent)
TinCanAddRecord(verb:::id:::http://adlnet.gov/expapi/verbs/interacted)
TinCanAddRecord(object:::id:::http://lcontent.ru/lms1/simulator2)
TinCanAddRecord(object:::objectType:::Activity)

TinCanAddRecord(object:::definition:::type:::http://www.lcontent.ru/lms1/simulator1)
TinCanAddRecord(object:::definition:::name:::en-US:::mathmodel)
TinCanAddRecord(object:::definition:::description:::en-US:::mathmodel log)

TinCanAddRecord(object:::extensions:::http://lcontent.ru/upsv/Teapot1 angle::: a1)
TinCanAddRecord(object:::extensions:::http://lcontent.ru/upsv/Teapot2 angle::: a2)
TinCanAddRecord(object:::extensions:::http://lcontent.ru/upsv/Teapot3 angle::: a3)
TinCanAddRecord(object:::extensions:::http://lcontent.ru/upsv/time::: (os.clock() veryoldtime))

TinCanAddRecord(actor:::mbox:::mailto:maxgammer@gmail.com)
TinCanAddRecord(actor:::name:::Maxim Gammer)
TinCanAddRecord(actor:::objectType:::Agent)
TinCanAddRecord(verb:::id:::http://adlnet.gov/expapi/verbs/interacted)
TinCanAddRecord(object:::id:::http://lcontent.ru/lms1/simulator2)
TinCanAddRecord(object:::objectType:::Activity)
TinCanAddRecord(object:::definition:::type:::http://lcontent.ru/lms1/simulator1)
TinCanAddRecord(object:::definition:::name:::en-US:::User move)
TinCanAddRecord(object:::definition:::description:::en-US:::User coordinates)
TinCanAddRecord(object:::extensions:::http://lcontent.ru/upsv/time::: (os.clock() veryoldtime))

TinCanAddRecord(object:::extensions:::http://lcontent.ru/upsv/X::: UserData.X)
TinCanAddRecord(object:::extensions:::http://lcontent.ru/upsv/Y::: UserData.Y)
TinCanAddRecord(object:::extensions:::http://lcontent.ru/upsv/Z::: UserData.Z)
TinCanAddRecord(object:::extensions:::http://lcontent.ru/upsv/HeadYaw::: UserData.HeadYaw)
TinCanAddRecord(object:::extensions:::http://lcontent.ru/upsv/HeadPitch::: UserData.HeadPitch)
TinCanAddRecord(object:::extensions:::http://lcontent.ru/upsv/HeadRoll::: UserData.HeadRoll)

Все, смотрим записи в LRS

"

InterfaceForTinCan.cpp
#include <stdio.h>
#include <fcntl.h>
#include <sys/stat.h>
#include #include <string.h>
#include #include #include #include #include #include #include <curl/curl.h>

//using namespace std;

#ifdef WIN32
#include "./cJSON.h"
#else
#include "./cJSON.h"
#endif

class InterfaceForTinCan
{
public:
InterfaceForTinCan();
void AddTinCanRecord(std::string str, std::string type);
void PostToLRS(std::string host, std::string login, std::string password);
void PostFileToLRS(std::string filename);
void PostToFile (std::string filename);


private:
std::vector<std::string> split(const std::string& s, const std::string& delim, const bool keep_empty = true ) ;

//созданные объекты
std::map <std::string, cJSON *> OBJECTS;
//
cJSON *top;

std::string LRS_host;
std::string LRS_login;
std::string LRS_password;

void PostStringToLRS(std::string zzz);

};

InterfaceForTinCan::InterfaceForTinCan()
{
top=cJSON_CreateObject();
}

void InterfaceForTinCan::AddTinCanRecord(std::string str, std::string type)
{
//1. преобразуем страку в вектор через разделитель (::: или @@@)
std::vector<std::string> words = split(str, ":::");
//последние 2 элемента это поле=значение
int numOfObject = words.size();

//
std::string z = words [0];
if( OBJECTS.end() != OBJECTS.find(z))
{
//ключ присутствует
}
else
{
//создаем
OBJECTS[z] =cJSON_CreateObject();
//клеим к root
cJSON_AddItemToObject(top,z.c_str(), OBJECTS[z]);
}

for (int i=1; i < numOfObject -2; i++)
{
std::string oldz = z;
z = z + ":::" + words [i];

if( OBJECTS.end() != OBJECTS.find(z))
{
//ключ присутствует
}
else
{
//создаем
OBJECTS[z] =cJSON_CreateObject();
//клеим к
cJSON_AddItemToObject(OBJECTS[oldz], words [i].c_str(), OBJECTS[z]);
}
}

std::string value = words [numOfObject-1];
if (type=="string")
{
cJSON_AddStringToObject(OBJECTS[z], words [numOfObject-2].c_str(), value.c_str());
}
else if (type=="number")
{
cJSON_AddNumberToObject(OBJECTS[z], words [numOfObject-2].c_str(), std::stod(value));
}
else if (type=="bool")
{
bool val = false;
if ((value=="true")||(value=="TRUE")) val = true;
cJSON_AddBoolToObject(OBJECTS[z], words [numOfObject-2].c_str(), val);
}
}

void InterfaceForTinCan::PostToLRS(std::string host, std::string login, std::string password)
{
char* out=cJSON_Print(top);
std::string zzz = out;
cJSON_Delete(top);
OBJECTS.clear();

printf("%s\n",out);
free(out);
top=cJSON_CreateObject();

LRS_host = host;
LRS_login = login;
LRS_password = password;

PostStringToLRS(zzz);
}

void InterfaceForTinCan::PostFileToLRS(std::string filename)
{
std::string zzz;
std::string line;
std::ifstream myfile (filename.c_str());
if (myfile.is_open())
{
while ( myfile.good() )
{
getline (myfile,line);
zzz = zzz + line;
}
myfile.close();
}
//
PostStringToLRS(zzz);
}

void InterfaceForTinCan::PostToFile(std::string filename)
{
char* out=cJSON_Print(top);
std::string zzz = out;
cJSON_Delete(top);
OBJECTS.clear();

std::ofstream myfile;
myfile.open (filename);
myfile << zzz;
myfile.close();

free(out);
top=cJSON_CreateObject();
}

void InterfaceForTinCan::PostStringToLRS(std::string zzz)
{
std::string URL = LRS_host; //"https://cloud.scorm.com/ScormEngineInterface/TCAPI/public/statements";
std::string loginpassword = LRS_login + ":" + LRS_password; //"test:test"

CURL *curl;
struct curl_slist *headers=NULL;

headers = curl_slist_append(headers, "Accept: application/json");
headers = curl_slist_append( headers, "Content-Type: application/json");
headers = curl_slist_append( headers, "X-Experience-API-Version:1.0.0");
headers = curl_slist_append( headers, "charsets: utf-8");

curl = curl_easy_init();

if (curl)
{
/* enable verbose for easier tracing */
curl_easy_setopt(curl, CURLOPT_VERBOSE, 1L);

curl_easy_setopt(curl, CURLOPT_URL, URL.c_str());
curl_easy_setopt(curl, CURLOPT_CUSTOMREQUEST, "POST"); //PUT
curl_easy_setopt(curl, CURLOPT_HTTPHEADER, headers);
//
curl_easy_setopt( curl, CURLOPT_USERPWD, loginpassword.c_str() ); //"test:test"
// With the curl command line tool, you disable this with -k/--insecure.
curl_easy_setopt(curl, CURLOPT_SSL_VERIFYPEER, false);
curl_easy_setopt(curl, CURLOPT_SSL_VERIFYHOST, false);

curl_easy_setopt(curl, CURLOPT_POST, 1);
curl_easy_setopt(curl, CURLOPT_POSTFIELDS, zzz.c_str());

std::cout<< "..." << std::endl;
CURLcode res = curl_easy_perform(curl);
std::cout<< std::endl << "..." << std::endl;

/* Check for errors */
if(res != CURLE_OK)
{
std::cout<< "error:" << std::endl;
fprintf(stderr, "curl_easy_perform() failed: %s\n", curl_easy_strerror(res));
std::cout << std::endl;
}

curl_easy_cleanup(curl);
}
else
{
std::cout << "false" << std::endl;
}
}

std::vector<std::string> InterfaceForTinCan::split(const std::string& s, const std::string& delim, const bool keep_empty)
{
std::vector <std::string> result;
if (delim.empty())
{
result.push_back(s);
return result;
}
std::string::const_iterator substart = s.begin(), subend;
while (true)
{
subend = search(substart, s.end(), delim.begin(), delim.end());
std::string temp(substart, subend);
if (keep_empty || !temp.empty()) {
result.push_back(temp);
}
if (subend == s.end()) {
break;
}
substart = subend + delim.size();
}
return result;
}



Подробнее..

Категории

Последние комментарии

  • Имя: Макс
    24.08.2022 | 11:28
    Я разраб в IT компании, работаю на арбитражную команду. Мы работаем с приламы и сайтами, при работе замечаются постоянные баны и лаги. Пацаны посоветовали сервис по анализу исходного кода,https://app Подробнее..
  • Имя: 9055410337
    20.08.2022 | 17:41
    поможем пишите в телеграм Подробнее..
  • Имя: sabbat
    17.08.2022 | 20:42
    Охренеть.. это просто шикарная статья, феноменально круто. Большое спасибо за разбор! Надеюсь как-нибудь с тобой связаться для обсуждений чего-либо) Подробнее..
  • Имя: Мария
    09.08.2022 | 14:44
    Добрый день. Если обладаете такой информацией, то подскажите, пожалуйста, где можно найти много-много материала по Yggdrasil и его уязвимостях для написания диплома? Благодарю. Подробнее..
© 2006-2024, personeltest.ru