При интеграции 1С с промышленным оборудованием часто возникает задача получить данные с OPC-сервера. Один из современных способов — использование HTTP-шлюза, который преобразует HTTP-запросы в нативные команды протокола OPC. Однако при такой настройке можно столкнуться с ошибкой 404 "Not Found", даже если адрес сервера и имя тега кажутся верными. Рассмотрим по шагам, как диагностировать и решить эту проблему.
Исходная ситуация: при попытке выполнить HTTP-запрос к OPC-серверу из 1С система возвращает ошибку 404 с текстом "The requested URL ... was not found on this server". Это говорит о том, что веб-сервер, к которому мы обращаемся, работает, но не может найти запрошенный ресурс (например, /read.json).
Ключевая ошибка часто кроется в неправильном понимании схемы взаимодействия. Когда мы используем программу-посредник, такую как OPC UA-HTTP Gateway, архитектура выглядит следующим образом:
[1С Клиент] <-- (HTTP/HTTPS запросы) --> [Компьютер с OPC UA-HTTP Gateway] <-- (протокол opc.tcp) --> [Станок / ПЛК с OPC-сервером]
Проблема, описанная в теме, заключалась в том, что HTTP-запросы из 1С отправлялись напрямую на IP-адрес станка. На станке (в данном случае, на контроллере ОВЕН) действительно был запущен веб-сервер, но он предназначался для администрирования (интерфейс LuCI), а не для обработки OPC-запросов по HTTP. Естественно, он не знал о ресурсе /read.json и возвращал ошибку 404.
Вывод: Все HTTP-запросы из 1С должны быть направлены на IP-адрес и порт того компьютера, где запущен OPC UA-HTTP Gateway, а не на IP-адрес конечного оборудования.
Прежде чем писать код в 1С, давайте убедимся, что сетевые настройки верны и шлюз работает корректно.
opc.tcp://АДРЕС_СТАНКА:ПОРТ. Стандартный порт для OPC UA — 4840.http://localhost или http://127.0.0.1. Не забудьте указать порт, на котором он работает (например, 8080).http://127.0.0.1:8080/get-servers.json. Успешный ответ будет означать, что шлюз работает и готов принимать команды.
Test-NetConnection -ComputerName АДРЕС_ШЛЮЗА -port ПОРТ_ШЛЮЗА
В выводе команды параметр TcpTestSucceeded должен иметь значение True.
После того как мы убедились, что шлюз работает и мы знаем его правильный адрес, можно формировать запрос в 1С. Разберем код на примере.
Важный момент: Имена тегов в OPC могут содержать спецсимволы, такие как пробелы, вертикальные черты (`|`) и другие. Чтобы они корректно передались в строке URL, их необходимо кодировать. Для этого в 1С используется функция КодироватьСтроку() со способом кодирования URLВКодировкеURL.
Посмотрим на пример кода для чтения тега:
// Адрес и порт, на котором запущен OPC UA-HTTP Gateway
ИмяСервера = "127.0.0.1";
Порт = 8080; // Укажите порт из настроек вашего шлюза
// Имя OPC-сервера, как оно задано в конфигурации шлюза.
// Это НЕ IP-адрес, а логическое имя.
ИмяOPCСервера = "opcserversim.Instance.1";
// Полное имя тега, который мы хотим прочитать
ИмяТега = "NS4|string||var|PLC210 OPC-UA.Application.GVL.auto_mode";
// 1. Формируем строку параметров запроса
СтрокаПараметров = "?server=" + ИмяOPCСервера + "&tag=" + ИмяТега;
// 2. Кодируем всю строку ресурса, включая параметры, для корректной передачи
// Обратите внимание, что сам ресурс (/read.json) тоже является частью кодируемой строки.
Ресурс = КодироватьСтроку("/read.json" + СтрокаПараметров, СпособКодированияСтроки.URLВКодировкеURL);
// 3. Создаем соединение и отправляем запрос
Попытка
// Создаем соединение с сервером, где работает ШЛЮЗ
Соединение = Новый HTTPСоединение(ИмяСервера, Порт);
Запрос = Новый HTTPЗапрос(Ресурс);
Результат = Соединение.Получить(Запрос);
// 4. Анализируем ответ
Если Результат.КодСостояния = 200 Тогда
// Запрос выполнен успешно
ТелоОтвета = Результат.ПолучитьТелоКакСтроку();
Сообщить("Нам вернули код: " + Результат.КодСостояния);
Сообщить("Тело результата: " + ТелоОтвета);
// Пример успешного ответа: {"command":"","success":true,"processed":0,"data": []}
Иначе
// Ошибка при выполнении запроса
Сообщить("Ошибка! Нам вернули код: " + Результат.КодСостояния);
Сообщить("Тело результата: " + Результат.ПолучитьТелоКакСтроку());
КонецЕсли;
Исключение
Сообщить("Не удалось выполнить HTTP-запрос: " + ОписаниеОшибки());
КонецПопытки;
После исправления адреса назначения запроса (с IP станка на IP шлюза) и, возможно, порта, автор исходной темы получил успешный ответ с кодом 200. Пустой массив `data` в ответе — это нормальная ситуация, которая означает, что соединение установлено, но на момент запроса у тега не было новых значений. Главное — получен код 200 OK, что свидетельствует о решении проблемы.
opc.tcp) — к конечному устройству.КодироватьСтроку() для параметров запроса, чтобы избежать проблем со спецсимволами.