Перейти к содержанию

Структура шаблонов


Modbus FS - Структура шаблонов

Описание структуры, параметров и правил для создания и редактирования Modbus шаблонов

Группы параметров (секции)

Файл шаблона разделён на секции (или группы), каждая из которых содержит ряд связанных параметров.

Всего поддерживается несколько типов секций:

  • [main] - базовая секция. Содержит версию шаблона.
  • [sensors] - секция датчиков. В основном используется для чтения данных с Modbus-устройств.
  • [gpio]- секция для управления дискретными значениями
  • [pwm]- секция для управления числовыми значениями (💫 Beta)

В одном шаблоне может быть несколько секций одного типа.

Все секции, кроме [main] - не обязательные. Например, если в устройстве нет необходимости использовать дискретные входы/выходы, то просто опускаем секцию [gpio].

Далее разберём структуру шаблонов на примере шаблона для популярного датчика WB-MSW от компании Wiren Board.
Также для справки понадобится карта Modbus-регистров этого датчика.
Полный текст шаблона для датчика WB-MSW представлен в каталоге шаблонов.

Базовая секция - [main]

Пример
[main]
ver=1
🔸 ver - номер версии шаблона

Этот же номер указывается в файле modbus.list. Номер версии в modbus.list указывается после имени шаблона через ; (имя шаблона = имя файла без расширения).

Подробнее про версии и механизм обновления шаблонов см. раздел Обновление шаблонов с сервера

Секция датчиков - [sensors]

Пример
// Уровень шума, Температура, Влажность
[sensors] 
typereg=0x04 ; (1)!
startreg=0x0003 ; (2)!
cntreg=3 ; (3)!
mask=r1d2,rd2t3,rd2t4 ; (4)!
  1. 🔍 Тип регистров: Input
  2. 🔍 Читаем регистры с адреса 0x0003
  3. 🔍 Количество регистров для чтения - 3
  4. 🔍 Расшифровка маски:
    • r1d2 0x0003 - Уровень шума, x0.01, дБ
      • r1 - читаем один регистр,
      • d2 - сразу учитываем что в регистре хранится значение умноженное на 100, и нам надо "переставить" запятую в числе на 2 знака влево
    • rd2t3 0x0004 - Температура, x0.01, °C
      • r - читаем один регистр,
      • d2 - учитываем что последние 2 цифры в значении регистра - это дробная часть
      • t3 - тип метрики "Температура"
    • rd2t4 0x0005 - Относительная влажность, x0.01, %RH
      • t4 - всё аналогично предыдущему, только тип метрики "Влажность"

Секция [sensors] предназначена для чтения данных из Modbus устройств.

В шаблоне может быть несколько секций [sensors].
Каждая секция читает определённую область Modbus регистров.

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

Количество переменных (метрик), читаемое во всех секциях [sensors]
в рамках одного шаблона не должно превышать 50.

Количество устройств задаётся на этапе подготовки прошивки,
в поле Количество устройств (для всех режимов)

Параметры секции [sensors]:

🔸 typereg - тип регистров
  • 3 или 0x03 - Holding Registers (RW)
  • 4 или 0x04 - Input Registers (RO)
🔸 startreg - начальный адрес области регистров
Может быть указан в формате как hex, так и десятичное (например, 0x0080, 0x80, 128)
🔸 cntreg - количество регистров в области
Может быть как hex, так и десятичное
🔸 mask - поле маски
Правила формирования маски описаны в следующем разделе.
Пример: mask=r2d2,r2
Пример с дополнительными математическими вычислениями: mask=r2d2[*16/10],r2

Формирование маски - поле mask

Пример значения поля маски в секции [sensors] для датчика WB-MSW
mask=r1d2,rd2t3,rd2t4 ; (1)!
  1. 🔍 Расшифровка маски:
    • r1d2 0x0003 - Уровень шума, x0.01, дБ
      • r1 - читаем один регистр,
      • d2 - сразу учитываем что в регистре хранится значение умноженное на 100, и нам надо "переставить" запятую в числе на 2 знака влево
    • rd2t3 0x0004 - Температура, x0.01, °C
      • r - читаем один регистр,
      • d2 - учитываем что последние 2 цифры в значении регистра - это дробная часть
      • t3 - тип метрики "Температура"
    • rd2t4 0x0005 - Относительная влажность, x0.01, %RH
      • t4 - всё аналогично предыдущему, только тип метрики "Влажность"

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

Маски для чтения значений переменных из устройства составляются по определённым правилам.
Поле mask может содержать несколько масок для переменных.
Маски для переменных перечисляются в поле mask через запятую.
При написании маски допустимо опускать число "1" (например, маски r1d2 и rd2 идентичны)

Параметры

Ниже описаны параметры, которые применяются для формирования маски для переменной:

Примечание. Параметры маски выделены значками:
🔸 - обязательный параметр; 🔹 - дополнительный параметр

🔸 rX, eX, gX - параметр маски, определяющий порядок и количество регистров
Описание параметра

Этот параметр задаёт правила для извлечения значения переменной из Modbus регистров

  • Символ - определяет порядок регистров при декодировании значения

    • r - обратный порядок регистров - little-endian
      Первый регистр - младшая часть в значении (внутри регистра - старший байт первый)

    • g - прямой порядок регистров - big-endian
      Первый регистр - старшая часть в значении (внутри регистра - старший байт первый)

    Дополнительная информация
    • если считывается один регистр (X = 1 или отсутствует) - обычно используется символ r
    • в случае, если значение занимает более одного регистра - символ определяет порядок чтения регистров (а также порядок байт внутри регистра)
    • в соответствии со стандартом, порядок байт внутри Modbus регистра всегда прямой. Но в редких случаях некоторые устройства имеют обратный порядок байт.

    Дополнительные варианты символов:

    • e - обратный порядок регистров + обратный (нестандартный) порядок байт
      Первый регистр - младшая часть в значении. Внутри регистра - младший байт первый.
  • Число X - задаёт количество Modbus-регистров

    • допустимые значения: 1, 2, 4
    • записи r1 и r идентичны (единицу можно не писать)
Пример использования

Пример чтения 32-битной переменной

Предположим, в Modbus-ответе на запрос чтения двух регистров пришли следующие данные:
AA BB CC DD
(2 регистра по 2 байта)

В результате применения различных масок получим следующие значения переменной:
(hex - шестнадцатеричное представление числа, dec - десятичное представление числа)

mask hex dec
g2 AABBCCDD 2864434397
r2 CCDDAABB 3437079227
e2 DDCCBBAA 3721182122

Пояснения:

  • g2 - прямой порядок регистров big-endian и прямой порядок байт
    Байты преобразуются в число в том же порядке, как они расположены в Modbus-ответе.
    То есть просто копируем байты из данных, не меняя порядок.

  • r2 - обратный порядок регистров little-endian и прямой порядок байт

  • e2 - обратный порядок регистров и обратный (нестандартный) порядок байт
    В значении все байты "переворачиваются" относительно исходного порядка данных.

🔹 dX - делитель /10, /100, /1000
Описание параметра

Добавляет запятую после нужного разряда

Параметр позволяет преобразовать целое значение переменной (после извлечения из регистров) в дробное значение:

  • d1 - вывод одного знака после запятой (значение переменной / 10)
  • d2 - вывод 2-х знаков после запятой (значение переменной / 100)
  • d3 - вывод 3-х знаков после запятой (значение переменной / 1000)

Например, значение регистра 1234 с маской r1d2 дает число 12,34

Если необходимо уменьшить точность, и совсем убрать знаки после запятой - нужно вместо параметра d использовать деление через математическое выражение. Например: для 32-разрядной переменной используем конструкцию вида: r2[/100], вместо r2d2

🔹 mX - множитель x10, x100, x1000
Описание параметра

Умножает значение переменной на множитель, кратный 10.
Значение множителя определяет X (max X=9)

  • m1 - x10
  • m2 - x100
  • m3 - x1000
  • ...

🔹 i - параметр указывает, что число имеет знак

🔹 f - float переменная
Описание параметра

Вывод значений с плавающей запятой из Modbus регистров

Используются подпараметры fa и fb в зависимости от порядка байт в устройстве.
Дополнительно можно указать количество знаков после запятой, по умолчанию 2.

🔹 l - модификатор типа: приводит 32 bit переменную к 16 bit r2l
Описание параметра

r2l - выражение такого вида служит для приведения 32-разрядных значений к 16 разрядам.
При этом старшая часть числа (старшие 16 бит) будет отброшена!

Внутреннее пространство переменных прошивки является 32-битным, но есть несколько опций, которые не имеют возможности полноценной работы с 32-битными значениями. Например переменные в опции "Термостат" и передаваемые метрики в опции "Lora" часто используют 16-битные значения. Модификатор "l" может быть полезен, когда нужно адаптировать данные с Modbus устройств под использование в подобных случаях.

Модификатор l может указываться также после делителя d.
Примеры идентичных масок с использованием модификатора: r2d2l, r2ld2

🔹 tX - указывает тип переменной (тип метрики)
Список типов метрик
  • t0 - неизвестный датчик c положительными (+) целыми значениями - 16 или 32 bit (uint16_t, uint32_t)
  • t3 - температура (Temperature), °C
  • t4 - относительная влажность (Humidity), %RH
  • t5 - давление (Pressure), mmHg
  • t6 - значение счётчика (Counter)
  • t7 - освещённость (Light), люкс (лк, lux)
  • t8 - концентрация CO2, ppm (миллионная доля)
  • t9 - напряжение (Voltage), В (V)
  • t10 - ток (Current), A
  • t11 - мощность (Power), Вт (W), (Ватт)
  • t12 - энергия (потребление электроэнергии), кВт*ч (Energy) (киловатт-час)
  • t14 - неизвестный датчик c знаковыми (+/-) целыми значениями - 16 или 32 bit со знаком (int16_t, int32_t)
  • t16 - уровень сигнала (RSSI), Дб (db)
  • t17 - заряд батареи (Battery), %
  • t18 - вес (Weight)
  • t19 - угол (Angle)
  • t20 - плодородие (Fertility)
  • t21 - расстояние (Distance)
  • t22 - радиация (Radiation)
  • t24 - частота (Frequency), Гц (Hz)
  • t25 - PMS1.0 (наличие частиц размером 0.3–1 мкм), мкг/м3 (mkg/m3)
  • t26 - PMS2.5 (наличие частиц размером 1–2.5 мкм), мкг/м3 (mkg/m3)
  • t27 - PMS10 (наличие частиц размером 2.5-10 мкм), мкг/м3 (mkg/m3)
  • t29 - качество воздуха (концентрация VOC), ppb (миллиардная доля)

Тип указывается в конце маски для переменной, пример: g2d2t7 - освещенность

🔹 sX - пропуск X регистров
Описание параметра

Иногда в области регистров, определяемой параметрами startreg, cntreg необходимы не все данные.
Чтобы пропустить часть регистров применяется параметр s с указанием количества регистров для пропуска (X).

Внимание! sX не сработает, если пропускаемых регистров не существует в устройстве!
В этом случае нужно будет создать новую секцию (например, [sensors]), и задать нужную область регистров с другими startreg, cntreg.

Математические выражения
Пример маски с дополнительными вычислениями
// обычная маска: mask=r2d2,r2

// добавляем умножение на коэффициент 1,6 для первой переменной
mask=r2d2[*16/10],r2

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

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

В поле mask возможно применение различных выражений для каждой из переменных по-отдельности.

Порядок выполнения операций - рассмотрим на примере: r2d2[*16/10-45/4]
Математические операции будут производиться последовательно слева-направо.
В примере происходят операции в следующей последовательности *16, /10, -45, /4

Интеграция с MQTT

Названия MQTT-топиков можно указывать в поле маски в фигурных скобках в конце каждого параметра.
Пропишем MQTT-топики для примера маски:

Пример значения поля маски в секции [sensors] для датчика WB-MSW
mask=r1d2{noise},rd2t3{temp},rd2t4{hum} ; (1)!
  1. 🔍 Расшифровка маски:
    • r1d2{noise} 0x0003 - Уровень шума, x0.01, дБ
      • r1 - читаем один регистр,
      • d2 - сразу учитываем что в регистре хранится значение умноженное на 100, и нам надо "переставить" запятую в числе на 2 знака влево
      • noise - имя MQTT топика
    • rd2t3{temp} 0x0004 - Температура, x0.01, °C
      • r - читаем один регистр,
      • d2 - учитываем что последние 2 цифры в значении регистра - это дробная часть
      • t3 - тип метрики "Температура"
      • temp - имя MQTT топика
    • rd2t4{hum} 0x0005 - Относительная влажность, x0.01, %RH
      • t4 - всё аналогично предыдущему, только тип метрики "Влажность"
      • hum - имя MQTT топика

Подробная расшифровка параметров доступна по значку с вопросом в коде примера выше

Допустим, мы настроили устройство на подключение к MQTT-серверу с логином (пользователем) user

Устройство названо TEST_DEVICE (это название высвечивается на главной, можно поменять во вкладке Main).
На вкладке ModBus настраиваем первое устройство - Device: 1

В итоге на MQTT сервер будут отсылаться данные в следующих топиках:

  • user/TEST_DEVICE/mb1/noise - Уровень шума
  • user/TEST_DEVICE/mb1/temp - Температура
  • user/TEST_DEVICE/mb1/hum - Относительная влажность

По данным топикам можно будет считать показания датчика в соответствии с правилами преобразований из mask

Более подробно можно посмотреть практические примеры в каталоге шаблонов.
Например, описание и пример применения шаблона WB-Info.

Запись через MQTT

Также для регистров с возможностью записи (typereg=3 - Holding register) доступна запись значений в Modbus через запись в MQTT-топики. Если прошивка была сгенерирована с включенным отдельным топиком на запись, то в путь к исходному топику после префикса user/TEST_DEVICE/ надо добавить set/

Например, если параметр с возможностью записи имеет маску c указанием {topic}, то полные имена топиков для MQTT-пользователя user и устройства TEST_DEVICE для вкладки ModBus, Device 1 будут такими:

  • user/TEST_DEVICE/mb1/topic - топик для чтения
  • user/TEST_DEVICE/set/mb1/topic - топик для записи

Например, эту возможность можно использовать для смены modbus-адреса Wiren Board устройства через MQTT.
Этот и другие примеры работы Modbus cовместно с MQTT cм. в каталоге шаблонов.

Секция [gpio]

Пример
// buzzer WB-MSW (статус при чтении, вкл/выкл при записи) 
// Single Coil (func: 0x01 read, 0x05 write)
[gpio]
typereg=0x01
startreg=0
cntreg=1

Секция [gpio] предназначена для чтения или записи дискретных значений (0/1).

Переменные из Modbus устройства, описанные в секции, встраиваются в систему в виде виртуальных GPIO, и становятся доступны для использования в различных опциях прошивки (MQTT, Lora, Web Key, Interpreter и др.)

На данный момент в одном шаблоне может быть до 4-х секций этого типа.

Суммарное количество элементов GPIO зависит от выбранного количества GPIO на этапе подготовки прошивки.

Параметры секции [gpio]:

🔸 typereg - тип регистра
  • 1 или 0x01 - Coils (RW)
  • 2 или 0x02 - Discrete Inputs (RO)
  • 3 или 0x03 - Holding Registers (RW)
  • 4 или 0x04 - Input Registers (RO)
  • 6 или 0х06 - Holding Registers (RW), функция записи: Write Single Register (типы 3 и 6 аналогичны)
  • 16 или 0х10 - Holding Registers (RW), функция записи: Write Multiple Registers
Особенности использования типов для регистров Holding(3,6,16) и Input(4)

Существует возможность "побитно" читать/писать в регистры

  • startreg - указываем адрес регистра
  • cntreg - указываем количество бит в регистре, которые нужно читать или писать "побитно"

Таким образом биты из регистра будут связаны с виртуальными GPIO.
Это может быть полезно если биты Holding или Input регистра хранят статусы или управляют режимами работы ModBus устройства

При записи в определённый бит регистра выполняются следующие операции:

  • чтение всего регистра (16 бит)
  • изменение значения нужного бита
  • запись всего регистра (16 бит)
🔸 startreg - начальный адрес области регистров
Может быть указан в формате как hex, так и десятичное (например, 0x000А, 10)
🔸 cntreg - количество регистров (количество бит) в области
Может быть как hex, так и десятичное
🔹 fastmode - режим "Быстрый Modbus"

Этот параметр опциональный, по-умолчанию режим "Быстрый Modbus" выключен.
Этот параметр можно использовать для ускорения обмена с устройствами от компании Wiren Board, для определённых регистров которые поддерживают режим "Быстрый Modbus".

  • 1 - "Быстрый Modbus" включен
  • 0 - "Быстрый Modbus" выключен

Секция [pwm] 💫

💫 Beta Внимание: это новая разработка, бета-версия. В будущем планируется расширение функционала.

Секция [pwm] предназначена для чтения или записи значений из регистров Input или Holding.

Переменные из Modbus устройства, описанные в секции, встраиваются в систему в виде виртуальных PWM, и становятся доступны для использования в различных опциях прошивки (PWM, MQTT, Lora, Interpreter и др.)

Таким образом, секция [pwm] позволяет вводить в систему элементы контроля и управления: изменять параметры исполнительных устройств (из веб-интерфейса или по удалённым каналам связи), переключать их режимы работы, и др. Например, через соответствующие модули Modbus можно реализовать управление яркостью освещения в помещении или управление скоростью вращения вентилятора в вентиляционной установке.

В шаблоне может быть несколько секций [pwm].
Предел зависит от указанного количества PWM на этапе подготовки прошивки.

💫 В бета-версии диапазон допустимых значений PWM элемента находится в пределах 0-255

Параметры секции [pwm]:

🔸 typereg - тип регистра
  • 3 или 0x03 - Holding Registers (RW)
  • 4 или 0x04 - Input Registers (RO)
  • 6 или 0х06 - Holding Registers (RW), функция записи: Write Single Register (типы 3 и 6 аналогичны)
  • 16 или 0х10 - Holding Registers (RW), функция записи: Write Multiple Registers
🔸 startreg - начальный адрес области регистров
Может быть указан в формате как hex, так и десятичное (например, 0x0080, 0x80, 128)
🔸 cntreg - количество регистров в области
Может быть как hex, так и десятичное

Дополнительные материалы

Таблица для выбора typereg

Таблица соответствия typereg (типа регистра) и используемых функций Modbus

typereg (dec) typereg (hex) Группа регистров Read Write Функция чтения Функция записи
1 0x01 Coils 01 (0x01) Read Coils 05 (0x05) Write Single Coil
2 0x02 Discrete Inputs 02 (0x02) Read Discrete Inputs запись не доступна по стандарту Modbus
3 0x03 Holding Registers 03 (0x03) Read Holding Registers 06 (0x06) Write Single Register
4 0x04 Input Registers 04 (0x04) Read Input Registers запись не доступна по стандарту Modbus
6 0x06 Holding Registers 03 (0x03) Read Holding Registers 06 (0x06) Write Single Register
16 0x10 Holding Registers 03 (0x03) Read Holding Registers 16 (0x10) Write Multiple registers
Примечание по работе с Holding Registers

Удобно выбирать typereg в соответствии с кодом Modbus функции.

Таким образом, для чтения Holding Registers в шаблонах обычно используют typereg=0x03.

Для записи Holding Registers возможен выбор одной из двух функции записи:

  • typereg=0x06 - означает использование функции Write Single Register для записи
  • typereg=0x10 - означает использование функции Write Multiple Registers для записи

Если регистр с typereg=0x03 будет использован также для записи, запись будет осуществляться функцией Write Single Register.

То есть typereg=0x03 и typereg=0x06 идентичны и введены для удобства, чтобы в шаблоне можно было указать предполагаемый тип доступа к регистру.

Комментарии

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

// пример комментария, содержимое строки игнорируется

Примеры работы с шаблонами представлены в каталоге шаблонов.