Драйвер с помощью ИИ

Драйвер — это небольшой код, который объясняет U-Logic, как разговаривать с конкретным устройством: какие команды ему отправлять и как понимать его ответы (подробно — в «Dynamic Driver»). Если драйвера для вашего устройства нет, его можно написать самому. Для этого не обязательно уметь программировать: чат с ИИ напишет код по документации протокола устройства, а вам останется вставить этот код в редактор драйверов и проверить.

Для кого. Для интегратора, у которого есть документация протокола устройства (список команд и примеры ответов), но нет готового драйвера.

Что получится. Драйвер в списке драйверов U-Logic: его можно выбрать в узле соединения, а затем отправлять устройству команды узлом device - command и получать ответы узлом device - response - listener.

Предупреждение

ИИ может ошибиться в команде или в разборе ответа. Не подключайте сгенерированный драйвер к оборудованию, которое нельзя безопасно включать, выключать или переключать, пока не проверили каждую команду на безопасном устройстве. Не отправляйте в чат пароли и ключи доступа: драйвер берёт их из параметров соединения, а не из кода.

Что подготовить

  1. Документация на протокол устройства: PDF, страница сайта или текст. Достаточно страниц с командами, примерами ответов и описанием входа по паролю (если он нужен). Лишние страницы только мешают ИИ.

  2. Гайд для ИИ — driver-guide-for-ai.md. Это правила, по которым пишутся драйверы: без них ИИ придумает собственный формат, и U-Logic такой драйвер не примет. Скачайте файл и держите под рукой.

  3. Промпт — готовый текст из раздела «Промпт» ниже.

  4. Данные устройства: производитель и модель, способ подключения (TCP, UDP, SSH, Telnet, HTTP, RS232 и т. д.), порт и разделитель сообщений, если они есть в документации.

Шаги

  1. Откройте новый чат с ИИ, который умеет принимать файлы. Если файлы приложить нельзя, вставьте текст гайда и протокола в сообщение.

  2. Приложите гайд driver-guide-for-ai.md и документацию протокола (или нужные фрагменты).

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

  4. Отправьте сообщение. Если в документации не хватает данных, ИИ задаст вопросы. Ответьте на них. Если вопросов нет, но вы не уверены, что в документации есть всё нужное, попросите ИИ перечислить, какие команды и ответы он нашёл в документации, а какие — нет.

  5. Получите код драйвера целиком. Скопируйте его.

  6. Откройте U-Logic, нажмите значок меню справа вверху и выберите «Вид» → «Редактор драйверов». Редактор откроется в боковой панели.

  7. В верхней панели редактора выберите режим «Создать новый».

  8. Введите имя драйвера. Под этим именем драйвер появится в списке узла соединения, поэтому задайте понятное: например, название модели устройства.

  9. Вставьте скопированный код в область редактора вместо шаблона.

  10. Нажмите «Сохранить». Драйвер сразу появится в списке драйверов.

  11. Нажмите «Развернуть», чтобы U-Logic применил изменения.

Что вы увидите: драйвер появился в списке режима «Загрузить из списка» и в списке «Драйвер» в окне подключения (драйвер выбирают там, а не в самом узле device - command; если окно подключения было открыто, закройте и откройте его заново). Подробнее об окне редактора и его кнопках — на странице «Редактор драйверов».

Как проверить драйвер

  1. Добавьте на рабочую область узел device - command и в его окне создайте соединение с вашим драйвером, как описано в разделе «По шагам: подключить устройство и отправить команду» страницы «Узлы Dynamic Driver». Задайте транспорт: адрес и порт устройства.

  2. Добавьте device - response - listener с тем же соединением и в «Типы ответов» отметьте ответы драйвера. Как работают оба узла и как читать ответы — на странице «Команды устройствам и ответы».

  3. Подключите к выходу device - response - listener узел debug («весь msg») и разверните программу.

  4. Запустите отправку команды (узлом inject или кнопкой интерфейса) и посмотрите на статус узла и вкладку отладки.

Что вы увидите: статус узла device - command показывает состояние соединения (connected), а в отладке от слушателя приходит сообщение, в msg.payload которого есть поле type — имя ответа — и поля с данными. Начните с безобидной команды запроса состояния, а потом проверяйте остальные.

Промпт

Скопируйте текст целиком и замените строки в квадратных скобках вашими данными. Он написан по правилам гайда: если вы измените гайд, сверьте промпт с ним.

Роль: ты — опытный разработчик драйверов для Dynamic Driver в U-Logic. Твоя задача — по приложенному «Руководству по созданию драйверов для Dynamic Driver» (далее «Гайд») и приложенной документации протокола написать драйвер устройства. Переноси только протокол и поведение устройства, не придумывай то, чего нет в документации. Если данных для команды или ответа не хватает, не угадывай: сначала перечисли вопросы, и только после ответов пиши код.

Исходные данные:
- Устройство: [НАЗВАНИЕ И МОДЕЛЬ] ([ПРОИЗВОДИТЕЛЬ])
- Подключение: [TCP / UDP / SSH / Telnet / HTTP / RS232 — укажи конкретно, порт и разделитель сообщений, например \r\n]
- Нужен ли вход по паролю: [да, устройство само просит пароль после подключения / нет]
- Что должен уметь драйвер: [например, включение и выключение, выбор входа, громкость, запрос состояния]
- Особые требования: [например, только текстовые команды; без бинарного режима]

Требования (следуй Гайду строго):
1. Выдай один блок кода с полным драйвером: `const BaseDriver = require('base-driver');`, класс, наследующий BaseDriver, и `module.exports`. Используй только модули, разрешённые в Гайде; не используй fs, child_process, сторонние пакеты, eval.
2. В конструкторе вызови `super(options)` и задай `this.state = {};`.
3. `static metadata`: name, manufacturer, version, description, model. Если у устройства есть типовые порт и разделитель, задай `transportDefaults` для нужного транспорта. Если нужны логин, пароль или интервал опроса, опиши их в `parameters` (значения читай из `this.config`), а в код ничего секретного не вписывай.
4. `static commands`: все нужные команды. Для каждой — description и parameters (name, type, description, required; для чисел min/max, для списков enum). Для команд без параметров — `parameters: []`. Для каждой команды напиши метод с тем же именем. Метод возвращает `{ payload: 'СТРОКА\r\n' }` или Buffer (TCP, UDP, RS232, SSH, Telnet) либо `{ method, path, headers, payload }` (HTTP). Диапазоны и значения enum проверяй сам внутри метода: U-Logic их не проверяет.
5. Имена ответов: ключ записи в `static responses` — это имя сигнала. Давай ему короткое имя по смыслу (`power`, `mute`, `level`, `route`), без суффикса `Response`.
6. Ответы: либо `matcher.pattern` + `extract(match)` в `static responses`, либо метод `parseResponse(data)` — выбери один способ на весь драйвер и не смешивай. `parseResponse` нужен, если требуется запоминать состояние (`this`), в одном пакете приходит несколько ответов, протокол бинарный или JSON.
7. Что возвращать из ответов:
   - `extract` возвращает только данные, без `type`; обязательно добавь поле `value` со значением сигнала (число, строка или boolean — не объект), либо поле, названное так же, как ключ ответа. Лучше оба.
   - `parseResponse` возвращает «чистый» объект `{ type: 'имя', ...поля, value: значение }` или массив таких объектов; если ответ не распознан — `null`. Не оборачивай объект в `category`, `response`, `msg`.
   - В `parseResponse` аргумент — не строка, а объект транспорта: текст лежит в `data.data` (для HTTP — в `data.payload`); не вызывай `split`/`match` на самом `data`.
   - Для каждого ответа добавь описание: description, fields, valueField и, если ответов несколько для разных каналов или выходов, keyFields; в этом случае `extract` или `parseResponse` сам возвращает готовое поле `key`.
8. `initialize()` вызывается при каждом подключении: он должен быть безопасен для повторного вызова. Отправляй в нём только начальные запросы состояния через `this.publishCommand('имяКоманды')`. Если создаёшь таймер, сначала снимай прежний; ресурсы освобождай в `onDestroy()`.
9. Если устройству нужен периодический опрос, реализуй `KeepAlive()`: он ничего не возвращает и вызывает `this.publishCommand(...)`.
10. Если устройство после подключения требует вход по паролю, используй механизм из Гайда: `static requiresAuth = true`, `static authCommands`, `this._authReset()` первой строкой `initialize()`, `this._authMarkReady()` и `this._authMarkFailed(причина)` в `parseResponse`. Если вход выполняет сам транспорт (Telnet или SSH с паролем в настройках соединения), этот механизм не нужен.
11. Служебные методы (`initialize`, `KeepAlive`, `parseResponse`, `onDestroy`, `onParamsUpdated`) не перечисляй в `static commands`.
12. Стиль: небольшие команды, одна команда — одно действие; строгие enum, min и max; короткие понятные описания; без лишней логики и пояснительного текста в ответе.

Перед ответом проверь код по чек-листу Гайда: у каждого ответа есть `value` или поле с именем ключа; `parseResponse` не оборачивает результат и возвращает `null` для неизвестного; окончания строк команд (\r\n) совпадают с документацией; методы названы так же, как команды.

Документация протокола:
[ВСТАВЬ ИЛИ ПРИЛОЖИ: список команд, форматы ответов, примеры обмена, описание входа по паролю]

Частые ошибки

  • Драйвера нет в списке. Скорее всего, вы не нажали «Сохранить». Откройте режим «Загрузить из списка» и проверьте, есть ли там ваш драйвер; затем переоткройте окно узла соединения.

  • Узел всё ещё работает по-старому. Узлы, которые уже работают, используют прежнюю версию драйвера, пока вы не нажмёте «Развернуть». Исправили код в редакторе — сохраните и разверните.

  • Команда не уходит, ответы не приходят. Проверьте узел соединения: адрес, порт и транспорт. Если ответов нет совсем, возможно, не сработал ни один шаблон ответа или в коде не тот разделитель сообщений. Покажите ИИ реальный вывод debug и документацию, попросите исправить.

  • Ответ в отладке виден, а на панели ничего не меняется. В ответе нет значения сигнала: у ответа нет поля value и нет поля с именем ключа ответа, поэтому получатели молча отбрасывают такой ответ. Напишите ИИ: «У ответа нет value; исправь по требованию 7».

  • В отладке пришёл ответ с type: "response" и вложенным response. Драйвер сам добавил обёртку, которую система добавляет автоматически. Попросите ИИ возвращать только { type, ...поля, value }.

  • Ответ не приходит на нужный выход. Тип ответа должен совпадать с именем в «Типы ответов» узла device - response - listener; ответ с неизвестным типом уходит на первый выход.

  • Устройство требует пароль и молчит. Если устройство просит пароль после подключения, а ИИ не знал об этом, команды отбрасываются. Скажите об этом в промпте (строка «Нужен ли вход по паролю») и попросите механизм входа из Гайда. Пароль указывайте в параметрах драйвера, а не в коде; не заполняйте его ещё и в транспорте, иначе вход выполнится дважды.

  • В драйвере лишний текст. ИИ мог добавить пояснения вокруг кода. Вставляйте в редактор только содержимое блока кода.

  • Загрузка проекта вместо драйвера. Кнопка «Загрузить проект» заменяет все потоки и все драйверы архивом. Для одного нового драйвера она не нужна — используйте «Создать новый» и «Сохранить».