commit 40d80ef55ea25521052fb9c5665774e76817a67f Author: zavolo Date: Wed Jan 14 21:33:17 2026 +0300 Initial commit diff --git a/LICENSE b/LICENSE new file mode 100644 index 0000000..2c4f673 --- /dev/null +++ b/LICENSE @@ -0,0 +1,21 @@ +MIT License + +Copyright (c) 2023 RAA80 + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +SOFTWARE. diff --git a/README.md b/README.md new file mode 100644 index 0000000..8a3cd76 --- /dev/null +++ b/README.md @@ -0,0 +1,55 @@ +# python-owen + +Библиотека для работы с приборами фирмы [Овен] по протоколам Modbus и ОВЕН + +## 📋 Поддерживаемые модели + +| Модель | Модель | Модель | +| :--------: | :--------: | :--------: | +| [ТРМ101] | [ТРМ151] | [ТРМ210] | +| [ТРМ136] | [ТРМ200] | [ТРМ212] | +| [ТРМ138] | [ТРМ201] | [ТРМ251] | +| [ТРМ148] | [ТРМ202] | [2ТРМ1] | +| [ПР100] | | | + +> Возможна поддержка других моделей путем добавления настроек в файл `owen/device.py` +> Не со всеми моделями проверена работа библиотеки + +## ⚠️ Важная информация + +### Требования к версии pymodbus + +**Для корректной работы python-owen необходимо установить старую версию библиотеки pymodbus:** + +```bash +pip3 install pymodbus==2.5.3 +``` + +⚠️ **При использовании более новых версий pymodbus библиотека работать не будет!** + +### Особенности Овен ПР100 + +**Овен ПР100 не поддерживает протокол ОВЕН — только Modbus!** + +## 📦 О проекте + +Это форк репозитория: https://github.com/RAA80/python-owen + +--- + +## 📚 Ссылки на документацию приборов + +[Овен]: https://owen.ru +[ТРМ101]: https://owen.ru/product/trm101 +[ТРМ136]: https://owen.ru/product/trm136 +[ТРМ138]: https://owen.ru/product/trm138 +[ТРМ148]: https://owen.ru/product/trm148 +[ТРМ151]: https://owen.ru/product/trm151 +[ТРМ200]: https://owen.ru/product/trm200 +[ТРМ201]: https://owen.ru/product/trm201 +[ТРМ202]: https://owen.ru/product/trm202 +[ТРМ210]: https://owen.ru/product/trm210 +[ТРМ212]: https://owen.ru/product/trm212 +[ТРМ251]: https://owen.ru/product/trm251 +[2ТРМ1]: https://owen.ru/product/2trm1 +[ПР100]: https://owen.ru/product/pr100 \ No newline at end of file diff --git a/example/example.py b/example/example.py new file mode 100644 index 0000000..6c2807c --- /dev/null +++ b/example/example.py @@ -0,0 +1,54 @@ +#! /usr/bin/env python3 + +"""Пример использования библиотеки.""" + +import logging + +from pymodbus.client.sync import ModbusSerialClient +from serial import Serial + +from owen.client import OwenModbusClient, OwenSerialClient +from owen.device import TRM201 + +logging.basicConfig(level=logging.INFO) + + +if __name__ == "__main__": + transport = Serial(port="COM5", + baudrate=115200, + stopbits=1, + parity="N", + bytesize=8, + timeout=0.1) + trm = OwenSerialClient(transport=transport, device=TRM201, unit=1, addr_len_8=True) # длина адреса в битах: True=8, False=11 + + # transport = ModbusSerialClient(method="rtu", + # port="COM5", + # baudrate=115200, + # stopbits=2, + # parity="N", + # bytesize=8, # "rtu": bytesize=8, "ascii": bytesize=7 + # timeout=0.1, + # retry_on_empty=True) + # trm = OwenModbusClient(transport=transport, device=TRM201, unit=1) + + print(trm) + + """ !!! + Если параметр не использует индекс, т.е. index=None, + либо прибор одноканальный и у параметра index=0, + то индекс указывать необязательно + + Для многоканальных приборов (например ТРМ202) и протокола Modbus названия + параметров (например IN.T1, IN.T2) для совместимости с протоколом ОВЕН + преобразуются в: + IN.T1 --> name="IN.T", index=0 + IN.T2 --> name="IN.T", index=1 + """ + + name = "SP" # Остальные названия параметров в файле 'device.py' для конкретного устройства + value = trm.get_param(name=name, index=0) + print(f"{name} = {value}") + + result = trm.set_param(name=name, index=0, value=value) + print(f"{name} = {result}") diff --git a/main.py b/main.py new file mode 100644 index 0000000..cd07a1a --- /dev/null +++ b/main.py @@ -0,0 +1,272 @@ +#! /usr/bin/env python3 +"""Пример работы с программируемым логическим реле Овен ПР100""" +import logging +import time +import sys +from datetime import datetime +from pymodbus.client.sync import ModbusSerialClient +from pymodbus.exceptions import ModbusException +from owen.client import OwenModbusClient +from owen.device import PR100 + +logging.basicConfig( + level=logging.INFO, + format='%(asctime)s - %(name)s - %(levelname)s - %(message)s' +) +logger = logging.getLogger(__name__) + +def read_digital_inputs(pr100: OwenModbusClient, num_inputs: int = 4): + """Чтение состояния дискретных входов""" + logger.info("Чтение дискретных входов") + try: + # Читаем все входы одним регистром + di_value = pr100.get_param(name="DI") + logger.info(f"Регистр дискретных входов: {di_value} (0x{di_value:04X})") + # Декодируем отдельные входы + for i in range(num_inputs): + state = (di_value >> i) & 1 + logger.info(f" DI{i+1}: {'ВКЛ' if state else 'ВЫКЛ'}") + return True + except Exception as e: + logger.error(f"Ошибка при чтении дискретных входов: {e}") + return False + +def read_analog_inputs(pr100: OwenModbusClient): + """Чтение аналоговых входов""" + logger.info("Чтение аналоговых входов") + success_count = 0 + for i in range(1, 5): + try: + # Читаем как float + value_float = pr100.get_param(name=f"AI{i}") + logger.info(f"AI{i} (float): {value_float:.3f}") + # Читаем как int с учетом dp + value_int = pr100.get_param(name=f"AI{i}.INT") + dp = pr100.get_param(name=f"AI{i}.DP") + logger.info(f"AI{i} (int): {value_int}, точность: {dp} знаков") + success_count += 1 + except Exception as e: + logger.error(f"Ошибка при чтении AI{i}: {e}") + return success_count > 0 + +def control_outputs(pr100: OwenModbusClient, outputs: dict): + """ + Управление дискретными выходами + + Args: + pr100: Экземпляр клиента ПР100 + outputs: Словарь {номер_выхода: состояние}, например {1: True, 2: False} + """ + logger.info("Управление дискретными выходами") + try: + # Читаем текущее состояние + current_value = pr100.get_param(name="DO") + logger.info(f"Текущее состояние выходов: 0x{current_value:04X}") + # Формируем новое значение + new_value = current_value + for output_num, state in outputs.items(): + bit_pos = output_num - 1 + if state: + new_value |= (1 << bit_pos) # Установить бит + else: + new_value &= ~(1 << bit_pos) # Сбросить бит + # Записываем новое состояние + logger.info(f"Запись нового состояния: 0x{new_value:04X}") + pr100.set_param(name="DO", value=new_value) + # Показываем, что изменилось + for output_num, state in outputs.items(): + logger.info(f" Q{output_num}: {'ВКЛ' if state else 'ВЫКЛ'}") + return True + except Exception as e: + logger.error(f"Ошибка при управлении выходами: {e}") + return False + +def read_system_time(pr100: OwenModbusClient): + """Чтение системного времени ПР100""" + logger.info("Чтение системного времени") + try: + sec = pr100.get_param(name="TIME.SEC") + min_val = pr100.get_param(name="TIME.MIN") + hour = pr100.get_param(name="TIME.HOUR") + day = pr100.get_param(name="TIME.DAY") + month = pr100.get_param(name="TIME.MONTH") + year = pr100.get_param(name="TIME.YEAR") + dow = pr100.get_param(name="TIME.DOW") + days_of_week = ["Пн", "Вт", "Ср", "Чт", "Пт", "Сб", "Вс"] + logger.info(f"Дата: {day:02d}.{month:02d}.20{year:02d}") + logger.info(f"Время: {hour:02d}:{min_val:02d}:{sec:02d}") + logger.info(f"День недели: {days_of_week[dow]}") + return True + except Exception as e: + logger.error(f"Ошибка при чтении системного времени: {e}") + return False + +def set_system_time(pr100: OwenModbusClient): + """Установка системного времени ПР100 на текущее""" + logger.info("Установка системного времени") + try: + now = datetime.now() + pr100.set_param(name="TIME.SEC", value=now.second) + pr100.set_param(name="TIME.MIN", value=now.minute) + pr100.set_param(name="TIME.HOUR", value=now.hour) + pr100.set_param(name="TIME.DAY", value=now.day) + pr100.set_param(name="TIME.MONTH", value=now.month) + pr100.set_param(name="TIME.YEAR", value=now.year % 100) + logger.info(f"Время установлено: {now.strftime('%d.%m.%Y %H:%M:%S')}") + return True + except Exception as e: + logger.error(f"Ошибка при установке времени: {e}") + return False + +def monitoring_loop(pr100: OwenModbusClient, duration: int = 10): + """ + Цикл мониторинга входов и выходов + + Args: + pr100: Экземпляр клиента ПР100 + duration: Длительность мониторинга в секундах + """ + logger.info(f"Запуск мониторинга на {duration} секунд") + start_time = time.time() + error_count = 0 + max_errors = 5 + try: + while time.time() - start_time < duration: + try: + # Читаем входы + di = pr100.get_param(name="DI") + ai1 = pr100.get_param(name="AI1") + do = pr100.get_param(name="DO") + logger.info(f"DI: 0x{di:04X}, AI1: {ai1:.2f}, DO: 0x{do:04X}") + error_count = 0 # Сброс счетчика при успешном чтении + except Exception as e: + error_count += 1 + logger.error(f"Ошибка чтения (#{error_count}): {e}") + if error_count >= max_errors: + logger.error(f"Достигнуто максимальное количество ошибок ({max_errors}). Остановка мониторинга.") + return False + time.sleep(1) + return True + except KeyboardInterrupt: + logger.info("Мониторинг прерван пользователем") + return True + +def test_connection(transport: ModbusSerialClient, unit_id: int) -> bool: + """ + Проверка соединения с устройством + + Args: + transport: Клиент Modbus + unit_id: Адрес устройства + + Returns: + True если соединение успешно, False в противном случае + """ + try: + if not transport.connect(): + logger.error("Не удалось установить соединение с портом") + return False + # Пробуем прочитать регистр для проверки связи + result = transport.read_holding_registers(address=0, count=1, unit=unit_id) + if result.isError(): + logger.error(f"Устройство не отвечает на адресе {unit_id}") + return False + logger.info("Соединение установлено успешно") + return True + except Exception as e: + logger.error(f"Ошибка при проверке соединения: {e}") + return False + +def main(): + logger.info("=" * 60) + logger.info("Начало работы с Овен ПР100") + logger.info("=" * 60) + # Параметры подключения + PORT = "COM6" + BAUDRATE = 115200 + UNIT_ID = 1 # Адрес устройства Modbus + transport = None + try: + logger.info(f"Настройка подключения: {PORT}, {BAUDRATE} бод, адрес {UNIT_ID}") + # Создание клиента Modbus + transport = ModbusSerialClient( + method="rtu", + port=PORT, + baudrate=BAUDRATE, + stopbits=1, + parity="N", + bytesize=8, + timeout=0.5, + retry_on_empty=True + ) + # Проверка соединения + if not test_connection(transport, UNIT_ID): + logger.error("=" * 60) + logger.error("КРИТИЧЕСКАЯ ОШИБКА: Не удалось подключиться к устройству") + logger.error(f"Проверьте:") + logger.error(f" 1. Правильность имени порта ({PORT})") + logger.error(f" 2. Подключение кабеля") + logger.error(f" 3. Питание устройства") + logger.error(f" 4. Адрес устройства ({UNIT_ID})") + logger.error(f" 5. Скорость обмена ({BAUDRATE})") + logger.error("=" * 60) + return 1 + # Создание клиента ПР100 + pr100 = OwenModbusClient(transport=transport, device=PR100, unit=UNIT_ID) + logger.info("-" * 60) + # Чтение дискретных входов + read_digital_inputs(pr100, num_inputs=4) + logger.info("-" * 60) + # Чтение аналоговых входов + read_analog_inputs(pr100) + logger.info("-" * 60) + # Чтение системного времени + read_system_time(pr100) + logger.info("-" * 60) + # Установка системного времени (закомментировано по умолчанию) + # if input("Установить текущее время? (y/N): ").lower() == 'y': + # set_system_time(pr100) + # logger.info("-" * 60) + # Управление выходами + # ВНИМАНИЕ: Записывается только когда переключатель в положении СТОП! + logger.warning("ВНИМАНИЕ: Управление выходами работает только в режиме СТОП!") + control_outputs(pr100, {1: True, 2: False, 3: True}) + logger.info("-" * 60) + # Запуск мониторинга (закомментировано по умолчанию) + # monitoring_loop(pr100, duration=30) + logger.info("=" * 60) + logger.info("Работа завершена успешно") + logger.info("=" * 60) + return 0 + except FileNotFoundError as e: + logger.error("=" * 60) + logger.error(f"ОШИБКА: Порт {PORT} не найден") + logger.error("Доступные порты можно посмотреть с помощью команды:") + logger.error(" python -m serial.tools.list_ports") + logger.error("=" * 60) + return 1 + except ModbusException as e: + logger.error("=" * 60) + logger.error(f"ОШИБКА Modbus: {e}") + logger.error("=" * 60) + return 1 + except KeyboardInterrupt: + logger.info("=" * 60) + logger.info("Работа прервана пользователем") + logger.info("=" * 60) + return 0 + except Exception as e: + logger.error("=" * 60) + logger.error(f"НЕОЖИДАННАЯ ОШИБКА: {e}", exc_info=True) + logger.error("=" * 60) + return 1 + finally: + if transport is not None: + try: + transport.close() + logger.info("Соединение закрыто") + except Exception as e: + logger.error(f"Ошибка при закрытии соединения: {e}") + +if __name__ == "__main__": + sys.exit(main()) \ No newline at end of file diff --git a/owen/__init__.py b/owen/__init__.py new file mode 100644 index 0000000..e69de29 diff --git a/owen/__pycache__/__init__.cpython-314.pyc b/owen/__pycache__/__init__.cpython-314.pyc new file mode 100644 index 0000000..72e392c Binary files /dev/null and b/owen/__pycache__/__init__.cpython-314.pyc differ diff --git a/owen/__pycache__/client.cpython-314.pyc b/owen/__pycache__/client.cpython-314.pyc new file mode 100644 index 0000000..158f822 Binary files /dev/null and b/owen/__pycache__/client.cpython-314.pyc differ diff --git a/owen/__pycache__/converter.cpython-314.pyc b/owen/__pycache__/converter.cpython-314.pyc new file mode 100644 index 0000000..8d5e613 Binary files /dev/null and b/owen/__pycache__/converter.cpython-314.pyc differ diff --git a/owen/__pycache__/device.cpython-314.pyc b/owen/__pycache__/device.cpython-314.pyc new file mode 100644 index 0000000..a79a774 Binary files /dev/null and b/owen/__pycache__/device.cpython-314.pyc differ diff --git a/owen/__pycache__/protocol.cpython-314.pyc b/owen/__pycache__/protocol.cpython-314.pyc new file mode 100644 index 0000000..254f3c1 Binary files /dev/null and b/owen/__pycache__/protocol.cpython-314.pyc differ diff --git a/owen/client.py b/owen/client.py new file mode 100644 index 0000000..021757d --- /dev/null +++ b/owen/client.py @@ -0,0 +1,209 @@ +#! /usr/bin/env python3 + +"""Реализация класса клиента для управления контроллером ОВЕН.""" + +from __future__ import annotations + +from operator import mul, truediv +from typing import TYPE_CHECKING, Callable + +from pymodbus.constants import Endian +from pymodbus.payload import BinaryPayloadBuilder, BinaryPayloadDecoder + +from owen.protocol import Owen, OwenError + +if TYPE_CHECKING: + from pymodbus.client.sync import ModbusSerialClient + from pymodbus.pdu import ModbusResponse + from serial import Serial + + from owen.device import MODBUS_PARAMS, OWEN_DEVICE, OWEN_PARAMS + + +class ClientMixin: + """Класс-примесь клиента.""" + + @staticmethod + def check_index(name: str, dev: OWEN_PARAMS | MODBUS_PARAMS, + index: int | None) -> int | None: + """Проверка индекса.""" + + if not index: + index = None if None in dev["index"] else 0 + if index not in dev["index"]: + msg = f"'{name}' does not support index '{index}'" + raise OwenError(msg) + + return index + + @staticmethod + def check_value(name: str, dev: OWEN_PARAMS | MODBUS_PARAMS, + value: float | str | None) -> None: + """Проверка данных.""" + + if all([value is None, dev["min"] is not None, dev["max"] is not None]) or \ + all([value is not None, dev["min"] == dev["max"] is None or + value < dev["min"] or value > dev["max"]]): # type: ignore + msg = f"An '{name}' value of '{value}' is out of range" + raise OwenError(msg) + + +class OwenSerialClient(ClientMixin): + """Класс клиента для взаимодействия с устройством по протоколу ОВЕН.""" + + def __init__(self, transport: Serial, device: OWEN_DEVICE, unit: int, *, + addr_len_8: bool = True) -> None: + """Инициализация класса клиента с указанными параметрами.""" + + self.socket = transport + self.unit = unit + self.device = device + self.addr_len_8 = addr_len_8 + + self._owen = Owen(self.unit, addr_len_8) + + def __repr__(self) -> str: + """Строковое представление объекта.""" + + return (f"{type(self).__name__}(transport={self.socket}, unit={self.unit}, " + f"addr_len_8={self.addr_len_8})") + + def __del__(self) -> None: + """Закрытие соединения с устройством при удалении объекта.""" + + if self.socket: + self.socket.close() + + def bus_exchange(self, packet: bytes) -> bytes: + """Обмен по интерфейсу.""" + + self.socket.reset_input_buffer() + self.socket.reset_output_buffer() + + self.socket.write(packet) + return self.socket.read_until(b"\r") + + def send_message(self, flag: int, name: str, index: int | None, + data: bytes = b"") -> bytes: + """Подготовка данных для обмена.""" + + packet = self._owen.make_packet(flag, name, index, data) + answer = self.bus_exchange(packet) + return self._owen.parse_response(packet, answer) + + def get_param(self, name: str, index: int | None = None) -> float | str: + """Чтение данных из устройства.""" + + dev = self.device["Owen"][name.upper()] + index = self.check_index(name, dev, index) + result = self.send_message(1, name, index) + return self._owen.unpack_value(dev["type"], result, index) + + def set_param(self, name: str, index: int | None = None, + value: float | str | None = None) -> bool: + """Запись данных в устройство.""" + + dev = self.device["Owen"][name.upper()] + index = self.check_index(name, dev, index) + self.check_value(name, dev, value) + data = self._owen.pack_value(dev["type"], value) + return bool(self.send_message(0, name, index, data)) + + +class OwenModbusClient(ClientMixin): + """Класс клиента для взаимодействия с устройством по протоколу Modbus.""" + + def __init__(self, transport: ModbusSerialClient, device: OWEN_DEVICE, + unit: int) -> None: + """Инициализация класса клиента с указанными параметрами.""" + + self.socket = transport + self.unit = unit + self.device = device + + self.socket.connect() + + def __repr__(self) -> str: + """Строковое представление объекта.""" + + return f"{type(self).__name__}(transport={self.socket}, unit={self.unit})" + + def __del__(self) -> None: + """Закрытие соединения с устройством при удалении объекта.""" + + if self.socket: + self.socket.close() + + @staticmethod + def check_error(retcode: ModbusResponse) -> bool: + """Проверка возвращаемого значения на ошибку.""" + + if retcode.isError(): + raise OwenError(retcode) + return True + + def _read(self, dev: MODBUS_PARAMS, index: int | None) -> float | str: + """Чтение данных из регистра Modbus.""" + + count = {"U16": 1, "I16": 1, "U32": 2, "I32": 2, "F32": 2, "STR": 4, + }[dev["type"]] + result = self.socket.read_holding_registers(address=dev["index"][index], + count=count, + unit=self.unit) + self.check_error(result) + decoder = BinaryPayloadDecoder.fromRegisters(result.registers, Endian.Big) + + return {"U16": decoder.decode_16bit_uint, + "I16": decoder.decode_16bit_int, + "U32": decoder.decode_32bit_uint, + "I32": decoder.decode_32bit_int, + "F32": decoder.decode_32bit_float, + "STR": lambda: decoder.decode_string(8), + }[dev["type"]]() + + def modify_value(self, func: Callable[[float, float], float], dev: MODBUS_PARAMS, + index: int | None, value: float) -> float: + """Преобразование значения к нужной точности.""" + + if dev["dp"]: + dp_dev = self.device["Modbus"][dev["dp"]] + dp = self._read(dp_dev, index) + value = func(value, 10.0**int(dp)) + + prec = dev["precision"] + return func(value, 10.0**prec) if prec else value + + def get_param(self, name: str, index: int | None = None) -> float | str: + """Чтение данных из устройства.""" + + dev = self.device["Modbus"][name.upper()] + index = self.check_index(name, dev, index) + value = self._read(dev, index) + return self.modify_value(truediv, dev, index, value) + + def set_param(self, name: str, index: int | None = None, + value: float | str | None = None) -> bool: + """Запись данных в устройство.""" + + dev = self.device["Modbus"][name.upper()] + index = self.check_index(name, dev, index) + self.check_value(name, dev, value) + value = self.modify_value(mul, dev, index, value) + + builder = BinaryPayloadBuilder(None, Endian.Big) + {"U16": lambda value: builder.add_16bit_uint(int(value)), + "I16": lambda value: builder.add_16bit_int(int(value)), + "U32": lambda value: builder.add_32bit_uint(int(value)), + "I32": lambda value: builder.add_32bit_int(int(value)), + "F32": lambda value: builder.add_32bit_float(float(value)), + "STR": lambda value: builder.add_string(str(value)), + }[dev["type"]](value) + + result = self.socket.write_registers(address=dev["index"][index], + values=builder.build(), + skip_encode=True, + unit=self.unit) + return self.check_error(result) + + +__all__ = ["OwenModbusClient", "OwenSerialClient"] diff --git a/owen/converter.py b/owen/converter.py new file mode 100644 index 0000000..18fb6ee --- /dev/null +++ b/owen/converter.py @@ -0,0 +1,229 @@ +#! /usr/bin/env python3 + +"""Функции для упаковки и распаковки разных типов данных.""" + +from binascii import hexlify, unhexlify +from decimal import Decimal +from struct import pack, unpack + + +def pack_str(value: str) -> bytes: + """Упаковка данных типа STR.""" + + return bytes(value[::-1], encoding="cp1251") + + +def unpack_str(value: bytes, index: int) -> str: + """Распаковка данных типа STR.""" + + return bytes(value[::-1]).decode("cp1251") + + +def pack_u24(value: tuple[int, int]) -> bytes: + """Упаковка данных типа U24.""" + + return pack(">BH", *value)[:3] + + +def unpack_u24(value: bytes, index: int) -> tuple[int, int]: + """Распаковка данных типа U24.""" + + return unpack(">BH", value[:3]) + + +def pack_i8(value: int) -> bytes: + """Упаковка данных типа I8.""" + + return pack(">b", value)[:1] + + +def unpack_i8(value: bytes, index: int) -> int: + """Распаковка данных типа I8.""" + + return unpack(">b", value[:1])[0] + + +def pack_u8(value: int) -> bytes: + """Упаковка данных типа U8.""" + + return pack(">B", value)[:1] + + +def unpack_u8(value: bytes, index: int) -> int: + """Распаковка данных типа U8.""" + + return unpack(">B", value[:1])[0] + + +def pack_i16(value: int) -> bytes: + """Упаковка данных типа I16.""" + + return pack(">h", value)[:2] + + +def unpack_i16(value: bytes, index: int) -> int: + """Распаковка данных типа I16.""" + + return unpack(">h", value[:2])[0] + + +def pack_u16(value: int) -> bytes: + """Упаковка данных типа U16.""" + + return pack(">H", value)[:2] + + +def unpack_u16(value: bytes, index: int) -> int: + """Распаковка данных типа U16.""" + + return unpack(">H", value[:2])[0] + + +def pack_f24(value: float) -> bytes: + """Упаковка данных типа F24.""" + + return pack(">f", value)[:3] + + +def unpack_f24(value: bytes, index: int) -> float: + """Распаковка данных типа F24.""" + + return unpack(">f", value[:3] + b"\x00")[0] + + +def pack_f32(value: float) -> bytes: + """Упаковка данных типа F32.""" + + return pack(">f", value)[:4] + + +def unpack_f32(value: bytes, index: int) -> float: + """Распаковка данных типа F32.""" + + return unpack(">f", value[:4])[0] + + +def pack_f32t(value: tuple[float, int]) -> bytes: + """Упаковка данных типа F32+T.""" + + return pack(">fH", *value)[:6] + + +def unpack_f32t(value: bytes, index: int) -> tuple[float, int]: + """Распаковка данных типа F32+T.""" + + return unpack(">fH", value[:6]) + + +def pack_i32(value: int) -> bytes: + """Упаковка данных типа I32.""" + + return pack(">i", value)[:4] + + +def unpack_i32(value: bytes, index: int) -> int: + """Распаковка данных типа I32.""" + + return unpack(">i", value[:4])[0] + + +def pack_u32(value: int) -> bytes: + """Упаковка данных типа U32.""" + + return pack(">I", value)[:4] + + +def unpack_u32(value: bytes, index: int) -> int: + """Распаковка данных типа U32.""" + + return unpack(">I", value[:4])[0] + + +def pack_sdot(value: float) -> bytes: + """Упаковка данных типа STORED_DOT.""" + + sign, digits, exponent = Decimal(str(value)).as_tuple() + mantissa = int("".join(map(str, digits))) + + frmt, size, chunk = {mantissa < 16: (">B", 4, slice(1)), + mantissa >= 4096: (">I", 20, slice(1, 4)), + }.get(True, (">H", 12, slice(2))) + + bin_str = f"{sign:1b}{abs(exponent):03b}{mantissa:0{size}b}" + return pack(frmt, int(bin_str, 2))[chunk] + + +def unpack_sdot(value: bytes, index: int) -> float: + """Распаковка данных типа STORED_DOT.""" + + if index is not None: + value = value[:-2] + + data = int.from_bytes(value, "big") + shift = len(value) * 8 - 4 + + sign = data >> (shift + 3) & 1 + exponent = data >> shift & 7 + mantissa = data & (2 ** shift - 1) + + return (-1) ** sign * 10 ** (-exponent) * mantissa + + +def _encode_dot_u(value: float) -> bytes: + """Упаковка данных типа DEC_DOTi.""" + + value = int(value) + length = len(str(value)) + length += length % 2 + hexstr = f"{value:0{length}d}" + + return unhexlify(hexstr) + + +def pack_dot0(value: float) -> bytes: + """Упаковка данных типа DEC_DOT0.""" + + return _encode_dot_u(value) + + +def pack_dot3(value: float) -> bytes: + """Упаковка данных типа DEC_DOT3.""" + + return _encode_dot_u(value * 1000) + + +def _decode_dot_u(value: bytes, index: int) -> int: + """Распаковка данных типа DEC_DOTi.""" + + if index is not None: + value = value[:-2] + + return int(hexlify(value).decode()) + + +def unpack_dot0(value: bytes, index: int) -> int: + """Распаковка данных типа DEC_DOT0.""" + + return _decode_dot_u(value, index) + + +def unpack_dot3(value: bytes, index: int) -> float: + """Распаковка данных типа DEC_DOT3.""" + + return _decode_dot_u(value, index) / 1000.0 + + +OWEN_TYPE = {"F32+T": {"pack": pack_f32t, "unpack": unpack_f32t}, + "SDOT": {"pack": pack_sdot, "unpack": unpack_sdot}, + "DOT0": {"pack": pack_dot0, "unpack": unpack_dot0}, + "DOT3": {"pack": pack_dot3, "unpack": unpack_dot3}, + "F32": {"pack": pack_f32, "unpack": unpack_f32}, + "F24": {"pack": pack_f24, "unpack": unpack_f24}, + "U16": {"pack": pack_u16, "unpack": unpack_u16}, + "I16": {"pack": pack_i16, "unpack": unpack_i16}, + "U32": {"pack": pack_u32, "unpack": unpack_u32}, + "I32": {"pack": pack_i32, "unpack": unpack_i32}, + "U8": {"pack": pack_u8, "unpack": unpack_u8}, + "I8": {"pack": pack_i8, "unpack": unpack_i8}, + "U24": {"pack": pack_u24, "unpack": unpack_u24}, # для N.err + "STR": {"pack": pack_str, "unpack": unpack_str}} diff --git a/owen/device.py b/owen/device.py new file mode 100644 index 0000000..1980420 --- /dev/null +++ b/owen/device.py @@ -0,0 +1,1244 @@ +#! /usr/bin/env python3 + + +"""Данный файл содержит настройки приборов.""" + +# Назначение полей таблиц настроек: +# 1. Тип протокола Owen +# * Название параметра (в верхнем регистре) +# - Тип параметра +# - Словарь поддерживаемых индексов (None - индекса нет; 0,1 и т.д) + адрес индекса +# - Минимальное значение параметра +# - Максимальное значение параметра +# 2. Тип протокола Modbus +# * Название параметра (в верхнем регистре) +# - Тип параметра +# - Словарь поддерживаемых индексов (None - индекса нет; 0,1 и т.д) + адрес Modbus +# - Минимальное значение параметра +# - Максимальное значение параметра +# - Признак зависимости значения от другого параметра: название параметра или None +# - Кол-во знаков после запятой + +# Поддерживаемые типы данных: +# I8, U8 - signed and unsigned char (1 byte) +# I16, U16 - signed and unsigned short (2 bytes) +# I32, U32 - signed and unsigned int (4 bytes) +# U24 - for N.ERR (3 bytes) +# F24, F32 - float (3 or 4 bytes) +# F32+T - float + time modificator (6 bytes) +# STR - string (8 bytes) +# SDOT - STORED_DOT +# DOT0, DOT3 - DEC_DOT0, DEC_DOT3 + +from __future__ import annotations + +from typing import TypedDict + + +class OWEN_PARAMS(TypedDict): + type: str + index: dict[int | None, int | None] + min: int | float | None + max: int | float | None + + +class MODBUS_PARAMS(TypedDict): + type: str + index: dict[int | None, int] + min: int | float | None + max: int | float | None + dp: str | None + precision: int + + +class OWEN_DEVICE(TypedDict): + Owen: dict[str, OWEN_PARAMS] + Modbus: dict[str, MODBUS_PARAMS] + + +# Таблица настроек измерителя-ПИД-регулятора ТРМ101 +TRM101: OWEN_DEVICE = { + "Owen": {"PV": {"type": "F24", "index": {None: None}, "min": -1999, "max": 9999}, + "SP": {"type": "F24", "index": {None: None}, "min": -1999, "max": 9999}, + "R-S": {"type": "U8", "index": {None: None}, "min": 0, "max": 1}, + "AT": {"type": "U8", "index": {None: None}, "min": 0, "max": 1}, + "O": {"type": "F24", "index": {None: None}, "min": 0, "max": 100}, + "IN-T": {"type": "U8", "index": {None: None}, "min": 1, "max": 26}, + "DPT": {"type": "U8", "index": {None: None}, "min": 0, "max": 1}, + "DP": {"type": "U8", "index": {None: None}, "min": 0, "max": 3}, + "IN-L": {"type": "F24", "index": {None: None}, "min": -1999, "max": 9999}, + "IN-H": {"type": "F24", "index": {None: None}, "min": -1999, "max": 9999}, + "SL-L": {"type": "F24", "index": {None: None}, "min": -1999, "max": 9999}, + "SL-H": {"type": "F24", "index": {None: None}, "min": -1999, "max": 9999}, + "SH": {"type": "F24", "index": {None: None}, "min": -500, "max": 500}, + "KU": {"type": "F24", "index": {None: None}, "min": 0.500, "max": 2.000}, + "INF": {"type": "F24", "index": {None: None}, "min": 0, "max": 999}, + "FB": {"type": "F24", "index": {None: None}, "min": 0, "max": 9999}, + "AN-L": {"type": "F24", "index": {None: None}, "min": -1999, "max": 9999}, + "AN-H": {"type": "F24", "index": {None: None}, "min": -1999, "max": 9999}, + "EV-1": {"type": "U8", "index": {None: None}, "min": 0, "max": 2}, + "ALT": {"type": "U8", "index": {None: None}, "min": 0, "max": 11}, + "AL-D": {"type": "F24", "index": {None: None}, "min": -1999, "max": 9999}, + "AL-H": {"type": "F24", "index": {None: None}, "min": 0, "max": 9999}, + "OREU": {"type": "U8", "index": {None: None}, "min": 0, "max": 1}, + "CP": {"type": "U8", "index": {None: None}, "min": 1, "max": 250}, + "VSP": {"type": "F24", "index": {None: None}, "min": 0, "max": 9999}, + "CNTL": {"type": "U8", "index": {None: None}, "min": 0, "max": 1}, + "HYST": {"type": "F24", "index": {None: None}, "min": 0, "max": 9999}, + "ONST": {"type": "U8", "index": {None: None}, "min": 0, "max": 1}, + "ONER": {"type": "U8", "index": {None: None}, "min": 0, "max": 1}, + "RAMP": {"type": "U8", "index": {None: None}, "min": 0, "max": 1}, + "P": {"type": "F24", "index": {None: None}, "min": 0.001, "max": 9999}, + "I": {"type": "F24", "index": {None: None}, "min": 0, "max": 3999}, + "D": {"type": "F24", "index": {None: None}, "min": 0, "max": 3999}, + "DB": {"type": "F24", "index": {None: None}, "min": 0, "max": 200}, + "OL-L": {"type": "F24", "index": {None: None}, "min": 0, "max": 100}, + "OL-H": {"type": "F24", "index": {None: None}, "min": 0, "max": 100}, + "ORL": {"type": "F24", "index": {None: None}, "min": 0.2, "max": 100}, + "MVER": {"type": "F24", "index": {None: None}, "min": 0, "max": 100}, + "MVST": {"type": "F24", "index": {None: None}, "min": 0, "max": 100}, + "MDST": {"type": "U8", "index": {None: None}, "min": 0, "max": 1}, + "LBA": {"type": "U16", "index": {None: None}, "min": 0, "max": 9999}, + "LBAB": {"type": "F24", "index": {None: None}, "min": 0, "max": 9999}, + "ADDR": {"type": "U16", "index": {None: None}, "min": 0, "max": 2047}, + "RSDL": {"type": "U8", "index": {None: None}, "min": 1, "max": 45}, + "A.LEN": {"type": "U8", "index": {None: None}, "min": 0, "max": 1}, + "BPS": {"type": "U8", "index": {None: None}, "min": 0, "max": 8}, + "LEN": {"type": "U8", "index": {None: None}, "min": 1, "max": 1}, + "PRTY": {"type": "U8", "index": {None: None}, "min": 0, "max": 0}, + "SBIT": {"type": "U8", "index": {None: None}, "min": 0, "max": 0}, + "VER": {"type": "STR", "index": {None: None}, "min": None, "max": None}, + "DEV": {"type": "STR", "index": {None: None}, "min": None, "max": None}, + "APLY": {"type": "U8", "index": {None: None}, "min": None, "max": None}, + "INIT": {"type": "U8", "index": {None: None}, "min": None, "max": None}, + "N.ERR": {"type": "U24", "index": {None: None}, "min": 0, "max": 255}, + "ATTR": {"type": "U8", "index": {None: None}, "min": 0, "max": 1}, + "O-ED": {"type": "F24", "index": {None: None}, "min": 0, "max": 100}, + "O.": {"type": "F24", "index": {None: None}, "min": 0, "max": 100}, + "EDPT": {"type": "U8", "index": {None: None}, "min": 0, "max": 1}, + }, +} + +# Таблица настроек измерителя-регулятора шестиканального ТРМ136 +TRM136: OWEN_DEVICE = { + "Owen": {"IND.T": {"type": "DOT0", "index": {None: None}, "min": 1, "max": 600}, + "IND.R": {"type": "DOT0", "index": {None: None}, "min": 0, "max": 60}, + "IND.A": {"type": "U8", "index": {None: None}, "min": 0, "max": 1}, + "AL.DR": {"type": "DOT0", "index": {None: None}, "min": 0, "max": 6}, + "AL.HD": {"type": "DOT0", "index": {None: None}, "min": 1, "max": 600}, + "AL.ST": {"type": "U8", "index": {None: None}, "min": 0, "max": 1}, + "CJ-.C": {"type": "U8", "index": {None: None}, "min": 0, "max": 1}, + "SYST": {"type": "U8", "index": {None: None}, "min": 0, "max": 1}, + "BL.AR": {"type": "U8", "index": {None: None}, "min": 0, "max": 1}, + "IN.FD": {"type": "DOT0", "index": {None: None}, "min": 0, "max": 15}, + "PRT": {"type": "DOT0", "index": {None: None}, "min": 1, "max": 6}, + "IN.SH": {"type": "SDOT", "index": {None: None}, "min": -99.9, "max": 999.9}, + "IN.SL": {"type": "DOT3", "index": {None: None}, "min": 0.9, "max": 1.1}, + "IN-T": {"type": "U8", "index": {None: None}, "min": 0, "max": 21}, + "IN.FG": {"type": "SDOT", "index": {None: None}, "min": 0, "max": 100}, + "AIN.L": {"type": "SDOT", "index": {None: None}, "min": -999, "max": 9999}, + "AIN.H": {"type": "SDOT", "index": {None: None}, "min": -999, "max": 9999}, + "C.SP": {"type": "SDOT", "index": {None: None}, "min": -999, "max": 9999}, + "HYST": {"type": "SDOT", "index": {None: None}, "min": 1, "max": 9999}, + "C.SP.O": {"type": "SDOT", "index": {None: None}, "min": 0, "max": 9999}, + "HT.ON": {"type": "DOT0", "index": {None: None}, "min": 0, "max": 9000}, + "HT.OF": {"type": "DOT0", "index": {None: None}, "min": 0, "max": 9000}, + "DL.ON": {"type": "DOT0", "index": {None: None}, "min": 0, "max": 3600}, + "DL.OF": {"type": "DOT0", "index": {None: None}, "min": 0, "max": 3600}, + "BL.ST": {"type": "U8", "index": {None: None}, "min": 0, "max": 1}, + "DP_": {"type": "DOT0", "index": {None: None}, "min": 0, "max": 3}, + "ER.ST": {"type": "U8", "index": {None: None}, "min": 0, "max": 1}, + "AL.T": {"type": "DOT0", "index": {None: None}, "min": 0, "max": 5}, + "AO.L": {"type": "SDOT", "index": {None: None}, "min": -999, "max": 9999}, + "AO.H": {"type": "SDOT", "index": {None: None}, "min": -999, "max": 9999}, + "C.DR": {"type": "DOT0", "index": {None: None}, "min": 0, "max": 6}, + "C.LBT": {"type": "DOT0", "index": {None: None}, "min": 0, "max": 9000}, + "AL.OU": {"type": "U8", "index": {None: None}, "min": 0, "max": 1}, + "C.LBA": {"type": "SDOT", "index": {None: None}, "min": 1, "max": 100}, + "C.IN": {"type": "DOT0", "index": {None: None}, "min": 0, "max": 18}, + "BPS": {"type": "U8", "index": {None: None}, "min": 0, "max": 8}, + "LEN": {"type": "U8", "index": {None: None}, "min": 0, "max": 1}, + "PRTY": {"type": "U8", "index": {None: None}, "min": 0, "max": 2}, + "SBIT": {"type": "U8", "index": {None: None}, "min": 0, "max": 1}, + "A.LEN": {"type": "U8", "index": {None: None}, "min": 0, "max": 1}, + "ADDR": {"type": "U16", "index": {None: None}, "min": 0, "max": 2040}, + "N.FLT": {"type": "U8", "index": {None: None}, "min": 0, "max": 8}, + "DATA": {"type": "U8", "index": {None: None}, "min": 0, "max": 7}, + "T.INC": {"type": "U8", "index": {None: None}, "min": 0, "max": 1}, + "CHAR": {"type": "STR", "index": {None: None}, "min": None, "max": None}, + "SOUR": {"type": "U16", "index": {None: None}, "min": 0, "max": 2047}, + "READ": {"type": "F32+T", "index": {None: None}, "min": -2**127, "max": 2**127}, + "DR.DG": {"type": "DOT0", "index": {None: None}, "min": 0, "max": 1}, + "N.ERR": {"type": "U24", "index": {None: None}, "min": 0, "max": 255}, + }, + "Modbus": {"READ": {"type": "F32", "index": {0: 0x0003, 1: 0x0008, 2: 0x000D, 3: 0x0012, 4: 0x0017, 5: 0x001C}, "min": -999, "max": 9999, "dp": None, "precision": 0}, + "R.CAL": {"type": "F32", "index": {0: 0x0043, 1: 0x0048, 2: 0x004D, 3: 0x0052, 4: 0x0057, 5: 0x005C}, "min": -999, "max": 9999, "dp": None, "precision": 0}, + "R.CIN": {"type": "U16", "index": {0: 0x0000, 1: 0x0001, 2: 0x0002, 3: 0x0003, 4: 0x0004, 5: 0x0005}, "min": -999, "max": 9999, "dp": None, "precision": 0}, + "C.SP": {"type": "U16", "index": {0: 0x0011, 1: 0x0015, 2: 0x0019, 3: 0x001D, 4: 0x0021, 5: 0x0025}, "min": -999, "max": 9999, "dp": None, "precision": 0}, + "C.SP.S": {"type": "U16", "index": {0: 0x0013, 1: 0x0017, 2: 0x001B, 3: 0x001F, 4: 0x0023, 5: 0x0027}, "min": -999, "max": 9999, "dp": None, "precision": 0}, + "HYST": {"type": "U16", "index": {0: 0x0031, 1: 0x0033, 2: 0x0035, 3: 0x0037, 4: 0x0039, 5: 0x003B}, "min": 0.001, "max": 9999, "dp": None, "precision": 0}, + # "": {"type": "U16", "index": {0: 0x0000, 1: 0x0001, 2: 0x0002, 3: 0x0003, 4: 0x0004, 5: 0x0005}, "min": -999, "max": 9999, "dp": None, "precision": 0}, # Состояние ВУ - название параметра неизвестно + }, +} + +# Таблица настроек измерителя-регулятора восьмиканального ТРМ138 +TRM138: OWEN_DEVICE = { + "Owen": {"IND.T": {"type": "DOT0", "index": {None: None}, "min": 1, "max": 600}, + "IND.R": {"type": "DOT0", "index": {None: None}, "min": 0, "max": 60}, + "IND.A": {"type": "U8", "index": {None: None}, "min": 0, "max": 1}, + "AL.DR": {"type": "DOT0", "index": {None: None}, "min": 0, "max": 8}, + "AL.HD": {"type": "DOT0", "index": {None: None}, "min": 1, "max": 600}, + "AL.ST": {"type": "U8", "index": {None: None}, "min": 0, "max": 1}, + "CJ-.C": {"type": "U8", "index": {None: None}, "min": 0, "max": 1}, + "SYST": {"type": "U8", "index": {None: None}, "min": 0, "max": 1}, + "BL.AR": {"type": "U8", "index": {None: None}, "min": 0, "max": 1}, + "IN.FD": {"type": "DOT0", "index": {None: None}, "min": 0, "max": 15}, + "PRT": {"type": "DOT0", "index": {None: None}, "min": 1, "max": 8}, + "IN.SH": {"type": "SDOT", "index": {None: None}, "min": -99.9, "max": 999.9}, + "IN.SL": {"type": "DOT3", "index": {None: None}, "min": 0.9, "max": 1.1}, + "IN-T": {"type": "U8", "index": {None: None}, "min": 0, "max": 21}, + "IN.FG": {"type": "SDOT", "index": {None: None}, "min": 0, "max": 100}, + "AIN.L": {"type": "SDOT", "index": {None: None}, "min": -999, "max": 9999}, + "AIN.H": {"type": "SDOT", "index": {None: None}, "min": -999, "max": 9999}, + "C.SP": {"type": "SDOT", "index": {None: None}, "min": -999, "max": 9999}, + "HYST": {"type": "SDOT", "index": {None: None}, "min": 1, "max": 9999}, + "C.SP.O": {"type": "SDOT", "index": {None: None}, "min": 0, "max": 9999}, + "HT.ON": {"type": "DOT0", "index": {None: None}, "min": 0, "max": 9000}, + "HT.OF": {"type": "DOT0", "index": {None: None}, "min": 0, "max": 9000}, + "DL.ON": {"type": "DOT0", "index": {None: None}, "min": 0, "max": 3600}, + "DL.OF": {"type": "DOT0", "index": {None: None}, "min": 0, "max": 3600}, + "BL.ST": {"type": "U8", "index": {None: None}, "min": 0, "max": 1}, + "DP_": {"type": "DOT0", "index": {None: None}, "min": 0, "max": 3}, + "ER.ST": {"type": "U8", "index": {None: None}, "min": 0, "max": 1}, + "AL.T": {"type": "DOT0", "index": {None: None}, "min": 0, "max": 5}, + "AO.L": {"type": "SDOT", "index": {None: None}, "min": -999, "max": 9999}, + "AO.H": {"type": "SDOT", "index": {None: None}, "min": -999, "max": 9999}, + "C.DR": {"type": "DOT0", "index": {None: None}, "min": 0, "max": 8}, + "C.LBT": {"type": "DOT0", "index": {None: None}, "min": 0, "max": 9000}, + "AL.OU": {"type": "U8", "index": {None: None}, "min": 0, "max": 1}, + "C.LBA": {"type": "SDOT", "index": {None: None}, "min": 1, "max": 100}, + "C.IN": {"type": "DOT0", "index": {None: None}, "min": 0, "max": 19}, + "BPS": {"type": "U8", "index": {None: None}, "min": 0, "max": 8}, + "LEN": {"type": "U8", "index": {None: None}, "min": 0, "max": 1}, + "PRTY": {"type": "U8", "index": {None: None}, "min": 0, "max": 2}, + "SBIT": {"type": "U8", "index": {None: None}, "min": 0, "max": 1}, + "A.LEN": {"type": "U8", "index": {None: None}, "min": 0, "max": 1}, + "ADDR": {"type": "U16", "index": {None: None}, "min": 0, "max": 2040}, + "N.FLT": {"type": "U8", "index": {None: None}, "min": 0, "max": 8}, + "DATA": {"type": "U8", "index": {None: None}, "min": 0, "max": 7}, + "T.INC": {"type": "U8", "index": {None: None}, "min": 0, "max": 1}, + "CHAR": {"type": "STR", "index": {None: None}, "min": None, "max": None}, + "SOUR": {"type": "U16", "index": {None: None}, "min": 0, "max": 2047}, + "READ": {"type": "F32+T", "index": {None: None}, "min": -2**127, "max": 2**127}, + "DR.DG": {"type": "DOT0", "index": {None: None}, "min": 0, "max": 1}, + "N.ERR": {"type": "U24", "index": {None: None}, "min": 0, "max": 255}, + }, + "Modbus": {"READ": {"type": "F32", "index": {0: 0x0003, 1: 0x0008, 2: 0x000D, 3: 0x0012, 4: 0x0017, 5: 0x001C, 6: 0x0021, 7: 0x0026}, "min": -999, "max": 9999, "dp": None, "precision": 0}, + "R.CAL": {"type": "F32", "index": {0: 0x0043, 1: 0x0048, 2: 0x004D, 3: 0x0052, 4: 0x0057, 5: 0x005C, 6: 0x0061, 7: 0x0066}, "min": -999, "max": 9999, "dp": None, "precision": 0}, + "R.CIN": {"type": "U16", "index": {0: 0x0000, 1: 0x0001, 2: 0x0002, 3: 0x0003, 4: 0x0004, 5: 0x0005, 6: 0x0006, 7: 0x0007}, "min": -999, "max": 9999, "dp": None, "precision": 0}, + "C.SP": {"type": "U16", "index": {0: 0x0011, 1: 0x0015, 2: 0x0019, 3: 0x001D, 4: 0x0021, 5: 0x0025, 6: 0x0029, 7: 0x002D}, "min": -999, "max": 9999, "dp": None, "precision": 0}, + "C.SP.S": {"type": "U16", "index": {0: 0x0013, 1: 0x0017, 2: 0x001B, 3: 0x001F, 4: 0x0023, 5: 0x0027, 6: 0x002B, 7: 0x002F}, "min": -999, "max": 9999, "dp": None, "precision": 0}, + "HYST": {"type": "U16", "index": {0: 0x0031, 1: 0x0033, 2: 0x0035, 3: 0x0037, 4: 0x0039, 5: 0x003B, 6: 0x003D, 7: 0x003F}, "min": 0.001, "max": 9999, "dp": None, "precision": 0}, + "C.DR": {"type": "U16", "index": {0: 0x0041, 1: 0x0042, 2: 0x0043, 3: 0x0044, 4: 0x0045, 5: 0x0046, 6: 0x0047, 7: 0x0048}, "min": 0, "max": 8, "dp": None, "precision": 0}, + # "": {"type": "U16", "index": {0: 0x0051, 1: 0x0052, 2: 0x0053, 3: 0x0054, 4: 0x0055, 5: 0x0056, 6: 0x0057, 7: 0x0058}, "min": -999, "max": 9999, "dp": None, "precision": 0}, # Значение ЦАП ВУ - название параметра неизвестно + # "": {"type": "U16", "index": {0: 0x0000, 1: 0x0001, 2: 0x0002, 3: 0x0003, 4: 0x0004, 5: 0x0005, 6: 0x0006, 7: 0x0007}, "min": -999, "max": 9999, "dp": None, "precision": 0}, # Состояние ВУ - название параметра неизвестно + }, +} + +# Таблица настроек измерителя регулятора микропроцессорного ТРМ148 +TRM148: OWEN_DEVICE = { + "Owen": {"READ": {"type": "F32+T", "index": {None: None}, "min": -2**127, "max": 2**127}, + "R.CAL": {"type": "F32+T", "index": {None: None}, "min": -2**127, "max": 2**127}, + "CAL.T": {"type": "U8", "index": {0: 0, 1: 1, 2: 2, 3: 3, 4: 4, 5: 5, 6: 6, 7: 7}, "min": 0, "max": 9}, + "SP.LU": {"type": "SDOT", "index": {0: 0, 1: 1, 2: 2, 3: 3, 4: 4, 5: 5, 6: 6, 7: 7}, "min": -9999, "max": 9999}, + "P.-SP": {"type": "U8", "index": {0: 0, 1: 1, 2: 2, 3: 3, 4: 4, 5: 5, 6: 6, 7: 7}, "min": 0, "max": 1}, + "VER": {"type": "STR", "index": {None: None}, "min": None, "max": None}, + "DEV": {"type": "STR", "index": {None: None}, "min": None, "max": None}, + "MOD.V": {"type": "U8", "index": {None: None}, "min": 0, "max": 255}, + }, + "Modbus": {"R.ST": {"type": "U16", "index": {0: 0x0060, 1: 0x0061, 2: 0x0062, 3: 0x0063, 4: 0x0064, 5: 0x0065, 6: 0x0066, 7: 0x0067}, "min": 0, "max": 2, "dp": None, "precision": 0}, + # "": {"type": "F32", "index": {0: 0x0000, 1: 0x0002, 2: 0x0004, 3: 0x0006, 4: 0x0008, 5: 0x000A, 6: 0x000C, 7: 0x000E}, "min": -999, "max": 9999, "dp": None, "precision": 0}, # Измеритель - название параметра неизвестно + # "": {"type": "F32", "index": {0: 0x0020, 1: 0x0022, 2: 0x0024, 3: 0x0026, 4: 0x0028, 5: 0x002A, 6: 0x002C, 7: 0x002E}, "min": -999, "max": 9999, "dp": None, "precision": 0}, # Вычислитель - название параметра неизвестно + # "": {"type": "F32", "index": {0: 0x0040, 1: 0x0042, 2: 0x0044, 3: 0x0046, 4: 0x0048, 5: 0x004A, 6: 0x004C, 7: 0x004E}, "min": -999, "max": 9999, "dp": None, "precision": 0}, # Состояние ВУ - название параметра неизвестно + # "": {"type": "F32", "index": {0: 0x0080, 1: 0x0082, 2: 0x0084, 3: 0x0086, 4: 0x0088, 5: 0x008A, 6: 0x008C, 7: 0x008E}, "min": -999, "max": 9999, "dp": None, "precision": 0}, # Уставка рассчетная - название параметра неизвестно + "IN.T": {"type": "U16", "index": {0: 0x0100, 1: 0x0101, 2: 0x0102, 3: 0x0103, 4: 0x0104, 5: 0x0105, 6: 0x0106, 7: 0x0107}, "min": 1, "max": 41, "dp": None, "precision": 0}, + "IN.FD": {"type": "U16", "index": {0: 0x0110, 1: 0x0111, 2: 0x0112, 3: 0x0113, 4: 0x0114, 5: 0x0115, 6: 0x0116, 7: 0x0117}, "min": 0, "max": 1800, "dp": None, "precision": 0}, + "IN.FG": {"type": "F32", "index": {0: 0x0120, 1: 0x0122, 2: 0x0124, 3: 0x0126, 4: 0x0128, 5: 0x012A, 6: 0x012C, 7: 0x012E}, "min": 0, "max": 9999, "dp": None, "precision": 0}, + "ITRL": {"type": "F32", "index": {0: 0x0130, 1: 0x0132, 2: 0x0134, 3: 0x0136, 4: 0x0138, 5: 0x013A, 6: 0x013C, 7: 0x013E}, "min": 0, "max": 30, "dp": None, "precision": 0}, + "IN.SH": {"type": "F32", "index": {0: 0x0140, 1: 0x0142, 2: 0x0144, 3: 0x0146, 4: 0x0148, 5: 0x014A, 6: 0x014C, 7: 0x014E}, "min": -999, "max": 9999, "dp": None, "precision": 0}, + "IN.SL": {"type": "F32", "index": {0: 0x0150, 1: 0x0152, 2: 0x0154, 3: 0x0156, 4: 0x0158, 5: 0x015A, 6: 0x015C, 7: 0x015E}, "min": 0.9, "max": 1.1, "dp": None, "precision": 0}, + "AIN.L": {"type": "F32", "index": {0: 0x0160, 1: 0x0162, 2: 0x0164, 3: 0x0166, 4: 0x0168, 5: 0x016A, 6: 0x016C, 7: 0x016E}, "min": -999, "max": 9999, "dp": None, "precision": 0}, + "AIN.H": {"type": "F32", "index": {0: 0x0170, 1: 0x0172, 2: 0x0174, 3: 0x0176, 4: 0x0178, 5: 0x017A, 6: 0x017C, 7: 0x017E}, "min": -999, "max": 9999, "dp": None, "precision": 0}, + "A.IST": {"type": "F32", "index": {0: 0x0200, 1: 0x0202, 2: 0x0204, 3: 0x0206, 4: 0x0208, 5: 0x020A, 6: 0x020C, 7: 0x020E}, "min": -999, "max": 9999, "dp": None, "precision": 0}, + "REG.T": {"type": "U16", "index": {0: 0x0300, 1: 0x0301, 2: 0x0302, 3: 0x0303, 4: 0x0304, 5: 0x0305, 6: 0x0306, 7: 0x0307}, "min": 0, "max": 1, "dp": None, "precision": 0}, + "LBA": {"type": "U16", "index": {0: 0x0310, 1: 0x0311, 2: 0x0312, 3: 0x0313, 4: 0x0314, 5: 0x0315, 6: 0x0316, 7: 0x0317}, "min": 1, "max": 2, "dp": None, "precision": 0}, + "PB": {"type": "F32", "index": {0: 0x0320, 1: 0x0322, 2: 0x0324, 3: 0x0326, 4: 0x0328, 5: 0x032A, 6: 0x032C, 7: 0x032E}, "min": 0.001, "max": 9999, "dp": None, "precision": 0}, + "TI": {"type": "U16", "index": {0: 0x0330, 1: 0x0331, 2: 0x0332, 3: 0x0333, 4: 0x0334, 5: 0x0335, 6: 0x0336, 7: 0x0337}, "min": 0, "max": 65535, "dp": None, "precision": 0}, + "TD.TI": {"type": "F32", "index": {0: 0x0340, 1: 0x0342, 2: 0x0344, 3: 0x0346, 4: 0x0348, 5: 0x034A, 6: 0x034C, 7: 0x034E}, "min": 0, "max": 0.3, "dp": None, "precision": 0}, + "I.UPR": {"type": "F32", "index": {0: 0x0350, 1: 0x0352, 2: 0x0354, 3: 0x0356, 4: 0x0358, 5: 0x035A, 6: 0x035C, 7: 0x035E}, "min": -100, "max": 100, "dp": None, "precision": 0}, + "I.MIN": {"type": "F32", "index": {0: 0x0360, 1: 0x0362, 2: 0x0364, 3: 0x0366, 4: 0x0368, 5: 0x036A, 6: 0x036C, 7: 0x036E}, "min": -100, "max": 100, "dp": None, "precision": 0}, + "HYS.C": {"type": "F32", "index": {0: 0x0370, 1: 0x0372, 2: 0x0374, 3: 0x0376, 4: 0x0378, 5: 0x037A, 6: 0x037C, 7: 0x037E}, "min": 0, "max": 9999, "dp": None, "precision": 0}, + "P.RES": {"type": "F32", "index": {0: 0x0400, 1: 0x0402, 2: 0x0404, 3: 0x0406, 4: 0x0408, 5: 0x040A, 6: 0x040C, 7: 0x040E}, "min": 0, "max": 100, "dp": None, "precision": 0}, + "P.UPR": {"type": "F32", "index": {0: 0x0410, 1: 0x0412, 2: 0x0414, 3: 0x0416, 4: 0x0418, 5: 0x041A, 6: 0x041C, 7: 0x041E}, "min": -100, "max": 100, "dp": None, "precision": 0}, + "P.MIN": {"type": "F32", "index": {0: 0x0420, 1: 0x0422, 2: 0x0424, 3: 0x0426, 4: 0x0428, 5: 0x042A, 6: 0x042C, 7: 0x042E}, "min": -100, "max": 100, "dp": None, "precision": 0}, + "DLP": {"type": "U16", "index": {0: 0x0500, 1: 0x0501, 2: 0x0502, 3: 0x0503, 4: 0x0504, 5: 0x0505, 6: 0x0506, 7: 0x0507}, "min": 0, "max": 1, "dp": None, "precision": 0}, + "DB.F": {"type": "F32", "index": {0: 0x0510, 1: 0x0512, 2: 0x0514, 3: 0x0516, 4: 0x0518, 5: 0x051A, 6: 0x051C, 7: 0x051E}, "min": 0.05, "max": 10, "dp": None, "precision": 0}, + "T.STP": {"type": "U16", "index": {0: 0x0520, 1: 0x0521, 2: 0x0522, 3: 0x0523, 4: 0x0524, 5: 0x0525, 6: 0x0526, 7: 0x0527}, "min": 1, "max": 60, "dp": None, "precision": 0}, + "TP.L": {"type": "F32", "index": {0: 0x0530, 1: 0x0532, 2: 0x0534, 3: 0x0536, 4: 0x0538, 5: 0x053A, 6: 0x053C, 7: 0x053E}, "min": 0.1, "max": 10, "dp": None, "precision": 0}, + "TP.H": {"type": "U16", "index": {0: 0x0540, 1: 0x0541, 2: 0x0542, 3: 0x0543, 4: 0x0544, 5: 0x0545, 6: 0x0546, 7: 0x0547}, "min": 1, "max": 900, "dp": None, "precision": 0}, + "TFP": {"type": "F32", "index": {0: 0x0550, 1: 0x0552, 2: 0x0554, 3: 0x0556, 4: 0x0558, 5: 0x055A, 6: 0x055C, 7: 0x055E}, "min": 0.1, "max": 10, "dp": None, "precision": 0}, + "LSP": {"type": "F32", "index": {0: 0x0560, 1: 0x0562, 2: 0x0564, 3: 0x0566, 4: 0x0568, 5: 0x056A, 6: 0x056C, 7: 0x056E}, "min": 0, "max": 100, "dp": None, "precision": 0}, + "THP": {"type": "U16", "index": {0: 0x0600, 1: 0x0601, 2: 0x0602, 3: 0x0603, 4: 0x0604, 5: 0x0605, 6: 0x0606, 7: 0x0607}, "min": 1, "max": 81, "dp": None, "precision": 0}, + "T.L": {"type": "F32", "index": {0: 0x0610, 1: 0x0612, 2: 0x0614, 3: 0x0616, 4: 0x0618, 5: 0x061A, 6: 0x061C, 7: 0x061E}, "min": 0.05, "max": 0.5, "dp": None, "precision": 0}, + "AO.L": {"type": "F32", "index": {0: 0x0620, 1: 0x0622, 2: 0x0624, 3: 0x0626, 4: 0x0628, 5: 0x062A, 6: 0x062C, 7: 0x062E}, "min": -999, "max": 9999, "dp": None, "precision": 0}, + "AO.H": {"type": "F32", "index": {0: 0x0630, 1: 0x0632, 2: 0x0634, 3: 0x0636, 4: 0x0638, 5: 0x063A, 6: 0x063C, 7: 0x063E}, "min": -999, "max": 9999, "dp": None, "precision": 0}, + "ER.ST": {"type": "U16", "index": {0: 0x0640, 1: 0x0641, 2: 0x0642, 3: 0x0643, 4: 0x0644, 5: 0x0645, 6: 0x0646, 7: 0x0647}, "min": 0, "max": 1, "dp": None, "precision": 0}, + "D.LBA": {"type": "F32", "index": {0: 0x0650, 1: 0x0652, 2: 0x0654, 3: 0x0656, 4: 0x0658, 5: 0x065A, 6: 0x065C, 7: 0x065E}, "min": 0.001, "max": 9999, "dp": None, "precision": 0}, + "T.LBA": {"type": "U16", "index": {0: 0x0660, 1: 0x0661, 2: 0x0662, 3: 0x0663, 4: 0x0664, 5: 0x0665, 6: 0x0666, 7: 0x0667}, "min": 1, "max": 600, "dp": None, "precision": 0}, + "BPS": {"type": "U16", "index": {None: 0x1000}, "min": 0, "max": 8, "dp": None, "precision": 0}, + "A.LEN": {"type": "U16", "index": {None: 0x1004}, "min": 0, "max": 1, "dp": None, "precision": 0}, + "ADDR": {"type": "U16", "index": {None: 0x1005}, "min": 0, "max": 255, "dp": None, "precision": 0}, + "RS.DL": {"type": "U16", "index": {None: 0x1006}, "min": 0, "max": 50, "dp": None, "precision": 0}, + "LEN": {"type": "U16", "index": {None: 0x1001}, "min": 0, "max": 1, "dp": None, "precision": 0}, + "PRTY": {"type": "U16", "index": {None: 0x1002}, "min": 0, "max": 0, "dp": None, "precision": 0}, + "SBIT": {"type": "U16", "index": {None: 0x1003}, "min": 0, "max": 1, "dp": None, "precision": 0}, + # "": {"type": "U16", "index": {None: 0x1010}, "min": 0, "max": 0, "dp": None, "precision": 0}, # Команда смены сетевых настроек - название параметра неизвестно + "OR.SP": {"type": "U16", "index": {0: 0x0700, 1: 0x0701, 2: 0x0702, 3: 0x0703, 4: 0x0704, 5: 0x0705, 6: 0x0706, 7: 0x0707, 8: 0x0708, 9: 0x0709, 10: 0x070A, 11: 0x070B, 12: 0x070C, 13: 0x070D, 14: 0x070E, 15: 0x070F, 16: 0x0710, 17: 0x0711, 18: 0x0712, 19: 0x0713, 20: 0x0714, 21: 0x0715, 22: 0x0716, 23: 0x0717}, "min": -999, "max": 9999, "dp": None, "precision": 0}, + "LF.LU": {"type": "F32", "index": {0: 0x0720, 1: 0x0722, 2: 0x0724, 3: 0x0726, 4: 0x0728, 5: 0x072A, 6: 0x072C, 7: 0x072E, 8: 0x0730, 9: 0x0732, 10: 0x0734, 11: 0x0736, 12: 0x0738, 13: 0x073A, 14: 0x073C, 15: 0x073E, 16: 0x0740, 17: 0x0742, 18: 0x0744, 19: 0x0746, 20: 0x0748, 21: 0x074A, 22: 0x074C, 23: 0x074E}, "min": 0, "max": 9999, "dp": None, "precision": 0}, + "SP.LU": {"type": "F32", "index": {0: 0x0750, 1: 0x0752, 2: 0x0754, 3: 0x0756, 4: 0x0758, 5: 0x075A, 6: 0x075C, 7: 0x075E, 8: 0x0760, 9: 0x0762, 10: 0x0764, 11: 0x0766, 12: 0x0768, 13: 0x076A, 14: 0x076C, 15: 0x076E, 16: 0x0770, 17: 0x0772, 18: 0x0774, 19: 0x0776, 20: 0x0778, 21: 0x077A, 22: 0x077C, 23: 0x077E}, "min": -9999, "max": 9999, "dp": None, "precision": 0}, + "B.CH.L": {"type": "F32", "index": {0: 0x0780, 1: 0x0782, 2: 0x0784, 3: 0x0786, 4: 0x0788, 5: 0x078A, 6: 0x078C, 7: 0x078E, 8: 0x0790, 9: 0x0792, 10: 0x0794, 11: 0x0796, 12: 0x0798, 13: 0x079A, 14: 0x079C, 15: 0x079E, 16: 0x07A0, 17: 0x07A2, 18: 0x07A4, 19: 0x07A6, 20: 0x07A8, 21: 0x07AA, 22: 0x07AC, 23: 0x07AE}, "min": -9999, "max": 9999, "dp": None, "precision": 0}, + "B.CH.H": {"type": "F32", "index": {0: 0x07B0, 1: 0x07B2, 2: 0x07B4, 3: 0x07B6, 4: 0x07B8, 5: 0x07BA, 6: 0x07BC, 7: 0x07BE, 8: 0x07C0, 9: 0x07C2, 10: 0x07C4, 11: 0x07C6, 12: 0x07C8, 13: 0x07CA, 14: 0x07CC, 15: 0x07CE, 16: 0x07D0, 17: 0x07D2, 18: 0x07D4, 19: 0x07D6, 20: 0x07D8, 21: 0x07DA, 22: 0x07DC, 23: 0x07DE}, "min": -9999, "max": 9999, "dp": None, "precision": 0}, + "ABSC": {"type": "F32", "index": {0: 0x0800, 1: 0x0802, 2: 0x0804, 3: 0x0806, 4: 0x0808, 5: 0x080A, 6: 0x080C, 7: 0x080E, 8: 0x0810, 9: 0x0812, 10: 0x0814, 11: 0x0816, 12: 0x0818, 13: 0x081A, 14: 0x081C, 15: 0x081E, 16: 0x0820, 17: 0x0822, 18: 0x0824, 19: 0x0826}, "min": -999, "max": 9999, "dp": None, "precision": 0}, + "ORDN": {"type": "F32", "index": {0: 0x0900, 1: 0x0902, 2: 0x0904, 3: 0x0906, 4: 0x0908, 5: 0x090A, 6: 0x090C, 7: 0x090E, 8: 0x0910, 9: 0x0912, 10: 0x0914, 11: 0x0916, 12: 0x0918, 13: 0x091A, 14: 0x091C, 15: 0x091E, 16: 0x0920, 17: 0x0922, 18: 0x0924, 19: 0x0926}, "min": -16383, "max": 16383, "dp": None, "precision": 0}, + }, +} + +# Таблица настроек измерителя-регулятора ТРМ151 +TRM151: OWEN_DEVICE = { + "Owen": {"READ": {"type": "F32+T", "index": {None: None}, "min": -9999, "max": 9999}, + "R.CAL": {"type": "F32+T", "index": {0: 0, 1: 1, 2: 2, 3: 3, 4: 4, 5: 5, 6: 6, 7: 7}, "min": -9999, "max": 9999}, + "RD.RG": {"type": "F32", "index": {0: 0, 1: 1, 2: 2, 3: 3, 4: 4, 5: 5, 6: 6, 7: 7}, "min": 0, "max": 1}, + "R.OUT": {"type": "F32", "index": {0: 0, 1: 1}, "min": -1, "max": 1}, + "SET.P": {"type": "F32", "index": {0: 0, 1: 1, 2: 2, 3: 3, 4: 4, 5: 5, 6: 6, 7: 7}, "min": -999, "max": 9999}, + "R.KEY": {"type": "U16", "index": {0: 0, 1: 1, 2: 2, 3: 3, 4: 4, 5: 5, 6: 6, 7: 7}, "min": 0, "max": 1}, + "R.PRG": {"type": "U16", "index": {None: None}, "min": 0, "max": 1}, + "R.STP": {"type": "U16", "index": {None: None}, "min": 0, "max": 1}, + "R.ST": {"type": "U16", "index": {None: None}, "min": 0, "max": 1}, + "R.S": {"type": "U16", "index": {None: None}, "min": 0, "max": 2}, + }, +} + +# Таблица настроек измерителя двухканального ТРМ200 +TRM200: OWEN_DEVICE = { + "Owen": {"PV": {"type": "F24", "index": {None: None}, "min": -1999, "max": 9999}, + "LUPV": {"type": "F24", "index": {None: None}, "min": -1999, "max": 9999}, + "IN.T": {"type": "U8", "index": {0: 0, 1: 1}, "min": 1, "max": 26}, + "DPT": {"type": "U8", "index": {0: 0, 1: 1}, "min": 0, "max": 1}, + "DP": {"type": "U8", "index": {0: 0, 1: 1}, "min": 0, "max": 3}, + "IN.L": {"type": "F24", "index": {0: 0, 1: 1}, "min": -1999, "max": 9999}, + "IN.H": {"type": "F24", "index": {0: 0, 1: 1}, "min": -1999, "max": 9999}, + "SQR": {"type": "U8", "index": {0: 0, 1: 1}, "min": 0, "max": 1}, + "ILU": {"type": "U8", "index": {0: 0, 1: 1}, "min": 0, "max": 2}, + "SH": {"type": "F24", "index": {0: 0, 1: 1}, "min": -500, "max": 500}, + "KU": {"type": "F24", "index": {0: 0, 1: 1}, "min": 0.500, "max": 2.000}, + "FB": {"type": "F24", "index": {0: 0, 1: 1}, "min": 0, "max": 9999}, + "INF": {"type": "F24", "index": {0: 0, 1: 1}, "min": 0, "max": 999}, + "REST": {"type": "U8", "index": {None: None}, "min": 5, "max": 100}, + "PROT": {"type": "U8", "index": {None: None}, "min": 0, "max": 2}, + "BPS": {"type": "U8", "index": {None: None}, "min": 0, "max": 8}, + "A.LEN": {"type": "U8", "index": {None: None}, "min": 0, "max": 1}, + "ADDR": {"type": "U16", "index": {None: None}, "min": 0, "max": 2047}, + "RSDL": {"type": "U8", "index": {None: None}, "min": 1, "max": 45}, + "LEN": {"type": "U8", "index": {None: None}, "min": 0, "max": 1}, + "PRTY": {"type": "U8", "index": {None: None}, "min": 0, "max": 0}, + "SBIT": {"type": "U8", "index": {None: None}, "min": 0, "max": 1}, + "VER": {"type": "STR", "index": {None: None}, "min": None, "max": None}, + "DEV": {"type": "STR", "index": {None: None}, "min": None, "max": None}, + "PRTL": {"type": "U8", "index": {None: None}, "min": None, "max": None}, + "APLY": {"type": "U8", "index": {None: None}, "min": None, "max": None}, + "INIT": {"type": "U8", "index": {None: None}, "min": None, "max": None}, + "N.ERR": {"type": "U24", "index": {None: None}, "min": 0, "max": 255}, + "ATTR": {"type": "U8", "index": {None: None}, "min": 0, "max": 1}, + "OAPT": {"type": "U8", "index": {None: None}, "min": 0, "max": 1}, + "WTPT": {"type": "U8", "index": {None: None}, "min": 0, "max": 1}, + "EDPT": {"type": "U8", "index": {None: None}, "min": 0, "max": 1}, + }, + "Modbus": {"STAT": {"type": "U16", "index": {None: 0x0000}, "min": 0, "max": 65535, "dp": None, "precision": 0}, + "PV": {"type": "F32", "index": {0: 0x1009, 1: 0x100B}, "min": -1999, "max": 9999, "dp": None, "precision": 0}, + "LUPV": {"type": "F32", "index": {0: 0x100D, 1: 0x100F}, "min": -1999, "max": 9999, "dp": None, "precision": 0}, + "DEV": {"type": "STR", "index": {None: 0x1000}, "min": None, "max": None, "dp": None, "precision": 0}, + "VER": {"type": "STR", "index": {None: 0x1004}, "min": None, "max": None, "dp": None, "precision": 0}, + "PROT": {"type": "U16", "index": {None: 0x0100}, "min": 0, "max": 2, "dp": None, "precision": 0}, + "BPS": {"type": "U16", "index": {None: 0x0101}, "min": 0, "max": 8, "dp": None, "precision": 0}, + "A.LEN": {"type": "U16", "index": {None: 0x0102}, "min": 0, "max": 1, "dp": None, "precision": 0}, + "ADDR": {"type": "U16", "index": {None: 0x0103}, "min": 0, "max": 255, "dp": None, "precision": 0}, + "RSDL": {"type": "U16", "index": {None: 0x0104}, "min": 0, "max": 45, "dp": None, "precision": 0}, + "LEN": {"type": "U16", "index": {None: 0x0105}, "min": 0, "max": 1, "dp": None, "precision": 0}, + "PRTY": {"type": "U16", "index": {None: 0x0106}, "min": 0, "max": 0, "dp": None, "precision": 0}, + "SBIT": {"type": "U16", "index": {None: 0x0107}, "min": 0, "max": 1, "dp": None, "precision": 0}, + "N.ERR": {"type": "U16", "index": {None: 0x0108}, "min": 0, "max": 255, "dp": None, "precision": 0}, + "PRTL": {"type": "U16", "index": {None: 0x0109}, "min": 1, "max": 1, "dp": None, "precision": 0}, + "APLY": {"type": "U16", "index": {None: 0x010A}, "min": 1, "max": 1, "dp": None, "precision": 0}, + "INIT": {"type": "U16", "index": {None: 0x010B}, "min": 1, "max": 1, "dp": None, "precision": 0}, + "IN.T": {"type": "U16", "index": {0: 0x0200, 1: 0x020B}, "min": 1, "max": 26, "dp": None, "precision": 0}, + "DPT": {"type": "U16", "index": {0: 0x0201, 1: 0x020C}, "min": 0, "max": 1, "dp": None, "precision": 0}, + "DP": {"type": "U16", "index": {0: 0x0202, 1: 0x020D}, "min": 0, "max": 3, "dp": None, "precision": 0}, + "IN.L": {"type": "I16", "index": {0: 0x0203, 1: 0x020E}, "min": -1999, "max": 9999, "dp": "DP", "precision": 0}, + "IN.H": {"type": "I16", "index": {0: 0x0204, 1: 0x020F}, "min": -1999, "max": 9999, "dp": "DP", "precision": 0}, + "SH": {"type": "I16", "index": {0: 0x0205, 1: 0x0210}, "min": -500, "max": 500, "dp": "DP", "precision": 0}, + "KU": {"type": "U16", "index": {0: 0x0206, 1: 0x0211}, "min": 0.5, "max": 2.0, "dp": None, "precision": 3}, + "FB": {"type": "U16", "index": {0: 0x0207, 1: 0x0212}, "min": 0, "max": 9999, "dp": "DP", "precision": 0}, + "INF": {"type": "U16", "index": {0: 0x0208, 1: 0x0213}, "min": 0, "max": 999, "dp": None, "precision": 0}, + "SQR": {"type": "U16", "index": {0: 0x0209, 1: 0x0214}, "min": 0, "max": 1, "dp": None, "precision": 0}, + "ILU": {"type": "U16", "index": {0: 0x020A, 1: 0x0215}, "min": 0, "max": 2, "dp": None, "precision": 0}, + "REST": {"type": "U16", "index": {None: 0x0300}, "min": 5, "max": 100, "dp": None, "precision": 0}, + "OAPT": {"type": "U16", "index": {None: 0x0700}, "min": 0, "max": 1, "dp": None, "precision": 0}, + "WTPT": {"type": "U16", "index": {None: 0x0701}, "min": 0, "max": 1, "dp": None, "precision": 0}, + "EDPT": {"type": "U16", "index": {None: 0x0702}, "min": 0, "max": 1, "dp": None, "precision": 0}, + }, +} + +# Таблица настроек измерителя-регулятора одноканального ТРМ201 +TRM201: OWEN_DEVICE = { + "Owen": {"PV": {"type": "F24", "index": {None: None}, "min": -1999, "max": 9999}, + "SP": {"type": "F24", "index": {0: 0}, "min": -1999, "max": 9999}, + "IN.T": {"type": "U8", "index": {0: 0}, "min": 1, "max": 26}, + "DPT": {"type": "U8", "index": {0: 0}, "min": 0, "max": 1}, + "DP": {"type": "U8", "index": {0: 0}, "min": 0, "max": 3}, + "IN.L": {"type": "F24", "index": {0: 0}, "min": -1999, "max": 9999}, + "IN.H": {"type": "F24", "index": {0: 0}, "min": -1999, "max": 9999}, + "SQR": {"type": "U8", "index": {0: 0}, "min": 0, "max": 1}, + "SH": {"type": "F24", "index": {0: 0}, "min": -500, "max": 500}, + "KU": {"type": "F24", "index": {0: 0}, "min": 0.500, "max": 2.000}, + "FB": {"type": "F24", "index": {0: 0}, "min": 0, "max": 9999}, + "INF": {"type": "F24", "index": {0: 0}, "min": 0, "max": 999}, + "REST": {"type": "U8", "index": {None: None}, "min": 5, "max": 100}, + "SL.L": {"type": "F24", "index": {0: 0}, "min": -1999, "max": 9999}, + "SL.H": {"type": "F24", "index": {0: 0}, "min": -1999, "max": 9999}, + "CMP": {"type": "U8", "index": {0: 0}, "min": 0, "max": 4}, + "HYS": {"type": "F24", "index": {0: 0}, "min": 0, "max": 9999}, + "DON": {"type": "U8", "index": {0: 0}, "min": 0, "max": 250}, + "DOF": {"type": "U8", "index": {0: 0}, "min": 0, "max": 250}, + "TON": {"type": "U8", "index": {0: 0}, "min": 0, "max": 250}, + "TOF": {"type": "U8", "index": {0: 0}, "min": 0, "max": 250}, + "DAC": {"type": "U8", "index": {0: 0}, "min": 0, "max": 1}, + "CTL": {"type": "U8", "index": {0: 0}, "min": 0, "max": 1}, + "XP": {"type": "F24", "index": {0: 0}, "min": 0.002, "max": 9999}, + "AN.L": {"type": "F24", "index": {0: 0}, "min": -1999, "max": 9999}, + "AN.H": {"type": "F24", "index": {0: 0}, "min": -1999, "max": 9999}, + "OER": {"type": "U8", "index": {0: 0}, "min": 0, "max": 1}, + "PROT": {"type": "U8", "index": {None: None}, "min": 0, "max": 2}, + "BPS": {"type": "U8", "index": {None: None}, "min": 0, "max": 8}, + "A.LEN": {"type": "U8", "index": {None: None}, "min": 0, "max": 1}, + "ADDR": {"type": "U16", "index": {None: None}, "min": 0, "max": 2047}, + "RSDL": {"type": "U8", "index": {None: None}, "min": 1, "max": 45}, + "LEN": {"type": "U8", "index": {None: None}, "min": 0, "max": 1}, + "PRTY": {"type": "U8", "index": {None: None}, "min": 0, "max": 0}, + "SBIT": {"type": "U8", "index": {None: None}, "min": 0, "max": 1}, + "VER": {"type": "STR", "index": {None: None}, "min": None, "max": None}, + "DEV": {"type": "STR", "index": {None: None}, "min": None, "max": None}, + "PRTL": {"type": "U8", "index": {None: None}, "min": None, "max": None}, + "APLY": {"type": "U8", "index": {None: None}, "min": None, "max": None}, + "INIT": {"type": "U8", "index": {None: None}, "min": None, "max": None}, + "N.ERR": {"type": "U24", "index": {None: None}, "min": 0, "max": 255}, + "ATTR": {"type": "U8", "index": {None: None}, "min": 0, "max": 1}, + "R-L": {"type": "U8", "index": {None: None}, "min": 0, "max": 1}, + "R.OUT": {"type": "F24", "index": {None: None}, "min": 0, "max": 1}, + "OAPT": {"type": "U8", "index": {None: None}, "min": 0, "max": 2}, + "WTPT": {"type": "U8", "index": {None: None}, "min": 0, "max": 2}, + "EDPT": {"type": "U8", "index": {None: None}, "min": 0, "max": 1}, + }, + "Modbus": {"STAT": {"type": "U16", "index": {None: 0x0000}, "min": 0, "max": 65535, "dp": None, "precision": 0}, + "PV": {"type": "F32", "index": {None: 0x1009}, "min": -1999, "max": 9999, "dp": None, "precision": 0}, + "SP": {"type": "I16", "index": {None: 0x0002}, "min": -1999, "max": 9999, "dp": "DP", "precision": 0}, + "R-L": {"type": "U16", "index": {None: 0x0003}, "min": 0, "max": 1, "dp": None, "precision": 0}, + "R.OUT": {"type": "U16", "index": {None: 0x0004}, "min": 0, "max": 1, "dp": None, "precision": 3}, + "DEV": {"type": "STR", "index": {None: 0x1000}, "min": None, "max": None, "dp": None, "precision": 0}, + "VER": {"type": "STR", "index": {None: 0x1004}, "min": None, "max": None, "dp": None, "precision": 0}, + "PROT": {"type": "U16", "index": {None: 0x0100}, "min": 0, "max": 2, "dp": None, "precision": 0}, + "BPS": {"type": "U16", "index": {None: 0x0101}, "min": 0, "max": 8, "dp": None, "precision": 0}, + "A.LEN": {"type": "U16", "index": {None: 0x0102}, "min": 0, "max": 1, "dp": None, "precision": 0}, + "ADDR": {"type": "U16", "index": {None: 0x0103}, "min": 0, "max": 255, "dp": None, "precision": 0}, + "RSDL": {"type": "U16", "index": {None: 0x0104}, "min": 0, "max": 45, "dp": None, "precision": 0}, + "LEN": {"type": "U16", "index": {None: 0x0105}, "min": 0, "max": 1, "dp": None, "precision": 0}, + "PRTY": {"type": "U16", "index": {None: 0x0106}, "min": 0, "max": 0, "dp": None, "precision": 0}, + "SBIT": {"type": "U16", "index": {None: 0x0107}, "min": 0, "max": 1, "dp": None, "precision": 0}, + "N.ERR": {"type": "U16", "index": {None: 0x0108}, "min": 0, "max": 255, "dp": None, "precision": 0}, + "PRTL": {"type": "U16", "index": {None: 0x0109}, "min": 1, "max": 1, "dp": None, "precision": 0}, + "APLY": {"type": "U16", "index": {None: 0x010A}, "min": 1, "max": 1, "dp": None, "precision": 0}, + "INIT": {"type": "U16", "index": {None: 0x010B}, "min": 1, "max": 1, "dp": None, "precision": 0}, + "IN.T": {"type": "U16", "index": {None: 0x0200}, "min": 1, "max": 26, "dp": None, "precision": 0}, + "DPT": {"type": "U16", "index": {None: 0x0201}, "min": 0, "max": 1, "dp": None, "precision": 0}, + "DP": {"type": "U16", "index": {None: 0x0202}, "min": 0, "max": 3, "dp": None, "precision": 0}, + "IN.L": {"type": "I16", "index": {None: 0x0203}, "min": -1999, "max": 9999, "dp": "DP", "precision": 0}, + "IN.H": {"type": "I16", "index": {None: 0x0204}, "min": -1999, "max": 9999, "dp": "DP", "precision": 0}, + "SH": {"type": "I16", "index": {None: 0x0205}, "min": -500, "max": 500, "dp": "DP", "precision": 0}, + "KU": {"type": "U16", "index": {None: 0x0206}, "min": 0.5, "max": 2.00, "dp": None, "precision": 3}, + "FB": {"type": "U16", "index": {None: 0x0207}, "min": 0, "max": 9999, "dp": "DP", "precision": 0}, + "INF": {"type": "U16", "index": {None: 0x0208}, "min": 0, "max": 999, "dp": None, "precision": 0}, + "SQR": {"type": "U16", "index": {None: 0x0209}, "min": 0, "max": 1, "dp": None, "precision": 0}, + "REST": {"type": "U16", "index": {None: 0x0300}, "min": 5, "max": 100, "dp": None, "precision": 0}, + "SL.L": {"type": "I16", "index": {None: 0x0400}, "min": -1999, "max": 9999, "dp": "DP", "precision": 0}, + "SL.H": {"type": "I16", "index": {None: 0x0401}, "min": -1999, "max": 9999, "dp": "DP", "precision": 0}, + "CMP": {"type": "U16", "index": {None: 0x0402}, "min": 0, "max": 4, "dp": None, "precision": 0}, + "HYS": {"type": "U16", "index": {None: 0x0403}, "min": 0, "max": 9999, "dp": "DP", "precision": 0}, + "DON": {"type": "U16", "index": {None: 0x0404}, "min": 0, "max": 250, "dp": None, "precision": 0}, + "DOF": {"type": "U16", "index": {None: 0x0405}, "min": 0, "max": 250, "dp": None, "precision": 0}, + "TON": {"type": "U16", "index": {None: 0x0406}, "min": 0, "max": 250, "dp": None, "precision": 0}, + "TOF": {"type": "U16", "index": {None: 0x0407}, "min": 0, "max": 250, "dp": None, "precision": 0}, + "OER": {"type": "U16", "index": {None: 0x0408}, "min": 0, "max": 1, "dp": None, "precision": 0}, + "DAC": {"type": "U16", "index": {None: 0x0409}, "min": 0, "max": 1, "dp": None, "precision": 0}, + "AN.L": {"type": "I16", "index": {None: 0x040A}, "min": -1999, "max": 9999, "dp": "DP", "precision": 0}, + "AN.H": {"type": "I16", "index": {None: 0x040B}, "min": -1999, "max": 9999, "dp": "DP", "precision": 0}, + "CTL": {"type": "U16", "index": {None: 0x040C}, "min": 0, "max": 1, "dp": None, "precision": 0}, + "XP": {"type": "U16", "index": {None: 0x040D}, "min": 0.002, "max": 9999, "dp": "DP", "precision": 0}, + "OAPT": {"type": "U16", "index": {None: 0x0700}, "min": 0, "max": 2, "dp": None, "precision": 0}, + "WTPT": {"type": "U16", "index": {None: 0x0701}, "min": 0, "max": 2, "dp": None, "precision": 0}, + "EDPT": {"type": "U16", "index": {None: 0x0702}, "min": 0, "max": 1, "dp": None, "precision": 0}, + }, +} + +# Таблица настроек измерителя-регулятора двухканального ТРМ202 +TRM202: OWEN_DEVICE = { + "Owen": {"PV": {"type": "F24", "index": {None: None}, "min": -1999, "max": 9999}, + "LUPV": {"type": "F24", "index": {None: None}, "min": -1999, "max": 9999}, + "SP": {"type": "F24", "index": {0: 0, 1: 1}, "min": -1999, "max": 9999}, + "IN.T": {"type": "U8", "index": {0: 0, 1: 1}, "min": 1, "max": 26}, + "DPT": {"type": "U8", "index": {0: 0, 1: 1}, "min": 0, "max": 1}, + "DP": {"type": "U8", "index": {0: 0, 1: 1}, "min": 0, "max": 3}, + "IN.L": {"type": "F24", "index": {0: 0, 1: 1}, "min": -1999, "max": 9999}, + "IN.H": {"type": "F24", "index": {0: 0, 1: 1}, "min": -1999, "max": 9999}, + "SQR": {"type": "U8", "index": {0: 0, 1: 1}, "min": 0, "max": 1}, + "ILU": {"type": "U8", "index": {0: 0, 1: 1}, "min": 0, "max": 2}, + "SH": {"type": "F24", "index": {0: 0, 1: 1}, "min": -500, "max": 500}, + "KU": {"type": "F24", "index": {0: 0, 1: 1}, "min": 0.500, "max": 2.000}, + "FB": {"type": "F24", "index": {0: 0, 1: 1}, "min": 0, "max": 9999}, + "INF": {"type": "F24", "index": {0: 0, 1: 1}, "min": 0, "max": 999}, + "DISP": {"type": "U8", "index": {None: None}, "min": 0, "max": 2}, + "REST": {"type": "U8", "index": {None: None}, "min": 5, "max": 100}, + "SL.L": {"type": "F24", "index": {0: 0, 1: 1}, "min": -1999, "max": 9999}, + "SL.H": {"type": "F24", "index": {0: 0, 1: 1}, "min": -1999, "max": 9999}, + "CMP": {"type": "U8", "index": {0: 0, 1: 1}, "min": 0, "max": 4}, + "HYS": {"type": "F24", "index": {0: 0, 1: 1}, "min": 0, "max": 9999}, + "DON": {"type": "U8", "index": {0: 0, 1: 1}, "min": 0, "max": 250}, + "DOF": {"type": "U8", "index": {0: 0, 1: 1}, "min": 0, "max": 250}, + "TON": {"type": "U8", "index": {0: 0, 1: 1}, "min": 0, "max": 250}, + "TOF": {"type": "U8", "index": {0: 0, 1: 1}, "min": 0, "max": 250}, + "DAC": {"type": "U8", "index": {0: 0, 1: 1}, "min": 0, "max": 1}, + "CTL": {"type": "U8", "index": {0: 0, 1: 1}, "min": 0, "max": 1}, + "XP": {"type": "F24", "index": {0: 0, 1: 1}, "min": 0.002, "max": 9999}, + "AN.L": {"type": "F24", "index": {0: 0, 1: 1}, "min": -1999, "max": 9999}, + "AN.H": {"type": "F24", "index": {0: 0, 1: 1}, "min": -1999, "max": 9999}, + "OER": {"type": "U8", "index": {0: 0, 1: 1}, "min": 0, "max": 1}, + "PROT": {"type": "U8", "index": {None: None}, "min": 0, "max": 2}, + "BPS": {"type": "U8", "index": {None: None}, "min": 0, "max": 8}, + "A.LEN": {"type": "U8", "index": {None: None}, "min": 0, "max": 1}, + "ADDR": {"type": "U16", "index": {None: None}, "min": 0, "max": 2047}, + "RSDL": {"type": "U8", "index": {None: None}, "min": 1, "max": 45}, + "LEN": {"type": "U8", "index": {None: None}, "min": 0, "max": 1}, + "PRTY": {"type": "U8", "index": {None: None}, "min": 0, "max": 0}, + "SBIT": {"type": "U8", "index": {None: None}, "min": 0, "max": 1}, + "VER": {"type": "STR", "index": {None: None}, "min": None, "max": None}, + "DEV": {"type": "STR", "index": {None: None}, "min": None, "max": None}, + "PRTL": {"type": "U8", "index": {None: None}, "min": None, "max": None}, + "APLY": {"type": "U8", "index": {None: None}, "min": None, "max": None}, + "INIT": {"type": "U8", "index": {None: None}, "min": None, "max": None}, + "N.ERR": {"type": "U24", "index": {None: None}, "min": 0, "max": 255}, + "ATTR": {"type": "U8", "index": {None: None}, "min": 0, "max": 1}, + "R-L": {"type": "U8", "index": {None: None}, "min": 0, "max": 1}, + "R.OUT": {"type": "F24", "index": {None: None}, "min": 0, "max": 1}, + "OAPT": {"type": "U8", "index": {None: None}, "min": 0, "max": 2}, + "WTPT": {"type": "U8", "index": {None: None}, "min": 0, "max": 3}, + "EDPT": {"type": "U8", "index": {None: None}, "min": 0, "max": 1}, + }, + "Modbus": {"STAT": {"type": "U16", "index": {None: 0x0000}, "min": 0, "max": 65535, "dp": None, "precision": 0}, + "PV": {"type": "F32", "index": {0: 0x1009, 1: 0x100B}, "min": -1999, "max": 9999, "dp": None, "precision": 0}, + "LUPV": {"type": "F32", "index": {0: 0x100D, 1: 0x100F}, "min": -1999, "max": 9999, "dp": None, "precision": 0}, + "SP": {"type": "I16", "index": {0: 0x0005, 1: 0x0006}, "min": -1999, "max": 9999, "dp": "DP", "precision": 0}, + "R-L": {"type": "U16", "index": {0: 0x0007, 1: 0x0008}, "min": 0, "max": 1, "dp": None, "precision": 0}, + "R.OUT": {"type": "U16", "index": {0: 0x0009, 1: 0x000A}, "min": 0, "max": 1, "dp": None, "precision": 3}, + "DEV": {"type": "STR", "index": {None: 0x1000}, "min": None, "max": None, "dp": None, "precision": 0}, + "VER": {"type": "STR", "index": {None: 0x1004}, "min": None, "max": None, "dp": None, "precision": 0}, + "PROT": {"type": "U16", "index": {None: 0x0100}, "min": 0, "max": 2, "dp": None, "precision": 0}, + "BPS": {"type": "U16", "index": {None: 0x0101}, "min": 0, "max": 8, "dp": None, "precision": 0}, + "A.LEN": {"type": "U16", "index": {None: 0x0102}, "min": 0, "max": 1, "dp": None, "precision": 0}, + "ADDR": {"type": "U16", "index": {None: 0x0103}, "min": 0, "max": 255, "dp": None, "precision": 0}, + "RSDL": {"type": "U16", "index": {None: 0x0104}, "min": 0, "max": 45, "dp": None, "precision": 0}, + "LEN": {"type": "U16", "index": {None: 0x0105}, "min": 0, "max": 1, "dp": None, "precision": 0}, + "PRTY": {"type": "U16", "index": {None: 0x0106}, "min": 0, "max": 0, "dp": None, "precision": 0}, + "SBIT": {"type": "U16", "index": {None: 0x0107}, "min": 0, "max": 1, "dp": None, "precision": 0}, + "N.ERR": {"type": "U16", "index": {None: 0x0108}, "min": 0, "max": 255, "dp": None, "precision": 0}, + "PRTL": {"type": "U16", "index": {None: 0x0109}, "min": 1, "max": 1, "dp": None, "precision": 0}, + "APLY": {"type": "U16", "index": {None: 0x010A}, "min": 1, "max": 1, "dp": None, "precision": 0}, + "INIT": {"type": "U16", "index": {None: 0x010B}, "min": 1, "max": 1, "dp": None, "precision": 0}, + "IN.T": {"type": "U16", "index": {0: 0x0200, 1: 0x020B}, "min": 1, "max": 26, "dp": None, "precision": 0}, + "DPT": {"type": "U16", "index": {0: 0x0201, 1: 0x020C}, "min": 0, "max": 1, "dp": None, "precision": 0}, + "DP": {"type": "U16", "index": {0: 0x0202, 1: 0x020D}, "min": 0, "max": 3, "dp": None, "precision": 0}, + "IN.L": {"type": "I16", "index": {0: 0x0203, 1: 0x020E}, "min": -1999, "max": 9999, "dp": "DP", "precision": 0}, + "IN.H": {"type": "I16", "index": {0: 0x0204, 1: 0x020F}, "min": -1999, "max": 9999, "dp": "DP", "precision": 0}, + "SH": {"type": "I16", "index": {0: 0x0205, 1: 0x0210}, "min": -500, "max": 500, "dp": "DP", "precision": 0}, + "KU": {"type": "U16", "index": {0: 0x0206, 1: 0x0211}, "min": 0.50, "max": 2.00, "dp": None, "precision": 3}, + "FB": {"type": "U16", "index": {0: 0x0207, 1: 0x0212}, "min": 0, "max": 9999, "dp": "DP", "precision": 0}, + "INF": {"type": "U16", "index": {0: 0x0208, 1: 0x0213}, "min": 0, "max": 999, "dp": None, "precision": 0}, + "SQR": {"type": "U16", "index": {0: 0x0209, 1: 0x0214}, "min": 0, "max": 1, "dp": None, "precision": 0}, + "ILU": {"type": "U16", "index": {0: 0x020A, 1: 0x0215}, "min": 0, "max": 2, "dp": None, "precision": 0}, + "REST": {"type": "U16", "index": {None: 0x0300}, "min": 5, "max": 100, "dp": None, "precision": 0}, + "DISP": {"type": "U16", "index": {None: 0x0301}, "min": 0, "max": 2, "dp": None, "precision": 0}, + "SL.L": {"type": "I16", "index": {0: 0x0400, 1: 0x040E}, "min": -1999, "max": 9999, "dp": "DP", "precision": 0}, + "SL.H": {"type": "I16", "index": {0: 0x0401, 1: 0x040F}, "min": -1999, "max": 9999, "dp": "DP", "precision": 0}, + "CMP": {"type": "U16", "index": {0: 0x0402, 1: 0x0410}, "min": 0, "max": 4, "dp": None, "precision": 0}, + "HYS": {"type": "U16", "index": {0: 0x0403, 1: 0x0411}, "min": 0, "max": 9999, "dp": "DP", "precision": 0}, + "DON": {"type": "U16", "index": {0: 0x0404, 1: 0x0412}, "min": 0, "max": 250, "dp": None, "precision": 0}, + "DOF": {"type": "U16", "index": {0: 0x0405, 1: 0x0413}, "min": 0, "max": 250, "dp": None, "precision": 0}, + "TON": {"type": "U16", "index": {0: 0x0406, 1: 0x0414}, "min": 0, "max": 250, "dp": None, "precision": 0}, + "TOF": {"type": "U16", "index": {0: 0x0407, 1: 0x0415}, "min": 0, "max": 250, "dp": None, "precision": 0}, + "OER": {"type": "U16", "index": {0: 0x0408, 1: 0x0416}, "min": 0, "max": 1, "dp": None, "precision": 0}, + "DAC": {"type": "U16", "index": {0: 0x0409, 1: 0x0417}, "min": 0, "max": 1, "dp": None, "precision": 0}, + "AN.L": {"type": "I16", "index": {0: 0x040A, 1: 0x0418}, "min": -1999, "max": 9999, "dp": "DP", "precision": 0}, + "AN.H": {"type": "I16", "index": {0: 0x040B, 1: 0x0419}, "min": -1999, "max": 9999, "dp": "DP", "precision": 0}, + "CTL": {"type": "U16", "index": {0: 0x040C, 1: 0x041A}, "min": 0, "max": 1, "dp": None, "precision": 0}, + "XP": {"type": "U16", "index": {0: 0x040D, 1: 0x041B}, "min": 0.002, "max": 9999, "dp": "DP", "precision": 0}, + "OAPT": {"type": "U16", "index": {None: 0x0700}, "min": 0, "max": 2, "dp": None, "precision": 0}, + "WTPT": {"type": "U16", "index": {None: 0x0701}, "min": 0, "max": 3, "dp": None, "precision": 0}, + "EDPT": {"type": "U16", "index": {None: 0x0702}, "min": 0, "max": 1, "dp": None, "precision": 0}, + }, +} + +# Таблица настроек измерителя-ПИД-регулятора ТРМ210 +TRM210: OWEN_DEVICE = { + "Owen": {"PV": {"type": "F24", "index": {None: None}, "min": -1999, "max": 9999}, + "SP": {"type": "F24", "index": {None: None}, "min": -1999, "max": 9999}, + "R-S": {"type": "U8", "index": {None: None}, "min": 0, "max": 1}, + "AT": {"type": "U8", "index": {None: None}, "min": 0, "max": 1}, + "O": {"type": "F24", "index": {None: None}, "min": 0, "max": 100}, + "IN-T": {"type": "U8", "index": {None: None}, "min": 1, "max": 26}, + "DPT": {"type": "U8", "index": {None: None}, "min": 0, "max": 1}, + "DP": {"type": "U8", "index": {None: None}, "min": 0, "max": 3}, + "IN-L": {"type": "F24", "index": {None: None}, "min": -1999, "max": 9999}, + "IN-H": {"type": "F24", "index": {None: None}, "min": -1999, "max": 9999}, + "SL-L": {"type": "F24", "index": {None: None}, "min": -1999, "max": 9999}, + "SL-H": {"type": "F24", "index": {None: None}, "min": -1999, "max": 9999}, + "SH": {"type": "F24", "index": {None: None}, "min": -500, "max": 500}, + "KU": {"type": "F24", "index": {None: None}, "min": 0.500, "max": 2.000}, + "INF": {"type": "F24", "index": {None: None}, "min": 0, "max": 999}, + "FB": {"type": "F24", "index": {None: None}, "min": 0, "max": 9999}, + "AN-L": {"type": "F24", "index": {None: None}, "min": -1999, "max": 9999}, + "AN-H": {"type": "F24", "index": {None: None}, "min": -1999, "max": 9999}, + "EV-1": {"type": "U8", "index": {None: None}, "min": 0, "max": 2}, + "ALT": {"type": "U8", "index": {None: None}, "min": 0, "max": 11}, + "AL-D": {"type": "F24", "index": {None: None}, "min": -1999, "max": 9999}, + "AL-H": {"type": "F24", "index": {None: None}, "min": 0, "max": 9999}, + "OREU": {"type": "U8", "index": {None: None}, "min": 0, "max": 1}, + "CP": {"type": "U8", "index": {None: None}, "min": 1, "max": 250}, + "VSP": {"type": "F24", "index": {None: None}, "min": 0, "max": 9999}, + "CNTL": {"type": "U8", "index": {None: None}, "min": 0, "max": 1}, + "HYST": {"type": "F24", "index": {None: None}, "min": 0, "max": 9999}, + "ONST": {"type": "U8", "index": {None: None}, "min": 0, "max": 1}, + "ONER": {"type": "U8", "index": {None: None}, "min": 0, "max": 1}, + "RAMP": {"type": "U8", "index": {None: None}, "min": 0, "max": 1}, + "P": {"type": "F24", "index": {None: None}, "min": 0.001, "max": 9999}, + "I": {"type": "F24", "index": {None: None}, "min": 0, "max": 3999}, + "D": {"type": "F24", "index": {None: None}, "min": 0, "max": 3999}, + "DB": {"type": "F24", "index": {None: None}, "min": 0, "max": 200}, + "OL-L": {"type": "F24", "index": {None: None}, "min": 0, "max": 100}, + "OL-H": {"type": "F24", "index": {None: None}, "min": 0, "max": 100}, + "ORL": {"type": "F24", "index": {None: None}, "min": 0.2, "max": 100}, + "MVER": {"type": "F24", "index": {None: None}, "min": 0, "max": 100}, + "MVST": {"type": "F24", "index": {None: None}, "min": 0, "max": 100}, + "MDST": {"type": "U8", "index": {None: None}, "min": 0, "max": 1}, + "LBA": {"type": "U16", "index": {None: None}, "min": 0, "max": 9999}, + "LBAB": {"type": "F24", "index": {None: None}, "min": 0, "max": 9999}, + "PROT": {"type": "U8", "index": {None: None}, "min": 0, "max": 2}, + "ADDR": {"type": "U16", "index": {None: None}, "min": 0, "max": 2047}, + "RSDL": {"type": "U8", "index": {None: None}, "min": 1, "max": 45}, + "A.LEN": {"type": "U8", "index": {None: None}, "min": 0, "max": 1}, + "BPS": {"type": "U8", "index": {None: None}, "min": 0, "max": 8}, + "LEN": {"type": "U8", "index": {None: None}, "min": 1, "max": 1}, + "PRTY": {"type": "U8", "index": {None: None}, "min": 0, "max": 0}, + "SBIT": {"type": "U8", "index": {None: None}, "min": 0, "max": 1}, + "VER": {"type": "STR", "index": {None: None}, "min": None, "max": None}, + "DEV": {"type": "STR", "index": {None: None}, "min": None, "max": None}, + "PRTL": {"type": "U8", "index": {None: None}, "min": None, "max": None}, + "APLY": {"type": "U8", "index": {None: None}, "min": None, "max": None}, + "INIT": {"type": "U8", "index": {None: None}, "min": None, "max": None}, + "N.ERR": {"type": "U24", "index": {None: None}, "min": 0, "max": 255}, + "ATTR": {"type": "U8", "index": {None: None}, "min": 0, "max": 1}, + "R-L": {"type": "U8", "index": {None: None}, "min": 0, "max": 1}, + "R.OUT": {"type": "F24", "index": {None: None}, "min": 0, "max": 1}, + "EDPT": {"type": "U8", "index": {None: None}, "min": 0, "max": 1}, + }, + "Modbus": {"STAT": {"type": "U16", "index": {None: 0x0000}, "min": 0, "max": 65535, "dp": None, "precision": 0}, + "PV": {"type": "F32", "index": {None: 0x1009}, "min": -1999, "max": 9999, "dp": None, "precision": 0}, + "SP": {"type": "I16", "index": {None: 0x0002}, "min": -1999, "max": 9999, "dp": "DP", "precision": 0}, + "SET.P": {"type": "F32", "index": {None: 0x100D}, "min": -1999, "max": 9999, "dp": None, "precision": 0}, + "O": {"type": "F32", "index": {None: 0x100F}, "min": 0, "max": 100, "dp": None, "precision": 0}, + "R-L": {"type": "U16", "index": {None: 0x0005}, "min": 0, "max": 1, "dp": None, "precision": 0}, + "R.OUT": {"type": "U16", "index": {None: 0x0006}, "min": 0, "max": 1, "dp": None, "precision": 3}, + "R-S": {"type": "U16", "index": {None: 0x0007}, "min": 0, "max": 1, "dp": None, "precision": 0}, + "AT": {"type": "U16", "index": {None: 0x0008}, "min": 0, "max": 1, "dp": None, "precision": 0}, + "DEV": {"type": "STR", "index": {None: 0x1000}, "min": None, "max": None, "dp": None, "precision": 0}, + "VER": {"type": "STR", "index": {None: 0x1004}, "min": None, "max": None, "dp": None, "precision": 0}, + "PROT": {"type": "U16", "index": {None: 0x0100}, "min": 0, "max": 2, "dp": None, "precision": 0}, + "BPS": {"type": "U16", "index": {None: 0x0101}, "min": 0, "max": 8, "dp": None, "precision": 0}, + "A.LEN": {"type": "U16", "index": {None: 0x0102}, "min": 0, "max": 1, "dp": None, "precision": 0}, + "ADDR": {"type": "U16", "index": {None: 0x0103}, "min": 1, "max": 247, "dp": None, "precision": 0}, + "RSDL": {"type": "U16", "index": {None: 0x0104}, "min": 0, "max": 45, "dp": None, "precision": 0}, + "LEN": {"type": "U16", "index": {None: 0x0105}, "min": 0, "max": 1, "dp": None, "precision": 0}, + "PRTY": {"type": "U16", "index": {None: 0x0106}, "min": 0, "max": 0, "dp": None, "precision": 0}, + "SBIT": {"type": "U16", "index": {None: 0x0107}, "min": 0, "max": 1, "dp": None, "precision": 0}, + "N.ERR": {"type": "U16", "index": {None: 0x0108}, "min": 0, "max": 255, "dp": None, "precision": 0}, + "PRTL": {"type": "U16", "index": {None: 0x0109}, "min": 1, "max": 1, "dp": None, "precision": 0}, + "APLY": {"type": "U16", "index": {None: 0x010A}, "min": 1, "max": 1, "dp": None, "precision": 0}, + "INIT": {"type": "U16", "index": {None: 0x010B}, "min": 1, "max": 1, "dp": None, "precision": 0}, + "IN-T": {"type": "U16", "index": {None: 0x0200}, "min": 1, "max": 26, "dp": None, "precision": 0}, + "DPT": {"type": "U16", "index": {None: 0x0201}, "min": 0, "max": 1, "dp": None, "precision": 0}, + "DP": {"type": "U16", "index": {None: 0x0202}, "min": 0, "max": 3, "dp": None, "precision": 0}, + "IN-L": {"type": "I16", "index": {None: 0x0203}, "min": -1999, "max": 9999, "dp": "DP", "precision": 0}, + "IN-H": {"type": "I16", "index": {None: 0x0204}, "min": -1999, "max": 9999, "dp": "DP", "precision": 0}, + "SH": {"type": "I16", "index": {None: 0x0205}, "min": -500, "max": 500, "dp": "DP", "precision": 0}, + "KU": {"type": "U16", "index": {None: 0x0206}, "min": 0.5, "max": 2.0, "dp": None, "precision": 3}, + "FB": {"type": "U16", "index": {None: 0x0207}, "min": 0, "max": 9999, "dp": "DP", "precision": 0}, + "INF": {"type": "U16", "index": {None: 0x0208}, "min": 0, "max": 999, "dp": None, "precision": 0}, + "SL-L": {"type": "I16", "index": {None: 0x0300}, "min": -1999, "max": 9999, "dp": "DP", "precision": 0}, + "SL-H": {"type": "I16", "index": {None: 0x0301}, "min": -1999, "max": 9999, "dp": "DP", "precision": 0}, + "OREU": {"type": "U16", "index": {None: 0x0302}, "min": 0, "max": 1, "dp": None, "precision": 0}, + "CNTL": {"type": "U16", "index": {None: 0x0303}, "min": 0, "max": 1, "dp": None, "precision": 0}, + "CP": {"type": "U16", "index": {None: 0x0304}, "min": 1, "max": 250, "dp": None, "precision": 0}, + "RAMP": {"type": "U16", "index": {None: 0x0305}, "min": 0, "max": 1, "dp": None, "precision": 0}, + "P": {"type": "U16", "index": {None: 0x0306}, "min": 1, "max": 9999, "dp": "DP", "precision": 0}, + "I": {"type": "U16", "index": {None: 0x0307}, "min": 0, "max": 3999, "dp": None, "precision": 0}, + "D": {"type": "U16", "index": {None: 0x0308}, "min": 0, "max": 3999, "dp": None, "precision": 0}, + "DB": {"type": "U16", "index": {None: 0x0309}, "min": 0, "max": 200, "dp": "DP", "precision": 0}, + "VSP": {"type": "U16", "index": {None: 0x030A}, "min": 0, "max": 9999, "dp": "DP", "precision": 0}, + "OL-L": {"type": "U16", "index": {None: 0x030B}, "min": 0, "max": 100, "dp": None, "precision": 0}, + "OL-H": {"type": "U16", "index": {None: 0x030C}, "min": 0, "max": 100, "dp": None, "precision": 0}, + "ORL": {"type": "U16", "index": {None: 0x030D}, "min": 0.2, "max": 100, "dp": None, "precision": 1}, + "MVER": {"type": "U16", "index": {None: 0x030E}, "min": 0, "max": 100, "dp": None, "precision": 0}, + "MDST": {"type": "U16", "index": {None: 0x030F}, "min": 0, "max": 1, "dp": None, "precision": 0}, + "MVST": {"type": "U16", "index": {None: 0x0310}, "min": 0, "max": 100, "dp": None, "precision": 0}, + "HYST": {"type": "U16", "index": {None: 0x0311}, "min": 0, "max": 9999, "dp": "DP", "precision": 0}, + "ONST": {"type": "U16", "index": {None: 0x0312}, "min": 0, "max": 1, "dp": None, "precision": 0}, + "ONER": {"type": "U16", "index": {None: 0x0313}, "min": 0, "max": 1, "dp": None, "precision": 0}, + "EV-1": {"type": "U16", "index": {None: 0x0400}, "min": 0, "max": 2, "dp": None, "precision": 0}, + "LBA": {"type": "U16", "index": {None: 0x0401}, "min": 0, "max": 9999, "dp": None, "precision": 0}, + "LBAB": {"type": "U16", "index": {None: 0x0402}, "min": 0, "max": 9999, "dp": "DP", "precision": 0}, + "ALT": {"type": "U16", "index": {None: 0x0403}, "min": 0, "max": 11, "dp": None, "precision": 0}, + "AL-D": {"type": "U16", "index": {None: 0x0404}, "min": -1999, "max": 9999, "dp": "DP", "precision": 0}, + "AL-H": {"type": "U16", "index": {None: 0x0405}, "min": 0, "max": 9999, "dp": "DP", "precision": 0}, + "AN-L": {"type": "I16", "index": {None: 0x0406}, "min": -1999, "max": 9999, "dp": "DP", "precision": 0}, + "AN-H": {"type": "I16", "index": {None: 0x0407}, "min": -1999, "max": 9999, "dp": "DP", "precision": 0}, + }, +} + +# Таблица настроек измерителя-ПИД-регулятора ТРМ212 +TRM212: OWEN_DEVICE = { + "Owen": {"PV": {"type": "F24", "index": {None: None}, "min": -1999, "max": 9999}, + "LUPV": {"type": "F24", "index": {None: None}, "min": -1999, "max": 9999}, + "SP": {"type": "F24", "index": {None: None}, "min": -1999, "max": 9999}, + "SET.P": {"type": "F24", "index": {None: None}, "min": -1999, "max": 9999}, + "R-S": {"type": "U8", "index": {None: None}, "min": 0, "max": 1}, + "AT": {"type": "U8", "index": {None: None}, "min": 0, "max": 1}, + "O": {"type": "F24", "index": {None: None}, "min": 0, "max": 100}, + "IN.T": {"type": "U8", "index": {0: 0, 1: 1}, "min": 1, "max": 26}, + "DPT": {"type": "U8", "index": {0: 0, 1: 1}, "min": 0, "max": 1}, + "DP": {"type": "U8", "index": {0: 0, 1: 1}, "min": 0, "max": 3}, + "IN.L": {"type": "F24", "index": {0: 0, 1: 1}, "min": -1999, "max": 9999}, + "IN.H": {"type": "F24", "index": {0: 0, 1: 1}, "min": -1999, "max": 9999}, + "SQR": {"type": "U8", "index": {0: 0, 1: 1}, "min": 0, "max": 2}, + "SH": {"type": "F24", "index": {0: 0, 1: 1}, "min": -500, "max": 500}, + "KU": {"type": "F24", "index": {0: 0, 1: 1}, "min": 0.500, "max": 2.000}, + "FB": {"type": "F24", "index": {0: 0, 1: 1}, "min": 0, "max": 9999}, + "INF": {"type": "F24", "index": {0: 0, 1: 1}, "min": 0, "max": 9999}, + "INP2": {"type": "U8", "index": {None: None}, "min": 0, "max": 4}, + "CALC": {"type": "U8", "index": {None: None}, "min": 0, "max": 34}, + "KPV1": {"type": "F24", "index": {None: None}, "min": -19.99, "max": 99.99}, + "KPV2": {"type": "F24", "index": {None: None}, "min": -19.99, "max": 99.99}, + "SL-L": {"type": "F24", "index": {None: None}, "min": -1999, "max": 3000}, + "SL-H": {"type": "F24", "index": {None: None}, "min": -1999, "max": 3000}, + "OREU": {"type": "U8", "index": {None: None}, "min": 0, "max": 1}, + "RAMP": {"type": "U8", "index": {None: None}, "min": 0, "max": 1}, + "PV0": {"type": "F24", "index": {None: None}, "min": -100, "max": 2000}, + "P": {"type": "F24", "index": {None: None}, "min": 0.001, "max": 9999}, + "I": {"type": "F24", "index": {None: None}, "min": 0, "max": 3999}, + "D": {"type": "F24", "index": {None: None}, "min": 0, "max": 3999}, + "KA": {"type": "F24", "index": {None: None}, "min": 0, "max": 9999}, + "DB": {"type": "F24", "index": {None: None}, "min": 0, "max": 200}, + "VSP": {"type": "F24", "index": {None: None}, "min": 0, "max": 9999}, + "OL-L": {"type": "F24", "index": {None: None}, "min": 0, "max": 100}, + "OL-H": {"type": "F24", "index": {None: None}, "min": 0, "max": 100}, + "MVER": {"type": "F24", "index": {None: None}, "min": 0, "max": 100}, + "MVST": {"type": "F24", "index": {None: None}, "min": 0, "max": 100}, + "MDST": {"type": "U8", "index": {None: None}, "min": 0, "max": 1}, + "LBA": {"type": "U16", "index": {None: None}, "min": 0, "max": 9999}, + "LBAB": {"type": "F24", "index": {None: None}, "min": 0, "max": 9999}, + "ALT": {"type": "U8", "index": {None: None}, "min": 0, "max": 14}, + "AL-D": {"type": "F24", "index": {None: None}, "min": -1999, "max": 3000}, + "AL-H": {"type": "F24", "index": {None: None}, "min": 0, "max": 3000}, + "V.MOT": {"type": "F24", "index": {None: None}, "min": 5, "max": 999}, + "V.DB": {"type": "F24", "index": {None: None}, "min": 0, "max": 9999}, + "V.GAP": {"type": "F24", "index": {None: None}, "min": 0, "max": 10}, + "V.REV": {"type": "F24", "index": {None: None}, "min": 0, "max": 10}, + "V.TOF": {"type": "U8", "index": {None: None}, "min": 0, "max": 10}, + "DIS1": {"type": "U8", "index": {None: None}, "min": 0, "max": 1}, + "DIS2": {"type": "U8", "index": {None: None}, "min": 0, "max": 1}, + "DIS3": {"type": "U8", "index": {None: None}, "min": 0, "max": 1}, + "DIS4": {"type": "U8", "index": {None: None}, "min": 0, "max": 1}, + "DIS5": {"type": "U8", "index": {None: None}, "min": 0, "max": 1}, + "RET": {"type": "U8", "index": {None: None}, "min": 5, "max": 100}, + "NODE": {"type": "U8", "index": {None: None}, "min": 1, "max": 10}, + "X": {"type": "F24", "index": {1: 1, 2: 2, 3: 3, 4: 4, 5: 5, 6: 6, 7: 7, 8: 8, 9: 9, 10: 10}, "min": -1999, "max": 3000}, + "Y": {"type": "F24", "index": {1: 1, 2: 2, 3: 3, 4: 4, 5: 5, 6: 6, 7: 7, 8: 8, 9: 9, 10: 10}, "min": -1999, "max": 3000}, + "PROT": {"type": "U8", "index": {None: None}, "min": 0, "max": 2}, + "BPS": {"type": "U8", "index": {None: None}, "min": 0, "max": 8}, + "A.LEN": {"type": "U8", "index": {None: None}, "min": 0, "max": 1}, + "ADDR": {"type": "U16", "index": {None: None}, "min": 0, "max": 2047}, + "RSDL": {"type": "U8", "index": {None: None}, "min": 1, "max": 45}, + "LEN": {"type": "U8", "index": {None: None}, "min": 0, "max": 1}, + "PRTY": {"type": "U8", "index": {None: None}, "min": 0, "max": 0}, + "SBIT": {"type": "U8", "index": {None: None}, "min": 0, "max": 1}, + "VER": {"type": "STR", "index": {None: None}, "min": None, "max": None}, + "DEV": {"type": "STR", "index": {None: None}, "min": None, "max": None}, + "PRTL": {"type": "U8", "index": {None: None}, "min": None, "max": None}, + "APLY": {"type": "U8", "index": {None: None}, "min": None, "max": None}, + "INIT": {"type": "U8", "index": {None: None}, "min": None, "max": None}, + "N.ERR": {"type": "U24", "index": {None: None}, "min": 0, "max": 255}, + "ATTR": {"type": "U8", "index": {None: None}, "min": 0, "max": 1}, + "R-L": {"type": "U8", "index": {None: None}, "min": 0, "max": 1}, + "R.OUT": {"type": "F24", "index": {None: None}, "min": -1, "max": 1}, + "OAPT": {"type": "U8", "index": {None: None}, "min": 0, "max": 2}, + "WTPT": {"type": "U8", "index": {None: None}, "min": 0, "max": 3}, + "EDPT": {"type": "U8", "index": {None: None}, "min": 0, "max": 1}, + }, + "Modbus": {"STAT": {"type": "U16", "index": {None: 0x0000}, "min": 0, "max": 65535, "dp": None, "precision": 0}, + "PV": {"type": "F32", "index": {0: 0x1009, 1: 0x100B}, "min": -1999, "max": 9999, "dp": None, "precision": 0}, + "LUPV": {"type": "F32", "index": {None: 0x100D}, "min": -1999, "max": 9999, "dp": None, "precision": 0}, + "SP": {"type": "I16", "index": {None: 0x0004}, "min": -1999, "max": 9999, "dp": "DP", "precision": 0}, + "SET.P": {"type": "F32", "index": {None: 0x1011}, "min": -1999, "max": 9999, "dp": None, "precision": 0}, + "O": {"type": "F32", "index": {None: 0x1013}, "min": 0, "max": 100, "dp": None, "precision": 0}, + "R-L": {"type": "U16", "index": {None: 0x0007}, "min": 0, "max": 1, "dp": None, "precision": 0}, + "R.OUT": {"type": "U16", "index": {None: 0x0008}, "min": -1.0, "max": 1.0, "dp": None, "precision": 3}, + "R-S": {"type": "U16", "index": {None: 0x0009}, "min": 0, "max": 1, "dp": None, "precision": 0}, + "AT": {"type": "U16", "index": {None: 0x000A}, "min": 0, "max": 1, "dp": None, "precision": 0}, + "DEV": {"type": "STR", "index": {None: 0x1000}, "min": None, "max": None, "dp": None, "precision": 0}, + "VER": {"type": "STR", "index": {None: 0x1004}, "min": None, "max": None, "dp": None, "precision": 0}, + "PROT": {"type": "U16", "index": {None: 0x0100}, "min": 0, "max": 2, "dp": None, "precision": 0}, + "BPS": {"type": "U16", "index": {None: 0x0101}, "min": 0, "max": 8, "dp": None, "precision": 0}, + "A.LEN": {"type": "U16", "index": {None: 0x0102}, "min": 0, "max": 1, "dp": None, "precision": 0}, + "ADDR": {"type": "U16", "index": {None: 0x0103}, "min": 1, "max": 247, "dp": None, "precision": 0}, + "RSDL": {"type": "U16", "index": {None: 0x0104}, "min": 0, "max": 45, "dp": None, "precision": 0}, + "LEN": {"type": "U16", "index": {None: 0x0105}, "min": 0, "max": 1, "dp": None, "precision": 0}, + "PRTY": {"type": "U16", "index": {None: 0x0106}, "min": 0, "max": 0, "dp": None, "precision": 0}, + "SBIT": {"type": "U16", "index": {None: 0x0107}, "min": 0, "max": 1, "dp": None, "precision": 0}, + "N.ERR": {"type": "U16", "index": {None: 0x0108}, "min": 0, "max": 255, "dp": None, "precision": 0}, + "PRTL": {"type": "U16", "index": {None: 0x0109}, "min": 1, "max": 1, "dp": None, "precision": 0}, + "APLY": {"type": "U16", "index": {None: 0x010A}, "min": 1, "max": 1, "dp": None, "precision": 0}, + "INIT": {"type": "U16", "index": {None: 0x010B}, "min": 1, "max": 1, "dp": None, "precision": 0}, + "IN.T": {"type": "U16", "index": {0: 0x0200, 1: 0x020A}, "min": 1, "max": 26, "dp": None, "precision": 0}, + "DPT": {"type": "U16", "index": {0: 0x0201, 1: 0x020B}, "min": 0, "max": 1, "dp": None, "precision": 0}, + "DP": {"type": "U16", "index": {0: 0x0202, 1: 0x020C}, "min": 0, "max": 3, "dp": None, "precision": 0}, + "IN.L": {"type": "I16", "index": {0: 0x0203, 1: 0x020D}, "min": -1999, "max": 9999, "dp": "DP", "precision": 0}, + "IN.H": {"type": "I16", "index": {0: 0x0204, 1: 0x020E}, "min": -1999, "max": 9999, "dp": "DP", "precision": 0}, + "SH": {"type": "I16", "index": {0: 0x0205, 1: 0x020F}, "min": -500, "max": 500, "dp": "DP", "precision": 0}, + "KU": {"type": "U16", "index": {0: 0x0206, 1: 0x0210}, "min": 0.5, "max": 2.0, "dp": None, "precision": 3}, + "FB": {"type": "U16", "index": {0: 0x0207, 1: 0x0211}, "min": 0, "max": 9999, "dp": "DP", "precision": 0}, + "INF": {"type": "U16", "index": {0: 0x0208, 1: 0x0212}, "min": 0, "max": 999, "dp": None, "precision": 0}, + "SQR": {"type": "U16", "index": {0: 0x0209, 1: 0x0213}, "min": 0, "max": 1, "dp": None, "precision": 0}, + "INP2": {"type": "U16", "index": {None: 0x0300}, "min": 0, "max": 4, "dp": None, "precision": 0}, + "CALC": {"type": "U16", "index": {None: 0x0301}, "min": 0, "max": 3, "dp": None, "precision": 0}, + "KPV1": {"type": "I16", "index": {None: 0x0302}, "min": -19.99, "max": 99.99, "dp": None, "precision": 2}, + "KPV2": {"type": "I16", "index": {None: 0x0303}, "min": -19.99, "max": 99.99, "dp": None, "precision": 2}, + "SL-L": {"type": "I16", "index": {None: 0x0304}, "min": -1999, "max": 3000, "dp": "DP", "precision": 0}, + "SL-H": {"type": "I16", "index": {None: 0x0305}, "min": -1999, "max": 3000, "dp": "DP", "precision": 0}, + "OREU": {"type": "U16", "index": {None: 0x0306}, "min": 0, "max": 1, "dp": None, "precision": 0}, + "PV0": {"type": "I16", "index": {None: 0x0307}, "min": -100, "max": 2000, "dp": None, "precision": 0}, + "RAMP": {"type": "U16", "index": {None: 0x0308}, "min": 0, "max": 1, "dp": None, "precision": 0}, + "P": {"type": "U16", "index": {None: 0x0309}, "min": 1, "max": 9999, "dp": "DP", "precision": 0}, + "I": {"type": "U16", "index": {None: 0x030A}, "min": 0, "max": 3999, "dp": None, "precision": 0}, + "D": {"type": "U16", "index": {None: 0x030B}, "min": 0, "max": 3999, "dp": None, "precision": 0}, + "DB": {"type": "U16", "index": {None: 0x030C}, "min": 0, "max": 200, "dp": "DP", "precision": 0}, + "VSP": {"type": "U16", "index": {None: 0x030D}, "min": 0, "max": 9999, "dp": "DP", "precision": 0}, + "OL-L": {"type": "U16", "index": {None: 0x030E}, "min": 0, "max": 100, "dp": None, "precision": 0}, + "OL-H": {"type": "U16", "index": {None: 0x030F}, "min": 0, "max": 100, "dp": None, "precision": 0}, + "LBA": {"type": "U16", "index": {None: 0x0310}, "min": 0, "max": 9999, "dp": None, "precision": 0}, + "LBAB": {"type": "U16", "index": {None: 0x0311}, "min": 0, "max": 9999, "dp": "DP", "precision": 0}, + "MVER": {"type": "U16", "index": {None: 0x0312}, "min": 0, "max": 100, "dp": None, "precision": 0}, + "MVST": {"type": "U16", "index": {None: 0x0313}, "min": 0, "max": 100, "dp": None, "precision": 0}, + "MDST": {"type": "U16", "index": {None: 0x0314}, "min": 0, "max": 1, "dp": None, "precision": 0}, + "ALT": {"type": "U16", "index": {None: 0x0315}, "min": 0, "max": 14, "dp": None, "precision": 0}, + "AL-D": {"type": "U16", "index": {None: 0x0316}, "min": -1999, "max": 3000, "dp": "DP", "precision": 0}, + "AL-H": {"type": "U16", "index": {None: 0x0317}, "min": 0, "max": 3000, "dp": "DP", "precision": 0}, + "V.MOT": {"type": "U16", "index": {None: 0x0400}, "min": 5, "max": 999, "dp": None, "precision": 0}, + "V.DB": {"type": "U16", "index": {None: 0x0401}, "min": 0, "max": 9999, "dp": None, "precision": 0}, + "V.GAP": {"type": "U16", "index": {None: 0x0402}, "min": 0, "max": 10, "dp": None, "precision": 1}, + "V.REV": {"type": "U16", "index": {None: 0x0403}, "min": 0, "max": 10, "dp": None, "precision": 1}, + "V.TOF": {"type": "U16", "index": {None: 0x0404}, "min": 0, "max": 10, "dp": None, "precision": 0}, + "RET": {"type": "U16", "index": {None: 0x0500}, "min": 5, "max": 100, "dp": None, "precision": 0}, + "DIS1": {"type": "U16", "index": {None: 0x0501}, "min": 0, "max": 1, "dp": None, "precision": 0}, + "DIS2": {"type": "U16", "index": {None: 0x0502}, "min": 0, "max": 1, "dp": None, "precision": 0}, + "DIS3": {"type": "U16", "index": {None: 0x0503}, "min": 0, "max": 1, "dp": None, "precision": 0}, + "DIS4": {"type": "U16", "index": {None: 0x0504}, "min": 0, "max": 1, "dp": None, "precision": 0}, + "DIS5": {"type": "U16", "index": {None: 0x0505}, "min": 0, "max": 1, "dp": None, "precision": 0}, + "NODE": {"type": "U16", "index": {None: 0x0600}, "min": 1, "max": 10, "dp": None, "precision": 0}, + "X": {"type": "I16", "index": {1: 0x0601, 2: 0x0603, 3: 0x0605, 4: 0x0607, 5: 0x0609, 6: 0x060B, 7: 0x060D, 8: 0x060F, 9: 0x0611, 10: 0x0613}, "min": -1999, "max": 3000, "dp": "DP", "precision": 0}, + "Y": {"type": "I16", "index": {1: 0x0602, 2: 0x0604, 3: 0x0606, 4: 0x0608, 5: 0x060A, 6: 0x060C, 7: 0x060E, 8: 0x0610, 9: 0x0612, 10: 0x0614}, "min": -1999, "max": 3000, "dp": "DP", "precision": 0}, + "OAPT": {"type": "U16", "index": {None: 0x0700}, "min": 0, "max": 2, "dp": None, "precision": 0}, + "WTPT": {"type": "U16", "index": {None: 0x0701}, "min": 0, "max": 4, "dp": None, "precision": 0}, + "EDPT": {"type": "U16", "index": {None: 0x0702}, "min": 0, "max": 1, "dp": None, "precision": 0}, + }, +} + +# Таблица настроек измерителя-регулятора ТРМ251 +TRM251: OWEN_DEVICE = { + "Owen": {"VER": {"type": "STR", "index": {None: None}, "min": None, "max": None}, + "DEV": {"type": "STR", "index": {None: None}, "min": None, "max": None}, + "CJ-.C": {"type": "U8", "index": {None: None}, "min": 0, "max": 1}, + "IN.RE": {"type": "U8", "index": {None: None}, "min": 0, "max": 1}, + "IN-T": {"type": "U8", "index": {0: 0, 1: 1}, "min": 0, "max": 36}, + "IN.FD": {"type": "U16", "index": {0: 0, 1: 1}, "min": 0, "max": 1800}, + "IN.FG": {"type": "U16", "index": {0: 0, 1: 1}, "min": 0, "max": 9999}, + "ITRL": {"type": "U16", "index": {0: 0, 1: 1}, "min": 0.3, "max": 30}, + "IN.SH": {"type": "SDOT", "index": {0: 0, 1: 1}, "min": -999, "max": 9999}, + "IN.SL": {"type": "U16", "index": {0: 0, 1: 1}, "min": 0.9, "max": 1.1}, + "AIN.L": {"type": "SDOT", "index": {0: 0, 1: 1}, "min": -999, "max": 9999}, + "AIN.H": {"type": "SDOT", "index": {0: 0, 1: 1}, "min": -999, "max": 9999}, + "REG.T": {"type": "U8", "index": {None: None}, "min": 0, "max": 1}, + "PB": {"type": "SDOT", "index": {None: None}, "min": 0.001, "max": 9999}, + "TI": {"type": "U16", "index": {None: None}, "min": 0, "max": 1092}, + "TD.TI": {"type": "U16", "index": {None: None}, "min": 0, "max": 0.3}, + "I.UPR": {"type": "I16", "index": {None: None}, "min": -100, "max": 100}, + "I.MIN": {"type": "I16", "index": {None: None}, "min": -100, "max": 100}, + "P.NOM": {"type": "U16", "index": {None: None}, "min": 0, "max": 100}, + "P.UPR": {"type": "U16", "index": {None: None}, "min": 0, "max": 100}, + "P.MIN": {"type": "U16", "index": {None: None}, "min": 0, "max": 100}, + "P.STP": {"type": "U16", "index": {None: None}, "min": 0, "max": 100}, + "P.RES": {"type": "U16", "index": {None: None}, "min": 0, "max": 1000}, + "HYS.C": {"type": "SDOT", "index": {None: None}, "min": 0, "max": 9999}, + "DEL": {"type": "U8", "index": {None: None}, "min": 0, "max": 200}, + "HOLD": {"type": "U8", "index": {None: None}, "min": 0, "max": 200}, + "YO": {"type": "SDOT", "index": {None: None}, "min": -9999, "max": 9999}, + "YDOP": {"type": "SDOT", "index": {None: None}, "min": 0, "max": 999}, + "POU": {"type": "U8", "index": {None: None}, "min": 0, "max": 1}, + "THP": {"type": "U8", "index": {None: None}, "min": 1, "max": 81}, + "T.L": {"type": "F24", "index": {None: None}, "min": 0.05, "max": 0.5}, + "RG.ON": {"type": "U8", "index": {None: None}, "min": 0, "max": 1}, + "AO.L": {"type": "SDOT", "index": {None: None}, "min": -999, "max": 9999}, + "AO.H": {"type": "SDOT", "index": {None: None}, "min": -999, "max": 9999}, + "SP": {"type": "SDOT", "index": {0: 0, 1: 1, 2: 2, 3: 3, 4: 4, 5: 5, 6: 6, 7: 7, 8: 8, 9: 9, 10: 10, 11: 11, 12: 12, 13: 13, 14: 14}, "min": -999, "max": 9999}, + "T.RS": {"type": "U16", "index": {0: 0, 1: 1, 2: 2, 3: 3, 4: 4, 5: 5, 6: 6, 7: 7, 8: 8, 9: 9, 10: 10, 11: 11, 12: 12, 13: 13, 14: 14}, "min": 0, "max": 65520}, + "T.STB": {"type": "U16", "index": {0: 0, 1: 1, 2: 2, 3: 3, 4: 4, 5: 5, 6: 6, 7: 7, 8: 8, 9: 9, 10: 10, 11: 11, 12: 12, 13: 13, 14: 14}, "min": 0, "max": 65520}, + "SIG.T": {"type": "U8", "index": {0: 0, 1: 1, 2: 2}, "min": 0, "max": 1}, + "S.H": {"type": "SDOT", "index": {0: 0, 1: 1, 2: 2}, "min": 0, "max": 9999}, + "S.L": {"type": "SDOT", "index": {0: 0, 1: 1, 2: 2}, "min": 0, "max": 9999}, + "LBA": {"type": "U8", "index": {0: 0, 1: 1, 2: 2}, "min": 0, "max": 1}, + "D.LBA": {"type": "SDOT", "index": {0: 0, 1: 1, 2: 2}, "min": 0.001, "max": 9999}, + "T.LBA": {"type": "U16", "index": {0: 0, 1: 1, 2: 2}, "min": 0.001, "max": 9999}, + "BPS": {"type": "U8", "index": {None: None}, "min": 0, "max": 8}, + "LEN": {"type": "U8", "index": {None: None}, "min": 7, "max": 8}, + "PRTY": {"type": "U8", "index": {None: None}, "min": 0, "max": 2}, + "SBIT": {"type": "U8", "index": {None: None}, "min": 1, "max": 2}, + "A.LEN": {"type": "U8", "index": {None: None}, "min": 8, "max": 11}, + "ADDR": {"type": "U16", "index": {None: None}, "min": 0, "max": 2040}, + "PROT": {"type": "U8", "index": {None: None}, "min": 0, "max": 2}, + "DOT": {"type": "U8", "index": {None: None}, "min": 0, "max": 3}, + "RS.DL": {"type": "U8", "index": {None: None}, "min": 0, "max": 50}, + "BEHV": {"type": "U8", "index": {None: None}, "min": 0, "max": 3}, + "T.SCL": {"type": "U8", "index": {None: None}, "min": 0, "max": 1}, + "NET.S": {"type": "U8", "index": {None: None}, "min": 0, "max": 1}, + "READ": {"type": "F32+T", "index": {None: None}, "min": -999, "max": 9999}, + "R.OUT": {"type": "F32", "index": {None: None}, "min": 0, "max": 1}, + "R.SIG": {"type": "U16", "index": {None: None}, "min": 0, "max": 1}, + "RD.RG": {"type": "F32", "index": {None: None}, "min": 0, "max": 1}, + "R.ST": {"type": "U16", "index": {None: None}, "min": 0, "max": 7}, + "R.PRG": {"type": "U16", "index": {None: None}, "min": 1, "max": 3}, + "R.STP": {"type": "U16", "index": {None: None}, "min": 1, "max": 5}, + "SET.P": {"type": "F32", "index": {None: None}, "min": -999, "max": 9999}, + "R-S": {"type": "U16", "index": {None: None}, "min": 0, "max": 1}, + }, + "Modbus": {"DOT": {"type": "I16", "index": {0: 0x0000, 1: 0x0006}, "min": 0, "max": 3, "dp": None, "precision": 0}, + "READ": {"type": "F32", "index": {0: 0x0004, 1: 0x000A}, "min": -999, "max": 9999, "dp": None, "precision": 0}, + "R.OUT": {"type": "I16", "index": {None: 0x000C}, "min": 0, "max": 1000, "dp": None, "precision": 0}, + "SET.P": {"type": "I16", "index": {None: 0x000D}, "min": -999, "max": 9999, "dp": None, "precision": 0}, + "R.SIG": {"type": "I16", "index": {None: 0x000E}, "min": 0, "max": 1, "dp": None, "precision": 0}, + "R.PRG": {"type": "I16", "index": {None: 0x000F}, "min": 0, "max": 3, "dp": None, "precision": 0}, + "R.STP": {"type": "I16", "index": {None: 0x0010}, "min": 1, "max": 5, "dp": None, "precision": 0}, + "R.ST": {"type": "I16", "index": {None: 0x0011}, "min": 0, "max": 7, "dp": None, "precision": 0}, + "T.SCL": {"type": "I16", "index": {None: 0x0100}, "min": 0, "max": 1, "dp": None, "precision": 0}, + "SP": {"type": "I16", "index": {0: 0x0101, 1: 0x0105, 2: 0x0109, 3: 0x010D, 4: 0x0111, 5: 0x0115, 6: 0x0119, 7: 0x011D, 8: 0x0121, 9: 0x0125, 10: 0x0129, 11: 0x012D, 12: 0x0131, 13: 0x0135, 14: 0x0139}, "min": -999, "max": 9999, "dp": None, "precision": 0}, + "T.RS": {"type": "I16", "index": {0: 0x0103, 1: 0x0107, 2: 0x010B, 3: 0x010F, 4: 0x0113, 5: 0x0117, 6: 0x011B, 7: 0x011F, 8: 0x0123, 9: 0x0127, 10: 0x012B, 11: 0x012F, 12: 0x0133, 13: 0x0137, 14: 0x013B}, "min": 0, "max": 1092, "dp": None, "precision": 0}, + "T.STB": {"type": "I16", "index": {0: 0x0104, 1: 0x0108, 2: 0x010C, 3: 0x0110, 4: 0x0114, 5: 0x0118, 6: 0x011C, 7: 0x0120, 8: 0x0124, 9: 0x0128, 10: 0x012C, 11: 0x0130, 12: 0x0134, 13: 0x0138, 14: 0x013C}, "min": 0, "max": 1092, "dp": None, "precision": 0}, + "S.H": {"type": "I16", "index": {0: 0x0140, 1: 0x0144, 2: 0x0148}, "min": 0, "max": 9999, "dp": None, "precision": 0}, + "S.L": {"type": "I16", "index": {0: 0x0142, 1: 0x0146, 2: 0x014A}, "min": 0, "max": 9999, "dp": None, "precision": 0}, + "R-S": {"type": "I16", "index": {None: 0x0050}, "min": 0, "max": 1, "dp": None, "precision": 0}, + }, +} + +# Таблица настроек измерителя-регулятора микропроцессорного двухканального 2ТРМ1 +_2TRM1: OWEN_DEVICE = { + "Modbus": {"STAT": {"type": "U16", "index": {None: 0x1008}, "min": 0, "max": 65535, "dp": None, "precision": 0}, + "DEV": {"type": "STR", "index": {None: 0x1000}, "min": None, "max": None, "dp": None, "precision": 0}, + "VER": {"type": "STR", "index": {None: 0x1004}, "min": None, "max": None, "dp": None, "precision": 0}, + "PV": {"type": "F32", "index": {0: 0x1009, 1: 0x100B}, "min": -1999, "max": 9999, "dp": None, "precision": 0}, + "FUN": {"type": "F32", "index": {0: 0x100D, 1: 0x100F}, "min": -1999, "max": 9999, "dp": None, "precision": 0}, + "SP": {"type": "F32", "index": {0: 0x1011, 1: 0x1013}, "min": -1999, "max": 9999, "dp": None, "precision": 0}, + "OUT.P": {"type": "F32", "index": {0: 0x1015, 1: 0x1017}, "min": -1999, "max": 9999, "dp": None, "precision": 0}, + "CTRL": {"type": "U16", "index": {None: 0x1019}, "min": 0, "max": 2, "dp": None, "precision": 0}, + "RESET": {"type": "U16", "index": {None: 0x101A}, "min": 1, "max": 1, "dp": None, "precision": 0}, + "TYPE": {"type": "U16", "index": {0: 0x0004, 1: 0x0104}, "min": 0, "max": 42, "dp": None, "precision": 0}, + "FIL.B": {"type": "F32", "index": {0: 0x0005, 1: 0x0105}, "min": -1999, "max": 9999, "dp": None, "precision": 0}, + "FIL.T": {"type": "U16", "index": {0: 0x0007, 1: 0x0107}, "min": 0, "max": 999, "dp": None, "precision": 0}, + "DPT": {"type": "U16", "index": {0: 0x0008, 1: 0x0108}, "min": 0, "max": 4, "dp": None, "precision": 0}, + "IND.L": {"type": "F32", "index": {0: 0x0009, 1: 0x0109}, "min": -1999, "max": 9999, "dp": None, "precision": 0}, + "IND.H": {"type": "F32", "index": {0: 0x000B, 1: 0x010B}, "min": -1999, "max": 9999, "dp": None, "precision": 0}, + "CF": {"type": "F32", "index": {0: 0x000E, 1: 0x0010}, "min": -100, "max": 100, "dp": None, "precision": 0}, + "DIN.T": {"type": "U16", "index": {0: 0x0012, 1: 0x0112}, "min": 0, "max": 30, "dp": None, "precision": 0}, + "DIN.D": {"type": "F32", "index": {0: 0x0013, 1: 0x0113}, "min": 0.2, "max": 9999, "dp": None, "precision": 0}, + "BARR": {"type": "U16", "index": {0: 0x0015, 1: 0x0115}, "min": 0, "max": 1, "dp": None, "precision": 0}, + "COR1.POINT": {"type": "F32", "index": {0: 0x0016, 1: 0x0116}, "min": -1999, "max": 9999, "dp": None, "precision": 0}, + "COR1.OFFSET": {"type": "F32", "index": {0: 0x0018, 1: 0x0118}, "min": -1999, "max": 9999, "dp": None, "precision": 0}, + "COR1.CLR": {"type": "U16", "index": {0: 0x001A, 1: 0x011A}, "min": 0, "max": 1, "dp": None, "precision": 0}, + "COR2.POINT": {"type": "F32", "index": {0: 0x001B, 1: 0x011B}, "min": -1999, "max": 9999, "dp": None, "precision": 0}, + "COR2.OFFSET": {"type": "F32", "index": {0: 0x001D, 1: 0x011D}, "min": -1999, "max": 9999, "dp": None, "precision": 0}, + "COR2.CLR": {"type": "U16", "index": {0: 0x001F, 1: 0x011F}, "min": 0, "max": 1, "dp": None, "precision": 0}, + "COR3.POINT": {"type": "F32", "index": {0: 0x0020, 1: 0x0120}, "min": -1999, "max": 9999, "dp": None, "precision": 0}, + "COR3.OFFSET": {"type": "F32", "index": {0: 0x0022, 1: 0x0122}, "min": -1999, "max": 9999, "dp": None, "precision": 0}, + "COR3.CLR": {"type": "U16", "index": {0: 0x0024, 1: 0x0124}, "min": 0, "max": 1, "dp": None, "precision": 0}, + "SP.LO": {"type": "F32", "index": {0: 0x0202, 1: 0x0302}, "min": -1999, "max": 9999, "dp": None, "precision": 0}, + "SP.HI": {"type": "F32", "index": {0: 0x0204, 1: 0x0304}, "min": -1999, "max": 9999, "dp": None, "precision": 0}, + "LBA.T": {"type": "U16", "index": {0: 0x0208, 1: 0x0308}, "min": 0, "max": 9999, "dp": None, "precision": 0}, + "LBA.B": {"type": "F32", "index": {0: 0x0209, 1: 0x0309}, "min": 0, "max": 9999, "dp": None, "precision": 0}, + "LOG.D": {"type": "U16", "index": {0: 0x0220, 1: 0x0320}, "min": 0, "max": 3, "dp": None, "precision": 0}, + "HYST": {"type": "F32", "index": {0: 0x0221, 1: 0x0321}, "min": 0, "max": 9999, "dp": None, "precision": 0}, + "D.ON": {"type": "U16", "index": {0: 0x0223, 1: 0x0323}, "min": 0, "max": 250, "dp": None, "precision": 0}, + "D.OFF": {"type": "U16", "index": {0: 0x0224, 1: 0x0324}, "min": 0, "max": 250, "dp": None, "precision": 0}, + "H.ON": {"type": "U16", "index": {0: 0x0225, 1: 0x0325}, "min": 0, "max": 250, "dp": None, "precision": 0}, + "H.OFF": {"type": "U16", "index": {0: 0x0226, 1: 0x0326}, "min": 0, "max": 250, "dp": None, "precision": 0}, + "CNT.P": {"type": "U16", "index": {0: 0x0227, 1: 0x0327}, "min": 1, "max": 250, "dp": None, "precision": 0}, + "ERR.D": {"type": "U16", "index": {0: 0x0228, 1: 0x0328}, "min": 0, "max": 1, "dp": None, "precision": 0}, + "STP.D": {"type": "U16", "index": {0: 0x0229, 1: 0x0329}, "min": 0, "max": 1, "dp": None, "precision": 0}, + "A.TYP": {"type": "U16", "index": {0: 0x0240, 1: 0x0340}, "min": 0, "max": 8, "dp": None, "precision": 0}, + "A.BND": {"type": "F32", "index": {0: 0x0241, 1: 0x0341}, "min": 0, "max": 9999, "dp": None, "precision": 0}, + "A.HYS": {"type": "F32", "index": {0: 0x0243, 1: 0x0343}, "min": 0, "max": 9999, "dp": None, "precision": 0}, + "F.BLC": {"type": "U16", "index": {0: 0x0245, 1: 0x0345}, "min": 0, "max": 1, "dp": None, "precision": 0}, + "LOG.A": {"type": "U16", "index": {0: 0x0260, 1: 0x0360}, "min": 0, "max": 3, "dp": None, "precision": 0}, + "XP": {"type": "F32", "index": {0: 0x0261, 1: 0x0361}, "min": 0, "max": 9999, "dp": None, "precision": 0}, # в документации HYST, но HYST уже есть + "OUT.L": {"type": "F32", "index": {0: 0x0263, 1: 0x0363}, "min": -1999, "max": 9999, "dp": None, "precision": 0}, + "OUT.H": {"type": "F32", "index": {0: 0x0265, 1: 0x0365}, "min": -1999, "max": 9999, "dp": None, "precision": 0}, + "ERR.A": {"type": "U16", "index": {0: 0x0267, 1: 0x0367}, "min": 0, "max": 1, "dp": None, "precision": 0}, + "STP.A": {"type": "U16", "index": {0: 0x0268, 1: 0x0368}, "min": 0, "max": 1, "dp": None, "precision": 0}, + "SCR": {"type": "U16", "index": {0: 0x0400, 1: 0x0401, 2: 0x0402, 3: 0x0403, 4: 0x0404, 5: 0x0405}, "min": 0, "max": 16, "dp": None, "precision": 0}, + "OUT.S": {"type": "U16", "index": {None: 0x0406}, "min": 0, "max": 1, "dp": None, "precision": 0}, + "RET.T": {"type": "U16", "index": {None: 0x0407}, "min": 0, "max": 4, "dp": None, "precision": 0}, + "CHG.T": {"type": "U16", "index": {None: 0x0408}, "min": 0, "max": 5, "dp": None, "precision": 0}, + "PROT": {"type": "U16", "index": {None: 0x0500}, "min": 0, "max": 1, "dp": None, "precision": 0}, + "ADDR": {"type": "U16", "index": {None: 0x0501}, "min": 1, "max": 247, "dp": None, "precision": 0}, + "BAUD": {"type": "U16", "index": {None: 0x0502}, "min": 0, "max": 8, "dp": None, "precision": 0}, + "DPS": {"type": "U16", "index": {None: 0x0503}, "min": 0, "max": 11, "dp": None, "precision": 0}, + "IDLE": {"type": "U16", "index": {None: 0x0504}, "min": 0, "max": 20, "dp": None, "precision": 0}, + "B.ORD": {"type": "U16", "index": {None: 0x0505}, "min": 0, "max": 1, "dp": None, "precision": 0}, + "APLY": {"type": "U16", "index": {None: 0x0506}, "min": 0, "max": 1, "dp": None, "precision": 0}, + "GRF.N": {"type": "U16", "index": {None: 0x0600}, "min": 0, "max": 10, "dp": None, "precision": 0}, + "IN.": {"type": "F32", "index": {0: 0x0601, 1: 0x0605, 2: 0x0609, 3: 0x060D, 4: 0x0611, 5: 0x0615, 6: 0x0619, 7: 0x061D, 8: 0x0621, 9: 0x0625}, "min": 0, "max": 10, "dp": None, "precision": 0}, + "SP.": {"type": "F32", "index": {0: 0x0603, 1: 0x0607, 2: 0x060B, 3: 0x060F, 4: 0x0613, 5: 0x0617, 6: 0x061B, 7: 0x061F, 8: 0x0623, 9: 0x0627}, "min": 0, "max": 10, "dp": None, "precision": 0}, + "PASS": {"type": "U16", "index": {None: 0x0800}, "min": 0, "max": 9999, "dp": None, "precision": 0}, + "PRT.E": {"type": "U16", "index": {None: 0x0801}, "min": 0, "max": 3, "dp": None, "precision": 0}, + "ATR.E": {"type": "U16", "index": {None: 0x0802}, "min": 0, "max": 2, "dp": None, "precision": 0}, + "CJS.E": {"type": "U16", "index": {None: 0x0803}, "min": 0, "max": 1, "dp": None, "precision": 0}, + }, +} + +# Таблица настроек программируемого логического реле ПР100 +PR100: OWEN_DEVICE = { + "Owen": {}, # Протокол OWEN не поддерживается для ПР100 + "Modbus": { + # Дискретные входы (для всех модификаций) + "DI": { + "type": "U16", + "index": {None: 0x0100}, # Все входы в одном регистре как битовая маска + "min": 0, + "max": 4095, # Максимум 12 входов (0xFFF) + "dp": None, + "precision": 0 + }, + # Универсальные входы (аналоговые) - float32 + "AI1": { + "type": "F32", + "index": {None: 0x0B00}, + "min": -999, + "max": 9999, + "dp": None, + "precision": 0 + }, + "AI2": { + "type": "F32", + "index": {None: 0x0B02}, + "min": -999, + "max": 9999, + "dp": None, + "precision": 0 + }, + "AI3": { + "type": "F32", + "index": {None: 0x0B04}, + "min": -999, + "max": 9999, + "dp": None, + "precision": 0 + }, + "AI4": { + "type": "F32", + "index": {None: 0x0B06}, + "min": -999, + "max": 9999, + "dp": None, + "precision": 0 + }, + # Универсальные входы - целое число (результат × 10^dp) + "AI1.INT": { + "type": "I16", + "index": {None: 0x0B80}, + "min": -1999, + "max": 9999, + "dp": "AI1.DP", + "precision": 0 + }, + "AI2.INT": { + "type": "I16", + "index": {None: 0x0B81}, + "min": -1999, + "max": 9999, + "dp": "AI2.DP", + "precision": 0 + }, + "AI3.INT": { + "type": "I16", + "index": {None: 0x0B82}, + "min": -1999, + "max": 9999, + "dp": "AI3.DP", + "precision": 0 + }, + "AI4.INT": { + "type": "I16", + "index": {None: 0x0B83}, + "min": -1999, + "max": 9999, + "dp": "AI4.DP", + "precision": 0 + }, + # Смещение десятичной точки + "AI1.DP": { + "type": "I16", + "index": {None: 0x0BC0}, + "min": 0, + "max": 3, + "dp": None, + "precision": 0 + }, + "AI2.DP": { + "type": "I16", + "index": {None: 0x0BC1}, + "min": 0, + "max": 3, + "dp": None, + "precision": 0 + }, + "AI3.DP": { + "type": "I16", + "index": {None: 0x0BC2}, + "min": 0, + "max": 3, + "dp": None, + "precision": 0 + }, + "AI4.DP": { + "type": "I16", + "index": {None: 0x0BC3}, + "min": 0, + "max": 3, + "dp": None, + "precision": 0 + }, + # Дискретные выходы (записываемые) + "DO": { + "type": "U16", + "index": {None: 0x0000}, # Все выходы в одном регистре + "min": 0, + "max": 1023, # Максимум 10 выходов (Q1-Q8, F1-F2) + "dp": None, + "precision": 0 + }, + # Системное время + "TIME.SEC": { + "type": "I16", + "index": {None: 0x0400}, + "min": 0, + "max": 59, + "dp": None, + "precision": 0 + }, + "TIME.MIN": { + "type": "I16", + "index": {None: 0x0401}, + "min": 0, + "max": 59, + "dp": None, + "precision": 0 + }, + "TIME.HOUR": { + "type": "I16", + "index": {None: 0x0402}, + "min": 0, + "max": 23, + "dp": None, + "precision": 0 + }, + "TIME.DAY": { + "type": "I16", + "index": {None: 0x0403}, + "min": 1, + "max": 31, + "dp": None, + "precision": 0 + }, + "TIME.MONTH": { + "type": "I16", + "index": {None: 0x0404}, + "min": 1, + "max": 12, + "dp": None, + "precision": 0 + }, + "TIME.YEAR": { + "type": "I16", + "index": {None: 0x0405}, + "min": 0, + "max": 99, + "dp": None, + "precision": 0 + }, + "TIME.DOW": { + "type": "I16", + "index": {None: 0x0406}, + "min": 0, + "max": 6, + "dp": None, + "precision": 0 + }, + "TIME.WOM": { + "type": "I16", + "index": {None: 0x0407}, + "min": 0, + "max": 5, + "dp": None, + "precision": 0 + }, + "TIME.WOY": { + "type": "I16", + "index": {None: 0x0408}, + "min": 0, + "max": 53, + "dp": None, + "precision": 0 + }, + } +} \ No newline at end of file diff --git a/owen/protocol.py b/owen/protocol.py new file mode 100644 index 0000000..4747b36 --- /dev/null +++ b/owen/protocol.py @@ -0,0 +1,151 @@ +#! /usr/bin/env python3 + +"""Реализация протокола взаимодействия ОВЕН.""" + +from __future__ import annotations + +import logging +from functools import reduce +from struct import error, unpack + +from owen.converter import OWEN_TYPE + +_logger = logging.getLogger(__name__) +_logger.addHandler(logging.NullHandler()) + + +HEADER = ord("#") +FOOTER = ord("\r") +OWEN_ASCII = {"0": 0, "1": 2, "2": 4, "3": 6, "4": 8, + "5": 10, "6": 12, "7": 14, "8": 16, "9": 18, + "A": 20, "B": 22, "C": 24, "D": 26, "E": 28, + "F": 30, "G": 32, "H": 34, "I": 36, "J": 38, + "K": 40, "L": 42, "M": 44, "N": 46, "O": 48, + "P": 50, "Q": 52, "R": 54, "S": 56, "T": 58, + "U": 60, "V": 62, "W": 64, "X": 66, "Y": 68, + "Z": 70, "-": 72, "_": 74, "/": 76, " ": 78} + + +class OwenError(Exception): + pass + + +class Owen: + """Класс, описывающий протокол ОВЕН.""" + + def __init__(self, unit: int, addr_len_8: bool) -> None: + """Инициализация класса клиента с указанными параметрами.""" + + self.unit = unit + self.addr_len_8 = addr_len_8 + + @staticmethod + def fast_calc(value: int, crc: int, bits: int) -> int: + """Вычисление значения полинома.""" + + return reduce(lambda crc, i: crc << 1 & 0xFFFF ^ (0x8F57 + if (value << i ^ crc >> 8) & 0x80 else 0), range(bits), crc) + + def owen_crc16(self, packet: tuple[int, ...]) -> int: + """Вычисление контрольной суммы.""" + + return reduce(lambda crc, val: self.fast_calc(val, crc, 8), packet, 0) + + def owen_hash(self, packet: tuple[int, ...]) -> int: + """Вычисление hash-функции.""" + + return reduce(lambda crc, val: self.fast_calc(val << 1, crc, 7), packet, 0) + + @staticmethod + def name2code(name: str) -> tuple[int, ...]: + """Преобразование локального идентификатора в числовой код.""" + + code: list[int] = reduce(lambda x, ch: [*x[:-1], x[-1] + 1] if ch == "." + else [*x, OWEN_ASCII[ch]], name.upper(), []) + return (*code, *[OWEN_ASCII[" "]] * (4 - len(code))) + + @staticmethod + def encode_frame(frame: tuple[int, ...]) -> bytes: + """Преобразование пакета из числового вида в строковый.""" + + chars = ([71 + (num >> 4), 71 + (num & 0xF)] for num in frame) + return bytes([HEADER, *sum(chars, []), FOOTER]) + + @staticmethod + def decode_frame(frame: bytes) -> tuple[int, ...]: + """Преобразование пакета из строкового вида в числовой.""" + + pairs = zip(*[iter(frame[1:-1])] * 2) + return tuple((i - 71 << 4) + (j - 71 & 0xF) for i, j in pairs) + + @staticmethod + def pack_value(frmt: str, value: float | str | None) -> bytes: + """Упаковка данных заданного формата.""" + + return b"" if value is None else OWEN_TYPE[frmt]["pack"](value) + + @staticmethod + def unpack_value(frmt: str, value: bytes, index: int | None) -> float | str: + """Распаковка данных заданного формата.""" + + try: + return OWEN_TYPE[frmt]["unpack"](value, index) + except error: + errcode = OWEN_TYPE["U8"]["unpack"](value, index) + msg = f"Device error={errcode:02X}" + raise OwenError(msg) from None + + def make_packet(self, flag: int, name: str, index: int | None, + data: bytes) -> bytes: + """Формирование пакета для записи.""" + + addr0, addr1 = (self.unit & 0xFF, 0) if self.addr_len_8 else \ + (self.unit >> 3 & 0xFF, (self.unit & 0x07) << 5) + if index is not None: + data = bytes([*data, *index.to_bytes(2, "big")]) + + cmd = self.owen_hash(self.name2code(name)) + frame = (addr0, addr1 | flag << 4 | len(data), *cmd.to_bytes(2, "big"), *data) + crc = self.owen_crc16(frame) + packet = self.encode_frame((*frame, *crc.to_bytes(2, "big"))) + + _logger.debug("Send param: address=%d, flag=%d, size=%d, cmd=%04X, " + "index=%s, data=%s, crc=%04X", self.unit, flag, len(data), + cmd, index, tuple(data), crc) + _logger.debug("Send frame: %r, size=%d", packet, len(packet)) + + return packet + + def parse_response(self, packet: bytes, answer: bytes) -> bytes: + """Расшифровка прочитанного пакета.""" + + _logger.debug("Recv frame: %r, size=%d", answer, len(answer)) + + if not answer or answer[0] != HEADER or answer[-1] != FOOTER: + msg = "Invalid message format" + raise OwenError(msg) + + frame = self.decode_frame(answer) + + address = frame[0] if self.addr_len_8 else frame[0] << 3 | frame[1] >> 5 + flag = frame[1] >> 4 & 1 + size = frame[1] & 0xF + cmd, *data, crc = unpack(f">H{size}BH", bytes(frame[2:])) + + _logger.debug("Recv param: address=%d, flag=%d, size=%d, cmd=%04X, data=%s, " + "crc=%04X", address, flag, size, cmd, tuple(data), crc) + + if self.owen_crc16(frame[:-2]) != crc: + msg = "Checksum error" + raise OwenError(msg) + if address != self.unit: + msg = "Sender and receiver addresses mismatch" + raise OwenError(msg) + if packet[7:9] != answer[7:9]: # hash mismatch + msg = "Network error={:02X}, hash={:02X}{:02X}".format(*data) + raise OwenError(msg) + + return bytes(data) + + +__all__ = ["Owen"] diff --git a/setup.py b/setup.py new file mode 100644 index 0000000..46f930b --- /dev/null +++ b/setup.py @@ -0,0 +1,27 @@ +#! /usr/bin/env python3 + +from setuptools import setup + +setup(name="python-owen", + version="0.4.2", + description="OWEN controllers library", + url="https://github.com/RAA80/python-owen", + author="Alexey Ryadno", + author_email="aryadno@mail.ru", + license="MIT", + packages=["owen"], + install_requires=["pymodbus < 3", "pyserial >= 3.4"], + platforms=["Linux", "Windows"], + classifiers=["Development Status :: 4 - Beta", + "Intended Audience :: Science/Research", + "Intended Audience :: Developers", + "License :: OSI Approved :: MIT License", + "Operating System :: Microsoft :: Windows", + "Operating System :: POSIX :: Linux", + "Operating System :: POSIX", + "Programming Language :: Python :: 3", + "Programming Language :: Python :: 3.9", + "Programming Language :: Python :: 3.10", + "Programming Language :: Python :: 3.11", + ], + ) diff --git a/test/test_client.py b/test/test_client.py new file mode 100644 index 0000000..a89b290 --- /dev/null +++ b/test/test_client.py @@ -0,0 +1,153 @@ +#! /usr/bin/env python3 + +import unittest +from unittest.mock import MagicMock, patch + +from pymodbus.client.sync import ModbusSerialClient +from pymodbus.pdu import ModbusResponse +from pymodbus.register_write_message import WriteMultipleRegistersResponse +from serial import Serial + +from owen.client import ClientMixin, OwenError, OwenModbusClient, OwenSerialClient +from owen.device import TRM201 + + +class FakeOwenSerialClient(OwenSerialClient): + + def bus_exchange(self, packet: bytes) -> bytes: + return {b"#GHHGTMOHHRTO\r": b"#GHGMTMOHJHJGJISSTGTIPLKK\r", # чтение параметра "DEV" тип "STR" + b"#GHHGHUTIKGJI\r": b"#GHGHHUTIGGJKGK\r", # чтение параметра "A.LEN" тип "U8" без индекса + b"#GHHIRJURGGGGHQIV\r": b"#GHGJRJURGHGGGGQROU\r", # чтение параметра "DP" тип "U8" с индексом + b"#GHHGPVMIJIMK\r": b"#GHGIPVMIGGGHNHIR\r", # чтение параметра "ADDR" тип "U16" без индекса + b"#GHHGROTVJNPQ\r": b"#GHGJROTVKIQJIOOJKN\r", # чтение параметра "PV" тип "F24" без индекса + b"#GHHIUSIGGGGGTJIT\r": b"#GHGLUSIGKKJROGGGGGPVUS\r", # чтение параметра "SL.H" тип "F24" с индексом + b"#GHHGGIJJRIQN\r": b"#GHGJGIJJKNRKMLLNJK\r", # чтение параметра "N.ERR" тип "U24" + + b"#GHGHHUTIGGJKGK\r": b"#GHGHHUTIGGJKGK\r", # запись параметра "A.LEN" тип "U8" без индекса + b"#GHGJQLQRGHGGGGPNOJ\r": b"#GHGJQLQRGHGGGGPNOJ\r", # запись параметра "CMP" тип "U8" с индексом + b"#GHGIPVMIGGGHNHIR\r": b"#GHGIPVMIGGGHNHIR\r", # запись параметра "ADDR" тип "U16" без индекса + b"#GHGJPPKMGGGGGGQMGJ\r": b"#GHGJPPKMGGGGGGQMGJ\r", # запись параметра "R.OUT" тип "F24" без индекса + b"#GHGLUSIGKKJROGGGGGPVUS\r": b"#GHGLUSIGKKJROGGGGGPVUS\r", # запись параметра "SL.H" тип "F24" с индексом + b"#GHGGGGUPJSUL\r": b"", # запись параметра "INIT" тип "U8" без индекса + }[packet] + + +class TestClientMixin(unittest.TestCase): + """The unittest for ClientMixin.""" + + def setUp(self) -> None: + self.client = ClientMixin() + + def tearDown(self) -> None: + del self.client + + def test_check_index(self) -> None: + name = "A.LEN" + dev = TRM201["Owen"][name] + + # correct index + self.assertEqual(None, self.client.check_index(name=name, dev=dev, index=None)) + # invalid index + self.assertRaises(OwenError, lambda: self.client.check_index(name=name, dev=dev, index=1)) + + def test_check_value(self) -> None: + name = "DEV" + dev = TRM201["Owen"][name] + + # correct value + self.assertIsNone(self.client.check_value(name=name, dev=dev, value=None)) + # invalid value + self.assertRaises(OwenError, lambda: self.client.check_value(name=name, dev=dev, value=1)) + + name = "SP" + dev = TRM201["Owen"][name] + + # correct value + self.assertTrue(10.0, self.client.check_value(name=name, dev=dev, value=10.0)) + # invalid value (> max) + self.assertRaises(OwenError, lambda: self.client.check_value(name=name, dev=dev, value=10000)) + # invalid value (< min) + self.assertRaises(OwenError, lambda: self.client.check_value(name=name, dev=dev, value=-10000)) + # invalid value + self.assertRaises(OwenError, lambda: self.client.check_value(name=name, dev=dev, value=None)) + + +class TestOwenSerialClient(unittest.TestCase): + """The unittest for OwenSerialClient.""" + + @patch("serial.Serial", autospec=True) + def setUp(self, mock_serial: Serial) -> None: + self.client = FakeOwenSerialClient(transport=mock_serial, device=TRM201, + unit=1, addr_len_8=True) + + def tearDown(self) -> None: + del self.client + + def test_get_param(self) -> None: + # correct index + self.assertEqual(0, self.client.get_param(name="A.LEN", index=None)) + self.assertEqual("ТРМ201", self.client.get_param(name="DEV", index=None)) + self.assertEqual(1, self.client.get_param(name="DP", index=0)) + self.assertEqual(1, self.client.get_param(name="ADDR", index=None)) + self.assertEqual(81.578125, self.client.get_param(name="PV", index=0)) + self.assertEqual(750.0, self.client.get_param(name="SL.H", index=0)) + self.assertEqual((71, 46181), self.client.get_param(name="N.ERR", index=None)) + # invalid index + self.assertRaises(OwenError, lambda: self.client.get_param(name="A.LEN", index=2)) + + def test_set_param(self) -> None: + # correct index and value + self.assertTrue(self.client.set_param(name="A.LEN", index=None, value=0)) + self.assertTrue(self.client.set_param(name="CMP", index=0, value=1)) + self.assertTrue(self.client.set_param(name="ADDR", index=None, value=1)) + self.assertTrue(self.client.set_param(name="R.OUT", index=None, value=0.0)) + self.assertTrue(self.client.set_param(name="SL.H", index=0, value=750.0)) + self.assertRaises(OwenError, lambda: self.client.set_param(name="INIT", index=None, value=None)) + # invalid index + self.assertRaises(OwenError, lambda: self.client.set_param(name="A.LEN", index=2, value=0)) + # invalid value + self.assertRaises(OwenError, lambda: self.client.set_param(name="A.LEN", index=None, value=2)) + self.assertRaises(OwenError, lambda: self.client.set_param(name="INIT", index=None, value=1)) + + +class TestOwenModbusClient(unittest.TestCase): + """The unittest for OwenModbusClient.""" + + @patch("pymodbus.client.sync.ModbusSerialClient", autospec=True) + def setUp(self, mock_modbus: ModbusSerialClient) -> None: + self.client = OwenModbusClient(transport=mock_modbus, device=TRM201, unit=1) + + def tearDown(self) -> None: + del self.client + + def test_check_error(self) -> None: + err = MagicMock(ModbusResponse) + + err.isError.return_value = False + self.assertTrue(self.client.check_error(retcode=err)) + + err.isError.return_value = True + self.assertRaises(OwenError, lambda: self.client.check_error(retcode=err)) + + def test_set_param(self) -> None: + # correct index and value + value = 20.0 + self.client.modify_value = MagicMock(return_value=value) + self.client.socket.write_registers = MagicMock(return_value=WriteMultipleRegistersResponse(1, 2)) + self.assertTrue(self.client.set_param(name="SP", index=0, value=value)) + # invalid index + self.assertRaises(OwenError, lambda: self.client.set_param(name="SP", index=2, value=value)) + # invalid value + self.assertRaises(OwenError, lambda: self.client.set_param(name="SP", index=0, value=None)) + + def test_get_param(self) -> None: + # correct index + self.client._read = MagicMock(return_value=bytearray([0x1, 0x3, 0x2, 0x0, 0x1, 0x79, 0x84])) + self.client.modify_value = MagicMock(return_value=20.0) + self.assertEqual(20.0, self.client.get_param(name="SP", index=0)) + # invalid index + self.assertRaises(OwenError, lambda: self.client.get_param(name="SP", index=2)) + + +if __name__ == "__main__": + unittest.main() diff --git a/test/test_protocol.py b/test/test_protocol.py new file mode 100644 index 0000000..6dcaddf --- /dev/null +++ b/test/test_protocol.py @@ -0,0 +1,158 @@ +#! /usr/bin/env python3 + +import unittest + +from owen.protocol import Owen, OwenError + + +class TestOwenProtocol(unittest.TestCase): + """The unittest for Owen protocol.""" + + def setUp(self) -> None: + self.trm = Owen(unit=1, addr_len_8=True) + self.trm11 = Owen(unit=400, addr_len_8=False) + + def tearDown(self) -> None: + del self.trm + del self.trm11 + + def test_fast_calc(self) -> None: + self.assertEqual(20158, self.trm.fast_calc(84, 159, 7)) + self.assertEqual(5565, self.trm.fast_calc(18, 36695, 8)) + self.assertEqual(53661, self.trm.fast_calc(71, 34988, 8)) + self.assertEqual(60031, self.trm.fast_calc(72, 0, 7)) + self.assertEqual(64238, self.trm.fast_calc(156, 23651, 7)) + self.assertIsInstance(self.trm.fast_calc(156, 23651, 7), int) + + def test_owen_crc16(self) -> None: + self.assertEqual(16434, self.trm.owen_crc16((1, 16, 30, 210))) + self.assertEqual(44267, self.trm.owen_crc16((1, 18, 200, 128, 0, 0))) + self.assertEqual(23007, self.trm.owen_crc16((1, 5, 225, 125, 195, 71, 230, 0, 0))) + self.assertEqual(40940, self.trm.owen_crc16((1, 5, 236, 32, 68, 59, 128, 0, 0))) + self.assertEqual(59803, self.trm.owen_crc16((1, 8, 45, 91, 52, 48, 48, 48, 46, 51, 48, 86))) + self.assertEqual(15584, self.trm.owen_crc16((1, 16, 232, 196))) + self.assertEqual(38212, self.trm.owen_crc16((1, 6, 214, 129, 49, 48, 50, 204, 208, 210))) + self.assertIsInstance(self.trm.owen_crc16((1, 6, 214, 129, 49, 48, 50, 204, 208, 210)), int) + + def test_owen_hash(self) -> None: + self.assertEqual(7890, self.trm.owen_hash((21, 42, 28, 46))) + self.assertEqual(60448, self.trm.owen_hash((56, 43, 34, 78))) + self.assertEqual(47327, self.trm.owen_hash((50, 62, 78, 78))) + self.assertEqual(39238, self.trm.owen_hash((55, 48, 60, 58))) + self.assertEqual(13800, self.trm.owen_hash((48, 78, 78, 78))) + self.assertEqual(46941, self.trm.owen_hash((25, 56, 51, 48))) + self.assertEqual(64104, self.trm.owen_hash((24, 38, 73, 24))) + self.assertEqual(11410, self.trm.owen_hash((28, 62, 72, 2))) + self.assertEqual(233, self.trm.owen_hash((36, 46, 36, 58))) + self.assertIsInstance(self.trm.owen_hash((36, 46, 36, 58)), int) + + def test_name2code(self) -> None: + self.assertEqual((21, 42, 28, 46), self.trm.name2code("A.LEN")) + self.assertEqual((56, 43, 34, 78), self.trm.name2code("SL.H")) + self.assertEqual((50, 62, 78, 78), self.trm.name2code("PV")) + self.assertEqual((55, 48, 60, 58), self.trm.name2code("R.OUT")) + self.assertEqual((48, 78, 78, 78), self.trm.name2code("O")) + self.assertEqual((25, 56, 51, 48), self.trm.name2code("C.SP.O")) + self.assertEqual((24, 38, 73, 24), self.trm.name2code("CJ-.C")) + self.assertEqual((28, 62, 72, 2), self.trm.name2code("EV-1")) + self.assertEqual((36, 46, 36, 58), self.trm.name2code("INIT")) + self.assertIsInstance(self.trm.name2code("INIT"), tuple) + + def test_encode_frame(self) -> None: + self.assertEqual(b"#GHHGHUTIKGJI\r", self.trm.encode_frame((1, 16, 30, 210, 64, 50))) + self.assertEqual(b"#GHGHHUTIGGJKGK\r", self.trm.encode_frame((1, 1, 30, 210, 0, 52, 4))) + self.assertEqual(b"#GHHISOOGGGGGQSUR\r", self.trm.encode_frame((1, 18, 200, 128, 0, 0, 172, 235))) + self.assertEqual(b"#GHGJSOOGGGGGGGUQRK\r", self.trm.encode_frame((1, 3, 200, 128, 0, 0, 0, 234, 180))) + self.assertEqual(b"#GHHIPHGNGGGGKKPV\r", self.trm.encode_frame((1, 18, 145, 7, 0, 0, 68, 159))) + self.assertEqual(b"#GHGLPHGNKHSOGGGGGGJOMV\r", self.trm.encode_frame((1, 5, 145, 7, 65, 200, 0, 0, 0, 56, 111))) + self.assertEqual(b"#GHHGHIGJUIMK\r", self.trm.encode_frame((1, 16, 18, 3, 226, 100))) + self.assertEqual(b"#GHGHHIGJGGIHHO\r", self.trm.encode_frame((1, 1, 18, 3, 0, 33, 24))) + self.assertIsInstance(self.trm.encode_frame((1, 1, 18, 3, 0, 33, 24)), bytes) + + def test_decode_frame(self) -> None: + self.assertEqual((1, 1, 30, 210, 0, 52, 4), self.trm.decode_frame(b"#GHGHHUTIGGJKGK\r")) + self.assertEqual((1, 3, 200, 128, 0, 0, 0, 234, 180), self.trm.decode_frame(b"#GHGJSOOGGGGGGGUQRK\r")) + self.assertEqual((1, 5, 57, 243, 0, 0, 0, 0, 0, 11, 51), self.trm.decode_frame(b"#GHGLJPVJGGGGGGGGGGGRJJ\r")) + self.assertEqual((1, 5, 225, 125, 195, 71, 230, 0, 0, 89, 223), self.trm.decode_frame(b"#GHGLUHNTSJKNUMGGGGLPTV\r")) + self.assertEqual((1, 8, 45, 91, 52, 48, 48, 48, 46, 51, 48, 86, 233, 155), self.trm.decode_frame(b"#GHGOITLRJKJGJGJGIUJJJGLMUPPR\r")) + self.assertEqual((1, 3, 180, 101, 0, 0, 0, 9, 1), self.trm.decode_frame(b"#GHGJRKMLGGGGGGGPGH\r")) + self.assertEqual((1, 3, 2, 51, 71, 180, 101, 87, 52), self.trm.decode_frame(b"#GHGJGIJJKNRKMLLNJK\r")) + self.assertEqual((1, 3, 2, 51, 71, 100, 234, 99, 78), self.trm.decode_frame(b"#GHGJGIJJKNMKUQMJKU\r")) + self.assertEqual((1, 1, 30, 37, 20, 126, 6), self.trm.decode_frame(b"#GHGHHUILHKNUGM\r")) + self.assertIsInstance(self.trm.decode_frame(b"#GHGHHUILHKNUGM\r"), tuple) + + def test_pack_value(self) -> None: + self.assertEqual(bytes([194, 71, 255, 167, 15, 225]), self.trm.pack_value("F32+T", (-49.99966049194336, 4065))) + self.assertEqual(bytes([66, 246, 233, 223]), self.trm.pack_value("F32", 123.45678)) + self.assertEqual(bytes([164, 14]), self.trm.pack_value("SDOT", -10.38)) + self.assertEqual(bytes([29, 172]), self.trm.pack_value("SDOT", 350.0)) + self.assertEqual(bytes([16, 16, 4]), self.trm.pack_value("SDOT", 410.0)) + self.assertEqual(bytes([16]), self.trm.pack_value("SDOT", 0.0)) + self.assertEqual(bytes([0]), self.trm.pack_value("DOT0", 0)) + self.assertEqual(bytes([153]), self.trm.pack_value("DOT0", 99)) + self.assertEqual(bytes([3, 4]), self.trm.pack_value("DOT0", 304)) + self.assertEqual(bytes([9, 135, 101, 67, 33]), self.trm.pack_value("DOT0", 987654321)) + self.assertEqual(bytes([66, 246, 233]), self.trm.pack_value("F24", 123.45678)) + self.assertEqual(bytes([4, 210]), self.trm.pack_value("U16", 1234)) + self.assertEqual(bytes([251, 46]), self.trm.pack_value("I16", -1234)) + self.assertEqual(bytes([12]), self.trm.pack_value("U8", 12)) + self.assertEqual(bytes([244]), self.trm.pack_value("I8", -12)) + self.assertEqual(bytes([50, 48, 50, 204, 208, 210]), self.trm.pack_value("STR", "ТРМ202")) + self.assertEqual(b"", self.trm.pack_value("U8", None)) # if empty buffer + self.assertIsInstance(self.trm.pack_value("I8", -12), bytes) + + def test_unpack_value(self) -> None: + self.assertEqual((-49.99966049194336, 4065), self.trm.unpack_value("F32+T", bytes([194, 71, 255, 167, 15, 225]), None)) + self.assertEqual(123.45677947998047, self.trm.unpack_value("F32", bytes([66, 246, 233, 223]), None)) + self.assertEqual(350.0, self.trm.unpack_value("SDOT", bytes([29, 172, 0, 0]), 0)) + self.assertEqual(410.0, self.trm.unpack_value("SDOT", bytes([16, 16, 4, 0, 0]), 0)) + self.assertEqual(350.0, self.trm.unpack_value("SDOT", bytes([29, 172]), None)) + self.assertEqual(410.0, self.trm.unpack_value("SDOT", bytes([16, 16, 4]), None)) + self.assertEqual(0.0, self.trm.unpack_value("SDOT", bytes([16, 0, 0]), 0)) + self.assertEqual(0.0, self.trm.unpack_value("SDOT", bytes([16]), None)) + self.assertEqual(0, self.trm.unpack_value("DOT0", bytes([0]), None)) + self.assertEqual(99, self.trm.unpack_value("DOT0", bytes([153]), None)) + self.assertEqual(304, self.trm.unpack_value("DOT0", bytes([3, 4]), None)) + self.assertEqual(304, self.trm.unpack_value("DOT0", bytes([3, 4, 0, 0]), 0)) + self.assertEqual(987654321, self.trm.unpack_value("DOT0", bytes([9, 135, 101, 67, 33]), None)) + self.assertEqual(123.455078125, self.trm.unpack_value("F24", bytes([66, 246, 233]), None)) + self.assertEqual((71, 46059), self.trm.unpack_value("U24", bytes([71, 179, 235]), None)) + self.assertEqual(1234, self.trm.unpack_value("U16", bytes([4, 210]), None)) + self.assertEqual(-1234, self.trm.unpack_value("I16", bytes([251, 46]), None)) + self.assertEqual(12, self.trm.unpack_value("U8", bytes([12]), None)) + self.assertEqual(-12, self.trm.unpack_value("I8", bytes([244]), None)) + self.assertEqual("ТРМ202", self.trm.unpack_value("STR", bytes([50, 48, 50, 204, 208, 210]), None)) + self.assertRaises(OwenError, lambda: self.trm.unpack_value("F32", bytes([253]), None)) # if error code + + def test_make_packet(self) -> None: + self.assertEqual(b"#GHHGHUTIKGJI\r", self.trm.make_packet(1, "A.LEN", None, b"")) + self.assertEqual(b"#GHHISOOGGGGGQSUR\r", self.trm.make_packet(1, "DON", 0, b"")) + self.assertEqual(b"#GHGLJPVJGGGGGGGGGGGRJJ\r", self.trm.make_packet(0, "FB", 0, bytes([0, 0, 0]))) + self.assertEqual(b"#GHGLUHNTSJKNUMGGGGLPTV\r", self.trm.make_packet(0, "SL.L", 0, bytes([195, 71, 230]))) + self.assertEqual(b"#GHGHRNIUGGMJSQ\r", self.trm.make_packet(0, "SBIT", None, bytes([0]))) + self.assertEqual(b"#GHGLPHGNKHSOGGGGGGJOMV\r", self.trm.make_packet(0, "SP", 0, bytes([65, 200, 0]))) + self.assertEqual(b"#GHGHRNMGGORMUL\r", self.trm.make_packet(0, "BPS", None, bytes([8]))) + + self.assertEqual(b"#JIHIPHGNGGGGJHVJ\r", self.trm11.make_packet(1, "SP", 0, b"")) + self.assertEqual(b"#JIGLPHGNKHRHPQGGGGUMHO\r", self.trm11.make_packet(0, "SP", 0, bytes([65, 177, 154]))) + self.assertIsInstance(self.trm11.make_packet(0, "SP", 0, bytes([65, 177, 154])), bytes) + + def test_parse_response(self) -> None: + self.assertEqual(bytes([0]), self.trm.parse_response(b"#GHHGHUTIKGJI\r", b"#GHGHHUTIGGJKGK\r")) + self.assertEqual(bytes([0, 0, 0]), self.trm.parse_response(b"#GHHISOOGGGGGQSUR\r", b"#GHGJSOOGGGGGGGUQRK\r")) + self.assertEqual(bytes([195, 71, 230, 0, 0]), self.trm.parse_response(b"#GHHIUHNTGGGGPULL\r", b"#GHGLUHNTSJKNUMGGGGLPTV\r")) + self.assertEqual(bytes([52, 48, 48, 48, 46, 51, 48, 86]), self.trm.parse_response(b"#GHHGITLRRKVN\r", b"#GHGOITLRJKJGJGJGIUJJJGLMUPPR\r")) + self.assertEqual(bytes([71, 180, 101]), self.trm.parse_response(b"#GHHGGIJJRIQN\r", b"#GHGJGIJJKNRKMLLNJK\r")) + self.assertEqual(bytes([100]), self.trm.parse_response(b"#GHHGJONIJKMN\r", b"#GHGHJONIMKKIMP\r")) + self.assertRaises(OwenError, lambda: self.trm.parse_response(b"#GHHGHUTIKGJI\r", b"")) # if empty message + self.assertRaises(OwenError, lambda: self.trm.parse_response(b"#GHHGHUTIKGJI\r", b"GHHGHUTIKGJI\r")) # if first byte not '#' + self.assertRaises(OwenError, lambda: self.trm.parse_response(b"#GHHGHUTIKGJI\r", b"#GHHGHUTIKGJI")) # if last byte not '\r' + self.assertRaises(OwenError, lambda: self.trm.parse_response(b"#GHHINNRQGGGGRUIR\r", b"#GHGJGIJJKNNNRQPUSV\r")) # if error code + self.assertRaises(OwenError, lambda: self.trm.parse_response(b"#GHHIUHNTGGGGPULL\r", b"#GHGLUHNTSJKNUMGGGGLPTD\r")) # if checksum error + self.assertRaises(OwenError, lambda: self.trm.parse_response(b"#GHHGROTVJNPQ\r", b"#IJKJGIJJJHKOKNIJTO\r")) # if addresses mismatch + self.assertIsInstance(self.trm.parse_response(b"#GHHGJONIJKMN\r", b"#GHGHJONIMKKIMP\r"), bytes) + self.assertIsInstance(self.trm.parse_response(b"#GHGLUHNTJVOGGGGGGGQGIG\r", b"#GHGLUHNTJVOGGGGGGGQGIG\r"), bytes) + + +if __name__ == "__main__": + unittest.main()