Работаем с датчиками

Содержание
  • Ваш первый эксперимент
  • Ручной ввод значения
  • Серии измерений и загрузка из файла
  • Обозначение географических координат для измерений
  • Серии от разных датчиков в одном файле
  • Данные о чём угодно
  • Отправка данных через REST API
  • Аутентификация в API
  • Отправка серий данных за один раз
  • Потоковая передача серий данных

Ваш первый эксперимент

В проектных заданиях ГлобалЛаб вы можете собирать и анализировать различные данные: числа, тексты, изображения, видео, точки на карте и многое другое. Однако наиболее увлекательным типом данных являются данные с датчиков. Чтобы лучше понять этот процесс, давайте создадим собственное проектное задание, включающее сбор таких данных. В нашем проекте мы будем исследовать температуру воздуха при различных условиях, включая их изменения.

Создадим своё собственное проектное задание, в анкету которого добавим следующие вопросы:

  1. «Место проведения измерения» — вопрос с типом «Карта».
  2. «Температура» — вопрос с типом «Данные от датчика» и типом датчика «Температура (°C)».
  3. «Условия» — вопрос с типом «Текст» с отмеченным флажком «многострочный».

Вопрос «Условия» предназначен для того, чтобы участники описывали изменения, происходившие при измерении температуры. Например: «Это значение температуры я получил, вставив термометр в горшок с землёй на окне» или «Я подносил к датчику пластиковый чайник с кипятком и держал его на расстоянии 5 см в течение 30 секунд». Как видно из примеров, в проектном задании мы можем собирать как единичные измерения температуры, так и множественные, показывающие изменение температуры за определённый период времени.

После того как вы закончите с настройкой вопросов в анкете, перейдём в раздел «Настройка результатов». Для того чтобы видеть собранные данные, добавим здесь виджет «Карта» с двумя слоями:

  1. Слой с вопросом «Температура». Настройки слоя можно оставить без изменения.
  2. Слой с вопросом «Условия».

Ручной ввод значения

Закончив с вопросами в анкете и виджетом, перейдём в режим предпросмотра, нажав на кнопку «Предпросмотр». Теперь перейдём к заполнению анкеты, нажав на кнопку «Заполнить анкету». В вопросе с датчиком вы увидите выпадающий список «Серии данных с ваших датчиков», переключатель «ручной ввод значения» и кнопку «Загрузить из файла». Как же заполнить такой вопрос?

Давайте начнём с самого простого варианта. Передвинем переключатель «ручной ввод значения» во включённое положение. Теперь вместо выпадающего списка «Серии данных с ваших датчиков» появилось обычное поле для ввода. В него вы можете ввести любое число. Одно число — это самая простая форма данных с датчика. В нашем примере мы измеряем температуру и одно число представляет собой просто одно показание термометра, будь то обычный или электронный.

Представим, что мы проводили простой опыт с втыканием термометра в землю. Введём любое значение в поле, например 23.5, отметим произвольную точку на карте в вопросе «Место проведения измерения» и ответим на вопрос «Условия», дав описание наподобие приведённого выше. Отправим анкету и вернёмся к просмотру результатов.

На карте появилась первая точка со значением температуры и иконкой, позволяющей посмотреть условия проведения эксперимента. Кликните на точку, и вы увидите небольшой график, на котором нанесена только одна точка — ваше единственное измерение температуры. Это здорово, но как сделать так, чтобы на графике было отмечено множество значений температуры, например для представления, как изменяется температура с течением времени, когда вы подносите к датчику горячий чайник? Для этого нам понадобится серия измерений.

Серии измерений и загрузка из файла

Когда мы внесли одно единственное значение температуры, это уже была серия измерений. Просто данные этой серии состояли только из одного значения. А вот пример серии, данные которой состоят из 5 значений (каждое расположено на новой строке):

23.5
24
24.5
25
25.5

По этой серии измерений видно, что температура постепенно повышается. Как вставить данные такой серии измерений в ответ на наш вопрос «Температура»?

Для этого создадим обычный текстовый файл в формате CSV"температура.csv" с помощью редактора Notepad и впишем туда нашу последовательность данных, указав на первой строке код датчика «temperature_c»:

temperature_c
23.5
24
24.5
25
25.5

Что такое «код датчика», который мы указали в первой строке? Это кодовое обозначение типа измеряемых значений и единицы измерения. В нашем случае это температура (temperature) и градусы Цельсия (c). Вот полный список всех кодов датчиков, поддерживаемых в ГлобалЛаб:

Код датчика Что измеряем (единица измерения)
acceleration_g Ускорение (g)
acceleration_mss Ускорение (м/с²)
angle Угол, азимут (°)
current_a Сила тока (А)
current_ma Сила тока (мА)
distance_m Расстояние (м)
force_n Сила (Н)
gas_mgl Содержание газа (мг/л)
gas_ppm Содержание газа (ppm)
heart_rate Частота сердечных сокращений (уд/мин)
humidity Влажность (%)
latitude Широта
light_klx Освещенность (клк)
light_lx Освещенность (лк)
longitude Долгота
magnetic_field_mt Магнитное поле (мТл)
microphone_v Микрофон (В)
other Другой датчик
ph Кислотность, pH
pressure_kpa Давление (кПа)
pressure_mbar Давление (мбар)
pressure_mmhg Давление (мм рт ст)
sound_db Датчик звука (дБ)
speed_kmh Скорость (км/ч)
speed_ms Скорость (м/с)
temperature_c Температура (°C)
uv Ультрафиолетовое излучение (Вт/м²)
uva Ультрафиолетовое излучение A (Вт/м²)
uvb Ультрафиолетовое излучение B (Вт/м²)
uvc Ультрафиолетовое излучение C (Вт/м²)
voltage_mv Напряжение (мВ)
voltage_v Напряжение (В)

Теперь снова заполним анкету, но только на этот раз в вопросе «Температура» мы нажмём кнопку «Загрузить из файла» и выберем только что созданный файл «температура.csv». После загрузки файла раскройте список «Серии данных с ваших датчиков» — в нём появилась ваша первая серия данных с указанием даты и кода датчика. Выберите эту серию.

Заполнив другие вопросы анкеты, отправьте данные и вернитесь к результатам. На карте появилась ещё одна точка. Кликните на неё. Теперь на графике уже не одна точка, а целая линия из 5 точек. Вы можете поэкспериментировать с загрузкой данных разных серий измерений. Например, сделайте серию, в которой температура скачет от 0 до 100 градусов и обратно при каждом измерении. Отправьте такие данные, и вы увидите, как график будет принимать пилообразную форму.

Обозначение географических координат для измерений

До сих пор мы обозначали место, где проводили измерение, ответом на вопрос «Место проведения измерения». А что, если мы проводим эксперимент, в котором смотрим на изменение температуры в зависимости от места? Например, мы движемся с датчиком температуры по летнему городу и переходим с раскалённой на солнце улицы в тенистый парк. Мы хотим зафиксировать, как при этом изменится температура. Для этого нам хорошо бы для каждого измерения указать географические координаты (широту и долготу), где они были получены.

Посмотрим в список кодов датчиков в ГлобалЛаб — там есть нужные нам датчики:

latitude — широта
longitude — долгота

Используем их в нашем файле «temperature.csv». Формат CSVпозволяет нам сделать несколько колонок данных, разделив их точкой с запятой. Кстати, создавать файлы CSVможно и в обычных офисных приложениях электронных таблиц, выбирая пункт «Сохранить как» и указывая формат «CSV».

Представим, что мы проводим измерения в Астрахани, перемещаясь сначала по улице Татищева, а затем сворачивая в Студенческий сквер. Вот какой вид может принять наш файл:

temperature_c; latitude; longitude
35.6; 46.377079; 48.051967
35.6; 46.377514; 48.052032
35.7; 46.377754; 48.052069
35.6; 46.377947; 48.052000
35.4; 46.377904; 48.051772
35.3; 46.377934; 48.051469
35.0; 46.377799; 48.051342
34.8; 46.377462; 48.051245
34.7; 46.377359; 48.051106
34.5; 46.377219; 48.051120

Снова заполним анкету, загрузив в вопрос «Температура» новую версию файла. Теперь в виджете с результатами появится более крупная точка в районе города Астрахани. Если мы максимально приблизим карту в районе этой точки, то она распадётся на множество отдельных точек — по одной на каждое измерение. Цвет каждой из них будет соответствовать температуре.

Серии от разных датчиков в одном файле

Давайте теперь усовершенствуем наше проектное задание так, чтобы в него можно было посылать данные не только о температуре, но и об относительной влажности воздуха. Для этого добавим в него ещё один вопрос «Влажность». Установим тип вопроса «Данные от датчика» и выберем в поле «Тип датчика» значение «Влажность».

Чтобы видеть новые данные о влажности, в наш виджет с картой добавим ещё один слой с нашим новым вопросом «Влажность». Выберите для него другую гамму цветов и маркер — например треугольник.

Теперь модифицируем наш файл, добавив в него колонку с кодом датчика «humidity»:

temperature_c; latitude; longitude; humidity
35.6; 46.377079; 48.051967; 50
35.6; 46.377514; 48.052032; 50
35.7; 46.377754; 48.052069; 51
35.6; 46.377947; 48.052000; 52
35.4; 46.377904; 48.051772; 53.5
35.3; 46.377934; 48.051469; 54.2
35.0; 46.377799; 48.051342; 55
34.8; 46.377462; 48.051245; 55.3
34.7; 46.377359; 48.051106; 55.2
34.5; 46.377219; 48.051120; 55.5

Снова заполним анкету. Обратите внимание, что после загрузки файла в вопрос «Температура» в выпадающем списке серий, как и раньше, появится поток с кодом датчика «temperature». Но и в вопросе «Влажность» в этом списке тоже появится серия данных, но с кодом «humidity». Таким образом, загрузив файл в один из вопросов один раз, вы добавили в каждый из них правильную серию. ГлобалЛаб сам «поймёт», в какой вопрос какая серия данных из файла подходит.

Выберите в каждом вопросе нужную серию и отправьте анкету. Теперь на виджете в районе Астрахани при достаточном приближении вы будете видеть сразу две серии: кружками будет обозначаться температура, а треугольниками — влажность. Если вы не видите треугольники, просто попереключайте видимость слоёв под картой так, чтобы треугольники оказались выше кругов.

Данные о чём угодно

Поскольку серия измерений в ГлобалЛаб — это просто список чисел, то с помощью неё можно представлять любые процессы, явления или события. Вот лишь несколько примеров:

  1. Регистрация цвета светофора на каждом перекрёстке в момент приближения к нему на автобусе. Обозначим красный цвет числом 1, жёлтый — 2, а зелёный — 3. Тогда серия из чисел 1, 3, 3, 3, 2, 3 будет указывать на то, что при вашем путешествии по городу вам везло и вы ловили зелёный почти на всех перекрёстках. Если похожие «зелёные улицы» будут встречаться часто в данных многих участников из одного города, то это будет свидетельствовать в пользу гипотезы о хорошей настройке светофоров в этом городе.
  2. Слежение за средней глубиной плавания рыбок в аквариуме. Число 1 будет говорить о том, что рыбки плавают в нижней части аквариума, 2 — в средней, 3 — в верхней. Если к этим данным добавить данные об атмосферном давлении, то вы сможете проверить гипотезу о связи средней глубины плавания рыбок с погодой.
  3. Регистрация частоты упоминания имени второстепенного героя в произведении. Для каждой страницы или абзаца небольшого рассказа подсчитаем число упоминаний имени одного из второстепенных героев. Тогда, например, серия измерений 1, 2, 0, 0, 0, 0, 0, 4 будет косвенно свидетельствовать о том, что этот герой важен только для начала и конца повествования.

В таблице кодов датчиков ГлобалЛаб, конечно, нет специальных кодов для «датчика светофора», «датчика глубины плавания рыб» и «датчика второстепенных персонажей». Однако есть свободный датчик с кодом «other», который можно использовать для чего угодно. Не забудьте при этом в соответствующем вопросе анкеты выбрать в поле «Тип датчика» вариант «Другой датчик».

Отправка данных через REST API

Полное описание сервисов REST API в формате OpenAPI вы можете найти здесь.

Серии данных с датчиков можно отправлять с помощью специального REST API. Этот способ прекрасно подходит для отправки данных с настоящих «железных» датчиков, которые вы создаёте на базе, например, Arduino или программируете в виде мобильных приложений. Конечно, и «железные» датчики, и приложения могут просто записывать файлы в формате CSV, которые вы потом загрузите в нужные вопросы анкет. Однако API имеет по сравнению с этим способом два огромных преимущества:

  1. Можно загружать данные без вашего участия.
  2. Можно загружать данные в реальном времени, в виде потока. В этом случае такие данные появляются на картах-виджетах сразу. При этом они обозначаются на карте мигающими маркерами, так что другие пользователи могут следить за изменениями ваших данных в реальном времени.

Аутентификация в API

Для отсылки данных через API вам понадобится специальный токен, который указывается в HTTP-заголовке «Authorization» каждого вашего вызова следующим образом:

Authorization: Bearer ваш_токен

Ваш токен вы можете создать в разделе «Мои датчики» вашего личного кабинета ГлобалЛаб. Такой токен не имеет срока действия, поэтому вы смело можете прописать его в исходный код вашей прошивки для Arduino или мобильное приложение. Если ваш токен скомпрометирован или вы потеряли его секретную часть, удалите его и создайте новый.

Отправка серий данных за один раз

Для отправки всех данных вашего эксперимента за один раз используйте сервис POST https://globallab.org/api/v2/logger/experiment/. Запрос отправляется в теле вызова в виде JSON-документа вида:

{
    "experiment": {
        "sensors": ["…", "…", … ],
        "data": [
            […, …, …],
            […, …, …],
            …
        ]
    }
}

Для отправки данных за один раз мы используем следующие поля:

sensors— массив кодов датчиков, перечисленных в порядке следования серий в массиве data.
data— массив серий данных, каждая серия в свою очередь является массивом чисел.

Обратите внимание, что число элементов во всех массивах внутри «data» должно быть строго одинаковым.

Попробуем отправить все данные нашего эксперимента с измерением температуры и влажности, приведённые выше, с помощью RESTAPI. Пример дан в виде команды для утилиты командной строки cURL (не забудьте вставить ваш токен вместо «ваш_токен»):

curl --location 'https://globallab.org/api/v2/logger/experiment/' \
--header 'Content-Type: application/json' \
--header 'Authorization: Bearer ваш_токен' \
--data '{    
    "experiment": {
        "sensors": ["temperature_c", "latitude", "longitude", "humidity"],
        "data": [
            [35.6, 35.6, 35.7, 35.6, 35.4, 35.3, 35.0, 34.8, 34.7, 34.5],
            [46.377079, 46.377514, 46.377754, 46.377947, 46.377904, 46.377934, 46.377799, 46.377462, 46.377359, 46.377219],
            [48.051967, 48.052032, 48.052069, 48.052000, 48.051772, 48.051469, 48.051342, 48.051245, 48.051106, 48.051120],
            [50, 50, 51, 52, 53.5, 54.2, 55, 55.3, 55.2, 55.5]
        ]
    }
}'

В ответ сервер вернёт:

{
     "experiment": {
        "experiment_id": "идентификатор_эксперимента"
     }
}

В поле experiment_id будет содержаться идентификатор эксперимента, который вам не понадобится при отправке данных за один раз. Он используется только при потоковой передаче.

Если что-то пошло не так, сервер вернёт сообщение об ошибке вида:

{
    "error_code": "Код ошибки",
    "error_description": "Описание ошибки"
}

Если после вызова сервиса вы зайдёте в проектное задание, которое мы создавали ранее, то увидите, что в вопросах «Температура» и «Влажность» в списке «Серии данных с ваших датчиков» появилась новая серия, как при загрузке данных из файла. Если вы сделаете вызов сервиса, находясь на странице проектного задания, то новая серия появится в списке сразу же. Такая «свежая» серия будет отмечена в списке зелёным кружочком.

При заполнении анкеты проектного задания ГлобалЛаб автоматически находит все ваши потоки, подходящие по типу датчика под вопрос, и показывает их в списке. Поэтому вы можете заранее отсылать серии данных в ГлобалЛаб, а потом использовать их в анкетах. Те серии, которые были прикреплены и отправлены в анкетах, уже не будут показываться при заполнении новых анкет, поскольку они считаются «занятыми».

Потоковая передача серий данных

До сих пор мы использовали передачу данных с датчиков целиком за один раз. В ГлобалЛаб можно передавать серии данных постепенно, по мере их измерения. В этом случае такие данные появляются на картах-виджетах сразу. При этом они обозначаются на карте мигающими маркерами так, что другие пользователи могут следить за изменениями ваших данных в реальном времени.

Вот как выглядит общая схема действий при такой передаче:

  1. С помощью вызова REST API POST https://globallab.org/api/v2/logger/experiment/ вы начинаете эксперимент. Фактически этим вызовом вы просто сообщаете серверу о том, что планируете передавать данные с датчиков определённых типов. Сами данные вы можете даже и не передавать. При этом вы можете сами присвоить эксперименту уникальный идентификатор или положиться на сервер, который вернёт такой идентификатор в ответе.
  2. Вы передаёте данные с помощью вызова второго сервиса ­­— PUT /experiment/{experiment_id}/data/. Здесь вы указываете идентификатор начатого на первом шаге эксперимента и вставляете серии данных в тело запроса. Этот сервис вы можете вызывать многократно, каждый раз передавая очередную порцию свежих данных.
  3. В любой момент после шага 1 вы можете увидеть вашу новую серию данных в любом проектном задании с подходящим по типу данных вопросом. Вы можете выбрать её и отослать анкету. Если в указанную вами серию продолжают поступать данные даже после отправки анкеты, эти свежие данные продолжат отображаться на картах и графиках.

Разберём отдельно каждый вызов.

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

curl --location 'https://globallab.org/api/v2/logger/experiment/' \
--header 'Content-Type: application/json' \
--header 'Authorization: Bearer ваш</a>_токен' \
--data '{ 
    "experiment": {
        "sensors": ["temperature_c", "latitude", "longitude", "humidity"]
    }
}'

Как и в случае с передачей за один раз, сервер вернёт вам присвоенный идентификатор эксперимента:

{
    "experiment": {
        "experiment_id": "идентификатор_эксперимента"
    }
}

Этот идентификатор вам понадобится для отсылки данных в эксперимент.

В некоторых случаях, например при создании ваших собственных датчиков на базе Arduino, разбирать ответ сервера для получения идентификатора достаточно сложно. На этот случай вы можете сами назначить идентификатор заранее и передать его вот так:

curl --location 'https://globallab.org/api/v2/logger/experiment/' \
--header 'Content-Type: application/json' \
--header 'Authorization: Bearer ваш_токен' \
--data '{    
    "experiment": {
        "experiment_id": "идентификатор_эксперимента",
        "sensors": ["temperature_c", "latitude", "longitude", "humidity"]
     }
}'

Идентификатор должен быть корректным UUID любой версии. Сервер сообщит об ошибке, если UUID некорректен или неуникален (то есть в ГлобалЛаб уже есть эксперимент с таким идентификатором).

После того как у нас появился идентификатор, мы можем отсылать данные такими вызовами:

curl --location --request PUT 'https://globallab.org/api/v2/logger/experiment/ идентификатор_эксперимента/data/' \
--header 'Content-Type: application/json' \
--header 'Authorization: Bearer ваш_токен' \
--data '{    
    "data": {
        "queue": 1,
        "series": [
            [35.6, 35.6, 35.7],
            [46.377079, 46.377514, 46.377754],
            [48.051967, 48.052032, 48.052069],
            [50, 50, 51]
        ]
     }
}'

Здесь мы отправили первые три значения температуры, влажности, широты и долготы из нашего примера. Обратите внимание на параметр «queue». Его необходимо увеличивать на единицу с каждой новой порцией данных. Так сервер будет знать порядок данных в серии и сможет восстановить его, если более поздние вызовы придут по какой-то причине на сервер раньше, чем более ранние.

Теперь вы можете провести следующий эксперимент:

  1. Отправьте первый запрос и зарезервируйте идентификатор эксперимента.
  2. Заполните анкету нашего проектного задания про температуру и влажность, выбрав в двух вопросах ту серию, которую вы только что отправили (она будет последней по дате). Отправьте анкету и перейдите к просмотру карты.
  3. Теперь, используя зарезервированный идентификатор, отправляйте второй запрос, меняя в нём данные, в том числе долготу и широту. Вы увидите, что точка с вашими данными на карте мигает, меняет цвет и перемещается по карте.