import { h, Fragment } from 'preact'; import ActivityIndicator from '../components/ActivityIndicator'; import Button from '../components/Button'; import Heading from '../components/Heading'; import Link from '../components/Link'; import { useWs } from '../api/ws'; import useSWR from 'swr'; import axios from 'axios'; import { Table, Tbody, Thead, Tr, Th, Td } from '../components/Table'; import { useState } from 'preact/hooks'; import Dialog from '../components/Dialog'; import TimeAgo from '../components/TimeAgo'; import copy from 'copy-to-clipboard'; const emptyObject = Object.freeze({}); export default function System() { const [state, setState] = useState({ showFfprobe: false, ffprobe: '' }); const { data: config } = useSWR('config'); const { value: { payload: stats }, } = useWs('stats'); const { data: initialStats } = useSWR('stats'); const { cpu_usages, gpu_usages, detectors, service = {}, detection_fps: _, ...cameras } = stats || initialStats || emptyObject; const detectorNames = Object.keys(detectors || emptyObject); const gpuNames = Object.keys(gpu_usages || emptyObject); const cameraNames = Object.keys(cameras || emptyObject); const onHandleFfprobe = async (camera, e) => { if (e) { e.stopPropagation(); } setState({ ...state, showFfprobe: true }); const response = await axios.get('ffprobe', { params: { paths: `camera:${camera}`, }, }); if (response.status === 200) { setState({ ...state, showFfprobe: true, ffprobe: response.data }); } else { setState({ ...state, showFfprobe: true, ffprobe: 'There was an error getting the ffprobe output.' }); } }; const onCopyFfprobe = async () => { copy(JSON.stringify(state.ffprobe).replace(/[\\\s]+/gi, '')); setState({ ...state, ffprobe: '', showFfprobe: false }); }; const onHandleVainfo = async (e) => { if (e) { e.stopPropagation(); } const response = await axios.get('vainfo'); if (response.status === 200) { setState({ ...state, showVainfo: true, vainfo: response.data, }); } else { setState({ ...state, showVainfo: true, vainfo: 'There was an error getting the vainfo output.' }); } }; const onCopyVainfo = async () => { copy(JSON.stringify(state.vainfo).replace(/[\\\s]+/gi, '')); setState({ ...state, vainfo: '', showVainfo: false }); }; return (
System {service.version} {config && ( go2rtc dashboard )}
{service.last_updated && (

Last refreshed:

)} {state.showFfprobe && (
Ffprobe Output {state.ffprobe != '' ? (
{state.ffprobe.map((stream, idx) => (
Stream {idx}:
Return Code: {stream.return_code}

{stream.return_code == 0 ? (
{stream.stdout.streams.map((codec, idx) => (
{codec.width ? (
Video:

Codec: {codec.codec_long_name}
Resolution: {codec.width}x{codec.height}
FPS: {codec.avg_frame_rate == '0/0' ? 'Unknown' : codec.avg_frame_rate}

) : (
Audio:

Codec: {codec.codec_long_name}

)}
))}
) : (
Error: {stream.stderr}
)}
))}
) : ( )}
)} {state.showVainfo && (
Vainfo Output {state.vainfo != '' ? (
Return Code: {state.vainfo.return_code}

Process {state.vainfo.return_code == 0 ? 'Output' : 'Error'}:

{state.vainfo.return_code == 0 ? state.vainfo.stdout : state.vainfo.stderr}
) : ( )}
)} {!detectors ? (
) : ( Detectors
{detectorNames.map((detector) => (
{detector}
P-ID Inference Speed CPU % Memory %
{detectors[detector]['pid']} {detectors[detector]['inference_speed']} ms {cpu_usages[detectors[detector]['pid']]?.['cpu'] || '- '}% {cpu_usages[detectors[detector]['pid']]?.['mem'] || '- '}%
))}
GPUs
{!gpu_usages ? (
Hardware acceleration has not been setup, see the docs to setup hardware acceleration.
) : (
{gpuNames.map((gpu) => (
{gpu}
{gpu_usages[gpu]['gpu'] == -1 ? (
There was an error getting usage stats. This does not mean hardware acceleration is not working. Either your GPU does not support this or Frigate does not have proper access to get statistics. This is expected for the Home Assistant addon.
) : (
GPU % Memory %
{gpu_usages[gpu]['gpu']} {gpu_usages[gpu]['mem']}
)}
))}
)} Cameras {!cameras ? ( ) : (
{cameraNames.map((camera) => (
{camera.replaceAll('_', ' ')}
{(() => { if (cameras[camera]['pid'] && cameras[camera]['detection_enabled'] == 1) return ( ); else if (cameras[camera]['pid'] && cameras[camera]['detection_enabled'] == 0) return ; return ; })()}
Process P-ID FPS CPU % Memory %
ffmpeg {cameras[camera]['ffmpeg_pid'] || '- '} {cameras[camera]['camera_fps'] || '- '} {cpu_usages[cameras[camera]['ffmpeg_pid']]?.['cpu'] || '- '}% {cpu_usages[cameras[camera]['ffmpeg_pid']]?.['mem'] || '- '}%
Capture {cameras[camera]['capture_pid'] || '- '} {cameras[camera]['process_fps'] || '- '} {cpu_usages[cameras[camera]['capture_pid']]?.['cpu'] || '- '}% {cpu_usages[cameras[camera]['capture_pid']]?.['mem'] || '- '}%
Detect {cameras[camera]['pid'] || '- '} {cameras[camera]['detection_fps']} ({cameras[camera]['skipped_fps']} skipped) disabled- {cpu_usages[cameras[camera]['pid']]?.['cpu'] || '- '}% {cpu_usages[cameras[camera]['pid']]?.['mem'] || '- '}%
))}
)}

System stats update automatically every {config.mqtt.stats_interval} seconds.

)}
); }