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

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

            {
                "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.

Как правильно прочитать нужный бит, если такая документация:

1:0:1 или указать явно размерность читаемого регистра в 32 бита и тогда уж читать 0:0:1

Не очень понятно. Можно пример?
Размерность указывается в format? И это не будет конфликтовать с битовым address?

Да.

                                "reg_type": "holding",
                                "format": "u32",
                                "address": "0:1:1",
                                "type": "switch",

Ну либо просто читать первый регистр…

Ничего не изменилось.

       "channels": [{
                                "name": "Status Register",
                                "reg_type": "holding",
                                "address": 0,
                                "type": "value",
                                "format": "u32",
                                "group": "device_status",
                                "readonly": true
                        },
                        {
                                "name": "Status - Online",
                                "reg_type": "holding",
                                "format": "u32",
                                "address": "0:1:1",
                                "type": "switch",
                                "group": "device_status",
                                "readonly": true
                        },
                        {
                                "name": "Status - On battery",
                                "reg_type": "holding",
                                "format": "u32",
                                "address": "0:2:1",
                                "type": "switch",
                                "group": "device_status",
                                "readonly": true
                        }
                

Screenshot_6

Интересно… Пожалуй даже бага,описал ее.

Надо: использовать 1:1:1 и 1:2:1 для чтения битов расположенных фактически в 1 регистре.
“format”: “u16” при этом.

Я не очень понимаю, исходя из приведенной документации и правильного чтения регистра как u32 целиком, почему для чтения младших бит нужен 1 регистр.

Мы планируем еще кондиционеры подключать по модбус (обычному) и хотелось бы все-таки с этим вопросом разобраться. Вероятно он звучит как “правильное чтение бит из регистра размерностью 32 бита”.
Спасибо!

Ну или как вариант - читать 32 бита, что похоже работает, и потом по его обновлению менять виртуальное устройство “статус”.

Да, именно это сейчас работает не совсем верно. То есть чтение битов возможно только с одного регистра. Нельзя прочитать младшие биты из “32битного” (пары регистров.
Я это описал и отдал разработчикам. То есть в случае указания битов для чтения игнорируется размерность.

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

Правильно ли я понял, что чтение бит работает только если регистр “обычный” 16-ти битный, а если он на 32 бита, то это не работает вообще никак никогда? (то есть читать тот же 0-й регистр битным образом как 16-ти битный тоже не дает правильного результата, если нужны младшие биты)?

И если делать через виртуальный контрол - он (виртуальный контрол) может быть только у виртуального устройства? Нельзя к “реальному” его добавить?

Спасибо!

Все регистры Modbus 16-битные. Представление их словами, двойными словами - это уже на более верхнем уровне.

Дает. Для одного регистра - работает. То есть из одного регистра все читается. Но младшие биты у вас в регистре 1. В 0 - страшие.

Можно, но связано с грязным хаком, который разработчики не рекомендуют категорически.
Просто для примера. Не надо так делать.
Как писал выше - сейчас просто читайте биты из 1 регистра.

Не работает так.
WARNING: [modbus] failed to read 1 holding(s) @ 1 of device modbus-tcp:1: Serial protocol error: illegal data address

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

Screenshot_8

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

Да, похоже на это. 0-й в 16 бит читает неверно. 1-й в 16 бит не читает.
Screenshot_10

Сейчас целесообразно все ж сделать разбор битов программно, баг описан но пока не в работе.

Эта тема была автоматически закрыта через 7 дней после последнего ответа. В ней больше нельзя отвечать.