206 lines
8.4 KiB
Python
206 lines
8.4 KiB
Python
"""Settings schema registry.
|
|
|
|
The single source of truth for which runtime settings exist. The settings panel
|
|
is rendered from this list, so adding a new integration/provider only requires
|
|
adding entries here — no frontend or model changes.
|
|
|
|
Field types: ``string``, ``secret``, ``boolean``, ``choice``, ``number``.
|
|
|
|
Optional keys:
|
|
- ``depends_on``: ``{"other.key": ["value_a", "value_b"]}`` — field is shown
|
|
only when every referenced setting currently holds one of the listed values.
|
|
- ``options``: list of strings or ``{"value", "label"}`` dicts (for ``choice``).
|
|
"""
|
|
from apps.live_monitoring.protocols import (
|
|
DEFAULT_PROTOCOL,
|
|
PROTOCOL_KEYS,
|
|
STREAM_PROTOCOLS,
|
|
protocol_choice_options,
|
|
)
|
|
|
|
|
|
def _camera_settings() -> list:
|
|
"""Build Live Monitoring settings from the protocol catalog.
|
|
|
|
Shared defaults always appear. Protocol-specific fields use ``depends_on``
|
|
so the settings panel stays dynamic as standards are added to the catalog.
|
|
"""
|
|
entries = [
|
|
{
|
|
"key": "camera.enabled",
|
|
"label": "Enable live camera monitoring",
|
|
"type": "boolean",
|
|
"category": "Live Monitoring",
|
|
"default": True,
|
|
},
|
|
{
|
|
"key": "camera.default_protocol",
|
|
"label": "Default stream protocol",
|
|
"type": "choice",
|
|
"category": "Live Monitoring",
|
|
"options": protocol_choice_options(),
|
|
"default": DEFAULT_PROTOCOL,
|
|
},
|
|
{
|
|
"key": "camera.stream_ttl_seconds",
|
|
"label": "Stream access token TTL (seconds)",
|
|
"type": "number",
|
|
"category": "Live Monitoring",
|
|
"default": 3600,
|
|
},
|
|
{
|
|
"key": "camera.prefer_secure",
|
|
"label": "Prefer secure schemes (HTTPS / RTSPS / RTMPS)",
|
|
"type": "boolean",
|
|
"category": "Live Monitoring",
|
|
"default": True,
|
|
},
|
|
{
|
|
"key": "camera.media_gateway_url",
|
|
"label": "Media gateway base URL",
|
|
"type": "string",
|
|
"category": "Live Monitoring",
|
|
"default": "",
|
|
"placeholder": "https://media.example.com",
|
|
},
|
|
{
|
|
"key": "camera.media_gateway_path_template",
|
|
"label": "Gateway path template",
|
|
"type": "string",
|
|
"category": "Live Monitoring",
|
|
"default": "{camera_id}/index.m3u8",
|
|
"placeholder": "{camera_id}/index.m3u8",
|
|
},
|
|
{
|
|
"key": "camera.default_username",
|
|
"label": "Default camera username",
|
|
"type": "string",
|
|
"category": "Live Monitoring",
|
|
"default": "",
|
|
},
|
|
{
|
|
"key": "camera.default_password",
|
|
"label": "Default camera password",
|
|
"type": "secret",
|
|
"category": "Live Monitoring",
|
|
"default": "",
|
|
},
|
|
{
|
|
"key": "camera.default_auth_method",
|
|
"label": "Default stream auth method",
|
|
"type": "choice",
|
|
"category": "Live Monitoring",
|
|
"options": [
|
|
{"value": "none", "label": "None"},
|
|
{"value": "basic", "label": "HTTP Basic"},
|
|
{"value": "digest", "label": "HTTP Digest"},
|
|
{"value": "bearer", "label": "Bearer token"},
|
|
{"value": "query_token", "label": "Query token"},
|
|
{"value": "ws_username_token", "label": "WS-UsernameToken (ONVIF)"},
|
|
{"value": "passphrase", "label": "Passphrase (SRT)"},
|
|
],
|
|
"default": "none",
|
|
},
|
|
]
|
|
|
|
# Protocol-specific defaults — visibility follows camera.default_protocol.
|
|
for key in PROTOCOL_KEYS:
|
|
meta = STREAM_PROTOCOLS[key]
|
|
dep = {"camera.default_protocol": [key]}
|
|
entries.append(
|
|
{
|
|
"key": f"camera.{key}.default_port",
|
|
"label": f"{meta['label']} — default port",
|
|
"type": "number",
|
|
"category": "Live Monitoring",
|
|
"default": meta["default_port"],
|
|
"depends_on": dep,
|
|
}
|
|
)
|
|
entries.append(
|
|
{
|
|
"key": f"camera.{key}.default_path",
|
|
"label": f"{meta['label']} — default path",
|
|
"type": "string",
|
|
"category": "Live Monitoring",
|
|
"default": meta["default_path"],
|
|
"placeholder": meta["default_path"] or "/",
|
|
"depends_on": dep,
|
|
}
|
|
)
|
|
if meta.get("transports"):
|
|
entries.append(
|
|
{
|
|
"key": f"camera.{key}.transport",
|
|
"label": f"{meta['label']} — transport",
|
|
"type": "choice",
|
|
"category": "Live Monitoring",
|
|
"options": list(meta["transports"]),
|
|
"default": meta["transports"][0],
|
|
"depends_on": dep,
|
|
}
|
|
)
|
|
|
|
# WebRTC needs ICE servers when selected.
|
|
entries.append(
|
|
{
|
|
"key": "camera.webrtc.ice_servers",
|
|
"label": "WebRTC ICE servers (JSON)",
|
|
"type": "string",
|
|
"category": "Live Monitoring",
|
|
"default": '[{"urls":"stun:stun.l.google.com:19302"}]',
|
|
"placeholder": '[{"urls":"stun:stun.l.google.com:19302"}]',
|
|
"depends_on": {"camera.default_protocol": ["webrtc"]},
|
|
}
|
|
)
|
|
# ONVIF profile token when ONVIF is the default.
|
|
entries.append(
|
|
{
|
|
"key": "camera.onvif.profile_token",
|
|
"label": "ONVIF media profile token",
|
|
"type": "string",
|
|
"category": "Live Monitoring",
|
|
"default": "",
|
|
"placeholder": "Profile_1",
|
|
"depends_on": {"camera.default_protocol": ["onvif"]},
|
|
}
|
|
)
|
|
# SRT passphrase (secret) when SRT is selected.
|
|
entries.append(
|
|
{
|
|
"key": "camera.srt.passphrase",
|
|
"label": "SRT passphrase",
|
|
"type": "secret",
|
|
"category": "Live Monitoring",
|
|
"default": "",
|
|
"depends_on": {"camera.default_protocol": ["srt"]},
|
|
}
|
|
)
|
|
return entries
|
|
|
|
|
|
SETTINGS_SCHEMA = [
|
|
# --- Odoo integration ---
|
|
{"key": "odoo.enabled", "label": "Enable Odoo integration", "type": "boolean", "category": "Odoo", "default": False},
|
|
{"key": "odoo.url", "label": "Odoo URL", "type": "string", "category": "Odoo", "default": "", "placeholder": "https://odoo.example.com"},
|
|
{"key": "odoo.database", "label": "Database", "type": "string", "category": "Odoo", "default": ""},
|
|
{"key": "odoo.username", "label": "Username", "type": "string", "category": "Odoo", "default": ""},
|
|
{"key": "odoo.auth_method", "label": "Auth method", "type": "choice", "category": "Odoo", "options": ["password", "api_key"], "default": "password"},
|
|
{"key": "odoo.password", "label": "Password", "type": "secret", "category": "Odoo", "default": ""},
|
|
{"key": "odoo.api_key", "label": "API key", "type": "secret", "category": "Odoo", "default": ""},
|
|
# --- SMS provider ---
|
|
{"key": "sms.provider", "label": "SMS provider", "type": "choice", "category": "SMS", "options": ["mock", "http"], "default": "mock"},
|
|
{"key": "sms.endpoint", "label": "HTTP endpoint", "type": "string", "category": "SMS", "default": "", "placeholder": "https://sms.provider.example/api/send"},
|
|
{"key": "sms.api_key", "label": "API key", "type": "secret", "category": "SMS", "default": ""},
|
|
{"key": "sms.sender", "label": "Sender number", "type": "string", "category": "SMS", "default": ""},
|
|
# --- Reservation schedule (dynamic slot generation) ---
|
|
{"key": "reservation.working_hours_start", "label": "Working hours start", "type": "string", "category": "Reservation", "default": "08:00", "placeholder": "HH:MM"},
|
|
{"key": "reservation.working_hours_end", "label": "Working hours end", "type": "string", "category": "Reservation", "default": "17:00", "placeholder": "HH:MM"},
|
|
{"key": "reservation.slot_duration_minutes", "label": "Slot duration (minutes)", "type": "number", "category": "Reservation", "default": 30},
|
|
{"key": "reservation.default_capacity", "label": "Default capacity per slot", "type": "number", "category": "Reservation", "default": 2},
|
|
# --- Live camera monitoring (protocol catalog driven) ---
|
|
*_camera_settings(),
|
|
]
|
|
|
|
SCHEMA_BY_KEY = {entry["key"]: entry for entry in SETTINGS_SCHEMA}
|