An open API service indexing awesome lists of open source software.

https://github.com/apostoldevel/process-streamserver

Process: Stream Server
https://github.com/apostoldevel/process-streamserver

Last synced: 3 months ago
JSON representation

Process: Stream Server

Awesome Lists containing this project

README

        

Потоковый сервер (Streaming server)
-
**Модуль** для [Апостол CRM](https://github.com/apostoldevel/apostol-crm).

Установка
-
Следуйте указаниям по сборке и установке [Апостол CRM](https://github.com/apostoldevel/apostol-crm#%D1%81%D0%B1%D0%BE%D1%80%D0%BA%D0%B0-%D0%B8-%D1%83%D1%81%D1%82%D0%B0%D0%BD%D0%BE%D0%B2%D0%BA%D0%B0)

Описание
-
**Сервер потоковых данных** предназначен для приёма и передачи данных с мобильных устройств и интернет вещей.

Протокол
-

Протокол разработан без привязки к определенному устройству.

### Терминология

* **Пакет** – единица передачи информации на уровне канала передачи данных.

* **Команда** – единица передачи информации прикладного уровня. Если команда длинная, она разбивается на пакеты.

Команда состоит из объединенных данных пакетов. Объединение выполняется от начального до конечного пакета в порядке возрастания номера пакета.

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

Если тип устройства неопределенный и идентификатор пустой, то это широковещательный пакет.

#### Общая структура пакета

Поле | Размер поля | Тип данных | Назначение, примечания
----- | ----------- | ---------- | ----------------------
Длина пакета | 1 или 2 байта. | length | Длина всего пакета (все поля кроме поля длины) в байтах.
Версия протокола | 1 байт | uint8 | Текущая версия = 1.
Параметры | 1 байт | bin | 0 бит – начальный пакет команды; 1 бит – конечный пакет команды; 2 бит – пакет к устройству; 3 бит – ответ на запрос.
Тип устройства | 1 байт | device_type | 0xA0 - IoT, 0xA1, 0xA2 - Мобильные устройства.
Размер серийного номера | 1 байт | uint8 | В байтах.
Серийный номер | ... | utf8 | Пример: ABC-012345678
Номер команды | 1 байт | uint8 | Циклически от 0 до 255. При ответе на запрос подставляется из запроса.
Номер пакета | 1 байт | uint8 | Номер пакета команды 0-255 (для каждой команды от 0).
Данные пакета | ... | ... |
Контрольная сумма | 2 байта | crc16 | Все поля кроме контрольной суммы.

#### Структура команды от устройства

Поле | Размер поля | Тип данных | Назначение, примечания
----- | ----------- | ---------- | ----------------------
Метка времени | 4 байта | time | Текущее время устройства: 0 – неопределенное время, 1 – ошибка времени.
Тип команды | 1 байт | uint8 | 0x01 – Текущее состояние истройства и т.д.
Код ошибки | 1 байт | uint8 | См. ниже. Если есть ошибка, то поле "Данные команды" отсутствует.
Данные команды | ... | ... | Формат и размер зависит от типа команды.

Тип команды ответа на запрос равен типу команды запроса со сброшенным старшим битом.
Например: запрос 0x81 – ответ 0x01, запрос 0x82 – ответ 0x02 и т.д.

Код ошибки:
* 0 - Нет ошибки;
* 1 - Неопределенная ошибка;
* 2 - Неизвестная команда;
* 3 - Некорректный формат команды;
* 4 - Некорректные параметры команды.

#### Структура команды к устройству

Поле | Размер поля | Тип данных | Назначение, примечания
----- | ----------- | ---------- | ----------------------
Тип команды | 1 байт | uint8 | 0x82 – запрос прозрачных данных и т.д.
Данные команды | ... | ... | Формат и размер зависит от типа команды.

### Типы команд

#### Текущее состояние устройства

**Команда**: `0x01`

* Посылается, если нет обмена в течении периода, заданного в конфигурации и в ответ на запрос "Запрос текущего состояния".

Поле | Размер поля | Тип данных | Назначение, примечания
----- | ----------- | ---------- | ----------------------
Состояние | 2 байта | device_state |
Текущий тариф | 1 байт | uint8 | 1, 2 и т.д. 0 – текущий тариф не задан.
Время последнего конфигурирования | 4 байта | time | 0 – конфигурирование не проводилось, 1 – ошибка времени при последнем конфигурировании.
Тип последней синхронизации времени | 1 байт | time_sync |
Время последней синхронизации времени | 4 байта | time | 0 – синхронизация не проводилась, 1 – ошибка времени при последней синхронизации времени.

#### Текущие значения устройства

**Команда**: `0x04`

Поле | Размер поля | Тип данных | Назначение, примечания
----- | ----------- | ---------- | ----------------------
Количество значений | 1 байт | uint8 | Количество текущих значений.
Для каждого значения: | |
Тип значения | 1 байт | value_type |
Размер значения | 1 байт | uint8 | В байтах.
Текущее значение | ... | ... | Формат зависит от типа значения.

#### Пример пакета

Команда `0x01` [Текущее состояние устройства](#текущее-состояние-устройства).
- Номер команды: `0xF0` (int8);
- Серийный номер: `1234` (utf8);
- Время: `2020-01-01 08:09:10` (time);
- Нет ошибок: `0x00` (int8);
- Время последней синхронизации времени: `2020-01-01 08:09:00` (time).

Команда в шестнадцатеричном виде:
````
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31
1E 01 03 06 04 31 32 33 34 F0 00 A6 53 0C 5E 01 00 00 00 04 00 00 00 00 02 9C 53 0C 5E 3E C7
│ │ │ │ │ │ │ │ ├──┐ │ │ │ │ │ │ │ └─ CRC16
│ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ └─ Время последней синхронизации времени: 5E0C539C₁₆ -> 1577866140₁₀ -> 2020-01-01T08:09:00+00:00
│ │ │ │ │ │ │ │ │ │ │ │ │ │ │ └─ Тип последней синхронизации времени: 0x02 - NTP синхронизация
│ │ │ │ │ │ │ │ │ │ │ │ │ │ └─ Время последнего конфигурирования: 0 – конфигурирование не проводилось
│ │ │ │ │ │ │ │ │ │ │ │ │ └─ Текущий тариф: 4
│ │ │ │ │ │ │ │ │ │ │ │ └─ Состояние: 0 (2 байта)
│ │ │ │ │ │ │ │ │ │ │ └─ Код ошибки: 0 (Нет ошибки)
│ │ │ │ │ │ │ │ │ │ └─ Тип команды: 0x01 (Текущее состояние)
│ │ │ │ │ │ │ │ │ └─ Метка времени: 5E0C53A6₁₆ -> 1577866150₁₀ -> 2020-01-01T08:09:10+00:00
│ │ │ │ │ │ │ │ └─ Данные пакета
│ │ │ │ │ │ │ └─ Номер пакета
│ │ │ │ │ │ └─ Номер команды
│ │ │ │ │ └─ Серийный номер
│ │ │ │ └─ Размер серийного номера
│ │ │ └─ Тип устройства
│ │ └─ Параметры: 03 -> 00000011 - начальный и конечный пакет команды
│ └─ Версия протокола
└─ Длина пакета: 1E - 30 байт (все поля кроме поля длины).
````

Команда `0x04` [Текущие значения устройства](#текущие-значения-устройства).
- Номер команды: `0x01` (int8);
- Серийный номер: `ABCD1234` (utf8);
- Время: `2020-11-01 02:03:04` (time);
- Заряд батареи: `87%` (int16);
- Широта: `55.754157803652780` (decimal_degree);
- Долгота: `37.620306072829976` (decimal_degree).

Команда в шестнадцатеричном виде:
````
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48
2F 01 03 A1 08 41 42 43 44 31 32 33 34 01 00 58 17 9E 5F 04 00 03 00 02 FC 21 01 08 1F 5B 2F 3E 88 E0 4B 40 02 08 50 28 7C 30 66 CF 42 40 14 49
│ │ │ │ │ │ │ │ ├──┐ │ │ │ │ │ │ │ │ │ │ │ │ └─ CRC16: 0x4914 -> 18708
│ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ └─ 4042CF66307C2850₁₆ -> 37.620306072829976₁₀
│ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ └─ Размер значения: 8 байт
│ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ └─ Тип значения: 2 - Долгота
│ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ └─ 404BE0883E2F5B1F₁₆ -> 55.754157803652780₁₀
│ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ └─ Размер значения: 8 байт
│ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ └─ Тип значения: 1 - Широта
│ │ │ │ │ │ │ │ │ │ │ │ │ │ │ └─ 21FC₁₆ -> 8700
│ │ │ │ │ │ │ │ │ │ │ │ │ │ └─ Размер значения: 2 байта
│ │ │ │ │ │ │ │ │ │ │ │ │ └─ Тип значения: 0 - Заряд батареи
│ │ │ │ │ │ │ │ │ │ │ │ └─ Количество значений: 3
│ │ │ │ │ │ │ │ │ │ │ └─ Код ошибки: 0 (Нет ошибки)
│ │ │ │ │ │ │ │ │ │ └─ Тип команды: 0x04 (Текущие значения устройства)
│ │ │ │ │ │ │ │ │ └─ Метка времени: 5F9E1758₁₆ -> 1604196184₁₀ -> 2020-11-01T02:03:04+00:00
│ │ │ │ │ │ │ │ └─ Данные пакета
│ │ │ │ │ │ │ └─ Номер пакета
│ │ │ │ │ │ └─ Номер команды
│ │ │ │ │ └─ Серийный номер: ABCD1234
│ │ │ │ └─ Размер серийного номера: 8
│ │ │ └─ Тип устройства: 0xA1 - Мобильное устройство на ОС Android
│ │ └─ Параметры: 03 -> 00000011 - начальный и конечный пакет команды
│ └─ Версия протокола: 1
└─ Длина пакета: 2F - 47 байт (все поля кроме поля длины).
````

### Типы данных

* Все типы данных передаются младшим байтом вперед.

**uint8**, **uint16**, **uint32**, **uint64** – тип данных, целочисленный беззнаковый двоичный, длиной 1, 2, 4, 8 байт соответственно.

**uint48** – целочисленный беззнаковый двоичный, длиной 6 байт. Аналогичен типу uint64 без двух старших байтов.

**uint24** – целочисленный беззнаковый двоичный, длиной 3 байта. Аналогичен типу uint32 без старшего байта.

**int8**, **int16** – тип данных, целочисленный знаковый двоичный, длиной, 1 или 2, байта соответственно (дополнительный код)

**bool** – логический тип, 1 байт, 0 - false, 1 - true

**time** - тип данных для отображения времени, принятый в UNIX-системах - time_t (uint32, количество секунд с 1970-01-01 00:00:00). Локальное время.

**utf8** – строка в кодировке UTF-8

**length** – длина данных (1 или 2 байта). 1 байт: 0-6 бит – младшие биты длины, 7 бит – длина данных 2 байта). 2 байт: присутствует если установлен 7 бит первого байта, 0-7 бит – старшие биты длины.

**crc16** - полином x16 + x15 + x2 + 1 (CRC16, Modbus). Пример расчета [CRC16](#crc16)

**freq** – частота (uint16). Герц *100 (12345 -> 123.45 Герц)

**temper** – температура (int8), градусы Цельсия

**degree** – градусы (uint16)

**decimal_degree** – десятичные градусы (ieee754_64)

**percent** – проценты (uint16), проценты *100 (10000 -> 100.00%)

**meter_second** - метры в секунду

**ieee754_32** - [IEEE 754](https://www.softelectro.ru/ieee754.html) - стандарт двоичной арифметики с плавающей точкой (32 бита)

**ieee754_64** - [IEEE 754](https://www.softelectro.ru/ieee754.html) - стандарт двоичной арифметики с плавающей точкой (64 бита)

**time_sync** – тип синхронизации времени:
* 0x00 - Не определенная;
* 0x01 - Ручная синхронизация с помощью команд "Установка времени";
* 0x02 - NTP синхронизация.

**device_type** - тип устройства:
* 0xA0 - IoT (Интернет вещь)
* 0xA1 - Мобильное устройство на ОС Android
* 0xA2 - Мобильное устройство на ОС iOS

**value_type** – тип значения (1 байт):
* 0 - Заряд батареи (percent)
* 1 - Широта - latitude (decimal_degree)
* 2 - Долгота - longitude (decimal_degree)
* 3 - Высота над уровнем моря - altitude (meter)
* 4 - Точность свойств latitude и longitude (meter)
* 5 - Точность свойства altitude (meter)
* 6 - В каком направлении движется устройство (degree)
* 7 - Скорость движения устройства (meter_second)

#### CRC16

* Примеры вычисления контрольной суммы CRC16.

На языке C#:
````csharp
/// CRC16 calculation
public static ushort Crc16(byte[] buffer, long index, long count)
{
int crc = 0xFFFF;

for (long i = index; i < index + count; i++)
{
crc = crc ^ buffer[i];

for (int j = 0; j < 8; ++j)
{
if ((crc & 0x01) == 1)
crc = (crc >> 1 ^ 0xA001);
else
crc >>= 1;
}
}
return (ushort)crc;
}
````