- BrainTools - https://www.braintools.ru -
Когда я впервые подключил агента к умному дому через MCP, ожидал простой эффект: “ну, будет еще один способ дергать API”. На практике вышло иначе. MCP в osysHome оказался не транспортом, а рабочим интерфейсом для эксплуатации: с понятными сущностями, историей изменений, проверками перед записью и безопасным контуром для автоматизации.
Покажу это на живых примерах: без магии на слайдах, на реальных инструментах и бытовых сценариях.
Обычный путь автоматизации часто выглядит так:
пишем скрипт на коленке;
через месяц забываем [1], где и почему что-то менялось.
С MCP все иначе. Агент работает не с “сырыми URL”, а с понятными инструментами предметной области:
osys_list_classes и osys_list_objects для инвентаризации;
osys_get_property и osys_get_property_history для наблюдения;
osys_call_method и osys_set_property для действий;
osys_validate_method_code и osys_run_method_dry для безопасной разработки;
osys_update_object / osys_update_class с if_match для управляемых изменений.
По ощущениям это как дежурный инженер для дома: сначала проверяет, потом действует.
В MCPServer для osysHome все строится вокруг endpoint /api/mcp и JSON-RPC поверх HTTP.
Из практики я бы выделил три вещи:
Токен-авторизация (Authorization: Bearer ... или X-MCP-Token).
Разделение прав (чтение отдельно, запись отдельно, управление отдельно).
Аудит неудачных попыток и контроль write-инструментов.
Это критично: дому нужен не “самый умный агент”, а предсказуемый агент с ограниченными правами.
Я придерживаюсь простого рабочего цикла:
Обнаружить контекст — какие классы, объекты и связи есть сейчас.
Проверить гипотезу — история свойств, текущие значения, логи.
Подготовить действие — dry-run, валидация кода или шаблона.
Выполнить изменение — только после проверки.
Верифицировать — убедиться, что эффект наступил и не зацепил соседние сценарии.
Звучит банально, но именно это отделяет “игрушку” от рабочего инструмента.
Запрос агенту человеческим языком:
“Включи свет в гостиной”.
Что делает агент:
Находит целевой объект освещения (например, Relay01 — “Свет(гостиная)”).
Вызывает безопасное действие через MCP (osys_set_property или osys_call_method).
Проверяет, что новое состояние применилось.
Технически запрос выглядит так:
{
"tool": "osys_set_property",
"arguments": {
"property_name": "Relay01.status",
"value": 1,
"source": "MCPAgent"
}
}
Ответ агента:
“Свет в гостиной включен.
Объект:Relay01(Свет(гостиная)).
Новое состояние:status = 1.”
Сценарий простой, но с него и начинают: проверили базовую команду, убедились, что все управляется, и только потом переходят к аналитике и сложным режимам.
Запрос агенту человеческим языком:
“Покажи сводку по энергопотреблению всего дома: сколько сейчас, где пики и насколько нагрузка стабильна по группе силовых устройств”.
Агент делает не один запрос, а целую цепочку:
находит все power-объекты (Power01..Power13, PowerPlug*, TotalPower) — всего 17;
берет агрегаты и текущие значения по TotalPower.power;
строит топ потребителей по текущим значениям *.power.
Короткий ответ агента, уже обычным языком:
“Нашел 17 объектов энергомониторинга.
Сейчас суммарная мощность дома: 168.71 Вт (TotalPower.power, объектTotalPower— Общее энергопотребление).
За последний месяц средняя нагрузка: 442.93 Вт, пиковое значение: 4838.83 Вт.
Текущий топ потребителей:
`Power05` — “Мощность(детские)” — 17.0 Вт
`Power06` — “Мощность(компьютер)” — 4.0 Вт
`Power09` — “Мощность(свет в гостиной)” — 1.48 Вт Остальные power-каналы сейчас близки к 0. По среднемесячной базе топ по вкладу в фон: `Power05` (23.63 Вт), `Power06` (8.58 Вт), `Power09` (6.86 Вт), `Power11` — “Мощность(бойлер)” (4.43 Вт).”
Что агент предлагает для снижения потребления по этой аналитике:
Проверить, почему Power05 держит высокий среднемесячный фон; добавить расписание/автоотключение в ночные часы.
Для Power06 (компьютер) включить сценарий “глубокий сон [2] ночью” и отключение периферии по отсутствию активности.
Для Power11 (бойлер) вынести нагрев в дешевые тарифные окна и ограничить верхний порог температуры.
Добавить еженедельный отчет “топ-5 потребителей за 30 дней”, чтобы видеть эффект изменений.
Практический смысл: это уже не “посмотреть на одно реле”, а цельная картина энергопотребления дома плюс конкретный план оптимизации.
Запрос агенту человеческим языком:
“Проверь, нет ли системных проблем за последний час. Смотри не только
errors.log, а несколько логов модулей, чтобы понять масштаб.”
Агент смотрит сразу несколько источников:
errors.log — системные stacktrace и сетевые ошибки [3];
OpenHasp.log — ошибки интеграции устройства/шины;
ESPHome.log — телеметрия и стабильность данных;
Modules.log — фоновая активность ядра/плагинов.
Короткий ответ агента:
“Проблемы действительно системные, не в одном файле.
Вerrors.logвижу TLS-ошибку при обращении кapi.telegram.org(SSLError: UNEXPECTED_EOF_WHILE_READING).
ВOpenHasp.logповторяется ошибка разбора события (Error processing message: 'event').
При этомESPHome.logиModules.logвыглядят стабильными (регулярные INFO-записи без ошибок).
Значит, инцидент локализуется в двух интеграционных зонах: сеть/Telegram и обработка OpenHasp-сообщений.”
Что агент предлагает как фиксы:
Для Telegram/TLS — проверить цепочку proxy/SSL, таймауты и актуальность cert store на хосте.
Для OpenHasp — валидировать входящий payload на ключ event и логировать raw-пакет при его отсутствии.
Добавить guard в обработчики: неполные сообщения не должны валить поток обработки.
Это не “магия ИИ”, а обычная инженерная рутина, просто заметно быстрее.
Инвентаризация без эксплуатационных флагов мало полезна. Нужна именно “карта риска”.
Запрос агенту человеческим языком:
“Составь список: какие устройства давно не выходят на связь и каким скоро нужно обслуживание (батарейки/связь)”.
Агент проходит по группе устройств и собирает единый список проблем:
устройства без связи по alive;
устройства с риском обслуживания по *.battery и minBattery;
при необходимости добавляет контекст по alive/aliveTimeout.
Короткий ответ агента:
“Сформировал список проблемных устройств.
Поalive = 0сейчас:
Door03— Дверь (лоджия)
Door07— Дверь(Саша)
Door08— Дверь(Ваня)
Door10— Дверь(шкаф 1)
Низкий заряд батареи:
Motion01— Движение(коридор) — 17%
Motion02— Движение(гостиная) — 17%
Зона внимания [4]:Motion06— Движение(Саша) — 43%.
Рекомендация: сначала восстановить связь/питание по объектам сalive = 0, затем заменить батарейки вMotion01/02.”
Так получается не точечная проверка одного объекта, а нормальная сервисная ведомость.
Вместо сложной ML-модели часто хватает базовой статистики + здравого смысла.
Запрос агенту человеческим языком:
“Найди аномалии по климату: где значения выбиваются из обычного диапазона, и что проверить первым делом”.
Агент проверяет не один датчик, а весь пул Climat01..Climat09: берет текущее значение temp и сравнивает с историческим avg для каждого.
Короткий ответ агента:
“Проверил 9 климатических датчиков на отклонение от исторической базы.
Топ аномалий:
`Climat07` — “Климат(лоджия)”: 19.5°C при среднем 13.55°C (сильное положительное отклонение).
`Climat03` — “Климат(туалет)”: 23.8°C при среднем 23.03°C (умеренное отклонение).
`Climat05` — “Климат(Ваня)”: 24.3°C при среднем 23.56°C (умеренное отклонение). Для `Climat08` — “Климат (кухня)” — среднее не рассчиталось (`avg = null`), нужно проверить полноту истории. Рекомендация: проверить сценарии отопления/проветривания на лоджии и восстановить корректное накопление истории для кухонного датчика.”
То есть агент отдает не сырые числа, а приоритизированный список аномалий с понятными действиями.
Это уже не аналитика, а реальное внедрение логики через MCP, где агент не просто “советует”, а сам собирает рабочую сущность.
Запрос агенту человеческим языком:
“Сделай режим Кинотеатр: отдельный объект, метод включения и метод выключения. Перед запуском проверь код безопасно.”
{
"tool": "osys_add_object",
"arguments": {
"object_name": "CinemaMode",
"class_name": "Modes",
"description": "Режим кинотеатр",
"update": true
}
}
{
"tool": "osys_add_object_method",
"arguments": {
"object_name": "CinemaMode",
"name": "activate",
"description": "Включить сценарий кинотеатра",
"code": "target = getProperty('targetBrightness')nif target is None:n target = 20nprev = getProperty('Dimmer01.status')nsetProperty('previousBrightness', prev, source='CinemaMode')nsetProperty('active', 1, source='CinemaMode')nsetProperty('sceneName', 'Cinema', source='CinemaMode')nsetProperty('lastActivated', datetime.now(), source='CinemaMode')nsetProperty('Relay15.status', 0, source='CinemaMode')nsetProperty('Dimmer01.status', target, source='CinemaMode')nsetProperty('Rgb05.status', 1, source='CinemaMode')nsetProperty('Rgb05.brightness', target, source='CinemaMode')",
"update": true
}
}
{
"tool": "osys_add_object_method",
"arguments": {
"object_name": "CinemaMode",
"name": "deactivate",
"description": "Выключить сценарий кинотеатра",
"code": "prev = getProperty('previousBrightness')nif prev is None:n prev = 0nsetProperty('active', 0, source='CinemaMode')nsetProperty('Dimmer01.status', prev, source='CinemaMode')nsetProperty('Rgb05.status', 0, source='CinemaMode')nsetProperty('Relay15.status', 1, source='CinemaMode')",
"update": true
}
}
Чтобы режимом можно было пользоваться и в сценариях, и в интерфейсе, агент добавляет базовые свойства:
active (int) — текущий статус режима (0/1);
targetBrightness (int) — яркость, которую пользователь задает для режима;
previousBrightness (int) — яркость, которая была до включения режима;
sceneName (str) — человекочитаемое имя сцены;
lastActivated (datetime) — когда режим запускался последний раз.
Технически это выглядит так (пример для одного свойства):
{
"tool": "osys_add_object_property",
"arguments": {
"object_name": "CinemaMode",
"name": "active",
"type": "int",
"description": "Статус режима кинотеатр",
"update": true
}
}
По аналогии агент добавляет остальные свойства (targetBrightness, previousBrightness, sceneName, lastActivated).
После выполнения шагов выше в системе появляется новый объект:
Объект: CinemaMode — “Режим кинотеатр”
Класс: Modes
Свойства: active, targetBrightness, previousBrightness, lastActivated
Методы: activate, deactivate
Код метода activate:
target = self.getProperty('targetBrightness')
if target is None:
target = 20
prev = getProperty('Dimmer01.status')
self.setProperty('previousBrightness', prev, source='CinemaMode')
self.setProperty('active', 1, source='CinemaMode')
self.setProperty('lastActivated', datetime.now(), source='CinemaMode')
setProperty('Relay15.status', 0, source='CinemaMode')
setProperty('Dimmer01.status', target, source='CinemaMode')
setProperty('Rgb05.status', 1, source='CinemaMode')
setProperty('Rgb05.brightness', target, source='CinemaMode')
Код метода deactivate:
prev = self.getProperty('previousBrightness')
if prev is None:
prev = 0
self.setProperty('active', 0, source='CinemaMode')
setProperty('Dimmer01.status', prev, source='CinemaMode')
setProperty('Rgb05.status', 0, source='CinemaMode')
setProperty('Relay15.status', 1, source='CinemaMode')
osys_validate_method_code — синтаксис и ограничения runtime.
osys_run_method_dry — dry-run без побочных эффектов.
Именно так можно проверить, что созданные свойства реально используются, а не просто “задекларированы”:
{
"tool": "osys_run_method_dry",
"arguments": {
"object_name": "CinemaMode",
"code": "target = getProperty('targetBrightness')nif target is None:n target = 20nprev = getProperty('Dimmer01.status')nsetProperty('previousBrightness', prev, source='CinemaMode')nsetProperty('active', 1, source='CinemaMode')nsetProperty('sceneName', 'Cinema', source='CinemaMode')nsetProperty('lastActivated', datetime.now(), source='CinemaMode')nsetProperty('Dimmer01.status', target, source='CinemaMode')"
}
}
Ожидаемый результат проверки: в captured_actions будут ключевые действия по свойствам:
active
targetBrightness
previousBrightness
lastActivated
Практический смысл этой схемы:
Пользователь заранее задает targetBrightness (например, 12 или 20).
На activate агент применяет именно это значение.
Перед применением агент сохраняет текущую яркость в previousBrightness.
На deactivate яркость возвращается к previousBrightness, то есть в состояние “как было до кинотеатра”.
И только после этого режим стоит включать в рабочий сценарий.
Так получается полноценный режим с предсказуемым включением и аккуратным откатом.
Ниже набор правил, который у меня реально работает:
перед любой работой агента с write-операциями делайте бэкап (минимум БД и критичных конфигов) и проверяйте, что восстановление реально работает;
выдавайте агенту read-only токен по умолчанию;
write-права открывайте только под конкретные задачи;
отдельно ограничивайте dangerous-инструменты (массовые апдейты, удаление сущностей);
все изменения через этап “validate/dry-run”;
ведите журнал “кто/что/когда” менял.
Главная мысль: не “слепо доверять агенту”, а строить контур, где ошибка локальна и обратима.
Что делать не стоит:
давать полные write-права 24/7 “потому что так удобнее”;
смешивать диагностику и изменение состояния в одном автоматическом шаге;
обновлять классы/объекты без ревизий и проверки актуальности;
считать dry-run “лишней формальностью”.
С агентами правило простое: чем аккуратнее дисциплина в начале, тем меньше ночных приключений потом.
MCP в osysHome для меня — это не про “поговорить с домом на естественном языке”.
Это скорее ощущение, что рядом появился спокойный и внимательный технапарник: ты формулируешь задачу обычными словами, а в ответ получаешь не магию, а понятный, проверяемый результат.
В повседневном использовании это очень чувствуется. Раньше многие вещи откладывались “на потом”, потому что нужно было вручную пройтись по данным, логам, связям и не забыть ничего сломать. С MCP этот путь стал короче и заметно спокойнее: меньше рутины, меньше дерганых правок, больше уверенности в том, что система под контролем.
И вот здесь для меня случился главный сюрприз.
В начале я ожидал “удобный интерфейс к API”. На выходе получил заметно больше: агент реально берет на себя кусок рутинной инженерной работы — от диагностики до безопасного внедрения изменений.
Если честно, это и есть тот самый вау-эффект: результат оказался намного сильнее стартовых ожиданий.
Автор: Anisan
Источник [5]
Сайт-источник BrainTools: https://www.braintools.ru
Путь до страницы источника: https://www.braintools.ru/article/29362
URLs in this post:
[1] забываем: http://www.braintools.ru/article/333
[2] сон: http://www.braintools.ru/article/9809
[3] ошибки: http://www.braintools.ru/article/4192
[4] внимания: http://www.braintools.ru/article/7595
[5] Источник: https://habr.com/ru/articles/1027806/?utm_source=habrahabr&utm_medium=rss&utm_campaign=1027806
Нажмите здесь для печати.