Написание функции, высчитывающей корректную температуру, шаблон Uponor Smatrix Base PRO Controller X-147

Какое количество регистров запрашивается одновременно, в одном запросе?
Как известно, длина посылки Modbus RTU не модет быть больше 252 байт.
Что указано в “max_read_registers”?
Выложите шаблон пожалуйста.

Сейчас обнаружил, что у меня в конфиге два одинаковых канала у девайса было. Убрал клона- всё стало ок

Можете прислать кусок шаблона с этими дублирующимися каналами, чтобы мы добавили корректную обработку такой ситуации?

Вот, два RoomSetTemp5

Конфиг
{
  "slave_id": "1",
  "name": "Uponor 1 floor",
  "id": "uponor_1",
  "enabled": true,
  "protocol": "modbus",
  "poll_interval": 1500,
  "channels": [
    {
      "name": "Actuator1",
      "type": "switch",
      "reg_type": "discrete",
      "address": 1,
      "format": "s16",
      "scale": 1,
      "offset": 0
    },
    {
      "name": "Actuator2",
      "type": "switch",
      "reg_type": "discrete",
      "address": 2,
      "format": "s16",
      "scale": 1,
      "offset": 0
    },
    {
      "name": "Actuator3",
      "type": "switch",
      "reg_type": "discrete",
      "address": 3,
      "format": "s16",
      "scale": 1,
      "offset": 0
    },
    {
      "name": "Actuator4",
      "type": "switch",
      "reg_type": "discrete",
      "address": 4,
      "format": "s16",
      "scale": 1,
      "offset": 0
    },
    {
      "name": "Actuator5",
      "type": "switch",
      "reg_type": "discrete",
      "address": 5,
      "format": "s16",
      "scale": 1,
      "offset": 0
    },
    {
      "name": "Actuator6",
      "type": "switch",
      "reg_type": "discrete",
      "address": 6,
      "format": "u16",
      "scale": 1,
      "offset": 0
    },
    {
      "name": "Actuator7",
      "type": "switch",
      "reg_type": "discrete",
      "address": 7,
      "format": "s16",
      "scale": 1,
      "offset": 0
    },
    {
      "name": "Actuator8",
      "type": "switch",
      "reg_type": "discrete",
      "address": 8,
      "format": "s16",
      "scale": 1,
      "offset": 0
    },
    {
      "name": "Actuator9",
      "type": "switch",
      "reg_type": "discrete",
      "address": 9,
      "format": "s16",
      "scale": 1,
      "offset": 0
    },
    {
      "name": "Actuator10",
      "type": "switch",
      "reg_type": "discrete",
      "address": 10,
      "format": "s16",
      "scale": 1,
      "offset": 0
    },
    {
      "name": "Actuator11",
      "type": "switch",
      "reg_type": "discrete",
      "address": 11,
      "format": "s16",
      "scale": 1,
      "offset": 0
    },
    {
      "name": "Actuator12",
      "type": "switch",
      "reg_type": "discrete",
      "address": 12,
      "format": "s16",
      "scale": 1,
      "offset": 0
    },
    {
      "name": "RoomRealTemp1",
      "type": "value",
      "reg_type": "input",
      "address": 2,
      "format": "s16",
      "scale": 0.055555556,
      "offset": -17.777778
    },
    {
      "name": "RoomRealTemp2",
      "type": "value",
      "reg_type": "input",
      "address": 3,
      "format": "s16",
      "scale": 0.055555556,
      "offset": -17.777778
    },
    {
      "name": "RoomRealTemp3",
      "type": "value",
      "reg_type": "input",
      "address": 4,
      "format": "s16",
      "scale": 0.055555556,
      "offset": -17.777778
    },
    {
      "name": "RoomRealTemp4",
      "type": "value",
      "reg_type": "input",
      "address": 5,
      "format": "s16",
      "scale": 0.055555556,
      "offset": -17.777778
    },
    {
      "name": "RoomRealTemp5",
      "type": "value",
      "reg_type": "input",
      "address": 6,
      "format": "s16",
      "scale": 0.055555556,
      "offset": -17.777778
    },
    {
      "name": "RoomRealTemp6",
      "type": "value",
      "reg_type": "input",
      "address": 7,
      "format": "s16",
      "scale": 0.055555556,
      "offset": -17.777778
    },
    {
      "name": "RoomRealTemp7",
      "type": "value",
      "reg_type": "input",
      "address": 8,
      "format": "s16",
      "scale": 0.055555556,
      "offset": -17.777778
    },
    {
      "name": "RoomRealTemp8",
      "type": "value",
      "reg_type": "input",
      "address": 9,
      "format": "s16",
      "scale": 0.055555556,
      "offset": -17.777778
    },
    {
      "name": "RoomRealTemp9",
      "type": "value",
      "reg_type": "input",
      "address": 10,
      "format": "s16",
      "scale": 0.055555556,
      "offset": -17.777778
    },
    {
      "name": "RoomRealTemp10",
      "type": "value",
      "reg_type": "input",
      "address": 11,
      "format": "s16",
      "scale": 0.055555556,
      "offset": -17.777778
    },
    {
      "name": "RoomRealTemp11",
      "type": "value",
      "reg_type": "input",
      "address": 12,
      "format": "s16",
      "scale": 0.055555556,
      "offset": -17.777778
    },
    {
      "name": "RoomRealTemp12",
      "type": "value",
      "reg_type": "input",
      "address": 13,
      "format": "s16",
      "scale": 0.055555556,
      "offset": -17.777778
    },
    {
      "name": "RoomSetTemp1",
      "type": "value",
      "reg_type": "holding_multi",
      "address": 1,
      "format": "s16",
      "scale": 0.055555556,
      "offset": -17.777778
    },
    {
      "name": "RoomSetTemp2",
      "type": "value",
      "reg_type": "holding_multi",
      "address": 2,
      "format": "s16",
      "scale": 0.055555556,
      "offset": -17.777778
    },
    {
      "name": "RoomSetTemp3",
      "type": "value",
      "reg_type": "holding_multi",
      "address": 3,
      "format": "s16",
      "scale": 0.055555556,
      "offset": -17.777778
    },
    {
      "name": "RoomSetTemp4",
      "type": "value",
      "reg_type": "holding_multi",
      "address": 4,
      "format": "s16",
      "scale": 0.055555556,
      "offset": -17.777778
    },
    {
      "name": "RoomSetTemp5",
      "type": "value",
      "reg_type": "holding_multi",
      "address": 5,
      "format": "s16",
      "scale": 0.055555556,
      "offset": -17.777778
    },
    {
      "name": "RoomSetTemp5",
      "type": "value",
      "reg_type": "holding_multi",
      "address": 5,
      "format": "s16",
      "scale": 0.055555556,
      "offset": -17.777778
    },
    {
      "name": "RoomSetTemp6",
      "type": "value",
      "reg_type": "holding_multi",
      "address": 6,
      "format": "s16",
      "scale": 0.055555556,
      "offset": -17.777778
    },
    {
      "name": "RoomSetTemp7",
      "type": "value",
      "reg_type": "holding_multi",
      "address": 7,
      "format": "s16",
      "scale": 0.055555556,
      "offset": -17.777778
    },
    {
      "name": "RoomSetTemp8",
      "type": "value",
      "reg_type": "holding_multi",
      "address": 8,
      "format": "s16",
      "scale": 0.055555556,
      "offset": -17.777778
    },
    {
      "name": "RoomSetTemp9",
      "type": "value",
      "reg_type": "holding_multi",
      "address": 9,
      "format": "s16",
      "scale": 0.055555556,
      "offset": -17.777778
    },
    {
      "name": "RoomSetTemp10",
      "type": "value",
      "reg_type": "holding_multi",
      "address": 10,
      "format": "s16",
      "scale": 0.055555556,
      "offset": -17.777778
    },
    {
      "name": "RoomSetTemp11",
      "type": "value",
      "reg_type": "holding_multi",
      "address": 11,
      "format": "s16",
      "scale": 0.055555556,
      "offset": -17.777778
    },
    {
      "name": "RoomSetTemp12",
      "type": "value",
      "reg_type": "holding_multi",
      "address": 12,
      "format": "s16",
      "scale": 0.055555556,
      "offset": -17.777778
    }
  ],
  "device_max_fail_cycles": 1000
}

В принципе, всё работает, но значения всё-таки не очень корректные приходят. как правильнее будет их “причесать”? Round_to?

image

Да, как в https://github.com/wirenboard/wb-mqtt-serial/:

1 лайк

Смотрите, температуру в комнате до округления показывает 13,5555555, по факту, на терморегуляторе показывает 13,5. При округлении до десятых, округляется по математическим правилам до 13,6. Как мне просто “отсечь” лишнее, без округления?

{
  "name": "RoomRealTemp1",
  "type": "value",
  "reg_type": "input",
  "address": 1,
  "format": "s16",
  "scale": 0.055555556,
  "offset": -17.777778,
  "round_to": 0.01
}

Всё ещё жду ответа)

Специальной функции нет. Если значения только положительные, то можно вычесть дополнительно 0.005, и потом

"round_to": 0.01

Если интересует, речь шла о Uponor Smatrix Base PRO Controller X-147. Успешно интегрировали, всё работает. Можете добавить в список поддерживаемых устройств.

3 лайка

отлично, спасибо! А можете поделиться здесь шаблоном?

1 лайк

Конечно, у меня тут 10 каналов настроено, а так вообще максимум- 12, емнип

Конфиг
{
  "slave_id": "1",
  "name": "Uponor 1 floor",
  "id": "uponor_1",
  "enabled": true,
  "protocol": "modbus",
  "poll_interval": 1500,
  "channels": [
    {
      "name": "Actuator1",
      "type": "switch",
      "reg_type": "discrete",
      "address": 0,
      "format": "s16",
      "scale": 1,
      "offset": 0
    },
    {
      "name": "Actuator2",
      "type": "switch",
      "reg_type": "discrete",
      "address": 1,
      "format": "s16",
      "scale": 1,
      "offset": 0
    },
    {
      "name": "Actuator3",
      "type": "switch",
      "reg_type": "discrete",
      "address": 2,
      "format": "s16",
      "scale": 1,
      "offset": 0
    },
    {
      "name": "Actuator4",
      "type": "switch",
      "reg_type": "discrete",
      "address": 3,
      "format": "s16",
      "scale": 1,
      "offset": 0
    },
    {
      "name": "Actuator5",
      "type": "switch",
      "reg_type": "discrete",
      "address": 4,
      "format": "s16",
      "scale": 1,
      "offset": 0
    },
    {
      "name": "Actuator6",
      "type": "switch",
      "reg_type": "discrete",
      "address": 5,
      "format": "u16",
      "scale": 1,
      "offset": 0
    },
    {
      "name": "Actuator7",
      "type": "switch",
      "reg_type": "discrete",
      "address": 6,
      "format": "s16",
      "scale": 1,
      "offset": 0
    },
    {
      "name": "Actuator8",
      "type": "switch",
      "reg_type": "discrete",
      "address": 7,
      "format": "s16",
      "scale": 1,
      "offset": 0
    },
    {
      "name": "Actuator9",
      "type": "switch",
      "reg_type": "discrete",
      "address": 8,
      "format": "s16",
      "scale": 1,
      "offset": 0
    },
    {
      "name": "Actuator10",
      "type": "switch",
      "reg_type": "discrete",
      "address": 9,
      "format": "s16",
      "scale": 1,
      "offset": 0
    },
    {
      "name": "RoomRealTemp1",
      "type": "value",
      "reg_type": "input",
      "address": 1,
      "format": "s16",
      "scale": 0.055555556,
      "offset": -17.777778,
      "round_to": 0.1
    },
    {
      "name": "RoomRealTemp2",
      "type": "value",
      "reg_type": "input",
      "address": 2,
      "format": "s16",
      "scale": 0.055555556,
      "offset": -17.777778,
      "round_to": 0.1
    },
    {
      "name": "RoomRealTemp3",
      "type": "value",
      "reg_type": "input",
      "address": 3,
      "format": "s16",
      "scale": 0.055555556,
      "offset": -17.777778,
      "round_to": 0.1
    },
    {
      "name": "RoomRealTemp4",
      "type": "value",
      "reg_type": "input",
      "address": 4,
      "format": "s16",
      "scale": 0.055555556,
      "offset": -17.777778,
      "round_to": 0.1
    },
    {
      "name": "RoomRealTemp5",
      "type": "value",
      "reg_type": "input",
      "address": 5,
      "format": "s16",
      "scale": 0.055555556,
      "offset": -17.777778,
      "round_to": 0.1
    },
    {
      "name": "RoomRealTemp6",
      "type": "value",
      "reg_type": "input",
      "address": 6,
      "format": "s16",
      "scale": 0.055555556,
      "offset": -17.777778,
      "round_to": 0.1
    },
    {
      "name": "RoomRealTemp7",
      "type": "value",
      "reg_type": "input",
      "address": 7,
      "format": "s16",
      "scale": 0.055555556,
      "offset": -17.777778,
      "round_to": 0.1
    },
    {
      "name": "RoomRealTemp8",
      "type": "value",
      "reg_type": "input",
      "address": 8,
      "format": "s16",
      "scale": 0.055555556,
      "offset": -17.777778,
      "round_to": 0.1
    },
    {
      "name": "RoomRealTemp9",
      "type": "value",
      "reg_type": "input",
      "address": 9,
      "format": "s16",
      "scale": 0.055555556,
      "offset": -17.777778,
      "round_to": 0.1
    },
    {
      "name": "RoomRealTemp10",
      "type": "value",
      "reg_type": "input",
      "address": 10,
      "format": "s16",
      "scale": 0.055555556,
      "offset": -17.777778,
      "round_to": 0.1
    },
    {
      "name": "RoomSetTemp1",
      "type": "value",
      "reg_type": "holding_multi",
      "address": 0,
      "format": "s16",
      "scale": 0.055555556,
      "offset": -17.777778,
      "round_to": 0.1
    },
    {
      "name": "RoomSetTemp2",
      "type": "value",
      "reg_type": "holding_multi",
      "address": 1,
      "format": "s16",
      "scale": 0.055555556,
      "offset": -17.777778,
      "round_to": 0.1
    },
    {
      "name": "RoomSetTemp3",
      "type": "value",
      "reg_type": "holding_multi",
      "address": 2,
      "format": "s16",
      "scale": 0.055555556,
      "offset": -17.777778,
      "round_to": 0.1
    },
    {
      "name": "RoomSetTemp4",
      "type": "value",
      "reg_type": "holding_multi",
      "address": 3,
      "format": "s16",
      "scale": 0.055555556,
      "offset": -17.777778,
      "round_to": 0.1
    },
    {
      "name": "RoomSetTemp5",
      "type": "value",
      "reg_type": "holding_multi",
      "address": 4,
      "format": "s16",
      "scale": 0.055555556,
      "offset": -17.777778,
      "round_to": 0.1
    },
    {
      "name": "RoomSetTemp6",
      "type": "value",
      "reg_type": "holding_multi",
      "address": 5,
      "format": "s16",
      "scale": 0.055555556,
      "offset": -17.777778,
      "round_to": 0.1
    },
    {
      "name": "RoomSetTemp7",
      "type": "value",
      "reg_type": "holding_multi",
      "address": 6,
      "format": "s16",
      "scale": 0.055555556,
      "offset": -17.777778,
      "round_to": 0.1
    },
    {
      "name": "RoomSetTemp8",
      "type": "value",
      "reg_type": "holding_multi",
      "address": 7,
      "format": "s16",
      "scale": 0.055555556,
      "offset": -17.777778,
      "round_to": 0.1
    },
    {
      "name": "RoomSetTemp9",
      "type": "value",
      "reg_type": "holding_multi",
      "address": 8,
      "format": "s16",
      "scale": 0.055555556,
      "offset": -17.777778,
      "round_to": 0.1
    },
    {
      "name": "RoomSetTemp10",
      "type": "value",
      "reg_type": "holding_multi",
      "address": 9,
      "format": "s16",
      "scale": 0.055555556,
      "offset": -17.777778,
      "round_to": 0.1
    }
  ],
  "device_max_fail_cycles": 1000
}
1 лайк

Дмитрий, а можете пожалуйста привести пример команды modbus_client и конфигурации U_BMS.txt? Не получается подключится получить хоть какой-либо ответ от контроллера, прошивку пробовал 116_1 и 910

U_BMS.txt сейчас не подскажу, но там ничего сверхъестественного. Вот пример команды:

modbus_client
root@wirenboard-ACF6YBP3:~# service wb-mqtt-serial stop
root@wirenboard-ACF6YBP3:~# modbus_client --debug -mrtu -peven -s1 /dev/ttyRS485-1 -b9600 -a1 -t0x03 -r0001
Opening /dev/ttyRS485-1 at 9600 bauds (E, 8, 1)
[01][03][00][01][00][01][D5][CA]
Waiting for a confirmation...
<01><03><02><01><9A><39><BF>
SUCCESS: read 1 of elements:
        Data: 0x019a

Вот мой U_BMS.txt

1
19200
even
off
0
0

// Setting ranges:
// Row 1: BMS Slave address = [1…247]
//
// Row 2: BMS Baud rate = [19200 or 9600]
//
// Row 3: BMS Parity = [even, odd or no]
//
// Row 4: HP integration via BMS = [on or off]
// Example: on = enables dynamic heat curve offset in integrated heat pump, and integrated heat pump defrost state
//
// Row 5: Exclude zone from heat curve offset calculation = [1,2,3,4,5,6,7,8,9,10,11,12, or 0=no channels]
// Select master channels of the zones (lowest numbered channel in the zone) to exclude.
// The zone subchannels follow the state of the master channel.
// Example: 3,5,12 = exludes channels with master channels 3, 5 and 12
//
// Row 6: Bypass zone = [1,2,3,4,5,6,7,8,9,10,11,12 or 0=no channels]
// Select master channels of the zones (lowest numbered channel in the zone) to bypass, MAXIMUM 2 channels.
// The zone subchannels follow the state of the master channel.
// Example: 4,12 = bypasses zones with master channels 4 and 12

Подскажите, потребовалось читать ещё и влажность, плюс ко всему. Но чёт приходит какая-то ерунда, в инструкции ничего вроде на этот счёт нет. Что я делаю не так?

{
  "name": "RoomRealHum2",
  "type": "value",
  "reg_type": "input",
  "address": 13,
  "format": "u16"
}

Инструкция: https://www.mikrocontroller.net/attachment/446274/Uponor_IM_Smatrix_Base_PRO_MODBUS-RTU_EN_1090255_032018.pdf

Здравствуйте! Ошибки не вижу. Какие данные получаете из регистра? Другие регистры при этом читаются нормально?
Попробуйте прочитать еще данные из соседних регистров (14, 15). Также попробуйте опросить регистры с помощью утилиты modbus_client.

1 лайк

Блин, да, результат я забыл написать :sweat_smile:

image

Да, не очень похоже на правду. А датчик влажности точно присутствует на этом канале? Если его нет, то и значение в регистре может быть странным.

Также сравните данные с содержимым из соседних регистров (14, 15). Также попробуйте опросить регистр 13 с помощью утилиты modbus_client и покажите сырые значения.

В качестве эксперимента попробуйте считать значение в виде 8-битного числа: в шаблоне указать тип “u8” вместо “u16” для регистра 13.