В прошлый раз я рассказал об идее и о том, как проект добрался до стабильной работы. Теперь — железная часть: из чего всё состоит, сколько потратил и сколько это стоит сейчас.
Сразу оговорюсь: цены на платы Luckfox взлетели раза эдак в два и, кажется, продолжают расти. С чем связано — честно, не знаю. Но для меня цена уже перестала быть гуманной, так что потихоньку ищу альтернативы. Одну плату по нынешним ценам я всё-таки купил — взамен сгоревшей во время экспериментов (об этом чуть позже).
Итак, что нам понадобится для сборки
1. Мозги
Главный компонент. Вариантов несколько, опишу все, но с нюансами. Перечисленные ниже платы поддерживают оба модуля камеры (про них дальше) и гарантированно работают с моим приложением.
Luckfox Pico Pro — чип RV1106G2, NPU 0.5 TOPS, 128 MB DDR3L, Ethernet 10/100. Самая минимальная рабочая. NPU не самый мощный, так что, когда доберусь до детекции на самой плате, здесь, скорее всего, будет чуть урезанный вариант. В остальном — всё, что нужно, есть.
Luckfox Pico Max — RV1106G3, NPU 1 TOPS, 256 MB DDR3L, Ethernet 10/100. Отличный вариант. Потянет всё, что можно придумать под эти камеры.
Luckfox Pico Ultra BW — RV1106G2, NPU 0.5 TOPS, 128 MB DDR3L, Ethernet, eMMC 8 GB, Wi‑Fi 6 и Bluetooth. Ключевые фишки — встроенная память и Wi‑Fi 6. NPU слабый. К USB можно подключить, например, модем с симкой — в теории должно работать, но, скорее всего, придётся перебирать систему (в планах проверить). Из Bluetooth можно попробовать сделать прокси или передавать данные с датчиков по Wi‑Fi в умный дом. Есть DPI‑интерфейс — можно подключить экран (тоже от Luckfox). Думаю из этого получился бы неплохой дверной глазок, потому что показывать видео с камеры на локальном экране иначе просто некуда.
Luckfox Pico Ultra W — RV1106G3, NPU 1 TOPS, 256 MB DDR3L, Ethernet, eMMC 8 GB, Wi‑Fi 6 и Bluetooth. А это уже «максималка»: есть всё, что у Ultra BW, плюс полноценный NPU и больше памяти — с заделом на будущую детекцию прямо на камере.
Важно: следующие две платы работают на другом процессоре (RV1103) и поддерживают только младший модуль камеры. С моим приложением я их не проверял, но в теории — должны.
Luckfox Pico Plus — RV1103, NPU 0.5 TOPS, 64 MB DDR2, Ethernet. Если оперативной памяти не хватит, можно выкрутиться swap на SD‑карте.
Luckfox Pico Mini B — RV1103, NPU 0.5 TOPS, 64 MB DDR2. Очень интересный вариант своим размером, но без Ethernet и Wi‑Fi. Есть SPI NAND Flash на 128 MB — теоретически туда можно поставить систему и запустить приложение (правда, для детекции памяти точно не хватит, а swap взять неоткуда). В слот SD‑карты можно вставить модуль Wi‑Fi. А если к USB подключить хаб с Ethernet, тогда и SD останется под swap. Надеюсь, дойдут руки протестировать.
2. Камеры
Тут всё проще. Два варианта:
SC3336 — 3 Мп, 2304×1296.
MIS5001 — 5 Мп, 2592×1944.
Пользуюсь обоими. Днём снимают отлично, ночью — пока чернота. Очень надеюсь, что это ошибки настроек и картинку ещё можно выкрутить. Сейчас ночью камеры видят только машины с фарами и людей с фонариком. Но у нас начинаются белые ночи — так что скоро всё будет видно! :D
3. Питание
Два пути. Если USB (есть на всех платах Luckfox) не используется, как у меня, — берёте любой блок питания на 5V и кабель USB‑C. Хочется попаять — берите модуль AC/DC 220V → 5V. По мощности: проверял блоки на 750 мА, но сейчас камеры подключены к 1 А — с запасом для зарядки UPS.
4. Карта памяти
MicroSD на хватит 4–32 ГБ. Берите любую, какая есть или подешевле, но не самую медленную и убитую: с неё будет работать система. Внимание: для Luckfox Pico Ultra (BW и W) карта не нужна — там используется встроенная eMMC, слота под SD нет.
5. Допики
Как упоминал ранее, можно прикрутить UPS. Я взял на Али модуль 5V под два аккумулятора 18650 — отличная штука. По моим замерам камера работает на них 5–7 часов (аккумуляторы 3000 мА·ч, уже познавшие жизнь). Бывают модули и под один 18650. Другой вариант: литий-ионная батарейка на 3V и модуль TP4056 со встроенной регулировкой выходного напряжения — тогда можно получить стабильные 5V. Правда, в последний раз такой вариант меня подвёл и спалил плату Luckfox :(
Ещё можно добавить подсветку — круговую, хоть IR, хоть LED. Но тут надо быть внимательным: большинство IR-подсветок рассчитано на 12V, а те, что на 5V, просят чуть ли не 2А (зависит от размера). Хорошего и при этом дешёвого варианта для себя пока не нашёл.
Цены "сейчас" актуальны на 15.05.26. Смотрел на озоне и алике. Наверняка можно найти и дешевле.
Сделать камеру для Frigate (прикольное приложение для обнаружения движений в кадре).
Максимально локально: никаких облаков, «китайских приложений», левых соединений наружу. Т.к. дома у родителей интернет от модема с симкой - скорость и качество соединения низкое.
Управление из Home Assistant. Потому что часть дома живет уже там и не хочется "плодить" приложения, да и отцу будет проще разобраться в чем-то одном.
В идеале — чтобы камера вообще могла жить без интернета (а на роутере можно было спокойно запретить ей выход наружу), и при этом всё управление оставалось внутри локальной сети.
То есть, с одной стороны — обычная IP-камера с RTSP. С другой — чтобы можно было в приложении поменять параметры и не лазить каждый раз в консоль. Почему не купил готовую? Можно было. Но мне нравится самому собирать, паять, прошивать.
Первая попытка: ESP32
Начинал с классики — ESP32-CAM и ESP32-S3 + OV2640.
ESP32 уже использовал в других проектах, платы мне знакомы и в целом близки.
Базовые штуки они делают неплохо:
картинку получить можно;
фотки в Telegram уходят отлично (даже с плохим интернетом);
Но как камера «для наблюдения» — боль:
стрим у меня был только MJPEG, а значит доп. нагрузка на сеть вайфая и миник, который собирал и перекодировал этот поток в h.264;
качество "видео"… мягко говоря, грустное;
Частые отвалы от Frigate. Да и фпс низкий и не очень стабильный.
Так я понял, что хочу H.264/H.265 с камеры и нормальный видеопайплайн, а это уже не про ESP32.
Находка: Luckfox — и первое разочарование
На Али наткнулся на платы Luckfox Pico на Rockchip RV1106. Почитал вики — выглядит как то, что нужно: аппаратное кодирование, нормальные сенсоры (камеры 4k и 1080р), есть готовые примеры. Да и цена приемлимая, в тот момент, когда покупал - вышло как сильно бюджетная камера.
Заказал, получил, попробовал… и разочаровался.
Встроенный RTSP-сервер (стандартный `rkipc`) у меня запускался и по Wi‑Fi (Luckfox Pico Ultra W), и по Ethernet (Pico Pro/Max). В помещении всё выглядело нормально. Радости не было придела!
Но стоило вынести камеру на улицу в солнечную погоду — картинка превратилась в белый экран. Я несколько дней ковырял настройки, пробовал разные профили — не победил.
Причем нейронки не смогли даже примерно подсказать в какую сторону "копать", где и что исправлять. В wiki тоже ничего не нашел. А на самом популярном репозитории на Github - плату использовали для разблокировки плойки.
Проект был заброшен в долгий ящик.
Возвращение: нейросети, грабли и маленькие победы
Примерно через полгода вернулся к идее — и начал методично разбирать, как это всё должно работать.
Параллельно мучил всё, что мучается: GPT/DeepSeek/Claude (без фанатизма, но иногда они хорошо помогают подсветить, где искать, о чем стоит задуматься и какие настройки вообще существуют).
В итоге, на базе примеров Luckfox и с кучей итераций получилось собрать свою реализацию, которая в реальной жизни ведёт себя предсказуемо и стабильно.
Вот что получилось реализовать в проекте:
Видео и потоки
Основной RTSP-стрим: H.264, в «родном» профиле сенсора (2K или 1080p, зависит от модуля).
Второй RTSP-стрим (sub/detect) для Frigate: уменьшенное видео (по умолчанию 640×360), "родное" разрешение детектора.
Управление из умного дома
Управление параметрами через MQTT.
Камера умеет Home Assistant MQTT Discovery — то есть появляется в HA как устройство автоматически, с сущностями/ползунками/переключателями.
Настройки сохраняются (переживают перезагрузку).
Что можно менять без перезапуска камеры (в HA)
FPS и битрейт потока.
Поворот/зеркало (mirror/flip).
Яркость/контраст/насыщенность/оттенок, резкость.
Режимы «день/ночь». Хотя по факту сейчас использую режим только "день".
Баланс белого: авто и пресеты.
Сейчас эксперементирую с корпусами, к одной камере напечатал корпус на 3D‑принтере.
Что ещё хочу сделать
Планы стараюсь держать реалистичными, но времени все-равно не хватает.
Детекция на самой камере (NPU 0.5/1 TOPS): платы это позволяют, хочется хотя бы MVP (человек/движение) и события в MQTT.
Разобраться с качеством в темное время суток, как по мне - чересчур много ряби и так быть не должно.
RTSP-авторизация: чтобы поток был не «всем в локалке открыт», а с логином/паролем.
Навести порядок в телеметрии MQTT: добавить полезные показатели и убрать тестовые, сейчас, как по мне - много лишнего.
Корпус: нормальный вариант под улицу, в идеале с сервой для поворота.
Звук: сейчас он есть в экспериментальном виде и ещё требует проверок по качеству.
P.S. Если будет интересно - дальше расскажу подробнее о стоимости, сборке и поделюсь кодом (на Github), а также покажу фото с камер, настройки Frigate и т.п.
1/2
Вот такие камеры сейчас установлены. У второй - пока корпус из банки, но главное ведь что внутри :D
Прошло примерно три месяца с момента моего первого поста в этом сообществе - про то как я сделал свой домашний сервер. Я был молод и наивен полон энтузиазма и считал что уже все сделал и был готов делится опытом.
Чтош, самое время подвести промежуточные итоги и рассказать о тех ошибках, которые я натворил, возможно кому то они помогут их избежать. Ну и просто похвастаться.
Как лаба выглела три месяца назад - видно в прошлом посте. Так выглядит сейчас. Визуально все не очень изменилось. Добавилось три коробки, из которых одна - временная.
Слой железа.
Добавилась еще одна машинка. Знакомый вворемя заметил тренд на подорожание оперативной памяти и посоветовал - если тебе что то нужно - бери сейчас или потом не ной. Поэтому я залез в кубышку и приобрел еще ASUS NUC 14 Pro Tall Kit RNUC14RVHV500002I (Intel Core U5 135H Processor, Intel Arc Graphics, Intel WiFi 6E, No Operating System, with EU Power Cord), добавил к нему WD_BLACK SN850X NVMe SSD 4 TB Internal SSD и Crucial DDR5 RAM 96GB Kit (2x48GB) 5600MHz SODIMM. Все вместе стоило 1158 евро, сейчас такой же набор уже обошелся бы мне 1973 евров. Моя жаба довольна, до тех пор пока не займусь плотно llm локальными - мне желаза хватит надолго.
Добавился TP-Link TL-SG3428X 24-Port Gigabit L2+ Managed Switch (4 10GE SFP+). Ранее все устройства были воткнуты напрямую в роутер - но это не очень правильно. Добавление считча позволило мне - обьединить все сервера в высокоскоростную сеть. - снять нагрузку с с CPU роутера
- интегрировать Omada и сделать более сложную топологию сети. Свитч подключен 10G к роутеру, остальные три порта заняты НАС и двумя машинами.
Совершенная ошибка: всего 4 быстрых порта в свитче, сейчас я бы взял 8 SFP+, а меди можно было взять меньше.
В свою защиту скажу что три месяца назад я вообще не знал что такое SFP+ и что бывают скорости больше 2.5 гигабита.
Добавился юсб - хаб, временное колхозное решение, но в серверах начало не хватать портов для переферии. Уберу в версии 2.0.
Слой ОС
Наиболее заметные изменения были именно на этом слое. Три месяца назад на одной машине у меня стоял OMV, на котором крутились все контейнеры, а на второй - Проксмокс, на котором крутились виртуалки Home Assistant.
Совершенная ошибка: OMV это прежде всего сетевое хранилище, на которое «сверху» прикрутили возможность запускать Docker. Если падает ОС или забивается системный диск логами Docker - падает всё сразу.
Сейчас OMV я убил полность, а на все три машины установлен Проксмокс, ноды обьединены в один управляемый кластер, критически важные машины используют SSD iSCSI-рейд на NAS.
Proxmox - это гипервизор 1-го уровня. Все сервисы живут отдельно. Падение одного не задевает другого. При наличии кластера (три+ устройства) можно использовать iSCSI луны как системные диски, можно обеспечивать High Availability state. Простыми словами - если запщущенная у меня на одной машине виртуалка падает, даже если вся машина полностью выходит из строя - проксмокс автоматически поднимает ее копию спустя пару минут на другой машине. Часто пользователь даже не замечает этого. В случае если нужно провести обслуживание одной машины - виртуалку за пару минут можно перенести на другоую машину без потери доступности. Proxmox Backup Server позволяет быстро и экономно хранить бекапы всего и вся.
Слой логики.
Совершенная ошибка: Я перетащил все 60 + контейнеров с моей машины OMV на ноду проскмос без проблем - но проблема началась позже. У меня не было распределения сервисов на "критические" и "контентные", все висело на одной виртуалке. Если она падала - падало все. А она падала! Решением стало выделение отдельной виртуалки (infra-gateway) для системных служб (Nginx Proxy Manager, Omada Controller, Authentik, AdGuard Home, Prometheus, Grafana, Alertmanager, Uptime Kuma, Dozzle Master и CrowdSec). Я повесил ее в режим High Availability state и это стало моим лучшим решением - никакие дальнейшие эксперименты в лабе не могли "сломать мне все". Пойдя дальше я разнес окружения контента и разработки тоже на отдельные машины, но об этом позже. В свое оправдание (да, люблю я оправдываться) могу сказать что про Single Point of Failure, сиречь единая точка отказа и про Blast Radius (радиус поражения) - я тогда не слышал и не задумывался. Хождение по граблям наше все.
Слой приложений. Этот слой тоже претерпел заметные изменения, как по содержанию, так и по логике.
Первый месяц после сборки своего сервера.
Совершенная ошибка: Первое время логика была такая - О, такая штука есть, я ее себе хочу. Таким образом у меня на OMV в докере появился например YunoHost (внутри которого, в докерах же, появились другие сервимы), или например заметную часть оперативки стал занимать почти корпоративный сервис для аудита безопасности GreenBone.
Пару месяцев спустя и заново изобрел подход (который изобрели задолго до меня) YAGNI (You Ain't Gonna Need It - не устанавливай сервис до тех пор, пока у тебя не возникла реальная, осязаемая потребность в нём. Сервисы нужно обновлять. Сервисы нужно защищать. Сервисы нужно пониторить. Сервисы нужно бекпить. Сервисы тратят ресурсы системы и электричество. Поэтому если я не планирую открывать сервис чаще чем раз в месяц - вероятно сервис мне не нужен.
Пока я не до конца прошел этот путь (у меня есть несколько сервисов с близкими или дублирующимся функциями), но постепенно от них избавляюсь. Уже избавился от Speedtest Tracker (тратит ресурсы, показывает всегда прямую линию), ByteStash (заменил Gitea), Terminal (заменил VC Code), Cockpit (заменил VC Code), YunoHost (работаю напрямую с контейнерами, так гибче и удобней)
Новые сервисы
Так сейчас выглядит мой дашблорд с сервисами.
Я все еще продолжаю (и планирую продолжать) экспериментировать с сервисами. Ставлю, смотрю удобно или нет, решает ли мою проблему какую то или нет. Если нет - удаляю, если да - то оставляю. Из интересного за последние месяцы появились
Authentik - единое окно авторизации. С настройкой пришлось повозится, но потом стало очень удобно, особенно когда подвключил к сервисам жену и других родственников. Единожды создаешь пользователя в goauthentik, пользователь помнит пароль только от goauthentik, остальные сервисы используют SSO авторизацию.
Filebrowser - файловый менеджер. Ближайший кандидат к удалению. Через VC Code удобней.
CrowdSec - один из сервисов, который я почти никогда не открываю - но удалять не планирую. Этот сервис "читает" логи Nginx Proxy Manager и Authentik в реальном времени. Он видит каждый IP-адрес и то, что он пытается сделать. Как только поведение признано враждебным, CrowdSec принимает решение: забанить этот IP на определенное время. Далее он передает через апи команду в Cloudflare Bouncer, и тот блокируется на уровне серверов Cloudflare. Решение работает и децентрилизовано - если злоумышленик пытался кого то взломать (тех, у кого тоже стоит краудсек), то он автоматически будет забанен и у меня.
Dockge - сервис имеет аналогичные функции с уже имеющимся у меня Portainer, но я зачем то перевел Portainer на бизнес лицензию (бесплатную для трех нод), поэтому для остальных машин нужно иметь какой то сервис управления докерами - и я выбрал этот. Сейчас Portainer у меня управляет основными нодами (инфраструктура и медиа), а разработка, аи инструменты, фригейт и прочие живут на Dockge
Adguard Slave поселился в добавок к основному - даже если HA машина с основным adguard перегружается или недоступна - доступ к интернету остается. Синкается автоматически.
Немного изменил медиа стек. Раньше я руками заходил в пролар, искал там что-то, отправлял в куторрент. А потом руками переносил в нужную папку - музыка ли, фильмы ли, сериалы ли. Сейчас работает не так - есть Jellyseerr, который выглядит почти как Нетфликс, в котором я просто выбираю что хочу посмотреть, нажимаю "скачать", а дальше происходит магия и нужный сериал или фильм появляется в плеере.
Gitea. Я начал работать с VC Code и гитом, хранить там всякие конфиги, стаки контейнеров, автоматизации, очень удобно.
Paperless-ngx - решает проблему бумажного и цифрового хаоса, превращает горы документов в структурированную базу данных с мгновенным поиском.
Firefly III - удобный менеджер финансов, записываю расходы, доходы, смотрю красивые отчеты охуеваю от того во сколько мне обходятся мои хобби.
Vikunja - удобный таск трекер для личных задач, хобби, развития. Работает для меня и жены.
Monica - Я постоянно забываю дни рождения и всякие важные даты друзей. Эта легкая срм помогает мне, как воробушку социофобушку выносить из "оперативной" памяти всякие дни рождения, свадью, имена детей, предпочтения в еде, карьерные успехи друзей и знакомых. Вероятно люди стали думать что я стал очень внимательный к ним.
Еще несколько сервисов в процессе изучения, и их пока описывать не буду. Если вы дочитали до сюда - вы мой герой с завидной концетрацией, буду рад ответить на вопросы если такие есть.
В ближайших планах
Разрбраться с протоколом связи Meshtastic, установить дома стационарную ноду
Перенести все барахло в специальный ящик, сделать кабель менеджмент
Подключить все это к нормальному ИБП (пока проблем с сетью нет - но могут быть)
В дальних планах
Купить для АИ стека машинку PGX 30KL - MT - 1 x GB10 Grace Blackwell Superchip - RAM 128 GB, попробовать поиграться с большими моделями.
В предыдущем посте внимательный @Machaeon, заметил у меня на фотке Coral USB Accelerator и спросил, как он. К тому времени я еще не успел его настроить, поэтому пообещал написать пост как разберусь. Не то что бы я полностью разобрался, но постараюсь в этой статье рассказать
- что такое система домашнего видеонаблюдения, какие они бывают - как установить Frigate и подключить к нему Coral TPU - как настроить распознавание лиц - какие ошибки я сделал в процессе настройки своей системы видеонаблюдения
Первые ошибки. Когда мы говорим про умный дом, часто имеем в виду лампочки, розетки или голосовых ассистентов. Но на самом деле важнейший элемент - это видеонаблюдение и аналитика. Первым моим решением (ошибочным) было купить камеру Aqara Camera E1.
Большую часть времени устройство провело в таком виде.
Минусы aqara стали мне очевидны только после покупки: - нет возможности подключения по кабелю (видеосигнал через вайфай не самое надежное решение) - нет нормальной интеграции с Home Assistant так как RTSP поток на ней не доступен (на самом деле после пары часов плясок с бубном и чатом гпт через go2rtc/HomeBridge мне удалось заставить HA увидеть камеру, но это был опыт который я не могу рекомендовать начинающим) - большинство интересных функций вроде обнаружения лиц, животных, пожара, машины, посылки - убрано в подписку HomeGuardian за 9.99 евро в месяц.
Мне хотелось другого:
хранить записи локально, на NAS (зря его что ли покупал)
получать уведомления о реальном движении, а не «порхающей мухи»
интегрировать камеры в Home Assistant
определять не просто событие "человек в комнате" - но и распознавать этого человека.
Решением стал связанный тандем: Frigate + Coral TPU.
Frigate — это NVR (система записи и аналитики IP-камер) с открытым исходным кодом, созданная специально под Home Assistant.
Основные возможности:
- подключение камер по RTSP,
- детекция объектов (люди, машины, животные),
- хранение записей только по событиям,
- интеграция через MQTT и Home Assistant API,
- поддержка аппаратных ускорителей (Coral TPU, GPU).
Coral Edge TPU — это аппаратный ускоритель от Google, оптимизированный для TensorFlow Lite моделей.
Выполняет до 4 трлн операций в секунду при очень низком энергопотреблении.
Да, вместо Frigate можно использовать MotionEye, Shinobi или Blue Iris, но в первом нет АИ, второй показался сложным в настройке, а третий вариант платновый и под винду - а я же энтузиаст докера уже третий месяц.
Вместо Coral TPU я тоже мог использовать аналоги - подключить AORUS Gaming Box RTX 3080 или вообще использовать CPU. Но Видеокарта жрет существенно больше энергии и шумит, а проц не очень тянет четыре камеры - а я хочу со временем сделать еще парочку - на парковку и с балкона.
Установка.
Сам процесс установки оказался достаточно простым. Я напомню что использую виртуализатор Proxmox VE.
Создаем новую виртуалку. Я где то читал что CORAL может не работать на 13 дебиане и советы ставить на 12 - но забегая вперед скажу что это не правда, все работает хорошо. Если совсем лень, то можно воспользоваться готовым комьюнити скриптом по разворачиванию LXC пакета с Frigate, но мне показалось что проще пробрасывать физические устройства в виртуалку, а не в контейнер, поэтому я ставил фригейт сам.
Начинаем с докера. Потом в Проксмоксе прокидываем наш usb порт с коралом. Я советую прокинуть именно весь порт, а не отдельное устройство, меньше ебли с тем что виртуалка не увидит свисток.
не обращаем внимание на надпись "не подключено", это из за того что прокинут весь порт.
Командой lsusb проверяем что корал виден, создаем каталоги под фригейт, монтируем NAS каталоги для хранения видео, создаем docker-compose.yml
Почти готово, вы великолепны. Осталось добавить интеграцию фригейт. Идем в HACS (надеюсь у вас он уже установлен!), затем подключить ее в разделе Настройки-Интеграции.
Отлично, ваши камеры видны в frigate и проброшены в HA по желанию.
Обучение.
После того как все установлено и настроено - настало время самого интересного - настройка распознавания. Нам же нужно что бы камеры не просто видели какого то человека - а понимали что это за человек (и передавали это дальше в автоматизацию, чего я правда еще не сделал).
Идем в Настройки - Обогащение (Settings - Enrichments) 2. Добавляем лицо через Add Face (лучше скинуть селфи фронталки с телефона, можно парочку). 3. Активно ходим вокруг камеры, что бы она детектила лицо. 4. Затем заходите в Face Library - Train и вручную размечаете фотографии. 5. Указываем в конфиге frigate.yml настройки точности. Тут можно поиграть с вариантами в зависимости от освещенности, типа камеры, размещения. 6. В принципе можно еще поиграть с настройками точности
Мне хватило порядка 100 фотографий в разных ракурсах, что бы в дальнейшем распознавание шло точно.
Google Coral достаточно редкий зверь, мне удалось достать его бушным на ебае только, поэтому прикладываю табличку сравнения - что бы понять чего его можно заменить.
Спасибо что дочитали, надеюсь кому то этот пост поможет избежать тех граблей, что были пройдены мной)
Нейросети, умный дом, видеонаблюдение. Выглядит как набор слов, не так ли?
Оказывается, 4 года назад я начинал рассказывать о первых шагах к умному дому. Произошел небольшой перерыв (да, я ленивая жопа!) и я решил - почему бы не продолжить?
А сегодня я расскажу о том, как имея в распоряжении ПК под домашний сервер и несколько wifi камер сделать действительно "умное" видеонаблюдение.
1. Зачем всё это?
Хотел не просто «запись по движению», а умный видеорегистратор: чтобы определял человека в кадре, отличал кота от коробки, а в идеале ещё и писал текстом, что происходит.
Frigate 0.15 умеет именно это:
определяет объекты нейросетью YOLOv7 → быстро, open-source;
семантический поиск (CLIP) — можно найти «красную машину» за секунду;
через GenAI кидает кадры в LLaVA и получает короткое описание сцены.
Всё крутится локально: никакой утечки видео на чужие сервера и ноль абонплаты.
Главная страница Frigate
А вот и "красная машина" =)
Но не без приколов - по мнению детектора, на видео на 83% кот =)
Камеры: любые с RTSP-потоком (у меня 6 штут Tapo C500)
3. Зачем нужен GPU passthrough?
Отдельно остановлюсь: почему я заморочился с пробросом GPU в VM, а не запустил всё на CPU или, скажем, на TPU (Coral)? Дело в том, что моя задача – тянуть обнаружение объектов в реальном времени на нескольких камерахи параллельно гонять тяжелую модель для описания. Даже один поток 1080p с современным детектором (YOLOv7) может загрузить CPU на 100%, не говоря уж про генеративную модель с 13 миллиардами параметров (LLaVA 13B) – её на CPU вообще считать не будешь (за минуту никакого описания не дождешься). GPU же позволяет распараллелить эти задачи и выполняет их на порядки быстрее.
Таким образом, GPU passthrough — обязательный шаг, чтобы внутри VM иметь аппаратное ускорение. Он нужен, чтобы Frigate мог использовать CUDA/TensorRT для инференса нейросети, а ffmpeg – аппаратное декодирование/кодирование видео (NVDEC/NVENC). Без GPU моя затея с локальным AI-прислугой просто не взлетела бы.
Настройка прошла относительно спокойно: включил IOMMU в BIOS, в Proxmox добавил устройство hostpci0 (с указанием ID видеокарты), отключил эмулируемую VGA. Ubuntu внутри пришлось снабдить драйверами NVIDIA – после этого карта стала доступна, как если бы она была в обычном PC.
Примечание: в более простых сценариях можно было бы использовать USB-акселератор типа Google Coral TPU – Frigate тоже умеет, но у меня его нет, а вот 3050 просилась в бой. К тому же Coral даёт только обнаружение, а для LLaVA всё равно нужен бы был GPU или очень мощный CPU. Так что выбор очевиден.
Страница событий
4. Docker Compose: поднимаем Frigate и Ollama
Система в VM готова, теперь разворачиваем два основных сервиса в контейнерах: Frigate NVR и Ollama. Оба будут запускаться через Docker Compose — это удобно, чтобы они стартовали вместе и были связаны в одну сеть.
Я установил Docker Engine и docker-compose в Ubuntu (для опытных пользователей это тривиально: несколько команд, либо скрипт установки Docker от официального репозитория). Предполагаю, что читатель уже умеет ставить Docker и Compose, поэтому опущу подробности apt-установки.
Перейдем сразу к Compose-файлу. Вот финальная версия моего docker-compose.yml (@SupportTech, когда будут уже нормальные код-сниппеты?!):
version: "3.9"
services:
frigate:
container_name: frigate
privileged: true # ← проще дать контейнеру весь /dev, чем перечислять /dev/nvidia*
restart: unless-stopped
image: blakeblackshear/frigate:0.15.0-tensorrt # ← нужная сборка с TensorRT под NVIDIA
я использую тег stable-tensorrt. Это сборка под amd64 с поддержкой NVIDIA GPU. В ней уже включены нужные библиотеки CUDA и TensorRT для аппаратного ускорения инференса. Обычный stable образ не умеет работать с TensorRT, имейте в виду.
Привилегированный режим:
privileged: true: я включил для простоты, чтобы контейнер без препонов получил доступ к устройствам хоста.
shm_size: 2048mb:
увеличиваем раздел общей памяти. Frigate хранит там кадры для обнаружения и прочие буферы. По умолчанию Docker даёт 64Мб, но с несколькими камерами в высоком разрешении этого мало. В 0.15 Frigate сам ругается, если /dev/shm маловат. Я поставил 2048 MB – у меня 6 камер, этого достаточно, при необходимости можно больше. Главное, чтобы не было переполнения, иначе Frigate может упасть или терять кадры.
Tmpfs на /tmp/cache:
важный трюк. Frigate использует /tmp/cache для разных временных файлов (например, для отслеживания объектов, кадры для распознавания и т.п.). Монтируя туда tmpfs, мы удерживаем эти операции в RAM, что ускоряет работу и снижает износ диска. Рекомендация из документации, и действительно, нагрузка на диск резко упала после этого (SSD сказал спасибо). Я выделил 1 ГБ; в зависимости от числа камер и их разрешения можно увеличить или уменьшить.
Порты:
8971 – новый веб UI Frigate. Начиная с 0.15, интерфейс доступен только на защищенном (с авторизацией) порту.
8554 – RTSP restream (от встроенного сервиса go2rtc). Через него я могу при желании подключаться VLC/телефоном к камерам через Frigate, не нагружая сами камеры множеством прямых коннектов. Удобно, хотя я пользуюсь в основном веб-интерфейсом.
8555 (tcp и udp) – это порты для WebRTC. Frigate через go2rtc умеет раздавать видеопоток прямо в браузер по WebRTC, минуя RTSP. Это быстрее и экономит трафик, и обходится без плагинов.
Переменные среды:
FRIGATE_RTSP_PASSWORD – я назначил пароль для RTSP, и в конфиге камер могу использовать шаблон ${FRIGATE_RTSP_PASSWORD}. Чтобы случайно не засветить пароли, удобнее вынести их в env. (Frigate поддерживает подстановку env-переменных в config.yml).
YOLO_MODELS: "yolov7-640" – переменная окружения для контейнеров Frigate, предназначенная исключительно для автоматической загрузки (и/или перекомпиляции) моделей YOLO при первом старте.
Ollama:
Использую официальный образ ollama/ollama.
Порт 11434: это дефолтный порт REST API Ollama. Я его открыл наружу, хотя можно было не делать этого, если обращаться к модели только из Frigate. Frigate, работая в той же докер-сети, может достучаться до ollama:11434 без проброса на хост. Но мне для отладки хотелось иногда самому попробовать запросы к Ollama, поэтому порт пробросил.
Volume ollama-data на /root/.ollama: здесь хранятся модели, которые скачивает Ollama. Обязательно делаем volume, иначе при пересоздании контейнера вам придётся опять тянуть десятки гигабайт моделей 😅. С volume скачанные модели останутся. (Модели, кстати, он скачивает из интернета при первом запросе, имейте в виду).
Запустив docker-compose up -d, я проверил:
Frigate успешно стартовал, в логах увидел, что он нашёл GPU (строка [INFO] Nvidia decoder initialized и что-то про TensorRT). Если бы он не увидел GPU, он либо упал бы с ошибкой, либо работал на CPU, что нам не подходит.
Ollama запустился и слушает на 11434 – это можно проверить docker logs ollama или открыв http://<IP_ВМ>:11434 (он должен вернуть приветственное сообщение типа Ollama vX.X API).
Оба сервиса работают, но пока Frigate “пустой” – без конфигурации, а Ollama не знает, какую модель мы от него хотим. Пора заполнить конфиг Frigate и подготовить нейросети.
Пример описания события нейросетью
5. Настройка Frigate (config.yml)
Конфигурационный файл config.yml задаёт параметры Frigate: какие камеры подключать, как выполнять детекцию и пр. Рассмотрим минимальный рабочий конфиг под нашу задачу – одна камера с детекцией на GPU (YOLOv7-640):
detectors – указываем, что используем детектор типа tensorrt (Nvidia TensorRT) под именем nvidia. Параметр device: 0 означает использовать первый GPU (если у вас несколько видеокарт, можно указать соответствующий индекс). Frigate автоматически подхватит CUDA/TensorRT, если контейнер запущен правильно.
model – путь и параметры модели. Мы нацелились на YOLOv7-640, поэтому путь указывает на файл yolov7-640.trt (который сгенерируется в директории /config/model_cache/tensorrt внутри контейнера). Параметры width/height должны совпадать с размером сети (640x640). Остальные настройки (input_tensor, pixel_format) стандартны для YOLO моделей (формат входного тензора nchw и rgb). Если вы решите использовать другую модель (например, yolov7-tiny-416), не забудьте здесь поменять пути и размеры.
cameras – секция с описанием камер. В примере добавлена одна камера cam1.
ffmpeg.inputs – список потоков для этой камеры. Указан RTSP URL основного потока (stream1). У большинства IP-камер RTSP-поток формата rtsp://<user>:<password>@<ip>:554/<название_потока>. В некоторых камерах основной поток – H.264, в других – H.265. В нашем примере указан пресет preset-nvidia-h264 для аппаратного декодирования H.264 на GPU Nvidia. Если ваша камера выдает H.265, замените на preset-nvidia-h265 (RTX 3050 аппаратно поддерживает и тот, и другой кодек). Роли detect и record означают, что мы используем один и тот же поток и для детекции объектов, и для записи. (При наличии у камеры второго, субпотока низкого разрешения, можно отправлять его на детектор, а основной – только на запись. Для простоты здесь оба роли на одном потоке.)
detect – параметры детекции для этой камеры. Важно указать реальное разрешение видеопотока (width и height), чтобы Frigate знал, какого размера кадры ожидать. Параметр fps ограничивает скорость анализа – 5 кадров/с обычно достаточно для уверенного определения движения и объектов, не тратя лишние ресурсы. Если поставить слишком высокий fps, будете зря грузить и GPU, и CPU (обработка видео).
record – включает запись видео. В данном случае настроена непрерывная запись только при движении (так работает Frigate по умолчанию при включенном режиме recordings с events): при обнаружении события он сохранит сегмент видео, начиная за pre_capture секунд до события и заканчивая через post_capture секунд после. Мы сохраняем записи 7 дней (параметр retain.days). Длительность и поведение записей можно гибко менять, но выходят за рамки данной статьи.
snapshots – включает сохранение снимков с обнаруженными объектами. Frigate сделает и сохранит кадр с пометкой (рамкой) каждого события. Также храним 7 дней для примера.
После прописывания конфигурации, сохраняем config.yml и перезапускаем контейнер Frigate (docker compose restart frigate). Зайдите в веб-интерфейс (порт 5000) – там должна появиться ваша камера. Если всё сделано правильно, поток видео будет идти плавно, а при появлении в кадре людей, машин или других объектов – они выделятся рамками с подписью класса и процентом уверенности. Также в разделе Events начнут появляться записи с событиями движения.
💡 Примечание: По умолчанию Frigate отслеживает только объект person (человек). Чтобы детектировать другие типы (авто, питомцев и пр.), нужно явно добавить их в настройках. В нашем примере мы сразу использовали модель, обученную на 80 объектах COCO, поэтому рекомендуется дополнительно указать в конфиге список объектов, которые вам интересны, например:
objects:
track:
- person
- car
- cat - dog
Иначе Frigate может игнорировать всё, кроме людей.
6. Первые грабли: ошибки и уроки
Как ни старайся, а без косяков настройка не обходится. Расскажу о своих “граблях” – возможно, сберегу чьи-то нервы:
Грабли №1: Забытый драйвер NVIDIA. Я так увлёкся пробросом GPU, что при первом запуске контейнеров увидел в логах Frigate: "no CUDA capable device found". Оказалось, внутри Ubuntu я не доустановил драйвер (думал, в образе Frigate уже всё есть – но образ-то видит только /dev/nvidia*, а драйвер – это модуль ядра!). Пришлось экстренно ставить apt install nvidia-headless-525 и перезапускать VM. После этого nvidia-smi появился, и Frigate успешно подхватил GPU. Вывод: не забываем про драйвер в гостевой ОС.
Грабли №2: Неправильный образ Frigate. Сначала по привычке потянул blakeblackshear/frigate:stable (обычный). Он, конечно, запустился, но тут же завалил CPU – ведь модель детекции работала на процессоре. Я-то ждал, что GPU поможет, ан нет – нужно же tensorrt версия! Ошибка быстро нашлась, контейнер переключил на stable-tensorrt, но потерял час на скачивание нового образа (~6 ГБ). Вывод: используйте правильный тег образа для вашего ускорителя.
Грабли №3: Мало памяти. Я сперва дал VM только 4 ГБ RAM, думал “для Linux хватит”. И правда, Frigate себе брал ~500 МБ, ffmpeg чуть, да система ~1Гб – норм. Но стоило включить semantic_search, как память улетела в своп. Модель CLIP (даже small) + база данных + кэш – жрали около 6 ГБ. Добавил до 12 ГБ – стало лучше, но при старте LLaVA всё равно подпёрло. В итоге 16 ГБ — впритык, но хватает (пиково видел 12 ГБ usage при описании сразу нескольких кадров). Вывод: не жалейте RAM, лучше с запасом. Если у вас 8 ГБ или меньше – или не включайте эти фичи, или готовьтесь к тормозам.
Грабли №4: Долгая генерация описаний. Первые попытки с LLaVA 13B иногда не давали результата: событие проходит, а описания нет. Оказалось, таймаут 60 сек и конкурентные запросы. Если, например, 3 события одновременно, Frigate кидает 3 запроса, а Ollama (по умолчанию) обрабатывает их последовательно. В результате последний может не уложиться в минуту и Frigate его бросит. Решение простое: я ограничил частоту детекций (FPS 5, плюс задержка между детектами по настройкам Frigate), и в реальной жизни редко более 1 объекта сразу появляется. Так что проблема минимизировалась. Вывод: не перегружайте GenAI запросами, это не real-time штука.
Конечно, были еще мелочи, но перечислил основные, над которыми повозился. К счастью, сообщество Frigate активное: многие вопросы находил на Github Discussions и Reddit. Стоило погуглить ошибку – почти всегда кто-то уже спрашивал, и либо автор (Blake Blackshear), либо другие пользователи помогали с советом.
Краткий чек-лист по настройке для Лиги Лени
Ниже я свёл основные шаги и настройки в короткий список. Если решитесь повторить подобное у себя, пройдитесь по чек-листу – всё ли учтено:
Proxmox и железо: убедиться, что включен IOMMU/VT-d в BIOS. Прописать в /etc/default/grub нужные опции (intel_iommu=on или amd_iommu=on). Добавить видеокарту в vfio (в Proxmox /etc/modprobe.d/blacklist.conf добавить blacklist nouveau и blacklist nvidia, а в /etc/modules загрузить модули vfio). Перезапустить хост.
Создание VM: UEFI BIOS (OVMF), Machine type q35, vga: none, добавить устройство PCIe (GPU и связанный с ним аудиоконтроллер). Дать достаточное RAM (не меньше 8 ГБ, лучше 16). CPU type host, cores – по потребности. Диск – побольше под видео или подмонтировать сетевой/NAS.
Установка гостевой ОС: Поставить Ubuntu 22.04 (или Debian 12) внутри VM. Обновить систему. Установить NVIDIA драйвер (рекомендуемый проприетарный). Проверить nvidia-smi.
Подготовка Docker Compose: Создать docker-compose.yml с двумя сервисами – frigate и ollama (см. пример выше). Убедиться, что указан правильный image для Frigate (stable-tensorrt) и runtime: nvidia для обоих. Настроить volume и порты. Добавить tmpfs и shm.
Конфиг Frigate: Написать config.yml. Обязательные секции: detectors (указать type: tensorrt), model (путь к файлу .trt модели и размеры), cameras (вставить RTSP ссылки, роли, параметры детектора, объекты, маски и т.д. как нужно). При необходимости – mqtt (если использовать MQTT), detect общие настройки (например, максимальное количество одновременно отслеживаемых объектов, я не менял, по дефолту ок).
Запуск Compose: docker-compose up -d. Проверить логи: docker logs frigate -f – должны появиться сообщения о старте, подключении камер, инициализации детектора без ошибок. docker logs ollama -f – убедиться, что API запущен (может висеть в ожидании запросов).
Первый тест: Зайти в веб-интерфейс Frigate – http://<IP_VM>:8971. Создать пользователя/пароль (первый запуск). Увидеть камеры (должны отображаться превью потоков). Помахать рукой в зону видимости – убедиться, что событие фиксируется, появляется bounding box "person" на видео.
Проверка AI-описаний: Открыть вкладку Explore в UI Frigate. Найти последнее событие с объектом, посмотреть – появляется ли под ним текстовое описание. Если нет – проверить docker logs frigate на наличие ошибок GenAI (возможно, проблема с подключением к Ollama).
Оптимизация: Поправить пороги, маски, fps, если слишком много/мало срабатываний. Оценить загрузку: nvidia-smi – посмотреть, сколько памяти занято, нагрузка (Decoder, Encoder, Compute). docker stats – нет ли контейнеров с зашкаливающим CPU (в идеале CPU низкий, GPU берёт нагрузку).
Оповещения: Настроить желаемый способ уведомлений – MQTT, Home Assistant, Telegram-бот или просто email. Для Telegram: создать бот через BotFather, получить токен, написать скрипт (либо использовать готовые интеграции, например, Home Assistant Notify).
Резерв: Настроить автозапуск Compose при перезагрузке (можно через restart: unless-stopped уже сделано, но сам Docker должен стартовать; на Ubuntu это по умолчанию). Резервное копирование конфигов и, возможно, базы Frigate (файл frigate.db – содержит события и embeddings).
Мониторинг: Желательно настроить мониторинг дискового пространства (чтобы видеоархив не переполнил диск). Frigate умеет удалять по retain настройкам, но на всякий случай.
Обновление: Следить за апдейтами Frigate. Например, подписаться на релизы в GitHub или форум. Обновлять образ и конфиг по необходимости.
Фух, внушительный список. Но когда делаешь по шагам, всё не так страшно.
Выводы
Проект удался: я получил умную систему видеонаблюдения, которая работает полностью локально и не уступает во многом облачным аналогам. Frigate 0.15 приятно удивил функционалом: поиск по описанию действительно находит нужные кадры, и больше не нужно пролистывать часы записи в надежде увидеть, когда приходил почтальон. Достаточно вбить пару слов.
Конечно, за всё платим ресурсами: RTX 3050 не скучает – где-то 50–60% её вычислительной мощи постоянно в деле (детекция + AI). Электричество тоже тратится, но я посчитал: в простой мой сервер потребляет ~50 Вт, под нагрузкой ~120 Вт. За возможности, которые я получил, меня это устраивает.
Зато никакой абонентской платы сервисам и никаких проблем с приватностью. Все видеоданные остаются дома, в зашифрованном хранилище. Да и просто это было весело – настроить кучу технологий воедино: Docker, AI, FFmpeg, MQTT, etc.
Что дальше? Буду играться с более продвинутыми моделями (может попробую YOLO-NAS – хвалят за точность). Также подумываю прикрутить распознавание лиц (есть же локальные модели типа InsightFace), но это уже другая история. Frigate пока распознаёт только тип объектов, а не кто именно. Но с помощью дополнений и Home Assistant можно и это реализовать, если очень надо.
Буду благодарен за ваше участие, и планирую писать ещё =)
Например, в следующей статье могу рассказать об автоматическом управлении котлом отопления через Home Assistant и Node-Red.
Картинка для затравки:
P.S.
Т.к. на пикабу до сих пор не прикрутили нормальных код-сниппетов, прикрепляю репозиторий c конфигами из статьи.
Будут вопросы - задавайте, отвечу по мере возможности =)
Сегодня, 01.01.2021 на момент написания поста я обнаружил вот это:
Google заблокировал расширение для своего браузера, а сам frigate удалил из своего магазина расширений (страница на них выдает ошибку 404 - Не удалось найти запрошенный URL на этом сервере), а сам я не могу посещать ранее интересные мне сайты.
Мне всё равно какие на это были причины, но сам факт ущемления моего права на перемещение в сети Интернет мне не понравился.
Спасибо товарищу betomorrow за предоставленный рабочий способ обойти ограничение от Google и заново задействовать это божественное расширение!
Следующая инструкция это пересказ его комментария и несет характер более структурированного описания способа обхода (а по сути, я пишу эту инструкцию для себя, что бы сохранить её тут, на Пикабу).
2. Скачается frigateXX.crx файл. Открой его обычным win-rar (или аналогичным) архиватором, а затем полученные файл распакуй в любую папку.
3. Иди в управление расширениями и включи режим разработчика.
4. На той же странице вверху слева нажми "Загрузить распакованное расширение". Найди папку, в которой находятся файлы расширения и выбери её.
Конец основной части. Frigate установлен и в большинстве случаев будет работать. Однако, рекомендую сделать ещё и следующие пункты.
5. Frigate появится на странице с расширениями. Выбери его в панели вверху справа, нажав на значок паззла > три точки > параметры.
6. Откроется окно настройки расширения. Добавь список, напиши любое имя, затем, открой этот список, кликнув по нему.
7. Добавь интересующий себя домен. Домен следует добавлять по представленной инструкции, что бы включить в прокси лист поддомены сайта. Это важно, иначе могут не грузится всякие картинки, видео и т.д.
8. Перейди на нужный сайт, который ранее не был доступен. Ты увидишь вот такую иконку вверху справа. Это означает успех! Выбери стрелочку (1) что бы свернуть в дальнейшем на сайте это окно и флаг страны (2) что бы сменить прокси сервер (иногда это важно, если сервер медленно отвечает, на нем так же заблокирован сайт или на нём бесконечная капча).
Возможно, Frigate протупит минуту другую перед запуском и будет писать "wait". Подожди эту минуту и он заработает.
Заключение: никто и никогда не остановит меня в посещении тех сайтов, которых я хочу! А после этого поста - и вас тоже.
Сегодня утром, обнаружил вот такое в своем Google Chrome. Расширение выключено и не может быть включено.
Судя по тому, что попытка открыть страницу с расширением отобразила 404 ошибку, так у всех.
Яндекс упоминал, что передал информацию не только лаборатории Касперского, но и в Google. Похоже, что Google проверили и подтвердили, что расширение может использоваться в преступных целях...
Upd: Пробовал переходить по ссылке со страницы расширения в расширениях и через поиск гугла. Так же поиск по расширениям гугла по запросу frigate выдал ничего.
Кто на чего перешел с него?
И да, раз уж так получилось, что 31.12
С наступающим всех. Пусть в 21м году у вас все получится так, как надо, а не так, как обычно.
Upd:
С наступившим всех! Спасибо всем за лайки и комментарии. Обязательно все прочитаю, но завтра, сегодня несколько не до того =)