### Start Local Development Server Source: https://github.com/roflcoopter/viseron/blob/dev/docs/README.md Starts a local development server for live preview. Changes are reflected without a server restart. ```bash $ yarn start ``` -------------------------------- ### Start Local Development Server Source: https://github.com/roflcoopter/viseron/blob/dev/docs/docs/developers/documentation.mdx Run this command from the `docs` directory to start a local server for viewing documentation as you type. The server runs on `http://localhost:3000`. ```shell npm run start ``` -------------------------------- ### Fancy Component Event Listener Setup Source: https://github.com/roflcoopter/viseron/blob/dev/docs/docs/developers/backend/vis_object.mdx Example of setting up an event listener within a Viseron component. It's crucial to store the unsubscribe callable and use it during component unload. ```python from viseron.const import EVENT_STATE_CHANGED from viseron.events import Event class FancyComponent: """Fancy component.""" def __init__(self, vis: Viseron) -> None: self._event_listeners = [] self._event_listeners.append( vis.listen_event(EVENT_STATE_CHANGED, self._on_state_changed) ) def _on_state_changed(self, event: Event) -> None: """Handle a state-changed event.""" state_data = event.data # ... do something with state_data def unload(self) -> None: """Clean up listeners.""" for unsubscribe in self._event_listeners: unsubscribe() self._event_listeners.clear() ``` -------------------------------- ### Minimal Viseron Configuration with FFmpeg and Darknet Source: https://context7.com/roflcoopter/viseron/llms.txt Example `config.yaml` for a minimal Viseron setup. Enables FFmpeg for a camera stream and Darknet for object detection. Sensitive values should be stored in `secrets.yaml`. ```yaml # /config/config.yaml — minimal example: FFmpeg camera + Darknet object detection ffmpeg: camera: camera_one: # camera identifier (alphanumeric + underscore) name: "Front Door" # friendly name shown in UI host: !secret camera_one_host # use /config/secrets.yaml for sensitive values port: 554 path: /Streaming/Channels/101/ username: !secret camera_one_username password: !secret camera_one_password fps: 5 # processing FPS (not stream FPS) width: 1920 height: 1080 recorder: continuous_recording: true # keep continuous footage (default: true) lookback: 5 # seconds before event to include in recording max_recording_time: 600 # cap event recordings at 10 min darknet: object_detector: cameras: camera_one: fps: 1 # scan FPS (lower = less CPU) scan_on_motion_only: true # only scan when motion detected labels: - label: person confidence: 0.7 trigger_event_recording: true # create recording on detection - label: car confidence: 0.6 storage: recorder: tiers: - path: / # store segments under /segments/ events: max_age: days: 14 # keep event recordings for 14 days continuous: max_size: gb: 50 # keep up to 50 GB of continuous footage webserver: auth: # enable authentication (disabled by default) session_expiry: days: 30 ``` -------------------------------- ### FFmpeg Configuration Example Source: https://github.com/roflcoopter/viseron/blob/dev/docs/src/pages/components-explorer/components/ffmpeg/index.mdx Example YAML configuration for setting up FFmpeg to read from a camera, including substream and MJPEG stream options. ```yaml ffmpeg: camera: camera_one: name: Camera 1 host: 192.168.XX.X port: 554 path: /Streaming/Channels/101/ username: !secret camera_one_user password: !secret camera_one_pass substream: path: /Streaming/Channels/102/ stream_format: rtsp port: 554 mjpeg_streams: my_stream: width: 100 height: 100 draw_objects: true rotate: 45 mirror: true objects: draw_objects: true draw_zones: true draw_motion: true draw_motion_mask: true draw_object_mask: true recorder: idle_timeout: 5 frame_timeout: 10 ``` -------------------------------- ### Gotify Configuration Example Source: https://github.com/roflcoopter/viseron/blob/dev/docs/src/pages/components-explorer/components/gotify/index.mdx Configure the Gotify component in your Viseron configuration file. This example shows URL, token, priority, detection labels, thumbnail settings, and camera-specific overrides. ```yaml gotify: gotify_url: "https://gotify.example.com" # URL to your Gotify server gotify_token: "YOUR_APPLICATION_TOKEN" # Application token from Gotify priority: 5 # Priority of the notifications (1-10) detection_label: "person,cat" # Labels of objects to send notifications for send_thumbnail: true # Send a thumbnail of the detected object use_public_url: true # Generate a temp public URL with a unique token for the image. Require public_base_url in webserver conf image_max_size: 800 # Maximum width/height in pixels for thumbnails (default: 800). For 4K cameras, use 1920 or higher image_quality: 95 # JPEG quality for images (1-100, default: 95). Higher = better quality but larger files cameras: camera1: # Camera identifier with empty config camera2: # Another camera identifier detection_label: "car,truck" # Override detection labels for this camera send_thumbnail: false # Override thumbnail setting for this camera ``` -------------------------------- ### Stateful Component Initialization Source: https://github.com/roflcoopter/viseron/blob/dev/docs/docs/developers/backend/components.mdx For components requiring shared resources like neural networks or connections, use both `setup()` for initialization and `setup_domains()` for registration. The `setup` function must return `True` on success. ```python from __future__ import annotations from typing import TYPE_CHECKING, Any if TYPE_CHECKING: from viseron import Viseron from .const import COMPONENT def setup(vis: Viseron, config: dict[str, Any]) -> bool: """Set up the fancy_component component. Initialize shared resources here. This runs before setup_domains(). """ # Initialize shared resources (neural networks, connections, etc.) vis.data[COMPONENT] = MySharedResource(config) return True def setup_domains(vis: Viseron, config: dict[str, Any]) -> None: """Set up domains for the fancy_component component.""" # Register your domains here pass ``` -------------------------------- ### Implement Domain Setup Function Source: https://github.com/roflcoopter/viseron/blob/dev/docs/docs/developers/backend/domains.mdx Create a `setup` function in your domain module to handle domain initialization. This function should return `True` on success or raise `DomainNotReady` to trigger a retry with backoff. ```python def setup(vis: Viseron, config: dict[str, Any], identifier: str, attempt: int) -> bool: """Set up the fancy_component camera domain. Args: vis: The Viseron instance. config: Configuration passed to setup_domain. identifier: Unique identifier for this domain instance. attempt: Current setup attempt number (optional and can be omitted). Returns: True if setup was successful. Raises: DomainNotReady: If setup should be retried later. """ try: Camera(vis, config[identifier], identifier) except ConnectionError as error: # Raise DomainNotReady to trigger retry with backoff raise DomainNotReady from error return True ``` -------------------------------- ### Example Viseron Configuration Source: https://github.com/roflcoopter/viseron/blob/dev/docs/docs/documentation/configuration.md This is an example YAML configuration file for Viseron, demonstrating how to set up multiple cameras with various detection and recording modules. It includes settings for camera hosts, stream formats, recording codecs, motion detection parameters, object detection labels, and NVR integration. ```yaml ffmpeg: camera: viseron_camera: name: Camera 1 host: 195.196.36.242 path: /mjpg/video.mjpg port: 80 stream_format: mjpeg fps: 6 recorder: idle_timeout: 1 codec: h264 viseron_camera2: name: Camera 2 host: storatorg.halmstad.se path: /mjpg/video.mjpg stream_format: mjpeg port: 443 fps: 2 protocol: https recorder: idle_timeout: 1 codec: h264 viseron_camera3: name: Camera 3 host: 195.196.36.242 path: /mjpg/video.mjpg port: 80 stream_format: mjpeg fps: 6 recorder: idle_timeout: 1 codec: h264 mog2: motion_detector: cameras: viseron_camera: fps: 1 viseron_camera2: fps: 1 background_subtractor: motion_detector: cameras: viseron_camera3: fps: 1 mask: - coordinates: - x: 400 y: 200 - x: 1000 y: 200 - x: 1000 y: 750 - x: 400 y: 750 darknet: object_detector: cameras: viseron_camera: fps: 1 scan_on_motion_only: false labels: - label: person confidence: 0.8 trigger_event_recording: true viseron_camera2: fps: 1 labels: - label: person confidence: 0.8 trigger_event_recording: true viseron_camera3: fps: 1 labels: - label: person confidence: 0.8 trigger_event_recording: true nvr: viseron_camera: viseron_camera2: viseron_camera3: webserver: logger: default_level: debug ``` -------------------------------- ### Component Configuration Example Source: https://github.com/roflcoopter/viseron/blob/dev/docs/docs/developers/backend/components.mdx Enable your component by adding its name to the `config.yaml` file. This tells Viseron to load and initialize the component. ```yaml fancy_component: ``` -------------------------------- ### Install Dependencies Source: https://github.com/roflcoopter/viseron/blob/dev/docs/README.md Installs project dependencies using Yarn. Run this command after cloning the repository. ```bash $ yarn ``` -------------------------------- ### CompreFace Configuration Example Source: https://github.com/roflcoopter/viseron/blob/dev/docs/src/pages/components-explorer/components/compreface/index.mdx Example configuration for the CompreFace component in YAML format. Specifies host, port, API key, enabled face plugins, and camera/label settings. ```yaml compreface: face_recognition: host: compreface port: 8000 recognition_api_key: !secret compreface_api_key train: true face_plugins: age,gender cameras: camera_one: labels: - person ``` -------------------------------- ### Install Pre-commit Hooks Source: https://github.com/roflcoopter/viseron/blob/dev/docs/docs/developers/development_environment/setup.mdx Installs the pre-commit hooks to ensure code quality and consistency before committing. ```shell pre-commit install ``` -------------------------------- ### Start Camera Source: https://context7.com/roflcoopter/viseron/llms.txt Starts (arms) a camera. ```APIDOC ## POST /api/v1/camera/{identifier}/start — Start Camera ### Description Starts (arms) a camera. ### Method POST ### Endpoint /api/v1/camera/{identifier}/start ### Parameters #### Path Parameters - **identifier** (string) - Required - The unique identifier of the camera. #### Header Parameters - **Authorization** (string) - Required - Bearer token for authentication. ``` -------------------------------- ### NVR Configuration Example Source: https://github.com/roflcoopter/viseron/blob/dev/docs/src/pages/components-explorer/components/nvr/index.mdx Example configuration for the NVR component, defining cameras to be managed. Ensure this is placed in your Viseron configuration file. ```yaml nvr: camera_one: camera_two: ``` -------------------------------- ### Restreaming Configuration Example Source: https://github.com/roflcoopter/viseron/blob/dev/docs/src/pages/components-explorer/components/go2rtc/index.mdx Configure go2rtc to restream camera feeds to Viseron or other services. This setup reduces per-camera connections. Ensure go2rtc ports are exposed if restreaming externally. ```yaml ffmpeg: camera: camera_one: name: Camera 1 host: localhost port: 8554 path: /camera_one camera_two: name: Camera 2 host: localhost port: 8554 path: /camera_two go2rtc: streams: camera_one: - rtsp://user:pass@192.168.XX.X:554/Streaming/Channels/101/ camera_two: - rtsp://user:pass@192.168.XX.X:554/Streaming/Channels/101/ ``` -------------------------------- ### Install Project Dependencies Source: https://github.com/roflcoopter/viseron/blob/dev/docs/docs/developers/development_environment/setup.mdx Installs project dependencies using pip. It is recommended to do this within a virtual environment. ```shell pip3 install -r requirements.txt -r requirements_test.txt -r requirements_test.txt ``` -------------------------------- ### Storage Configuration Example Source: https://github.com/roflcoopter/viseron/blob/dev/docs/src/pages/components-explorer/components/storage/index.mdx Configure tiered storage for recordings and snapshots, specifying paths and retention policies (max_age). ```yaml storage: recorder: tiers: - path: /ssd/tier1 events: max_age: days: 1 continuous: max_age: days: 1 - path: /hdd/tier2 events: max_age: days: 7 snapshots: tiers: - path: /config/tier1 max_age: days: 1 ``` -------------------------------- ### Setup Domains with Required Dependencies Source: https://github.com/roflcoopter/viseron/blob/dev/docs/docs/developers/backend/domains.mdx Use RequireDomain to ensure a domain is loaded before another domain's setup begins. The object detector waits for the camera to be LOADED. ```python from viseron.domains import RequireDomain, setup_domain from viseron.domains.object_detector.const import DOMAIN as OBJECT_DETECTOR_DOMAIN def setup_domains(vis: Viseron, config: dict[str, Any]) -> None: """Set up domains with required dependencies.""" for camera_identifier in config[CONFIG_OBJECT_DETECTOR][CONFIG_CAMERAS].keys(): setup_domain( vis, COMPONENT, OBJECT_DETECTOR_DOMAIN, config, identifier=camera_identifier, require_domains=[ RequireDomain( domain="camera", identifier=camera_identifier, ) ], ) ``` -------------------------------- ### YOLO Configuration Example Source: https://github.com/roflcoopter/viseron/blob/dev/docs/src/pages/components-explorer/components/yolo/index.mdx Example configuration for the YOLO component in Viseron's config.yaml. Specifies model path, camera-specific settings, and object labels with confidence thresholds. ```yaml yolo: object_detector: model_path: /detectors/models/yolo/my_model.pt cameras: viseron_camera1: fps: 1 scan_on_motion_only: true log_all_objects: false labels: - label: dog confidence: 0.7 trigger_event_recording: false - label: cat confidence: 0.8 ``` -------------------------------- ### Register QEMU for Cross-Building Source: https://github.com/roflcoopter/viseron/blob/dev/docs/docs/developers/docker.mdx Run this command to install QEMU on your builder machine, enabling cross-building for different CPU architectures using Docker. ```shell docker run --rm --privileged tonistiigi/binfmt --install all ``` -------------------------------- ### MOG2 Configuration Example Source: https://github.com/roflcoopter/viseron/blob/dev/docs/src/pages/components-explorer/components/mog2/index.mdx Configure the MOG2 component, including camera-specific settings like shadow detection, FPS, and masking. ```yaml mog2: motion_detector: cameras: camera_one: detect_shadows: true fps: 1 mask: - coordinates: - x: 400 y: 200 - x: 1000 y: 200 - x: 1000 y: 750 - x: 400 y: 750 camera_two: fps: 2 trigger_event_recording: true threshold: 25 ``` -------------------------------- ### Handle Domain Setup Failures with DomainNotReady Source: https://github.com/roflcoopter/viseron/blob/dev/docs/docs/developers/backend/domains.mdx Raise DomainNotReady when a domain setup fails but should be retried. This exception triggers retries with exponential backoff. ```python from viseron.exceptions import DomainNotReady def setup(vis: Viseron, config: dict[str, Any], identifier: str, attempt: int) -> bool: try: connect_to_camera(config) except TimeoutError as error: raise DomainNotReady from error # Will retry with backoff return True ``` -------------------------------- ### Setup Domains for a Component Source: https://github.com/roflcoopter/viseron/blob/dev/docs/docs/developers/backend/components.mdx Use `setup_domains()` to register all domains provided by a component. This function is called after `setup()` and should call `setup_domain()` for each domain instance. It is important that this function only registers domains as it can be called multiple times during hot-reloading. ```python def setup_domains(vis: Viseron, config: dict[str, Any]) -> None: """Set up fancy_component object detector domains.""" config = config[COMPONENT] for camera_identifier in config[CONFIG_OBJECT_DETECTOR][CONFIG_CAMERAS].keys(): setup_domain( vis, COMPONENT, CONFIG_OBJECT_DETECTOR, config, identifier=camera_identifier, require_domains=[ RequireDomain( domain="camera", identifier=camera_identifier, ) ], ) ``` -------------------------------- ### Static MJPEG Stream Configuration Example Source: https://github.com/roflcoopter/viseron/blob/dev/docs/src/pages/components-explorer/_domains/camera/mjpeg_streams.mdx Configuration example for static MJPEG streams in `config.yaml`. This allows for multiple streams without increased processing load as frames are processed only once. ```yaml : camera: front_door: ... mjpeg_streams: my-big-front-door-stream: width: 100 height: 100 draw_objects: true my-small-front-door-stream: width: 100 height: 100 draw_objects: true draw_zones: true draw_object_mask: true ``` -------------------------------- ### MQTT Configuration Example Source: https://github.com/roflcoopter/viseron/blob/dev/docs/src/pages/components-explorer/components/mqtt/index.mdx Configure the MQTT integration by specifying the broker address, port, username, and password. Ensure sensitive credentials are handled securely using secrets. ```yaml mqtt: broker: mqtt_broker.lan port: 1883 username: !secret mqtt_user password: !secret mqtt_pass ``` -------------------------------- ### go2rtc Configuration Example Source: https://github.com/roflcoopter/viseron/blob/dev/docs/src/pages/components-explorer/components/go2rtc/index.mdx Configure the go2rtc server with camera streams and WebRTC candidates. Ensure camera names match Viseron identifiers. Debug logging can be enabled. ```yaml go2rtc: streams: camera_one: - rtsp://user:pass@192.168.XX.X:554/Streaming/Channels/101/ camera_two: - rtsp://user:pass@192.168.XX.X:554/Streaming/Channels/101/ webrtc: candidates: - 192.168.XX.X:8555 - stun:8555 log: level: debug ``` -------------------------------- ### Setup Domains with Optional Dependencies Source: https://github.com/roflcoopter/viseron/blob/dev/docs/docs/developers/backend/domains.mdx Use OptionalDomain to specify dependencies that are not strictly required but can be utilized if configured. Viseron ignores optional dependencies if they are not configured. ```python from viseron.domains import OptionalDomain, RequireDomain, setup_domain setup_domain( vis, COMPONENT, NVR_DOMAIN, config, identifier=camera_identifier, require_domains=[ RequireDomain(domain="camera", identifier=camera_identifier), ], optional_domains=[ OptionalDomain(domain="object_detector", identifier=camera_identifier), OptionalDomain(domain="motion_detector", identifier=camera_identifier), ], ) ``` -------------------------------- ### Config Example for Image Rotation Source: https://github.com/roflcoopter/viseron/blob/dev/docs/src/pages/components-explorer/components/ffmpeg/index.mdx Provides a configuration example for rotating images by 180 degrees using FFmpeg's `transpose` filter. This configuration can be applied to both real-time processed images and recorded videos. ```yaml ffmpeg: camera: camera_1: .... video_filters: # These filters rotate the images processed by Viseron - transpose=2 - transpose=2 recorder: video_filters: # These filters rotate the recorded video - transpose=2 - transpose=2 ``` -------------------------------- ### Play Recording in VLC Source: https://context7.com/roflcoopter/viseron/llms.txt Example of how to play a recording directly in VLC or another HLS-capable player using the HLS playlist URL and an access token. ```bash # Play recording in VLC or other HLS-capable player: # vlc "http://localhost:8888/api/v1/hls/camera_one/42/index.m3u8?token=" ``` -------------------------------- ### Control Viseron Recording via MQTT Source: https://context7.com/roflcoopter/viseron/llms.txt Use mosquitto_pub to send commands to Viseron for starting or stopping manual recording. This allows for programmatic control of recording sessions. ```bash # Start manual recording via MQTT mosquitto_pub -h 192.168.1.10 \ -t "viseron/toggle/camera_one_manual_recording/command" \ -m '{"action": "start", "duration": 60}' ``` ```bash # Stop manual recording via MQTT mosquitto_pub -h 192.168.1.10 \ -t "viseron/toggle/camera_one_manual_recording/command" \ -m '{"action": "stop"}' ``` -------------------------------- ### Configure Webserver with Authentication and Reverse Proxy Source: https://context7.com/roflcoopter/viseron/llms.txt Setup for the Viseron webserver, including debug mode, subpath for reverse proxy, public URL settings, and session expiry for authentication. ```yaml webserver: debug: false subpath: "/viseron" # set when behind reverse proxy at /viseron/ public_base_url: "https://viseron.example.com" # for public image links public_url_expiry_hours: 24 # expire public image URLs after 24h (max 744) public_url_max_downloads: 0 # 0 = unlimited downloads per URL auth: session_expiry: days: 30 # auto-logout after 30 days inactivity ``` -------------------------------- ### Webhook Configuration Example Source: https://github.com/roflcoopter/viseron/blob/dev/docs/src/pages/components-explorer/components/webhook/index.mdx Configure a webhook to trigger on a specific event with an optional condition. The payload can be a static string or a dynamic template. ```yaml webhook: cool_hook: trigger: event: camera_one/motion_detected # The event to listen for condition: > # Optional condition to filter events, e.g., only trigger if motion is detected {{ event.motion_detected }} url: http://example.com/webhook payload: "Motion detected on {{ event.camera_identifier }}!" ``` -------------------------------- ### Start Manual Recording via REST API Source: https://github.com/roflcoopter/viseron/blob/dev/docs/docs/documentation/configuration/recordings.mdx Initiate a manual recording for a specific camera using a POST request to the REST API. An optional duration can be specified in seconds. ```json { "action": "start", "duration": 60 // Optional, duration in seconds } ``` -------------------------------- ### Enable Debug Logging for a Specific Component Source: https://github.com/roflcoopter/viseron/blob/dev/docs/src/pages/components-explorer/components/logger/index.mdx Enable debug logging for a single Viseron component to troubleshoot issues. This example targets the 'ffmpeg' component. ```yaml logger: logs: viseron.components.ffmpeg: debug ``` -------------------------------- ### Configure Hailo Object Detector Source: https://github.com/roflcoopter/viseron/blob/dev/docs/src/pages/components-explorer/components/hailo/index.mdx Example configuration for the Hailo object detector, specifying cameras, desired labels, confidence thresholds, and recording triggers. ```yaml hailo: object_detector: cameras: camera_one: fps: 1 labels: - label: person confidence: 0.8 - label: cat confidence: 0.8 camera_two: fps: 1 scan_on_motion_only: false labels: - label: dog confidence: 0.8 trigger_event_recording: false ``` -------------------------------- ### Start/Stop Manual Recording via MQTT Source: https://github.com/roflcoopter/viseron/blob/dev/docs/docs/documentation/configuration/recordings.mdx Control manual recordings by publishing messages to a specific MQTT topic. Supports starting recordings with an optional duration and stopping them. ```APIDOC ## Start Manual Recording via MQTT ### Description Starts a manual recording for a specified camera by publishing a message to the designated MQTT topic. ### Topic `/toggle/_manual_recording/command` ### Payload ```json { "action": "start", "duration": 60 // Optional, duration in seconds } ``` ## Stop Manual Recording via MQTT ### Description Stops an ongoing manual recording for a specified camera by publishing a message to the designated MQTT topic. ### Topic `/toggle/_manual_recording/command` ### Payload ```json { "action": "stop" } ``` ### Note For a default configuration with the camera identifier `camera1`, the topic would be `viseron/toggle/camera1_manual_recording/command`. ``` -------------------------------- ### Viseron Configuration for Subpath Source: https://github.com/roflcoopter/viseron/blob/dev/docs/docs/documentation/installation.mdx Configure the `subpath` in `config.yaml` to match your reverse proxy setup. Ensure it starts with a forward slash. ```yaml webserver: subpath: "/viseron" # Must start with / and match your reverse proxy path ``` -------------------------------- ### Docker Compose for tmpfs Configuration Source: https://github.com/roflcoopter/viseron/blob/dev/docs/src/pages/components-explorer/components/ffmpeg/index.mdx An example docker-compose configuration for Viseron that includes a tmpfs mount for `/tmp/tier1`. This setup directs video segments to be stored in RAM, optimizing for memory usage over disk writes. ```yaml services: viseron: image: roflcoopter/viseron:latest container_name: viseron shm_size: "1024mb" volumes: - {segments path}:/segments - {snapshots path}:/snapshots - {thumbnails path}:/thumbnails - {event clips path}:/event_clips - {timelapse path}:/timelapse - {config path}:/config - /etc/localtime:/etc/localtime:ro ports: - 8888:8888 tmpfs: - /tmp/tier1 ``` -------------------------------- ### Webserver Configuration Example Source: https://github.com/roflcoopter/viseron/blob/dev/docs/src/pages/components-explorer/components/webserver/index.mdx Configure the webserver port, public base URL, and settings for public image URL generation, including expiry hours and maximum downloads. Use `public_url_max_downloads: 0` for unlimited downloads. ```yaml webserver: port: 8888 public_base_url: "https://public.dns-viseron.org" public_url_expiry_hours: 240 # default: 24, max: 744 = 31 days public_url_max_downloads: 3 # default: 0 (unlimited) ``` -------------------------------- ### Stateless Component Initialization Source: https://github.com/roflcoopter/viseron/blob/dev/docs/docs/developers/backend/components.mdx Use this for simple components that only register domains without managing shared resources. The `setup_domains` function is called to register capabilities. ```python from __future__ import annotations from typing import TYPE_CHECKING, Any if TYPE_CHECKING: from viseron import Viseron def setup_domains(vis: Viseron, config: dict[str, Any]) -> None: """Set up domains for the fancy_component component.""" # Register your domains here pass ``` -------------------------------- ### Deploy Website (SSH) Source: https://github.com/roflcoopter/viseron/blob/dev/docs/README.md Builds the website and deploys it using SSH. Assumes SSH is configured for deployment. ```bash $ USE_SSH=true yarn deploy ``` -------------------------------- ### Dynamic MJPEG Stream URL Example Source: https://github.com/roflcoopter/viseron/blob/dev/docs/src/pages/components-explorer/_domains/camera/mjpeg_streams.mdx This is an example of a dynamic MJPEG stream URL. Query parameters can be appended to control stream output like resizing or drawing objects. ```url http://localhost:8888//mjpeg-stream ``` ```url http://localhost:8888//mjpeg-stream?=&= ``` -------------------------------- ### PTZ Camera Configuration Example Source: https://github.com/roflcoopter/viseron/blob/dev/docs/src/pages/components-explorer/components/ptz/index.mdx Configure PTZ cameras by specifying ONVIF connection details, movement limits for patrol mode, and predefined presets for startup or specific views. Ensure ONVIF credentials and ports are correctly set for each camera. ```yaml ptz: cameras: camera_1: onvif_port: 80 # The port the camera listens to for ONVIF connections onvif_username: # username associated with ONVIF onvif_password: # password associated with ONVIF camera_min_x: -0.73 # used in "patrol" mode to limit swings to useful fov camera_max_x: 0.04 # used in "patrol" mode to limit swings to useful fov presets: # allows switching between pre-defined (absolute) positions - name: front # name them x: 0.0 y: 0.0 on_startup: true # have the camera move to this preset when Viseron starts - name: left x: -0.5 y: 0.0 - name: right x: 0.5 y: 0.0 ``` -------------------------------- ### Config Example for Storing Segments in RAM Source: https://github.com/roflcoopter/viseron/blob/dev/docs/src/pages/components-explorer/components/ffmpeg/index.mdx Configuration snippet for Viseron's storage settings, demonstrating how to use a tmpfs mount (`/tmp/tier1`) to store up to 50 MB of video segments in RAM. It also includes a secondary tier for longer-term storage on a normal drive. ```yaml storage: recorder: tiers: # Store 50 MB of segments in RAM disk - path: /tmp/tier1 move_on_shutdown: true # Important to not lose segments on shutdown events: max_size: mb: 50 # Keep 50 GB of segments on a normal drive - path: /config/tier2 events: max_size: gb: 50 ``` -------------------------------- ### Get Single Camera Source: https://context7.com/roflcoopter/viseron/llms.txt Retrieves metadata for a specific camera. ```APIDOC ## GET /api/v1/camera/{identifier} — Get Single Camera ### Description Retrieves metadata for a specific camera. ### Method GET ### Endpoint /api/v1/camera/{identifier} ### Parameters #### Path Parameters - **identifier** (string) - Required - The unique identifier of the camera. #### Header Parameters - **Authorization** (string) - Required - Bearer token for authentication. ``` -------------------------------- ### Get Dates of Interest Source: https://context7.com/roflcoopter/viseron/llms.txt Retrieves dates with events and HLS availability for calendar view. ```APIDOC ## POST /api/v1/events/dates_of_interest ### Description Retrieves dates that have events and HLS availability, useful for calendar views. ### Method POST ### Endpoint /api/v1/events/dates_of_interest ### Parameters #### Request Body - **camera_identifiers** (array[string]) - Required - A list of camera identifiers to query. ### Request Example ```json { "camera_identifiers": ["camera_one"] } ``` ### Response #### Success Response (200) - **dates_of_interest** (object) - An object where keys are dates and values contain event counts and availability. - **date** (string) - The date in YYYY-MM-DD format. - **events** (integer) - The number of events on that date. - **timespanAvailable** (boolean) - Indicates if HLS timespan is available for that date. ### Response Example ```json { "dates_of_interest": { "2024-03-15": { "events": 20, "timespanAvailable": true } } } ``` ``` -------------------------------- ### Get System-Dispatched Events List Source: https://context7.com/roflcoopter/viseron/llms.txt Fetches a list of system-dispatched events. This endpoint is restricted to administrators. ```bash # Get system-dispatched events list (Admin only) curl -H "Authorization: Bearer eyJ..." \ http://localhost:8888/api/v1/system/dispatched_events ``` -------------------------------- ### User Authentication and Management Source: https://context7.com/roflcoopter/viseron/llms.txt Handles user login, token refresh, logout, and user creation/management. Authentication must be enabled in the Viseron configuration. ```bash # Check if auth is enabled curl http://localhost:8888/api/v1/auth/enabled # Response: {"enabled": true, "onboarding_complete": true} ``` ```bash # Login curl -c cookies.txt -X POST http://localhost:8888/api/v1/auth/login \ -H "Content-Type: application/json" \ -d '{ "username": "admin", "password": "mysecretpassword", "client_id": "my-app-client" }' # Response: # { # "access_token": "eyJ...", # "refresh_token": "...", # "token_type": "bearer", # "expires_in": 1800 # } ``` ```bash # Refresh access token using the refresh_token cookie curl -b cookies.txt -c cookies.txt -X POST http://localhost:8888/api/v1/auth/token \ -H "Content-Type: application/json" \ -d '{"grant_type": "refresh_token", "client_id": "my-app-client"}' ``` ```bash # Logout curl -b cookies.txt -X POST http://localhost:8888/api/v1/auth/logout \ -H "Authorization: Bearer eyJ..." ``` ```bash # Create a new user (requires Admin role) curl -b cookies.txt -X POST http://localhost:8888/api/v1/auth/create \ -H "Authorization: Bearer eyJ..." \ -H "Content-Type: application/json" \ -d '{ "name": "Jane Doe", "username": "jane", "password": "strongpass123", "role": "write" }' # Roles: "admin", "write", "read" ``` ```bash # List all users (Admin only) curl -b cookies.txt http://localhost:8888/api/v1/auth/users \ -H "Authorization: Bearer eyJ..." # Response: {"users": [{"id":"abc","name":"Jane Doe","username":"jane","role":"write",...}]} ``` ```bash # Admin change user password curl -b cookies.txt -X PUT \ http://localhost:8888/api/v1/auth/user/{user_id}/admin_change_password \ -H "Authorization: Bearer eyJ..." \ -H "Content-Type: application/json" \ -d '{"new_password": "newpass456"}' ``` -------------------------------- ### Get All Recordings for All Cameras Source: https://context7.com/roflcoopter/viseron/llms.txt Retrieves a list of all recordings across all cameras. Requires an authorization token. ```bash curl -H "Authorization: Bearer eyJ..." http://localhost:8888/api/v1/recordings ``` -------------------------------- ### Manual Recording Command Source: https://github.com/roflcoopter/viseron/blob/dev/docs/src/pages/components-explorer/components/mqtt/index.mdx Used for starting or stopping a manual recording. Payload can be 'ON'/'OFF' or a JSON object. ```APIDOC ## MQTT Topic: `{base_topic}/toggle/{camera_identifier}_manual_recording/command` ### Description Used for starting/stopping a manual recording. ### Payload * **Payload**: Can be 'ON' to start recording, 'OFF' to stop recording, or a JSON object. * **To start recording**: `{"action": "start", "duration": 120}` (duration in seconds) * **To stop recording**: `{"action": "stop"}` ``` -------------------------------- ### Get Latest Recording for All Cameras Source: https://context7.com/roflcoopter/viseron/llms.txt Retrieves the most recent recording for each camera. Appends '?latest' to the base recordings endpoint. ```bash curl -H "Authorization: Bearer eyJ..." "http://localhost:8888/api/v1/recordings?latest" ``` -------------------------------- ### Get Camera Snapshot Source: https://context7.com/roflcoopter/viseron/llms.txt Retrieves a snapshot (JPEG image) from a camera. Supports optional width and height for resizing. ```APIDOC ## GET /api/v1/camera/{identifier}/snapshot — Get Camera Snapshot ### Description Retrieves a snapshot (JPEG image) from a camera. Supports optional width and height for resizing. ### Method GET ### Endpoint /api/v1/camera/{identifier}/snapshot ### Parameters #### Path Parameters - **identifier** (string) - Required - The unique identifier of the camera. #### Query Parameters - **width** (integer) - Optional - The desired width of the snapshot in pixels. - **height** (integer) - Optional - The desired height of the snapshot in pixels. #### Header Parameters - **Authorization** (string) - Required - Bearer token for authentication (unless using `access_token` query parameter). ``` -------------------------------- ### Listen to Events with Placeholders Source: https://github.com/roflcoopter/viseron/blob/dev/docs/docs/developers/backend/vis_object.mdx Demonstrates how to listen to events that include runtime values in their names, such as camera identifiers. Ensure the event name is correctly formatted before subscribing. ```python from viseron.domains.object_detector.const import EVENT_OBJECT_DETECTOR_RESULT camera_identifier = "front_door" event_name = EVENT_OBJECT_DETECTOR_RESULT.format( camera_identifier=camera_identifier ) unsubscribe = vis.listen_event(event_name, self._on_result) ``` -------------------------------- ### Get Recordings for a Specific Camera Source: https://context7.com/roflcoopter/viseron/llms.txt Retrieves all recordings associated with a particular camera. Specify the camera name in the URL path. ```bash curl -H "Authorization: Bearer eyJ..." \ http://localhost:8888/api/v1/recordings/camera_one ``` -------------------------------- ### Run Viseron on Jetson Nano with Docker Source: https://github.com/roflcoopter/viseron/blob/dev/docs/docs/documentation/installation.mdx This Docker command is specifically for Jetson Nano devices, enabling hardware acceleration with `--privileged` and `--runtime=nvidia`. Ensure NVIDIA Container Toolkit is installed. ```shell docker run --rm \ -v {segments path}:/segments \ -v {snapshots path}:/snapshots \ -v {thumbnails path}:/thumbnails \ -v {event clips path}:/event_clips \ -v {timelapse path}:/timelapse \ -v {config path}:/config \ -v /etc/localtime:/etc/localtime:ro \ -p 8888:8888 \ --name viseron \ --shm-size=1024mb \ --runtime=nvidia \ --privileged \ roflcoopter/jetson-nano-viseron:latest ``` -------------------------------- ### Manual Recording Command Source: https://github.com/roflcoopter/viseron/blob/dev/docs/src/pages/components-explorer/components/mqtt/index.mdx Command to start or stop manual recording. Accepts 'ON'/'OFF' or a JSON payload for start/stop actions and duration. ```json { "action": "start", "duration": 120 } ``` ```text ON ``` ```json { "action": "stop" } ``` ```text OFF ``` -------------------------------- ### Browser WebSocket Client Example Source: https://context7.com/roflcoopter/viseron/llms.txt Connect to the Viseron WebSocket API, handle authentication, and send various commands for system information, camera data, state subscriptions, event subscriptions, timespan exports, snapshot exports, template rendering, and administrative tasks. Requires a valid access token for authentication. ```javascript // Browser WebSocket client example const ws = new WebSocket("ws://localhost:8888/api/websocket"); let cmdId = 0; ws.onopen = () => console.log("Connected"); ws.onmessage = (evt) => { const msg = JSON.parse(evt.data); // Step 1: Handle auth challenge if (msg.type === "auth_required") { ws.send(JSON.stringify({ type: "auth", access_token: "eyJ..." // from login response })); } // Step 2: Auth not required (auth disabled in config) if (msg.type === "auth_not_required" || msg.type === "auth_ok") { console.log("System info:", msg.system_information); // { version: "1.2.3", git_commit: "abc1234", safe_mode: false } // Ping ws.send(JSON.stringify({ command_id: ++cmdId, type: "ping" })); // Get all cameras ws.send(JSON.stringify({ command_id: ++cmdId, type: "get_cameras" })); // Get all entities (sensors, binary sensors, toggles) ws.send(JSON.stringify({ command_id: ++cmdId, type: "get_entities" })); // Subscribe to all state changes ws.send(JSON.stringify({ command_id: ++cmdId, type: "subscribe_states" })); // Subscribe to state changes for a specific entity ws.send(JSON.stringify({ command_id: ++cmdId, type: "subscribe_states", entity_id: "binary_sensor.camera_one_object_detected_person" })); // Subscribe to a custom Viseron event ws.send(JSON.stringify({ command_id: ++cmdId, type: "subscribe_event", event: "viseron/camera/camera_one/object_detected" })); // Subscribe to available timespans (updates when new segments are created/deleted) ws.send(JSON.stringify({ command_id: ++cmdId, type: "subscribe_timespans", camera_identifiers: ["camera_one"], date: "2024-03-15", // null for all time debounce: 5 // seconds debounce })); // Response (subscription_result): {"timespans": [{"start": ..., "end": ...}]} // Export recording to downloadable MP4 ws.send(JSON.stringify({ command_id: ++cmdId, type: "export_recording", camera_identifier: "camera_one", recording_id: 42 })); // Response (subscription_result): {"filename": "/tmp/...", "token": "uuid"} // Then download: GET /api/v1/download?token=uuid // Export a timespan to MP4 ws.send(JSON.stringify({ command_id: ++cmdId, type: "export_timespan", camera_identifier: "camera_one", start: 1710460800, end: 1710464400 })); // Export a snapshot image ws.send(JSON.stringify({ command_id: ++cmdId, type: "export_snapshot", event_type: "object", // "motion" | "object" | "face_recognition" | "license_plate_recognition" camera_identifier: "camera_one", snapshot_id: 123 })); // Render a Jinja2 template ws.send(JSON.stringify({ command_id: ++cmdId, type: "render_template", template: "{{ states('binary_sensor.camera_one_motion_detected') }}" })); // Admin: get raw config ws.send(JSON.stringify({ command_id: ++cmdId, type: "get_config" })); // Admin: save config (write new YAML content) ws.send(JSON.stringify({ command_id: ++cmdId, type: "save_config", config: "ffmpeg:\n camera:\n camera_one:\n ..." })); // Admin: reload config without full restart ws.send(JSON.stringify({ command_id: ++cmdId, type: "reload_config" })); // Response: {"success": true, "restart_required": false} // Admin: restart Viseron ws.send(JSON.stringify({ command_id: ++cmdId, type: "restart_viseron" })); // Admin: get component setup status ws.send(JSON.stringify({ command_id: ++cmdId, type: "get_setup_status" })); // Response: {"components": [{"name": "ffmpeg", "state": "loaded", ...}]} } // Handle responses if (msg.type === "result") { console.log(`Command ${msg.command_id} result:`, msg.success, msg.result); } if (msg.type === "subscription_result") { console.log(`Subscription ${msg.command_id} update:`, msg.result); } }; // Unsubscribe from a subscription ws.send(JSON.stringify({ command_id: ++cmdId, type: "unsubscribe_event", subscription: 3 // command_id of the subscribe command })); ``` -------------------------------- ### Get Latest Recording for a Specific Camera Source: https://context7.com/roflcoopter/viseron/llms.txt Retrieves the most recent recording for a specific camera. Appends '?latest' to the camera-specific recordings endpoint. ```bash curl -H "Authorization: Bearer eyJ..." \ "http://localhost:8888/api/v1/recordings/camera_one?latest" ``` -------------------------------- ### Get Recordings for a Camera on a Specific Date Source: https://context7.com/roflcoopter/viseron/llms.txt Retrieves recordings for a specific camera on a given date. The date is specified in the URL path. ```bash curl -H "Authorization: Bearer eyJ..." \ http://localhost:8888/api/v1/recordings/camera_one/2024-03-15 ``` -------------------------------- ### Register Domain with setup_domain Source: https://github.com/roflcoopter/viseron/blob/dev/docs/docs/developers/backend/domains.mdx Use `setup_domain` within your component's `setup_domains` function to register a domain instance. This method can be called multiple times during hot-reloading. ```python def setup_domains(vis: Viseron, config: dict[str, Any]) -> None: """Set up fancy_component domains.""" config = config[COMPONENT] for camera_identifier, camera_config in config[CONFIG_CAMERA].items(): setup_domain( vis, COMPONENT, CAMERA_DOMAIN, {camera_identifier: camera_config}, identifier=camera_identifier, ) ``` -------------------------------- ### Manual Recording Control Source: https://context7.com/roflcoopter/viseron/llms.txt Starts or stops manual recording for a specified camera. The camera must be active and connected. Supports optional duration. ```bash # Start a manual recording (runs until stopped or duration expires) curl -X POST -H "Authorization: Bearer eyJ..." \ -H "Content-Type: application/json" \ http://localhost:8888/api/v1/camera/camera_one/manual_recording \ -d '{"action": "start", "duration": 120}' # Response: {"success": true} (waits up to 5s for recording to actually start) ``` ```bash # Start without duration (runs until stopped) curl -X POST -H "Authorization: Bearer eyJ..." \ -H "Content-Type: application/json" \ http://localhost:8888/api/v1/camera/camera_one/manual_recording \ -d '{"action": "start"}' ``` ```bash # Stop a manual recording curl -X POST -H "Authorization: Bearer eyJ..." \ -H "Content-Type: application/json" \ http://localhost:8888/api/v1/camera/camera_one/manual_recording \ -d '{"action": "stop"}' # Response: {"success": true} ``` ```bash # Via MQTT (topic: /toggle/_manual_recording/command) mosquitto_pub -h mqtt-broker -t "viseron/toggle/camera_one_manual_recording/command" \ -m '{"action": "start", "duration": 60}' mosquitto_pub -h mqtt-broker -t "viseron/toggle/camera_one_manual_recording/command" \ -m '{"action": "stop"}' ``` -------------------------------- ### Docker Command for tmpfs Configuration Source: https://github.com/roflcoopter/viseron/blob/dev/docs/src/pages/components-explorer/components/ffmpeg/index.mdx An example Docker command to run Viseron with a tmpfs mount for the `/tmp/tier1` directory. This configuration allows video segments to be stored in RAM instead of on disk, reducing disk I/O. ```shell docker run --rm \ -v {segments path}:/segments \ -v {snapshots path}:/snapshots \ -v {thumbnails path}:/thumbnails \ -v {event clips path}:/event_clips \ -v {timelapse path}:/timelapse \ -v {config path}:/config \ -v /etc/localtime:/etc/localtime:ro \ -p 8888:8888 \ --tmpfs /tmp/tier1 \ --name viseron \ --shm-size=1024mb \ roflcoopter/viseron:latest ```