Получение данных с APC UPS Modbus TCP

Есть однофазные APC UPS серии SRT с сетевой картой. Еще раз переписали шаблоны с использованием документации производителя. Пока работает. Только со статусами есть сомнения в корректной работе. Может кто знает простую программу для чтения по сети регистров Modbus TCP?
Какой надо ставить адрес устройства, если подключение через порт Modbus TCP? Сейчас поставили 1.

Например Работа с Modbus-устройствами Wiren Board без контроллера — Wiren Board

Какой производитель установил. Да, если устройство за Modbus TCP одно - как правило и адрес “1”.
А статусы как получаете?

Спасибо, попробую.

Да, одно. Поставил 1. И относительно большие интервалы опроса. Ночь нормально проработало.

Скачал документацию на эту модель ИБП по регистрам. В шаблоне пишу такие строки:

                        {
                                "name": "Status - Outlet is powered",
                                "reg_type": "holding",
                                "address": "3:0:1",
                                "type": "switch",
                                "group": "device_status",
                                "readonly": true
                        },
    

Ну, тут подозрительно что “Outlet is powered” - false.
Но если это бит того же, 3 регистра, как и “Battery lefetime is OK” - то может так и должно быть.

При этом если прочитать весь регистр 0 (u32), то статус верный - 2.

                        {

                                "name": "Status Register",
                                "reg_type": "holding",
                                "address": 0,
                                "type": "value",
                                "format": "u32",
                                "group": "device_status",
                                "readonly": true
                        },

(полная картинка выше, основной регистр статуса - 0, в 3-м еще несколько дополнительных полезных данных)

А бывает тип данных “набор значений”? Скажем для переменной “состояние”. Если биты взаимоисключающие, можно было бы так сделать.

так нужен-то восьмой бит (регистры - 16-битные)

Нет, есть ограниченная версия - on_value и off_value
Но может добавим…

Не может быть проблема в том, что регистр 25 (который вроде как правильно читается битами) - только один (16-ти битный), а регистры 0 и 3 - фактически 32-х битные?

Если целиком считать 0-й как u32, то там будет значение “2”, а если

                        {
                                "name": "Status - Online",
                                "reg_type": "holding",
                                "address": "0:1:1",
                                "type": "switch",
                                "group": "device_status",
                                "readonly": true
                        },

то будет “0”.

2 десятичные - это поднятый первый бит.
тут “0:1:1” читаете тоже первый
Вот странно, включите debug в настройках драйвера, посмотрим что читает.

Такого журнала достаточно?
log_20230628T145339.log (9,3 КБ)

Некоторое время пытался понять что не так, почему у меня не складывается картина. Потом понял что журнал от новых к старым событиям…
Запись в шину, чтение 00 holding:

2023-06-28T11:53:34.964Z [wb-mqtt-serial] DEBUG: [port] 10.0.7.102: Write: 00 bc 00 00 00 06 01 03 00 00 00 02

Чтение ответа из шины:

2023-06-28T11:53:35.310Z [wb-mqtt-serial] DEBUG: [port] 10.0.7.102: ReadFrame: 03 04 00 00 00 02

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

Во вложении. Устройство 10.0.7.202 - только один этот бит в шаблоне.
log_20230629T112635.log (7,0 КБ)

Лог помог? Или еще что-то стоит прислать?

Да,я вижу чтение байта. Значение 0x02.

В шаблоне - только чтение бита:

{
        "title": "UPS APC SRT 1",
        "device_type": "APC_series_1",
        "group": "UPSdev_1",
        "device": {
                "name": "UPS_APC_SRT_1",
                "id": "UPS_APC_SRT_1",
                "max_read_registers": 0,
                "frame_timeout_ms": 8,
                "groups": [{
                        "title": "Device Status",
                        "id": "device_status",
                        "order": 1
                }],
                "channels": [{
                        "name": "Status - Online",
                        "reg_type": "holding",
                        "address": "0:1:1",
                        "type": "switch",
                        "group": "device_status",
                        "readonly": true
                }]
        }
}

Не добрался сегодня, завтра проверю…

Итак, шаблон:

            {
                "name": "RAW",
                "reg_type": "holding",
                "address": "199",
                "type": "value",
                "format": "u16",
                "group": "general"
            },
            {
                "name": "Manual",
                "reg_type": "holding",
                "address": "199:0:1",
                "type": "switch",
                "enabled": true,
                "group": "general"
            },
            {
                "name": "Auto",
                "reg_type": "holding",
                "address": "199:1:1",
                "type": "switch",
                "enabled": true,
                "group": "general"
            },

При “1” в регистре:
Screenshot_20230710_220148
При “2”:
Screenshot_20230710_220316
Ну, то есть все как и ожидается.

Мой вариант:

{
        "title": "UPS APC SRT 2",
        "device_type": "APC_series_2",
        "group": "UPSdev_1",
        "device": {
                "name": "UPS_APC_SRT_2",
                "id": "UPS_APC_SRT_2",
                "max_read_registers": 0,
                "frame_timeout_ms": 1000,
                "groups": [{
                        "title": "Device Status",
                        "id": "device_status",
                        "order": 1
                }],
                "channels": [{
                                "name": "Status Register",
                                "reg_type": "holding",
                                "address": 0,
                                "type": "value",
                                "format": "u32",
                                "group": "device_status",
                                "readonly": true
                        },
                        {
                                "name": "Status - Online",
                                "reg_type": "holding",
                                "address": "0:1:1",
                                "type": "switch",
                                "group": "device_status",
                                "readonly": true
                        },
                        {
                                "name": "Status - On battery",
                                "reg_type": "holding",
                                "address": "0:2:1",
                                "type": "switch",
                                "group": "device_status",
                                "readonly": true
                        }
                ]
        }
}

Screenshot_2

Обратите внимание, что по документации этот регистр на 32 бита.
В моем (первоначальном) шаблоне еще есть еще один бит, но он читается из другого регистра, который на 16 бит. И видимо правильно читается.

                        {
                                "name": "Status - Battery lifetime is ok",
                                "reg_type": "holding",
                                "address": "25:0:1",
                                "type": "switch",
                                "group": "device_status",
                                "readonly": true
                        }
 

Screenshot_4

Тогда младшие биты в регистре 1 - что логично. А шаблоном читаете биты 0 и 1 из регистра 0.