MYVMS v2 · Plugin dev

Viết plugin AI mới

Stateless async pattern · Auto register · Hot-reload qua restart worker.

1. Tạo file plugin

/root/MYVMS-v2/worker/app/plugins/loitering.py:

from datetime import datetime, timezone
from .base import Detection, Camera, Event

# state-free helper. Lifetime accounting nên đẩy về redis.
async def loitering_plugin(dets: list[Detection], cam: Camera) -> Event | None:
    persons = [d for d in dets if d.label == "person" and d.score > 0.5]
    if len(persons) < 1:
        return None
    # ví dụ: nếu cùng track_id xuất hiện > 30s thì raise event (cần redis lookup).
    return Event(
        camera_id=cam.id,
        type="loitering",
        confidence=max(p.score for p in persons),
        payload={"count": len(persons), "boxes": [p.box for p in persons]},
        ts=datetime.now(timezone.utc),
    )

2. Đăng ký vào registry

worker/app/plugins/__init__.py:

from .violence import violence_plugin
from .vehicle  import vehicle_plugin
from .person   import person_plugin
from .loitering import loitering_plugin   # ← THÊM

PLUGINS = {
    "violence":   violence_plugin,
    "vehicle":    vehicle_plugin,
    "person":     person_plugin,
    "loitering":  loitering_plugin,        # ← THÊM
}

3. Cho phép trong tenant + camera

# Mở feature ở mức tenant
docker compose exec postgres psql -U vms -d vms -c \
  "UPDATE tenants SET features = features || '[\"loitering\"]'::jsonb WHERE id='default';"

# Bật cho camera cụ thể
curl -X PATCH https://vmsclient.vnso.vn/v2/api/cameras/cam-1 \
  -H 'content-type: application/json' \
  -d '{"features":["person","loitering"]}'

4. Triển khai

cd /root/MYVMS-v2
docker compose build worker
docker compose up -d worker
docker compose logs -f worker | grep loitering

5. Test bằng redis publish (giả lập)

docker compose exec redis redis-cli PUBLISH events:loitering \
  '{"camera_id":"cam-1","type":"loitering","confidence":0.9,"payload":{"count":2}}'

# Verify
curl -s 'https://vmsclient.vnso.vn/v2/api/events?type=loitering&limit=5' | jq

Convention