В собственной базе строим каталог моделей, отличаем доступность локально, в облаке и возможность получения. Из реального описания создаём отдельный отбор и проверяем ответ сервиса, не скачивая и не устанавливая модели.
Где и как запускать
Полный серверный общий модуль УчебнаяРечь85 в новой базе УчебныеКаталогиРечи85; запуск из собственной управляемой формы ниже.
Подготовка
Создайте новую отдельную файловую учебную базу с именем конфигурации УчебныеКаталогиРечи85. Не переименовывайте рабочую УТ/КА/УНФ/БП ради обхода проверки и не подключайте рабочие обмены или задания.
Используйте платформу8.5.1.1343. Создайте общий модуль УчебнаяРечь85: Сервер=Да, Глобальный=Нет, Клиент=Нет. Каждый урок независим: вставляйте его полный основной код в пустой модуль, не объединяйте дублирующиеся процедуры двух уроков.
Администратор должен заранее настроить именно этот собственный стенд для реального сервиса речи по условиям вашего аккаунта и региона. Здесь нет автоматической регистрации, выдуманного URL, токена или пароля. Без доступного сервиса урок может завершиться ошибкой подключения.
Вызовы выполняются в серверном контексте. В файловой базе это серверная часть клиентского процесса; в клиент-серверной базе интернет, сертификаты, права и подключение нужны именно серверу, а не только браузеру пользователя.
В конфигураторе: Обработки → УчебнаяРечь85 → Формы → Пульт, тип Управляемая. Добавьте Согласие типа Булево, Итог типа Строка неограниченной длины; поле Итог сделайте многострочным и только для просмотра.
Вставьте полный модуль запуска из отдельного блока ниже. Назначьте обработчик ПриОткрытии событию формы. Создайте перечисленные команды формы и свяжите их с одноимёнными процедурами модуля; добавьте кнопки команд.
Нажмите F7 для проверки модулей и обновите только эту учебную базу. F7 не подтверждает доступность сервиса, корректность его ответа или звучание голоса.
Откройте собственную обработку и прочитайте условия тарифа, передачи данных и возможной оплаты. Согласие при каждом открытии сбрасывается в Ложь; установите его только перед осознанным ручным опытом.
Здесь код не запускался в1С и сеть не вызывалась: runtimeVerifiedScenarios=0. Выводимые модели и голоса зависят от настоящего каталога; заранее заданного числа или фиксированных ключей нет.
Для этого урока создайте команду ПоказатьМодели. Поле номера модели не нужно: учебный алгоритм выбирает первое настоящее описание с доступным локальным или внешним расположением; это не рекомендация лучшей модели.
Функция КаталогМоделей(Согласие) Экспорт
ПроверитьСвойСтенд(Согласие);
Модели = РаботаСРечью.ПолучитьОписаниеМоделейРаспознавания();
Если ТипЗнч(Модели) <> Тип("Массив") Тогда
ВызватьИсключение "Сервис должен вернуть массив описаний, не строки идентификаторов";
КонецЕсли;
Если Модели.Количество() = 0 Тогда
Возврат "Нет доступных моделей: проверьте реальное подключение, права и язык. Установка модели не выполнялась";
КонецЕсли;
Если Модели.Количество() > 1000 Тогда
ВызватьИсключение "Для учебного каталога допустимы не более1000моделей";
КонецЕсли;
Итог = "Моделей: " + Строка(Модели.Количество());
ВыбранныеПараметры = Неопределено;
Для Каждого Модель Из Модели Цикл
Если ТипЗнч(Модель) <> Тип("ОписаниеМоделиРаспознаванияРечи") Тогда
ВызватьИсключение "В массиве найден не дескриптор модели";
КонецЕсли;
Идентификатор = Модель.ИдентификаторМодели;
Если ТипЗнч(Идентификатор) <> Тип("ИдентификаторМоделиРаспознаванияРечи") Тогда
ВызватьИсключение "Идентификатор загрузки должен иметь собственный тип платформы";
КонецЕсли;
Итог = Итог + Символы.ПС + Модель.Описание
+ "; версия: " + Модель.Версия
+ "; акустика: " + Модель.ПредставлениеАкустики
+ "; грамматика: " + Модель.ПредставлениеГрамматики
+ "; локальная: " + Строка(Модель.ДоступнаВЛокальномВарианте)
+ "; внешняя: " + Строка(Модель.ДоступнаВоВнешнемВарианте)
+ "; можно получить: " + Строка(Модель.ДоступнаДляПолучения)
+ "; идентификатор загрузки: " + Строка(Идентификатор);
Если ВыбранныеПараметры = Неопределено
И (Модель.ДоступнаВЛокальномВарианте Или Модель.ДоступнаВоВнешнемВарианте) Тогда
ВыбранныеПараметры = Модель.ПолучитьПараметры();
КонецЕсли;
КонецЦикла;
Если ВыбранныеПараметры = Неопределено Тогда
Возврат Итог + Символы.ПС + "Нет модели с локальным или внешним расположением; фильтр не выполнялся";
КонецЕсли;
Если ТипЗнч(ВыбранныеПараметры) <> Тип("ПараметрыМоделиРаспознаванияРечи") Тогда
ВызватьИсключение "Параметры нужно получить от настоящего описания модели";
КонецЕсли;
Отбор = Новый ПараметрыМоделиРаспознаванияРечи;
Отбор.Акустика = ВыбранныеПараметры.Акустика;
Отбор.Грамматика = ВыбранныеПараметры.Грамматика;
Отбор.Версия = ВыбранныеПараметры.Версия;
Отбор.КодЯзыка = ВыбранныеПараметры.КодЯзыка;
Если Не ЗначениеЗаполнено(Отбор.КодЯзыка) Тогда
ВызватьИсключение "Пустой язык настоящей модели нельзя заменять придуманным кодом";
КонецЕсли;
Совпадения = РаботаСРечью.ПолучитьОписаниеМоделейРаспознавания(Отбор);
Если ТипЗнч(Совпадения) <> Тип("Массив") Тогда
ВызватьИсключение "Отбор должен вернуть настоящий массив моделей";
КонецЕсли;
Если Совпадения.Количество() = 0 Тогда
Возврат Итог + Символы.ПС + "Каталог изменился или сервис не нашёл модель по её параметрам. Повторите опыт вручную";
КонецЕсли;
Для Каждого Совпадение Из Совпадения Цикл
Если ТипЗнч(Совпадение) <> Тип("ОписаниеМоделиРаспознаванияРечи") Тогда
ВызватьИсключение "Отбор вернул не описание модели";
КонецЕсли;
ПараметрыСовпадения = Совпадение.ПолучитьПараметры();
Если ТипЗнч(ПараметрыСовпадения) <> Тип("ПараметрыМоделиРаспознаванияРечи") Тогда
ВызватьИсключение "Совпадение не содержит параметры модели";
КонецЕсли;
Если ПараметрыСовпадения.Акустика <> Отбор.Акустика
Или ПараметрыСовпадения.Грамматика <> Отбор.Грамматика
Или ПараметрыСовпадения.Версия <> Отбор.Версия
Или ПараметрыСовпадения.КодЯзыка <> Отбор.КодЯзыка Тогда
ВызватьИсключение "Сервис вернул модель с другими параметрами; не считайте её подтверждённым совпадением";
КонецЕсли;
КонецЦикла;
Если ВыбранныеПараметры.Акустика <> Отбор.Акустика
Или ВыбранныеПараметры.Грамматика <> Отбор.Грамматика
Или ВыбранныеПараметры.Версия <> Отбор.Версия
Или ВыбранныеПараметры.КодЯзыка <> Отбор.КодЯзыка Тогда
ВызватьИсключение "Свой отбор не должен менять параметры исходного описания";
КонецЕсли;
Возврат Итог + Символы.ПС + "Проверенных совпадений: " + Строка(Совпадения.Количество())
+ "; язык: " + Отбор.КодЯзыка + "; версия отбора: " + Строка(Отбор.Версия);
КонецФункции
Процедура ПроверитьСвойСтенд(Согласие)
Если ТипЗнч(Согласие) <> Тип("Булево") Или Не Согласие Тогда
ВызватьИсключение "Нужно явное согласие на обращение собственного стенда к сервису речи";
КонецЕсли;
Если ТранзакцияАктивна() Тогда
ВызватьИсключение "Не обращайтесь к сервису внутри транзакции";
КонецЕсли;
Если ТипЗнч(РаботаСРечью) <> Тип("МенеджерРаботыСРечью") Тогда
ВызватьИсключение "Нужен настоящий глобальный менеджер работы с речью";
КонецЕсли;
КонецПроцедурыУчебныеКаталогиРечи85.Пульт
УчебныеКаталогиРечи85 → Обработки → УчебнаяРечь85 → Формы → Пульт → Модуль
Полный модуль собственной управляемой формы; здесь не выполнялся.
&НаКлиенте
Процедура ПриОткрытии(Отказ)
Согласие = Ложь;
Итог = "Разрешите только собственное обращение к сервису после подготовки стенда";
КонецПроцедуры
&НаКлиенте
Процедура ПоказатьМодели(Команда)
Если Не Согласие Тогда
ВызватьИсключение "Согласие не установлено";
КонецЕсли;
Итог = "Получение моделей; прошлый результат сброшен";
ПоказатьМоделиНаСервере();
КонецПроцедуры
&НаСервере
Процедура ПоказатьМоделиНаСервере()
Итог = "Обращение к сервису; прошлый результат сброшен";
Попытка
Итог = УчебнаяРечь85.КаталогМоделей(Согласие);
Исключение
Итог = "Опыт не завершён. Повторные запросы и установка моделей автоматически не выполняются";
ВызватьИсключение;
КонецПопытки;
КонецПроцедурыРазбор по шагам
ПолучитьОписаниеМоделейРаспознавания без параметра получает настоящий массив всех доступных описаний. Пустой каталог — отдельный нормальный результат, а не повод создавать фиктивные модели.
Для каждого описания показываем локализованные названия акустики и грамматики, фактическую версию, три независимых признака доступности и настоящий типизированный идентификатор загрузки.
ДоступнаДляПолучения не означает, что модель уже установлена локально. ИдентификаторМодели предназначен для получения модели, а не является ключом задания распознавания.
ПолучитьПараметры вызывается у настоящего выбранного описания. Не задаём вручную General, версию или частоту дискретизации: частота относится к самой модели, а строки проверяет сервис.
Новый ПараметрыМоделиРаспознаванияРечи создаёт отдельный изменяемый объект. Все четыре значения копируются из настоящих параметров; исходный дескриптор только читается.
Второй вызов каталога использует этот объект как действующий фильтр. У каждого реального совпадения повторно получаем параметры и сравниваем все четыре поля; нельзя принять произвольный объект за подтверждённую выбранную модель.
После отбора проверяем неизменность параметров исходного описания. Нет совпадений — каталог мог измениться; повторный запрос выполняет сам пользователь, а не бесконечный цикл.
Как проверить результат
Без согласия команда должна остановиться до запроса. В чужой базе, другой версии платформы или активной транзакции серверный код также должен отказать.
При готовом подключении каталог показывает ровно те сведения, которые вернул ваш сервис. Число моделей, тексты и идентификаторы нельзя сравнивать с выдуманным эталоном.
Если найдена подходящая модель и сервис сохранил каталог, отбор должен вернуть как минимум одно фактическое совпадение, каждый из четырёх параметров которого прошёл сравнение.
При пустом исходном каталоге или отсутствии расположений нет второго запроса. При исчезновении выбранной модели выводится отдельное сообщение, а не ложный успех.
Сверьте локальность, внешнюю доступность и возможность загрузки по отдельности. После урока никакой новой установки, удаления или изменения регистрации базы быть не должно.
Ожидаемый результат
Фактический каталог и проверенное количество совпадений по параметрам выбранного описания. Модель не скачивается, микрофон не включается, распознавание не запускается.
На что обратить внимание
В контексте тонкого клиента часть операций с речью имеет другую доступность. Основной модуль этого урока серверный; не переносите его целиком в клиентский обработчик.
Нельзя считать сохранённый в тексте идентификатор готовым локальным распознавателем. Здесь нет конструктора фиктивного ID, загрузки, установки или распознавания.
Описание и представления локализованы: их не используют как машинные значения Акустика или Грамматика. Отбор получает значения только через ПолучитьПараметры.
Строки параметров проверяет сервис. Если реальный сервис нормализует значения или меняет каталог между запросами, строгая учебная проверка может завершиться ошибкой; она не маскируется успешным результатом.
Предел1000 — правило этого урока, не лимит платформы. Это проверка уже полученного массива, она не ограничивает память или время сетевого получения.
Имя конфигурации — ограждение учебного стенда, не полноценная защита прав. Не используйте его вместо прав доступа или для обращения к production.
Текст каталога не экспортируется и не сохраняется. Согласие не выдаёт привилегий; реальный аккаунт, соединение и условия оплаты настраиваются отдельно. runtimeVerifiedScenarios=0.
Пример не запускался в вашей базе. Перед применением проверьте его в указанном учебном контексте.