Skip to content

API (draft)

Aculeasis edited this page Aug 27, 2020 · 50 revisions

Протоколы передачи данных

Терминал принимает подключения на 7999 порту по протоколу TCP/IP на всех доступных интерфейсах. Принимается только одно подключение за раз. Соединение может быть отвергнуто согласно настройкам. Если от клиента не было данных за последние 5 секунд, соединение закроется по таймауту. При закрытии соединения терминал постарается прислать пустую строку \r\n\r\n (далее, \r\n = CRLF), все полученные данные декодируются в UTF-8 (не актуально для WebSocket).

Терминал поддерживает следующие способы коммуникации:

  • "Бросил - закрыл". Если терминал получил данные без CRLF и сокет закрылся, то он обработает их как команду. Естественно, прислать ответ он не сможет. Так делает MajorDoMo :)
  • Разделение строк через CRLF. В таком режиме терминал может получать много команд за сессию, в таком же режиме терминал присылает данные клиенту, при получении пустой строки терминал закроет соединение. Можно использовать telnet для связи.
  • WebSocket. Добавлять CRLF не нужно, только текст. Требует аутентификации - первой командой нужно отправить токен, который хранится в [system] ws_token (по умолчанию это token_is_unset). Если токены не совпадают или ws_token пустой, терминал пришлет сообщение (в ansi color) и закроет сокет. Пример на JS. Терминал не передает токен при исходящем соединении.

Команды

Поддерживается 2 способа передачи команд:

  • Нечто похожее на JSON-RPC 2.0:

    • Ключ jsonrpc опущен.
    • В целях совместимости params состоящий из списка с одной строкой будет интерпретирован как одиночная команда, а bool(params) == False как пустая строка. Иначе params являющийся списком или словарем будет сериализирован в json. Некоторые команды способны принять чистый JSON-RPC (с list\dict в params).
    • id может быть чем угодно.
    • Команды способные корректно принять чистый JSON-RPC: get, tts, ask.
    • Команды способные принять только чистый JSON-RPC: test.record, test.play, test.delete, test.test, test.list, authorization.self, authorization.totp.
  • Старый формат command:<str_data>. Терминал попытается ответить на нее в формате command:<json>, где <json> - ответ в формате JSON-RPC без поля id.

    • Определенные команды присылают ответ без сериализации в json, command:result, это: get.

Таким образом команды command:<str_data> и {"method": "command", params: ["<str_data>"]} эквивалентны.

Большинство команд доступны только после авторизации.

MajorDroid API

Стандартные команды для терминалов мажордомо:

  • hi: см. voice.
  • voice: Перейти в режим ожидания голосовой команды.
  • tts:текст: Произнести текст. JSON-RPC использует другой синтаксис и позволяет опционально задать провайдера: {"method": "tts", "params": {"text": "привет", "provider": "google"}}.
  • ask:текст: Произнести текст и перейти в режим ожидания голосовой команды. JSON-RPC использует другой синтаксис и позволяет опционально задать провайдера: {"method": "ask", "params": {"text": "скажи привет", "provider": "rhvoice-rest"}}.
  • play:URL: Отправить URL на воспроизведение музыкальному плееру, это может быть как URL так и локальный (для терминала) файл. Нужен контроль над плеером.
  • pause: Переключить паузу на музыкальном плеере. Нужен контроль над плеером.
  • settings: Переопределена MDM VoiceAssistant API.
  • volume:X: Изменить системную громкость терминала на X, где X число от 0 до 100.
  • nvolume:X: Аналог volume (громкость уведомлений в MajorDroidAPI).
  • mvolume:X: Изменить громкость музыкального плеера на X, где X число от 0 до 100.
  • home, url, rtsp, run: Не поддерживаются.

MDM VoiceAssistant API

Односторонний обмен

  • maintenance.reload: "Горячий" перезапуск терминала.

  • maintenance.stop: Завершение работы терминала.

  • rec:rec_N_X: Перейти в режим записи образца номер X для модели N. X должен быть от 1 до 3.

  • rec:play_N_X: Воспроизвести образец номер X для модели N, если файл существует.

  • rec:compile_N_X: Скомпилировать образцы для модели N в модель. Если длинна X больше 1, он станет пользователем модели, иначе будет проигнорирован. После успешной компиляции образцы удаляются.

  • rec:del_N_0: Удалить модель N.

  • rec:save_0_0: Выполнить "горячий" перезапуск терминала.

  • rec:update_0_0: Проверить обновления и обновить терминал.

  • rec:rollback_0_0: Откатить терминал до предыдущего успешного обновления.

  • nvolume_say:X: Аналог nvolume, но озвучивает результат.

  • mvolume_say:X: Аналог mvolume, но озвучивает результат.

  • listener:(on|off|): Включает (on) или выключает (off) прослушивание микрофона терминалом. Если не указано, выполнит переключение режима. Пришлет уведомление при изменении, после перезагрузки прослушивание будет включено.

    Важно: Относится только к постоянному прослушиванию с поиском ключевого слова, запись все еще может быть активирована через API.

  • pong(:data): Если data есть и число, вывести в лог ping с текущем временем из которого вычли data (время из time.time() питона).

  • send_model:<модель в json>: Сохранить модель и все ее данные, если формат корректен. Если файл модели с таким именем уже существует он будет перезаписан.

  • settings:json: Преобразует json-объект в словарь и использует для изменения настроек. Если настройки изменились они будут применены и сохранены. Над данными полученными таким образом совершаются дополнительные преобразования:

    • Все ключи приводятся к нижнему регистру.
    • Вложенные объекты секций которых нет в конфиге игнорируются.
    • Если ключ соответствует паттерну section_key то он преобразуется в [section] key, 0 в имени такой секции интерпретируются как -.
    • Все ключи без секций преобразуются в [settings] key.
    • Если ключ существует, то значение приводится к типу существующего значения. Иначе к str.
    • И некоторые другие преобразования...
  • sre:текст: Обработает текст так, как если бы он был успешно распознан. JSON-RPC позволяет опционально задать RMS и имя модели: {"method": "sre", "params": {"text": "выключи свет", "rms": [1, 2, 3], "model": "model1.pmdl"}}.

Двухсторонний обмен

  • get_map_settings: Возвращает настройки по умолчанию с подробным описанием (большой json).

  • remote_log(:raw|json|colored): Подключит сокет к логгеру, см. remote_log

  • recv_model:filename: Вернет <модель в json>.

  • list_models: Вернет <список моделей в json>.

  • ping(:data): Вернет "result": "data", если data пустое вернет строку с unixtime (с ms после знака).

  • info(:cmd): Вернет <информацию о команде> cmd.

  • upgrade duplex: Переключает сокет в специальный режим для двухстороннего обмена сообщениями.

  • authorization:: Авторизация, повышает привилегии текущего подключения.

  • deauthorization: Отменяет авторизацию для текущего подключения.

  • call.plugin:<json>: Вызывает метод активного плагина напрямую и возвращает результат вызова, не безопасно. Для работы нужно включить в настройках [smarthome] unsafe_rpc = on. Параметры в json:

    • path: Путь до метода, начинается с имени плагина а имена объектов разделяются точками. Например, путь вызова Templates.cfg из mdmt2-web-config будет web-config._tpl.cfg.
    • args: Список аргументов которые будут переданы вместе с вызовом, опционально.
    • kwargs: Массив именованных аргументов которые будут переданы вместе с вызовом, опционально.
  • notifications.list: Возвращает список событий на которые подписан notifier и которые он присылает в качестве уведомлений.

  • notifications.add:events: Подписывает notifier на новые события, вернет список добавленных подписок. События разделяются запятыми или передаются списком в JSON (notifications.add:a,b,c, {"method": "notifications.add" "params": ["a,b,c"]}, {"method": "notifications.add" "params": ["a", "b", "c"]}).

  • notifications.remove:events: Отписывает notifier от событий, вернет список удаленных подписок. События разделяются запятыми или передаются списком в JSON. Событие * отменяет все подписки.

  • get:key: Возвращает значение в зависимости от key вместе с ним самим. Возможные значения key - volume, nvolume, mvolume, mstate, listener. Например:

    -> get:volume
    <- volume:23
    

    С JSON-RPC можно запросить несколько значений:

    -> {"method": "get", "params": ["volume", "nvolume", "mvolume", "mstate"], "id": "test"}
    <- {"result": {"volume": 15, "nvolume": 15, "mvolume": 100, "mstate": "pause"}, "id": "test"}
    
  • test.*: Группа команд для тестирования (STT).

  • backup.manual: Запускает процедуру создания нового бэкапа, старые бэкапы никогда не удаляются.

  • backup.restore:filename: Инициирует процедуру восстановления из бэкапа, в ответ терминал пришлет {"filename": filename, "timestamp": float} или ошибку. Если в качестве filename указать last будет использован последний бэкап.

    Процедура: Терминал остановит все свои системы кроме логгера, выполнит создание нового бэкапа (старые бэкапы никогда не удаляются), проверит файл на корректность, выполнит восстановление, остановит логгер и перезапустится.

    Бэкап не имеющий корректного файла timestamp или содержащий что-то помимо settings.ini, data/ и resources/models/ не может быть восстановлен.

  • backup.list: Вернет список из доступных для восстановления бэкапов в формате {"filename": str, "timestamp": float}.

remote_log

При получении команды remote_log сокет подключается к логгеру. Терминал перестает читать данные из сокета, также он не будет закрыт по таймауту и не будет занимать подключение. Одновременно возможно только одно подключение к логгеру. В сокет будут отправляться логи в реальном времени так как если бы они выводились в консоль с уровнем debug. Доступно 3 режима получения логов:

  • remote_log: Режим по умолчанию, раскрашенные логи.
  • remote_log:raw: Логи без ansi color.
  • remote_log:json: Логи в json {"lvl": str, "time": float, "callers": list<str>, "msg": str}.

Выполнение команд отправленных после remote_log не гарантируется.

объекты в result

<модель в json>

  • filename: Валидное имя файла модели, обязательно.
  • data: Файл модели закодированный в base64, обязательно.
  • phrase: Ключевая фраза модели, если есть.
  • username: Пользователь модели, если есть.

<список моделей в json>

  • models: Список всех моделей в виде имен файлов которые есть у терминала, может быть пустым.
  • allow: Список моделей полученный из [models] allow, может быть пустым.

<информация о команде>

  • cmd: Команда, если команда не была указана - список всех доступных команд.
  • msg: Описание команды.
  • flags: Список флагов команды в list<str>. Отсутствует, если у команды нет флагов.

Использование API в MajorDoMo

После установки MDM VoiceAssistant можно отправлять любые команды терминалу используя sendToMpt($command, $data, $target):

  • command: команда терминалу.
  • data: данные могут быть как массивом так и готовым json так и просто текстом.
  • target: системное имя терминала либо его ip.