Исторические данные

Одна из главных задач Платформы - обеспечение клентов сохранёнными историческими данными. Клиенты получают данные с помощью запроса GET по адресу /v1/data/. Эта команда будет подробно объяснена ниже.

Правила работы с данными

Важно

При работе с историческими данными запомним следующие правила:

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

  2. Если в тэге нет значений с метками времени из будущего, то последнее сохранённое на текущий момент времени в тэге значение является текущим значением тэга.

  3. Если значения тэга числовые:

    1. Если атрибут тэга prsStep равен true, тогда значения тэга между двумя метками времени не интерполируются.

    2. Если атрибут тэга prsStep равен false (по умолчанию), тогда значения тэга между двумя метками времени вычисляются с помощью линейной интерполяции.

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

  4. Все метки времени внутри платформы и в исторической базе данных хранятся и обрабатываются как целочисленные данные. Каждая метка времени - это количество микросекунд, начиная с 01-01-1970 00:00:00+00:00. Пример: 1000000 = 01-01-1970 00:00:01+00:00

  5. Если клиент посылает в платформу метку времени как строку в формате ISO 8601 и не указывает временнУю зону, то Платформа устанавливает для такой метки времени зону по умолчанию UTC (+00:00).

  6. Клиенты могут записывать значения тэгов с метками времени из будущего.

  7. Ответ на запрос GET /v1/data/ содержит массив значений тэга, отсортированный по метке времени в возрастающем порядке.

  8. Если тэг содержит несколько значений на одну и ту же метку времени, то текущим значением тэга на эту метку времени считается записанное последним.

  9. Каждое значение в тэге содержит код качества q. Если q = 0 или null, то значению тэга можно доверять. Иначе значение тэга ошибочно, код q определяет ошибку. См. коды качества.

    Следующие правила касаются ключей count, start, finish и timeStep в запросе GET /v1/data/.

  10. Комбинации ключей start, finish и timeStep совместно с ключом count определяют границы периода для возвращаемых данных.

  11. Ключ count определяет количество возвращаемых данных. Учитывается общее количество: и реально записанные в базе данных, и интерполированные значения тэгов.

  12. В случае отсутствия ключа finish его значение принимается равным текущему моменту времени. Это правило по умолчанию отсекает данные, записанные с метками времени из будущего.

Коды качества

У каждого записанного в базу значения тэга есть так называемый «код качества», который возвращается в ключе q.

Код качества - это, другими словами, код ошибки данных.

Коды качества

Код

Описание

0 | null

Обычное значение. Данные «хорошие».

100

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

101

Платформа завершила работу. Используется совместно со значением тэга null и записывается в процессе завершения платформой работы.

102

Разорвана связь между коннектором и поставщиком данных. Используется совместно со значением тэга null.

Получение данных

Подробно рассмотрим примеры получения исторических данных.

Пример массива данных

Допустим, у нас есть тэг Tag1 у объекта Object1. Идентификатор тега - 1500c712-726a-103e-9264-a5021ec2dae1. Атрибут prsTagValueTypeCode этого тэга равен 1 и это значит, что тэг хранит вещественные значения. Исторические данные этого тэга:

_images/datapool.png

Примечание

Для простоты будем оперировать только часами и минутами в качестве меток времени.

Итак, исторические данные тэга Tag1:

[
  [1, "09:30"],
  [3, "09:35"],
  [2.5, "09:40"],
  [5, "09:45"],
  [4, "09:50"]
]

Формат запроса на получение данных

Пример:

{
  "tagId": ["id первого тэга", "id второго тэга"],
  "start": "2018-12-09 12:00:00+03:00",
  "finish": "2018-12-09 14:00:00+03:00",
  "count": 8,
  "timeStep": 60000000,
  "maxCount": 700,
  "actual": false,
  "format": true,
  "value": 10
}
  • tagId (str или массив из str), обязательный - тэг(и) для которых необходимо получить данные.

  • start (int, str), необязательный - метка времени начала периода для получения данных (see). Если start - строка, то ее значение обрабатывается в соответствии со стандартом ISO 8601.

    Возможные значения:

    • «2018-12-20 00:00:00+03:00»

    • «2018-12-20 00:00:00» - временнАя зона для этого значения будет установлена в UTC (00:00)

    • 1544662830000000 значение равно: «2018-12-13 01:00:30+00:00»

    • «01:00» предположим, что текущая дата на сервере платформы - 2018-12-20, тогда «01:00» будет преобразовано в «2018-12-20 01:00:00+00:00»

    • «01:00,5+03:00» равно (оставим предыдущее предположение о дате) «2018-12-20 01:00:30+3:00»

    • другие примеры указания времени можно посмотреть на странице стандарта ISO 8601

  • finish (int, str), необязательный - метка времени конца периода, соответствует тем же правилам, что и ключ start.

  • count (int), необязательный - количество значений, ожидаемых в ответе

  • timeStep (int), необязательный - промежуток времени между соседними возвращаемыми значениями тэга

  • maxCount (int), необязательный - ключ используется, в основном, виджетами и принимает значение ширины виджета в пикселях. Таким образом, Платформа знает, что виджет не может показать больше значений, чем указано в maxCount. В этом случае платформа возвращает не больше значений, чем указано в maxCount.

    Ключ maxCount предотвращает излишнюю загрузку платформы при работе с большими массивами данных.

  • format (любой тип и значение), необязательный - если этот ключ присутствует и не равен None, тогда метки времени возвращаются в виде строк в формате ISO 8601, часовая зона - зона сервера, на котором работает платформа.

  • actual (bool), необязательный - если этот ключ присутствует и установлен в true, тогда в ответе на запрос присутствуют только реальные записанные базу данных значения тэга.

  • value (any), необязательный - фильтр значений тега.

Формат ответа на запрос на получение данных

Пример:

{
   "data": [
     {
       "exceed": false,
       "tagId": "id тега",
       "data": [
         [1, "2018-12-31T00:00:00+03:00", null],
         [120, "2018-12-31T00:01:00+03:00", null]
       ]
     }
   ]
}

Если запрос выполнен без ошибок, ответ всегда содержит один ключ - data, который является массивом элементов типа json, каждый элемент - данные по одному тегу из запроса.

Ключи элемента из массива:

  • exceed (bool) - флаг того, что данных в архиве больше, чем запрошено; логика работы флага: если в запросе указан ключ maxCount, то в ответе устанавливается флаг exceed; если этот флаг = true, то это означает, что в архиве содержится больше значений, чем указано в запросе в ключе maxCount, поэтому возвращённые значения тега усреденены и лучший выход - изменить запрос, запросив меньшее количество значений тега; если в запросе нет ключа maxCount, то ключ exceed в ответе отсутствует;

  • tagId (str) - идентификатор тега;

  • data (массив массивов) - массив значений, попадающих в запрошенный период; каждый элемент массива - в свою очередь, тоже массив и состоит из трёх элементов: [y, x , q], где:

    y - значение тега; x - метка времени, с которой записано значение тега; q - код качества значения.

Ниже - примеры запросов.

Получение текущего значения тэга

Самый простой запрос на получение данных выглядит так:

{
  "tagId": "1500c712-726a-103e-9264-a5021ec"
}

Запрос выше показывает, как можно получить текущее значение одного тэга.

Допустим, текущий момент времени - 09:53:

_images/tagId_step.png

Ответом будет:

{
  "data": [
    {
      "tagId": "1500c712-726a-103e-9264-a5021ec2dae1",
      "data": [
        [4, 1545288780000000, null]
      ]
    }
  ]
}

В соответствии с правилом 2 текущее значение тэга - 4. Метка времени (1545288780000000) соответствует текущему моменту времени. Такой ответ будет идентичен для тэгов с атрибутом prsStep, равным true и false.

Примечание

  1. Для простоты понимания меток времени во всех следующих запросах будем использовать ключ format.

  2. Опять же для простоты исключим из всех дальнейших меток времени дату.

Метки времени в будущем и prsStep = false

Допустим, текущий момент времени 09:47:30. Это значит, что мы имеем одно значение тэга, сохранённое с меткой времени в будущем. Пусть prsStep = false, то есть мы должны интерполировать значения тэгов.

_images/tagId_stepFalse.png

Тогда запрос

{
  "tagId": "1500c712-726a-103e-9264-a5021ec2dae1",
  "format": true
}

Вернёт:

{
  "data": [
    {
      "tagId": "1500c712-726a-103e-9264-a5021ec2dae1",
      "data": [
        [4.5, "09:47:30", null]
      ]
    }
  ]
}

Метки времени в будущем, prsStep = true

Этот пример отличается от предыдущего тем, что prsStep = true.

_images/tagId_stepTrue.png

Тогда запрос

{
  "tagId": "1500c712-726a-103e-9264-a5021ec2dae1",
  "format": true
}

Вернёт:

{
  "data": [
    {
      "tagId": "1500c712-726a-103e-9264-a5021ec2dae1",
      "data": [
        [5, "09:47:30", null]
      ]
    }
  ]
}

Ключ start

prsStep = false

Добавим к нашему запросу ключ start. Ключ start устанавливает начало периода для получения данных. Пусть start = 09:32:30 и prsStep = false.

_images/period_fromStepFalse.png

Запрос:

{
  "tagId": "1500c712-726a-103e-9264-a5021ec2dae1",
  "format": true,
  "start": "09:32:30"
}

Ответ:

{
  "data": [
    {
      "tagId": "1500c712-726a-103e-9264-a5021ec2dae1",
      "data": [
        [2, "09:32:30", null],
        [3, "09:35:00", null],
        [2.5, "09:40:00", null],
        [5, "09:45:00", null],
        [4, "09:50:00", null],
        [4, "09:53:00", null]
      ]
    }
  ]
}

prsStep = true

_images/period_fromStepTrue.png

Запрос:

{
  "tagId": "1500c712-726a-103e-9264-a5021ec2dae1",
  "format": true,
  "start": "09:32:30"
}

Ответ:

{
  "data": [
    {
      "tagId": "1500c712-726a-103e-9264-a5021ec2dae1",
      "data": [
        [1, "09:32:30", null],
        [3, "09:35:00", null],
        [2.5, "09:40:00", null],
        [5, "09:45:00", null],
        [4, "09:50:00", null],
        [4, "09:53:00", null]
      ]
    }
  ]
}

Начало периода в запросе - перед любой меткой времени в базе

Пусть start = 09:27:30.

_images/period_fromBeforeData.png

Запрос:

{
  "tagId": "1500c712-726a-103e-9264-a5021ec",
  "format": true,
  "start": "09:27:30"
}

Ответ:

{
  "data": [
    {
      "tagId": "1500c712-726a-103e-9264-a5021ec2dae1",
      "data": [
        [null ,"09:27:30", null],
        [1, "09:30:00", null],
        [3, "09:35:00", null],
        [2.5, "09:40:00", null],
        [5, "09:45:00", null],
        [4, "09:50:00", null],
        [4, "09:53:00", null]
      ]
    }
  ]
}

Начало периода в запросе - после любой метки времени в базе

Пусть start = 09:52:30.

_images/period_fromAfterData.png

Запрос:

{
  "tagId": "1500c712-726a-103e-9264-a5021ec",
  "format": true,
  "start": "09:52:30"
}

Возвращается последнее значение в базе как на метку start, так и на текущую метку времени

Ответ:

{
  "data": [
    {
      "tagId": "1500c712-726a-103e-9264-a5021ec2dae1",
      "data": [
        [4, "09:52:30", null],
        [4, "09:55:00", null]
      ]
    }
  ]
}

Ключ finish

finish = произвольной метке времени

Устанавливая ключ finish, мы ограничиваем конец периода получения данных.

_images/period_to.png

Запрос:

{
  "tagId": "1500c712-726a-103e-9264-a5021ec",
  "format": true,
  "finish": "09:32:30"
}

Ответ:

{
  "data": [
    {
      "tagId": "1500c712-726a-103e-9264-a5021ec2dae1",
      "data": [
        [2, "09:32:30", null]
      ]
    }
  ]
}

Ключ finish установлен перед любой существующей в базе меткой времени

_images/period_toBefore.png

Запрос:

{
  "tagId": "1500c712-726a-103e-9264-a5021ec",
  "format": true,
  "finish": "09:27:30"
}

Ответ:

{
  "data": [
    {
      "tagId": "1500c712-726a-103e-9264-a5021ec2dae1",
      "data": [
        ["09:27:30", "y": null]
      ]
    }
  ]
}

Ключ finish равен текущей метке времени

Если мы установим ключ finish на текущую метку времени, то запрос будет в точности таким же, как в запросе Получение текущего значения тэга.

Ключи start и finish

Ниже - несколько примеров одновременно установленных ключей start и finish.

start и finish внутри существующих в базе меток

_images/period_fromAndToReal.png

Запрос:

{
  "tagId": "1500c712-726a-103e-9264-a5021ec",
  "format": true,
  "start": "09:32:30",
  "finish": "09:47:30"
}

Ответ:

{
  "data": [
    {
      "tagId": "1500c712-726a-103e-9264-a5021ec2dae1",
      "data": [
        [2, "09:32:30", null],
        [3, "09:35:00", null],
        [2.5, "09:40:00", null],
        [5, "09:45:00", null],
        [4.5, "09:47:30", null]
      ]
    }
  ]
}

start выходит за пределы меток

_images/period_fromNotReal.png

Запрос:

{
  "tagId": "1500c712-726a-103e-9264-a5021ec",
  "format": true,
  "start": "09:27:30",
  "finish": "09:47:30"
}

Ответ:

{
  "data": [
    {
      "tagId": "1500c712-726a-103e-9264-a5021ec2dae1",
      "data": [
        [null, "09:27:30", null],
        [1, "09:30:00", null],
        [3, "09:35:00", null],
        [2.5, "09:40:00", null],
        [5, "09:45:00", null],
        [4.5, "09:47:30", null]
      ]
    }
  ]
}

start и finish вне меток времени

_images/period_fromToOutside.png

Запрос:

{
  "tagId": "1500c712-726a-103e-9264-a5021ec",
  "format": true,
  "start": "09:27:30",
  "finish": "09:55:00"
}

Ответ:

{
  "data": [
    {
      "tagId": "1500c712-726a-103e-9264-a5021ec2dae1",
      "data": [
        [null, "09:27:30", null],
        [1, "09:30:00", null],
        [3, "09:35:00", null],
        [2.5, "09:40:00", null],
        [5, "09:45:00", null],
        [4, "09:50:00", null],
        [4, "09:55:00", null]
      ]
    }
  ]
}

Ключ count

Ключ count определяет запрашиваемое количество данных.

В соответствии с правилом 10 ключ finish равен текущей метке времени в случае, если установлен только ключ count.

Ключи count и finish

Предположим, что мы установили ключ finish на момент времени, не существующий в базе данных:

_images/toAndCount.png

Запрос:

{
  "tagId": "1500c712-726a-103e-9264-a5021ec",
  "format": true,
  "finish": "09:47:30",
  "count": 3
}

Этот запрос вернёт два сохранённых значения и одно интерполированное.

Ответ:

{
  "data": [
    {
      "tagId": "1500c712-726a-103e-9264-a5021ec2dae1",
      "data": [
        [2.5, "09:40:00", null],
        [5, "09:45:00", null],
        [4.5, "09:47:30", null]
      ]
    }
  ]
}

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

_images/toAndCount2.png

Запрос:

{
  "tagId": "1500c712-726a-103e-9264-a5021ec",
  "format": true,
  "finish": "09:45:00",
  "count": 3
}

Запрос вернёт три сохранённых значения.

Ответ:

{
  "data": [
    {
      "tagId": "1500c712-726a-103e-9264-a5021ec2dae1",
      "data": [
        [3, "09:35:00", null],
        [2.5, "09:40:00", null],
        [5, "09:45:00", null]
      ]
    }
  ]
}

Запрос:

Ключ count превышает количество существующих значений (основываемся на предыдущей картинке).

{
  "tagId": "1500c712-726a-103e-9264-a5021ec",
  "format": true,
  "finish": "09:45:00",
  "count": 5
}

Ответ:

{
  "data": [
    {
      "tagId": "1500c712-726a-103e-9264-a5021ec2dae1",
      "data": [
        [1, "09:30:00", null],
        [3, "09:35:00", null],
        [2.5, "09:40:00", null],
        [5, "09:45:00", null]
      ]
    }
  ]
}

Ключ finish превышает последнюю существующую метку времени:

_images/toAndCount3.png

Запрос:

{
  "tagId": "1500c712-726a-103e-9264-a5021ec",
  "format": true,
  "finish": "09:52:30",
  "count": 3
}

Будут возвращены два сохранённых и последнее существующее значение на метку времени finish:

Ответ:

{
  "data": [
    {
      "tagId": "1500c712-726a-103e-9264-a5021ec2dae1",
      "data": [
        [5, "09:45:00", null],
        [4, "09:50:00", null],
        [4, "09:52:30", null]
      ]
    }
  ]
}

Ключи count и start

Совместное использование ключей count и start похоже на случай совместного использования ключей finish и count за исключением того, что мы ограничиваем не конец периода, а начало.

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

_images/fromAndCount.png

Запрос count = 1:

{
  "tagId": "1500c712-726a-103e-9264-a5021ec",
  "format": true,
  "start": "09:42:30",
  "count": 1
}

Ответ:

{
  "data": [
    {
      "tagId": "1500c712-726a-103e-9264-a5021ec2dae1",
      "data": [
        [3.3, "09:42:30", null]
      ]
    }
  ]
}

Запрос count = 2:

{
  "tagId": "1500c712-726a-103e-9264-a5021ec",
  "format": true,
  "start": "09:42:30",
  "count": 2
}

Ответ:

{
  "data": [
    {
      "tagId": "1500c712-726a-103e-9264-a5021ec2dae1",
      "data": [
        [3.3, "09:42:30", null],
        [5, "09:45:00", null]
      ]
    }
  ]
}

Запрос count = 3:

{
  "tagId": "1500c712-726a-103e-9264-a5021ec",
  "format": true,
  "start": "09:42:30",
  "count": 3
}

Ответ:

{
  "data": [
    {
      "tagId": "1500c712-726a-103e-9264-a5021ec2dae1",
      "data": [
        [3.3, "09:42:30", null],
        [5, "09:45:00", null],
        [4, "09:50:00", null]
      ]
    }
  ]
}

Запрос count = 4:

{
  "tagId": "1500c712-726a-103e-9264-a5021ec",
  "format": true,
  "start": "09:42:30",
  "count": 4
}

Ответ:

{
  "data": [
    {
      "tagId": "1500c712-726a-103e-9264-a5021ec2dae1",
      "data": [
        [3.3, "09:42:30", null],
        [5, "09:45:00", null],
        [4, "09:50:00", null],
        [4, "09:52:30", null]
      ]
    }
  ]
}

Запрос count = 5: ответ будет в точности таким же, как предыдущий.

Давайте переместим текущую метку времени:

_images/fromAndCount2.png

Запрос count = 3:

{
  "tagId": "1500c712-726a-103e-9264-a5021ec",
  "format": true,
  "start": "09:42:30",
  "count": 3
}

Ответ:

{
  "data": [
    {
      "tagId": "1500c712-726a-103e-9264-a5021ec2dae1",
      "data": [
        [3.3, "09:42:30", null],
        [5, "09:45:00", null],
        [4.5, "09:47:30", null]
      ]
    }
  ]
}

Запрос count = 4: ответ будет таким же, как предыдущий в связи с правилом 10, вне зависимости от того, что существует значение с меткой времени в будущем (09:50:00).

Ключ timeStep

Ключ timeStep устанавливает временнОй период между соседними возвращаемыми значениями. Используйте этот ключ совместно с ключом count.

Значения ключа timeStep измеряется в микросекундах.

timeStep и count

Как определено в правиле 2, значение по умолчанию ключа finish - текущая метка времени.

_images/timeStepAndCount.png

Запрос (timeStep равен 5 минутам):

{
  "tagId": "1500c712-726a-103e-9264-a5021ec",
  "format": true,
  "timeStep": 300000000,
  "count": 3
}

Ответ:

{
  "data": [
    {
      "tagId": "1500c712-726a-103e-9264-a5021ec2dae1",
      "data": [
        [3.7, "09:42:30", null],
        [4.5, "09:47:30", null],
        [4, "09:52:30", null]
      ]
    }
  ]
}

Теперь рассмотрим тот же запрос, но выполненный в момент времени 10:05:

_images/timestep_count_2.png

Запрос (timeStep равен 5 минутам):

{
  "tagId": "1500c712-726a-103e-9264-a5021ec",
  "format": true,
  "timeStep": 300000000,
  "count": 3
}

Ответ:

{
  "data": [
    {
      "tagId": "1500c712-726a-103e-9264-a5021ec2dae1",
      "data": [
        [4, "09:55:00", null],
        [4, "10:00:00", null],
        [4, "10:05:00", null]
      ]
    }
  ]
}

Запрос (count = 6):

{
  "tagId": "1500c712-726a-103e-9264-a5021ec",
  "format": true,
  "timeStep": 300000000,
  "count": 6
}

Ответ:

{
  "data": [
    {
      "tagId": "1500c712-726a-103e-9264-a5021ec2dae1",
      "data": [
        [null, "09:27:30", null],
        [2, "09:32:30", null],
        [2.725, "09:37:30", null],
        [3.3, "09:42:30", null],
        [4.5, "09:47:30", null],
        [4, "09:52:30", null]
      ]
    }
  ]
}

timeStep, count и finish

Поведение запросов с ключами timeStep, count и finish такое же, как в предыдущих примерх, за исключением того, что ключ finish явно задаёт окончание периода.

timeStep, count и start

В этом случае ключ finish вычисляется в соответствии с правилом 12.

_images/timeStepFromCount.png

Запрос (timeStep равен 5 минутам):

{
  "tagId": "1500c712-726a-103e-9264-a5021ec",
  "format": true,
  "start": "09:35:00",
  "timeStep": 300000000,
  "count": 4
}

Ответ:

{
  "data": [
    {
      "tagId": "1500c712-726a-103e-9264-a5021ec2dae1",
      "data": [
        [3, "09:35:00", null],
        [2.5, "09:40:00", null],
        [4.5, "09:45:00", null]
      ]
    }
  ]
}

Несмотря на то, что ключ count равен 4, возвращено только 3 значения, т.к. еще одно значение, имеющееся в базе, относится к будущему.

timeStep, start и finish

_images/timeStepFromTo.png

Запрос (timeStep равен 5 минутам):

{
  "tagId": "1500c712-726a-103e-9264-a5021ec",
  "format": true,
  "start": "09:35:00",
  "finish": "09:42:30",
  "timeStep": 300000000
}

Ответ:

{
  "data": [
    {
      "tagId": "1500c712-726a-103e-9264-a5021ec2dae1",
      "data": [
        [3, "09:35:00", null],
        [2.5, "09:40:00", null]
      ]
    }
  ]
}

Запрос (timeStep равен 10 минутам):

{
  "tagId": "1500c712-726a-103e-9264-a5021ec",
  "format": true,
  "start": "09:35:00",
  "finish": "09:42:30",
  "timeStep": 600000000
}

Ответ:

{
  "data": [
    {
      "tagId": "1500c712-726a-103e-9264-a5021ec2dae1",
      "data": [
        [3, "09:35:00", null]
      ]
    }
  ]
}

Ключ maxCount

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

Представим тренд на экране. Его ширина - 800 пикселей. Это значит, что тренд может отрисовать не более 800 значений по оси x.

Тренд устанавливает ключ maxCount в 800, при любом запросе на получение данных. Если в хранилище больше, чем 800 значений за выбранный период, платформа установит в ответе ключ excess в true и вернёт только 800 значений.

Примечание

maxCount имеет приоритет над count.

Примечание

Использование ключа maxCount предотвращает крах платформы и повышает скорость работы. Установка этого ключа не обязательна, но рекомендуется.

Ключ actual

Если ключ actual установлен в true, выводятся только данные, находящиеся в базе данных без интерполяции/присвоения на границах диапазона. По умолчанию ключ actual установлен в false. Если ключ actual установлен в true, ключ timeStep не учитывается.

Ниже представлены случаи использования ключа actual с различными комбинациями других ключей.

start и actual

В этом случае возвращаются данные от метки времени, заданной start, до текущего момента времени. Если на метку start и/или на текущий момент времени данных нет, на эти метки времени ничего не возвращается.

_images/fromAndCountActual.png

Запрос:

{
  "tagId": "1500c712-726a-103e-9264-a5021ec",
  "format": true,
  "start": "09:32:00",
  "actual": true
}

Ответ:

{
  "data": [
    {
      "tagId": "1500c712-726a-103e-9264-a5021ec2dae1",
      "data": [
        [3, "09:35:00", null],
        [2.5, "09:40:00", null],
        [5, "09:45:00", null],
        [4, "09:50:00", null]
      ]
    }
  ]
}

start, count, actual

Возвращаются данные в количестве, заданном в count. Если данных в базе меньше, чем задано в count, возвращаются только имеющиеся данные.

_images/fromAndCountActual.png

Запрос:

{
  "tagId": "1500c712-726a-103e-9264-a5021ec",
  "format": true,
  "start": "09:32:00",
  "count": 3,
  "actual": true
}

Ответ:

{
  "data": [
    {
      "tagId": "1500c712-726a-103e-9264-a5021ec2dae1",
      "data": [
        [3, "09:35:00", null],
        [2.5, "09:40:00", null],
        [5, "09:45:00", null]
      ]
    }
  ]
}

Запрос:

{
  "tagId": "1500c712-726a-103e-9264-a5021ec",
  "format": true,
  "start": "09:32:00",
  "count": 10,
  "actual": true
}

Ответ:

{
  "data": [
    {
      "tagId": "1500c712-726a-103e-9264-a5021ec2dae1",
      "data": [
        [3, "09:35:00", null],
        [2.5, "09:40:00", null],
        [5, "09:45:00", null],
        [4, "09:50:00", null]
      ]
    }
  ]
}

actual и finish

В этом случае возвращается значение на метку времени finish или последнее имеющееся значение перед меткой времени finish с соответствующей меткой времени, если значения на метку времени finish нет.

_images/toAndCountActual.png

Запрос:

{
  "tagId": "1500c712-726a-103e-9264-a5021ec",
  "format": true,
  "finish": "09:47:30",
  "actual": true
}

Ответ:

{
  "data": [
    {
      "tagId": "1500c712-726a-103e-9264-a5021ec2dae1",
      "data": [
        [5, "09:45:00", null]
      ]
    }
  ]
}

finish, count, actual

Возвращаются данные в количестве, заданном в count, от метки времени finish. Если данных в базе меньше, чем задано в count, возвращаются только имеющиеся данные.

_images/toAndCountActual.png

Запрос:

{
  "tagId": "1500c712-726a-103e-9264-a5021ec",
  "format": true,
  "finish": "09:47:30",
  "count": 3,
  "actual": true
}

Ответ:

{
  "data": [
    {
      "tagId": "1500c712-726a-103e-9264-a5021ec2dae1",
      "data": [
        [3, "09:35:00", null],
        [2.5, "09:40:00", null],
        [5, "09:45:00", null]
      ]
    }
  ]
}

start, finish, actual

В этом случае возвращаются имеющиеся в базе данные от метки времени start до метки времени finish.

_images/period_fromAndToRealActual.png

Запрос:

{
  "tagId": "1500c712-726a-103e-9264-a5021ec",
  "format": true,
  "start": "09:32:30",
  "finish": "09:47:30",
  "actual": true
}

Ответ:

{
  "data": [
    {
      "tagId": "1500c712-726a-103e-9264-a5021ec2dae1",
      "data": [
        [3, "09:35:00", null],
        [2.5, "09:40:00", null],
        [5, "09:45:00", null]
      ]
    }
  ]
}

start, finish, count, actual

Возвращаются данные в количестве, заданном в count. Если данных в базе меньше, чем задано в count, возвращаются только имеющиеся данные.

_images/period_fromAndToRealActual.png

Запрос:

{
  "tagId": "1500c712-726a-103e-9264-a5021ec",
  "format": true,
  "start": "09:32:30",
  "finish": "09:47:30",
  "count":2,
  "actual": true
}

Ответ:

{
  "data": [
    {
      "tagId": "1500c712-726a-103e-9264-a5021ec2dae1",
      "data": [
        [3, "09:35:00", null],
        [2.5, "09:40:00", null]
      ]
    }
  ]
}

Запрос:

{
  "tagId": "1500c712-726a-103e-9264-a5021ec",
  "format": true,
  "start": "09:32:30",
  "finish": "09:47:30",
  "count":10,
  "actual": true
}

Ответ:

{
  "data": [
    {
      "tagId": "1500c712-726a-103e-9264-a5021ec2dae1",
      "data": [
        [3, "09:35:00", null],
        [2.5, "09:40:00", null],
        [5, "09:45:00", null]
      ]
    }
  ]
}

start, finish, maxCount, actual

Возвращаются данные в количестве, заданном в maxCount. Если данных в базе меньше, чем задано в maxCount, возвращаются все данные из базы и флаг excess устанавливается в false. Если данных в базе больше, чем задано в maxCount, интервал времени разбивается на отрезки в соответствии с maxCount. Данные интерполируются/заполняются. Если на метку start нет данных, возвращается null. Если на метку finish нет данных, возвращается последнее имеющееся значение перед меткой времени finish.

_images/period_fromAndToRealActual.png

Запрос:

{
  "tagId": "1500c712-726a-103e-9264-a5021ec",
  "format": true,
  "start": "09:32:30",
  "finish": "09:47:30",
  "maxCount": 10,
  "actual": true
}

Ответ:

{
  "data": [
    {
      "tagId": "1500c712-726a-103e-9264-a5021ec2dae1",
      "data": [
        [3, "09:35:00", null],
        [2.5, "09:40:00", null],
        [5, "09:45:00", null],
      ]
    }
  ]
}

Запрос:

{
  "tagId": "1500c712-726a-103e-9264-a5021ec",
  "format": true,
  "start": "09:32:30",
  "finish": "09:47:30",
  "maxCount": 2,
  "actual": true
}

Ответ:

{
  "data": [
    {
      "excess": true,
      "tagId": "1500c712-726a-103e-9264-a5021ec2dae1",
      "data": [
        [null, "09:32:30", null],
        [5, "09:47:30", null]
      ]
    }
  ]
}

Ключ value

Ключ value используется для фильтрации запрошенных данных. Применяется в том случае, когда необходимо получить конкретные значения тэга.

_images/value.png

Запрос:

{
  "tagId": "1500c712-726a-103e-9264-a5021ec",
  "format": true,
  "start": "09:32:30",
  "value": [3]
}

Ответ:

{
  "data": [
    {
      "tagId": "1500c712-726a-103e-9264-a5021ec2dae1",
      "data": [
        [3, "09:35:00", null],
        [3, "09:42:00", null]
      ]
    }
  ]
}

Запрос:

{
  "tagId": "1500c712-726a-103e-9264-a5021ec",
  "format": true,
  "start": "09:32:30",
  "value": [3, 4]
}

Ответ:

{
  "data": [
    {
      "tagId": "1500c712-726a-103e-9264-a5021ec2dae1",
      "data": [
        [3, "09:35:00", null],
        [3, "09:41:00", null],
        [4, "09:43:00", null],
        [4, "09:50:00", null],
        [4, "09:53:00", null]
      ]
    }
  ]
}

value и actual

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

Запрос:

{
  "tagId": "1500c712-726a-103e-9264-a5021ec",
  "format": true,
  "start": "09:32:30",
  "value": [3, 4],
  "actual": true
}

Ответ:

{
  "data": [
    {
      "tagId": "1500c712-726a-103e-9264-a5021ec2dae1",
      "data": [
        [3, "09:35:00", null],
        [4, "09:50:00", null]
      ]
    }
  ]
}

null в истории данных

Важным моментом при работе с данными является случай, когда значением тэга является null.

Получение значения null в качестве данных тэга возможно, в первую очередь, тогда, когда тэг создан и в его историю ещё ничего не записано (для этого атрибут тэга smtTagDefaultValue должен быть пустым).

Кроме того, значение null записывается в тэг, когда:

  1. Тэг привязан к источнику данных и с коннектором, записывающим данные в тэг, рвётся связь. В этом случае Платформа запишет в тэг значение null, код качества значения q = 100.

  2. Платформа завершает работу. В этом случае во все тэги записывается значение null, код качества значения q = 101.

  3. Тэг привязан к источнику данных и у коннектора рвётся связь с поставщиком данных. В этом случае коннектор запишет в тэг значение null с кодом качества значения q = 102.

  4. Тэг привязан к источнику данных и коннектор получает от поставщика данных значение null.

  5. В тэг было записано значение null командой data/set.

Считается, что с момента записи в тэг значения null до записи следующего значения мы ничего не знаем о данных тэга, в них как бы образовывается дыра. Поэтому значения тэга не интерполируются на этом промежутке.

При запросе данных за период null возвращается клиенту, если попадает в этот промежуток.

На картинке ниже показывается, как интерпретируются данные в случае, если в истории есть null.

_images/withNull.png

Далее - несколько примеров запросов к данным, показанным на картинке выше с ответами.

_images/withNull2.png
{
  "tagId": "1500c712-726a-103e-9264-a5021ec",
  "format": true,
  "start": "09:30:00",
  "finish": "09:50:00"
}

Ответ без ``null``:

{
  "data": [
    {
      "tagId": "1500c712-726a-103e-9264-a5021ec2dae1",
      "data": [
        [1, "09:30:00", null],
        [3, "09:35:00", null],
        [2.5, "09:40:00", null],
        [5, "09:45:00", null],
        [4, "09:50:00", null]
      ]
    }
  ]
}

Ответ с ``null``:

{
  "data": [
    {
      "tagId": "1500c712-726a-103e-9264-a5021ec2dae1",
      "data": [
        [1, "09:30:00", null],
        [3, "09:35:00", null],
        [null, "09:37:00", null],
        [2.5, "09:40:00", null],
        [5, "09:45:00", null],
        [4, "09:50:00", null]
      ]
    }
  ]
}
_images/withNull3.png
{
  "tagId": "1500c712-726a-103e-9264-a5021ec",
  "format": true,
  "start": "09:32:30",
  "finish": "09:39:00"
}

Ответ без ``null``:

{
  "data": [
    {
      "tagId": "1500c712-726a-103e-9264-a5021ec2dae1",
      "data": [
        [2, "09:32:30", null],
        [3, "09:35:00", null],
        [2.6, "09:39:00", null]
      ]
    }
  ]
}

Ответ с ``null``:

{
  "data": [
    {
      "tagId": "1500c712-726a-103e-9264-a5021ec2dae1",
      "data": [
        [2, "09:32:30", null],
        [3, "09:35:00", null],
        [null, "09:37:00", null],
        [null, "09:39:00", null]
      ]
    }
  ]
}
_images/withNull4.png
{
  "tagId": "1500c712-726a-103e-9264-a5021ec",
  "format": true,
  "start": "09:38:00",
  "finish": "09:39:00"
}

Ответ без ``null``:

{
  "data": [
    {
      "tagId": "1500c712-726a-103e-9264-a5021ec2dae1",
      "data": [
        [2.7, "09:38:00", null],
        [2.6, "09:39:00", null]
      ]
    }
  ]
}

Ответ с ``null``:

{
  "data": [
    {
      "tagId": "1500c712-726a-103e-9264-a5021ec2dae1",
      "data": [
        [null, "09:38:00", null],
        [null, "09:39:00", null]
      ]
    }
  ]
}

Сделаем запрос с флагом timeStep в 4 минуты:

_images/timestep_none_1.png
{
  "tagId": "1500c712-726a-103e-9264-a5021ec",
  "format": true,
  "start": "09:32:00",
  "finish": "09:43:00",
  "timeStep": 240000000
}

Ответ без ``null``:

{
  "data": [
    {
      "tagId": "1500c712-726a-103e-9264-a5021ec2dae1",
      "data": [
        [1.8, "09:32:00", null],
        [2.9, "09:36:00", null],
        [2.5, "09:40:00", null]
      ]
    }
  ]
}

Ответ с ``null``:

{
  "data": [
    {
      "tagId": "1500c712-726a-103e-9264-a5021ec2dae1",
      "data": [
        [1.8, "09:32:00", null],
        [3, "09:36:00", null],
        [2.5, "09:40:00", null]
      ]
    }
  ]
}

Теперь сделаем запрос с флагом timeStep в 2 минуты:

_images/timestep_none_2.png
{
  "tagId": "1500c712-726a-103e-9264-a5021ec",
  "format": true,
  "start": "09:32:00",
  "finish": "09:43:00",
  "timeStep": 120000000
}

Ответ без ``null``:

{
  "data": [
    {
      "tagId": "1500c712-726a-103e-9264-a5021ec2dae1",
      "data": [
        [1.8, "09:32:00", null],
        [2.6, "09:34:00", null],
        [2.9, "09:36:00", null],
        [2.7, "09:38:00", null],
        [2.5, "09:40:00", null],
        [3.5, "09:42:00", null]
      ]
    }
  ]
}

Ответ с ``null``:

{
  "data": [
    {
      "tagId": "1500c712-726a-103e-9264-a5021ec2dae1",
      "data": [
        [1.8, "09:32:00", null],
        [2.6, "09:34:00", null],
        [3, "09:36:00", null],
        [null, "09:38:00", null],
        [2.5, "09:40:00", null],
        [3.5, "09:42:00", null]
      ]
    }
  ]
}