Вопрос по float и little_endian

читаю Holding Reg
там лежит температура 32-бит с плавающей запятой (IEEE754 4 байта)
порядок байт little endian

читаю клиентом:

2024-12-13 12:36:21,924 [DEBUG] RPC Client <- {'response': '300304051248c04c69'}
2024-12-13 12:36:22,926 [DEBUG] Response: 300304051248c04c69
2024-12-13 12:36:22,927 [DEBUG] <30><03><04><05><12><48><c0><4c><69>
SUCCESS: read 2 elements:
        Data: 0x0512 0x48c0

свапаем порядок - 0xc0481205
считаем в калькуляторе - получаем -3.1261
похоже на реальное значение

шаблон устройства:

"format" : "float",
"reg_type" : "holding",
"word_order" : "little_endian"

word_order - little_endian

а у меня byte_order

штатных вариантов решения нет?

Здравствуйте.

Прошу добавить контекста:

  • Что читаете? Какое устройство? Какой регистр?
  • Чем читаете? Какое ПО, ОС? Есть ли у вас наш контроллер?
  • Что хотелось бы видеть при чтении регистров?

Благодарю за ответы

вроде-бы все эти вопросы расписал в первом посте

читаю с wb 7.4
шаблон под него же делаю

вопрос в том, что параметр “word_order” : “little_endian” меняет порядок слов, а мне надо поменять порядок байт, такого параметра не предусмотрено для шаблона?

Действительно, смена порядка байт в слове для float не предусмотрена драйвером wb-mqtt-serial и в рамках шаблона такое не реализовать.

В качестве решения можно применить преобразование через правило wb-rules, например:

defineRule('fix_byte_order', {
  whenChanged: 'modbusDevice/temperature_raw',
  then: function (newValue) {
    // Меняем порядок байтов в каждом слове
    let swapped = ((newValue & 0xFF) << 8) | ((newValue >> 8) & 0xFF);
    // Преобразуем значение в float
    let floatValue = parseFloat(swapped);
    dev['virtualDevice/temperature_fixed'] = floatValue;
  }
});

Также уточните, пожалуйста, какое именно устройство вы интегрируете?

Запишу разработчикам идею на улучшение драйвера.

Интегрирую термостат Теплолюкс2000

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

Float у нас 32 битный, я переписал по аналогии, но все равно результат неадекватный

           ((newValue & 0xFF) << 24)
           | ((newValue & 0xFF00) << 8)
           | ((newValue >> 8) & 0xFF00)
           | ((newValue >> 24) & 0xFF)

Само значение с прибора в каком формате считывать?
По идее надо читать DWORD переставлять байты потом преобразовывать DWORDtoFLOAT
Но в драйвере нет возможности читать ни DWORD ни WORD

Здравствуйте.

Думаю, этот формат вам подойдет.

вы рекомендуете:

double" - число с плавающей точкой двойной точности IEEE 754. 64 bit. (big-endian).
                            //     (занимает 4 регистра, начиная с указанного)

у меня данные занимают 32 бита, 2 регистра модбас или 2 слова или DWord

В качестве резюме:
1.В драйвере все-же надо сделать свап байтов little/big endian
2.Очень ущербный джаваскрипт в движке правил и нет документации по нему нормальной
Я в итоге решил вопрос баш скриптом, котрый вашим же modbus_client_rpc читает 2 слова, комбинирует их в DWORD далее свапает байты, конвертит в 32 бит флоат и публикует в MQTT

Да, я записал идею разработчикам.

На основной странице документации wb-rules сказано:

Для написания правил необходимы базовые знания синтаксиса языка JavaScript с учетом особенностей ECMAScript 5. Если вы ранее не работали с JavaScript, то рекомендуем учебник learn.javascript.ru.

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

Какую еще документацию вам хотелось бы видеть?