636b70b64c
Phase 4a — control plane через ZMQ REP socket с JSON-командами.
Позволяет операторам менять text overlay'и runtime'ом без рестарта.
Live-validated: команды set_text label-parking → "⚠ ВНИМАНИЕ ⚠"
и set_text label-gate → "Машина у ворот" отрабатывают, текст
обновляется в потоке RTSP без перерывов.
Phase 4b — MQTT health publisher через libmosquitto. Каждые 10с в
composer/<instance>/health публикуется JSON {active,stale,dead,total,
uptime_s} с retain=true. Опционально публикуется HA MQTT discovery
config — четыре сенсора (active/stale/dead/total) появляются в HA
автоматически с expire_after=30s.
Содержимое:
- include/cuframes_composer/overlay.h — cfc_overlay_set_id/get_id/get_type
для lookup'а через control plane.
- include/cuframes_composer/composer.h — cfc_composer_find_overlay(id).
- include/cuframes_composer/control.h — cfc_control_config_t (endpoint +
composer + cuda_ctx для text rebuild в worker thread).
- src/control.c — ZMQ REP socket в фоновом потоке + zmq_poll с 200мс
timeout'ом для проверки stop_flag. JSON-диспатчер для команд ping /
health / set_text / set_visible / list_overlays. cuCtxSetCurrent
на старте worker'а — без этого update_text валится на cuMemAlloc.
- include/cuframes_composer/health.h — cfc_health_config_t (host/port/
user/pass + topic_prefix/instance + interval + publish_discovery).
- src/health.c — mosquitto_connect_async + loop_start + background
thread с publish health каждые N секунд + один разовый publish_discovery
для HA.
- examples/grid_record — флаги --control tcp://0.0.0.0:5599,
--mqtt host[:port], --mqtt-instance NAME, --mqtt-user/--mqtt-pass.
Для text overlay'ев — prefix "id=NAME:" в --text задаёт control-plane ID.
CMakeLists.txt — find_library(zmq), find_library(json-c),
find_library(mosquitto) + linkage всех трёх.
Production TODO: создать отдельного MQTT user'а для composer'а вместо
переиспользования frigate creds (используется только в smoke).
57 lines
2.2 KiB
C
57 lines
2.2 KiB
C
/* cuframes-composer — control plane через ZMQ + JSON.
|
||
*
|
||
* Слушает JSON-команды на ZMQ REP socket, диспатчит их в composer/overlay.
|
||
* Используется операторами для:
|
||
* - изменения text overlay'я live ("NO SIGNAL" → "RECORDING")
|
||
* - toggle visible/alpha без рестарта
|
||
* - health-репортов (active/stale/dead) для observability и автоматики
|
||
*
|
||
* Протокол:
|
||
* Запрос: JSON-объект {"cmd": "<команда>", ...}
|
||
* Ответ: {"ok": true, ...} либо {"error": "<сообщение>"}
|
||
*
|
||
* Команды Phase 4a:
|
||
* {"cmd": "ping"} → {"ok":true,"pong":1}
|
||
* {"cmd": "health"} → {"ok":true,"active":N,"stale":M,"dead":K}
|
||
* {"cmd": "list_overlays"} → {"ok":true,"overlays":[{"id":"...","type":N},...]}
|
||
* {"cmd": "set_text", "id": "...",
|
||
* "text": "...", "r":255,"g":255,"b":255,"visible":1}
|
||
* → {"ok":true}
|
||
* {"cmd": "set_visible", "id": "...",
|
||
* "visible": 0|1} → {"ok":true}
|
||
*
|
||
* Сервер работает в фоновом потоке. REP socket — блокирующий, но мы используем
|
||
* zmq_poll с таймаутом для проверки stop_flag'а.
|
||
*
|
||
* Лицензия: LGPL-2.1+
|
||
*/
|
||
|
||
#ifndef CUFRAMES_COMPOSER_CONTROL_H
|
||
#define CUFRAMES_COMPOSER_CONTROL_H
|
||
|
||
#include "composer.h"
|
||
|
||
#ifdef __cplusplus
|
||
extern "C" {
|
||
#endif
|
||
|
||
typedef struct cfc_control_config {
|
||
const char *bind_endpoint; /* "tcp://0.0.0.0:5599" или "ipc:///run/composer.sock" */
|
||
cfc_composer_t *composer; /* для health-запросов и lookup overlay'ев */
|
||
CUcontext cuda_ctx; /* push'нется в control thread (для cuMemAlloc в text rebuild) */
|
||
} cfc_control_config_t;
|
||
|
||
typedef struct cfc_control cfc_control_t;
|
||
|
||
/* Создать control plane сервер и запустить background thread. */
|
||
int cfc_control_create(const cfc_control_config_t *cfg, cfc_control_t **out);
|
||
|
||
/* Остановить и освободить. */
|
||
int cfc_control_destroy(cfc_control_t *ctl);
|
||
|
||
#ifdef __cplusplus
|
||
}
|
||
#endif
|
||
|
||
#endif /* CUFRAMES_COMPOSER_CONTROL_H */
|