commit f749579e96d3c30136dcd5099f18ab34ee22ffdd Author: sirmrak Date: Sun Jun 28 13:40:22 2026 +0300 Загрузить файлы в «/» diff --git a/README.md b/README.md new file mode 100644 index 0000000..3f431a4 --- /dev/null +++ b/README.md @@ -0,0 +1,396 @@ +# RT Key Integration for Home Assistant + +[![Home Assistant](https://img.shields.io/badge/Home%20Assistant-Integration-blue)](https://www.home-assistant.io/) +[![License: MIT](https://img.shields.io/badge/License-MIT-yellow.svg)](https://opensource.org/licenses/MIT) + +Интеграция для работы с камерами и домофонами **Ростелеком Key** в Home Assistant. + +## 📋 Возможности + +### 📹 Камеры +- **Live-стрим** с камер в реальном времени +- **Периодические скриншоты** с настраиваемым интервалом +- **Автоматическое обновление токенов** при ошибках доступа +- **Отслеживание доступности** камер (online/offline) + +### 🏢 Домофоны +- **Удалённое открытие** двери через кнопку +- **Отслеживание событий**: + - Открытие по ключу (с определением владельца ключа) + - Открытие через приложение + - Открытие по коду/DTMF +- **Скриншоты событий** — фото на момент события +- **Архивное видео** — запись с камеры на момент события + +### ️ Настройки +- Гибкая настройка через UI +- Выбор качества скриншотов +- Настраиваемый уровень логирования +- Интервал обновления скриншотов (0 = отключено) + +## 📦 Установка + +### Вариант 1: Через HACS (рекомендуется) + +1. Откройте **HACS** в Home Assistant +2. Перейдите в раздел **Интеграции** +3. Нажмите **⋮** (три точки) → **Пользовательские репозитории** +4. Добавьте URL вашего репозитория +5. Установите интеграцию **RT Key** +6. Перезапустите Home Assistant + +### Вариант 2: Вручную + +1. Скопируйте папку `rtkey` в директорию `/config/custom_components/` +2. Перезапустите Home Assistant +3. Перейдите в **Настройки** → **Устройства и службы** +4. Нажмите **Добавить интеграцию** +5. Найдите **RT Key** + +## 🔑 Получение токена доступа + +Для работы интеграции необходим токен доступа к API Ростелеком Key. + +### Пошаговая инструкция: + +1. **Авторизуйтесь** на портале Ростелеком Key: + [https://key.rt.ru/main/pwa/dashboard](https://key.rt.ru/main/pwa/dashboard) + +2. **Откройте инструменты разработчика**: + - Нажмите `F12` (или `Ctrl+Shift+I` / `Cmd+Option+I` на Mac) + - Перейдите на вкладку **Network** (Сеть) + +3. **Отфильтруйте запросы**: + В поле фильтра введите: + - `household.key.rt.ru` + - или `keyapis.key.rt.ru` + +4. **Обновите страницу** (`F5`) — появятся запросы к API + +5. **Выберите любой запрос** из списка (например, `intercom` или `camera_video_data/list`) + +6. **Скопируйте токен**: + - Перейдите во вкладку **Headers** (Заголовки) + - Найдите заголовок `Authorization` + - Скопируйте значение **после слова `Bearer`** (без пробела) + + Пример: + ``` + Authorization: Bearer eyJhbGciOiJSUzI1NiIsImtpZCI6... + ↑ скопируйте отсюда + ``` + +7. **Вставьте токен** при настройке интеграции в Home Assistant + +> ⚠️ **Важно**: Токен чувствителен к регистру! Копируйте полностью, без пробелов и переносов строк. + +## ⚙️ Настройка интеграции + +После добавления интеграции откройте её настройки: + +### Основные параметры + +| Параметр | Описание | По умолчанию | +|----------|----------|--------------| +| **Название** | Уникальное имя интеграции | RT Key | +| **Токен** | Токен доступа (см. выше) | — | +| **Интервал скриншотов** | Частота обновления (сек), 0 = отключено | 60 сек | +| **Качество скриншотов** | Маленькое / Среднее / Большое / Точное | Среднее | +| **Уровень логов** | DEBUG / INFO / WARNING / ERROR | INFO | + +### Настройки событий + +| Параметр | Описание | По умолчанию | +|----------|----------|--------------| +| **Отслеживание событий** | Включить мониторинг событий | ✅ Вкл | +| **Интервал опроса** | Частота проверки событий | 15 сек | +| **Задержка времени камеры** | Лаг синхронизации (сек) | 25 сек | +| **Секунд до события** | Показывать видео до события | 10 сек | +| **Скриншот события** | Создавать сущность скриншота | ✅ Вкл | +| **Архив события** | Создавать камеру архива | ✅ Вкл | +| **Сенсор события** | Создавать сенсор последнего события | ✅ Вкл | + +## Сущности + +После настройки интеграция создаст следующие сущности: + +### Для каждой камеры + +| Сущность | Тип | Описание | +|----------|-----|----------| +| `{name}` | Camera | Live-стрим с камеры | +| `Скриншот {name}` | Image | Периодический скриншот | + +### Для каждого домофона + +| Сущность | Тип | Описание | +|----------|-----|----------| +| `Открыть {name}` | Button | Кнопка открытия двери | +| `Последнее событие {name}` | Sensor | Информация о последнем событии | +| `Скриншот события {name}` | Image | Скриншот на момент события (диагностика) | +| `Архив события {name}` | Camera | Архивное видео события (диагностика) | + +> 💡 **Совет**: Сущности из раздела "Диагностика" можно переместить на основную панель через настройки устройства. + +## 🎯 Использование + +### Просмотр камер + +1. Откройте **Панель управления** → **Обзор** +2. Добавьте карточку **Camera** или **Picture Entity** +3. Выберите нужную камеру + +### Открытие домофона + +1. Найдите сущность `button.{name}_open` +2. Нажмите на кнопку в интерфейсе +3. Или используйте в автоматизациях: + ```yaml + service: button.press + target: + entity_id: button.my_intercom_open + ``` + +### Автоматизации + +Примеры использования в автоматизациях: + +#### Уведомление при открытии двери ключом + +```yaml +automation: + - alias: "Уведомление об открытии двери" + trigger: + platform: state + entity_id: sensor.my_intercom_last_event + condition: + condition: template + value_template: "{{ 'Ключ' in trigger.to_state.state }}" + action: + - service: notify.mobile_app + data: + message: "Дверь открыл: {{ trigger.to_state.state }}" + title: "🚪 Домофон" +``` + +#### Включение света при открытии двери вечером + +```yaml +automation: + - alias: "Свет при открытии двери" + trigger: + platform: state + entity_id: sensor.my_intercom_last_event + condition: + - condition: sun + after: sunset + - condition: template + value_template: "{{ 'Ключ' in trigger.to_state.state }}" + action: + - service: light.turn_on + target: + entity_id: light.hallway +``` + +#### Отправка скриншота события в Telegram + +```yaml +automation: + - alias: "Скриншот события в Telegram" + trigger: + platform: state + entity_id: sensor.my_intercom_last_event + action: + - service: telegram_bot.send_photo + data: + url: >- + {{ state_attr('image.my_intercom_event_screenshot', 'entity_picture') }} + caption: "Событие: {{ trigger.to_state.state }}" +``` + +## 🔧 Диагностика + +### Проверка доступности камер + +Если камера отображается как **недоступна** (серая в интерфейсе): + +1. **Проверьте атрибуты сущности**: + ```yaml + Статус: Нет связи + ``` + +2. **Посмотрите логи Home Assistant**: + ``` + Камера "Название камеры" (xxx-xxx-xxx) недоступна (404), помечаем как offline + ``` + +3. **Камера автоматически восстановится** при появлении связи: + ``` + ✅ Камера "Название камеры" (xxx-xxx-xxx) снова доступна + ``` + +### Обновление токенов + +При получении ошибки **403 Forbidden** интеграция автоматически: +1. Обнаруживает протухший токен +2. Запрашивает новые токены из API +3. Повторяет неудачный запрос + +**Пример в логах:** +``` +⚠️ Токен для Камера 1 (xxx-xxx) протух (403), запускаем обновление... + Принудительное обновление токенов... +✅ Токены обновлены для N устройств +``` + +### Уровень логирования + +Измените уровень в настройках интеграции для более детальной отладки: + +| Уровень | Когда использовать | +|---------|-------------------| +| **DEBUG** | При проблемах с интеграцией — подробная информация о всех запросах | +| **INFO** | Повседневное использование (рекомендуется) | +| **WARNING** | Только предупреждения и ошибки | +| **ERROR** | Только критические ошибки | + +### Просмотр событий в реальном времени + +Для отладки отслеживания событий установите уровень **DEBUG** и ищите в логах: + +``` + Запущен цикл опроса событий (интервал 15.0с) +✅ Загружено N домофонов: ['intercom_id_1', 'intercom_id_2'] +🔔 Новое событие для домофона intercom_id_1: Ключ {имя} в 2026-01-01 12:00:00 +✅ Скриншот события получен xxxxxxxx-... (NNNNN байт) +``` + +## 🐛 Решение проблем + +### ❌ Интеграция не добавляется + +**Симптом**: Ошибка "Invalid token" или "Authentication failed" + +**Решение**: +1. ✅ Убедитесь, что токен скопирован **полностью** (начинается с `eyJ...`) +2. ✅ Проверьте, что в токене **нет пробелов и переносов строк** +3. ✅ Убедитесь, что вы скопировали токен **без слова `Bearer`** +4. ✅ Попробуйте получить новый токен (старый мог истечь) + +### ❌ Камеры не показывают видео + +**Симптом**: Чёрный экран или ошибка загрузки + +**Решение**: +1. Проверьте статус камеры в атрибутах (`❌ Нет связи`) +2. Убедитесь, что камера работает в **приложении Ростелеком Key** +3. Перезагрузите интеграцию +4. Проверьте логи на наличие ошибок `403` или `404` + +### ❌ Скриншоты не обновляются + +**Симптом**: Изображение не меняется в карточке + +**Решение**: +1. Проверьте **интервал обновления** в настройках (не установлен ли `0`) +2. Увеличьте интервал (минимум 30 сек) +3. Проверьте логи на наличие ошибок + +### ❌ События не отслеживаются + +**Симптом**: Сенсор событий показывает "Нет событий" + +**Решение**: +1. Убедитесь, что в настройках включено **"Отслеживание событий"** +2. Проверьте **интервал опроса** (рекомендуется 15 сек) +3. Посмотрите логи — должны быть сообщения `🔔 Новое событие для домофона...` +4. Проверьте, что домофон в списке: `✅ Загружено N домофонов: [...]` + +### ❌ Неправильное время событий + +**Симптом**: Время события не совпадает с реальным + +**Решение**: +1. Убедитесь, что в Home Assistant правильно настроен **часовой пояс** + (**Настройки** → **Система** → **Общее** → **Часовой пояс**) +2. Проверьте параметр **"Задержка времени камеры"** в настройках + (по умолчанию 25 сек — может отличаться для разных камер) + +## 📊 Структура проекта + +``` +custom_components/rtkey/ +├── __init__.py # Основной модуль, API клиент +├── button.py # Кнопки открытия домофона +├── camera.py # Live-камеры и архив событий +── config_flow.py # Настройка через UI +├── image.py # Скриншоты камер и событий +├── sensor.py # Сенсоры событий +├── manifest.json # Метаданные интеграции +├── translations/ +│ ├── en.json # Английские переводы +│ └── ru.json # Русские переводы +└── README.md # Документация +``` + +### Ключевые API endpoints + +| Endpoint | Назначение | +|----------|-----------| +| `keyapis.key.rt.ru/vc/api/v1/camera_video_data/list` | Список всех камер и домофонов | +| `household.key.rt.ru/api/v2/app/devices/intercom` | Информация о домофонах | +| `household.key.rt.ru/api/v2/app/devices/{id}/open` | Открытие домофона | +| `events.key.rt.ru/api/v2/events/list` | События (открытие, звонки) | +| `key.rt.ru/screenshot/image/...` | Скриншоты камер | +| `live-vdk4.camera.rt.ru/stream/...` | Live-стрим и архивное видео | + +## 🔐 Безопасность + +- ✅ **Токен хранится** в зашифрованном хранилище Home Assistant +- ⚠️ **Не передавайте** токен третьим лицам +- 🔄 **Регулярно обновляйте** токен (рекомендуется раз в 3-6 месяцев) +- 👤 Используйте **отдельный аккаунт** для интеграции, если возможно +- 🚫 **Не публикуйте** токен в публичных репозиториях или логах + +## 📝 Changelog + +### Версия 1.0.0 (2026) +- ✅ Добавлена поддержка камер и домофонов +- ✅ Автоматическое обновление токенов при 403 +- ✅ Отслеживание доступности камер (404) +- ✅ События с маппингом ключей +- ✅ Скриншоты и архивное видео событий +- ✅ Гибкие настройки через UI (слайдеры, dropdown) +- ✅ Настраиваемый уровень логирования +- ✅ Переводы на русский и английский +- ✅ Корректная конвертация UTC → локальное время HA + +## 🤝 Вклад в развитие + +Приветствуются: +- 🐛 Bug reports (с логами и описанием) +- 💡 Feature requests +- 🔧 Pull requests +- 📚 Улучшение документации +- 🌍 Новые языковые переводы + +## 📄 Лицензия + +MIT License — используйте на свой страх и риск. + +## 🙏 Благодарности + +- **Ростелеком** за API домофонов +- **Сообществу Home Assistant** за отличную платформу +- **Всем тестировщикам** за помощь в отладке и обратную связь + +--- + +
+ +**Разработано с ❤️ для Home Assistant** + +[ Наверх](#rt-key-integration-for-home-assistant) + +
+ diff --git a/hacs.json b/hacs.json new file mode 100644 index 0000000..47a5ac3 --- /dev/null +++ b/hacs.json @@ -0,0 +1,8 @@ +{ + "name": "RT Key", + "render_readme": true, + "content_in_root": false, + "hide_default_branch": true, + "country": ["RU"], + "homeassistant": "2024.1.0" +} \ No newline at end of file diff --git a/help.md b/help.md new file mode 100644 index 0000000..e1b9a1b --- /dev/null +++ b/help.md @@ -0,0 +1,82 @@ +# Проект: Кастомная интеграция Home Assistant для Ростелеком Key (rtkey) + +## Описание +Интеграция для работы с камерами и домофонами Ростелеком Key (key.rt.ru). +Позволяет просматривать live-стримы, скриншоты, открывать домофоны, +отслеживать события (открытие по ключу, через приложение и т.д.). + +## API endpoints +1. **Камеры (все устройства)**: + GET https://keyapis.key.rt.ru/vc/api/v1/camera_video_data/list + Возвращает: uid, токены (streamer, screenshot, user), статус, модель, IP, MAC + +2. **Домофоны**: + GET https://household.key.rt.ru/api/v2/app/devices/intercom + Возвращает: id, camera_id, serial_number, inter_codes (ключи с именами), capabilities + +3. **Открытие домофона**: + POST https://household.key.rt.ru/api/v2/app/devices/{id}/open + +4. **События**: + GET https://events.key.rt.ru/api/v2/events/list?device_ids=...&limit=1&sort_by=raised_at + Возвращает: event_type, raised_at (UTC), rfid_id, request_id + +5. **Скриншоты**: + - Последний: https://key.rt.ru/screenshot/image/{quality}/{camera_id}/last.jpg?token=... + - По времени: https://key.rt.ru/screenshot/image/{quality}/{camera_id}/{timestamp_sec}.jpg?token=... + +6. **Стрим**: https://live-vdk4.camera.rt.ru/stream/{camera_id}/live.mp4?token=... +7. **Архив**: https://live-vdk4.camera.rt.ru/stream/{camera_id}/{timestamp_sec}.mp4?token=... + +## Критически важные нюансы +- **Лаг времени камеры ~25 секунд**: если событие в T, то в видео/скриншоте оно отображается на T+25. + Для получения точного кадра нужно запрашивать timestamp = T - 25. +- **Время событий в UTC**: raised_at приходит в UTC, для отображения конвертируем в hass.config.time_zone +- **Токены привязаны к IP**: при смене IP сервера РТ токены становятся невалидными (403). + Нужно периодически обновлять через camera_video_data/list. +- **Токены живут долго** (exp ~через год), но привязка к IP — проблема. + +## Архитектура +- `RTKeyCamerasApi` — основной класс, хранит все данные, делает запросы +- Один общий таймер опроса событий (asyncio.Task) для всех домофонов +- Callback-система для уведомления сущностей об обновлении событий +- Кэш картинок (4 сек) для предотвращения дублей запросов +- Маппинги: intercom_id → camera_id, rfid_id → имя ключа + +## Сущности для каждого домофона +- `button` "Открыть" — открытие двери +- `sensor` "Последнее событие" — показывает кто открыл (с маппингом rfid_id → имя) +- `image` "Скриншот события" — JPEG на момент события +- `camera` "Архив события" — видео с момента события + +## Сущности для каждой камеры +- `camera` — live-стрим +- `image` "Скриншот" — периодический скриншот (интервал настраивается, 0 = отключено) + +## Настройки (Options Flow) +- camera_image_refresh_interval (слайдер 0-600, шаг 30) +- screenshot_quality (dropdown) +- log_level (dropdown) +- events_enabled, events_refresh_interval, event_time_lag (25 по умолчанию) +- pre_event_seconds, event_screenshot_enabled, event_archive_enabled и т.д. + +## Что уже работает +- Live-стримы камер +- Периодические скриншоты +- Открытие домофонов через кнопку +- Отслеживание событий с маппингом ключей +- Скриншоты и архивное видео на момент события +- Правильная конвертация UTC → локальное время HA +- Настройки через Options Flow с слайдерами и dropdown + +## Что можно улучшить (задачи на будущее) +- [ ] Автоматическое обновление токенов при получении 403 (сейчас только по таймеру) +- [ ] Обработка ошибок в таймерах (чтобы таймер не умирал при исключениях) +- [ ] Уведомления в HA при звонке в домофон (если появится такой тип события) +- [ ] История событий (не только последнее) + +## Стиль кода +- Русские комментарии и логи +- Логирование через _LOGGER с эмодзи для важных событий (✅, 🔔, 🔄) +- Типизация (Python 3.11+) +- Использование async/await, async_add_executor_job для blocking calls \ No newline at end of file