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 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: JSON.stringify(response.data, null, 2) });
} else {
setState({ ...state, showFfprobe: true, ffprobe: 'There was an error getting the ffprobe output.' });
}
};
const onCopyFfprobe = async () => {
copy(JSON.stringify(state.ffprobe, null, 2));
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: JSON.stringify(response.data, null, 2) });
} else {
setState({ ...state, showVainfo: true, vainfo: 'There was an error getting the vainfo output.' });
}
};
const onCopyVainfo = async () => {
copy(JSON.stringify(state.vainfo, null, 2));
setState({ ...state, vainfo: '', showVainfo: false });
};
return (
System {service.version}
{state.showFfprobe && (
)}
{state.showVainfo && (
)}
{!detectors ? (
) : (
Detectors
{detectorNames.map((detector) => (
{detector}
P-ID |
Inference Speed |
CPU % |
{detectors[detector]['pid']} |
{detectors[detector]['inference_speed']} ms |
{cpu_usages[detectors[detector]['pid']]?.['cpu'] || '- '}% |
))}
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. Either your GPU does not support this or frigate does
not have proper access.
) : (
GPU % |
Memory % |
{gpu_usages[gpu]['gpu']} |
{gpu_usages[gpu]['mem']} |
)}
))}
)}
Cameras
{!cameras ? (
) : (
{cameraNames.map((camera) => (
{camera.replaceAll('_', ' ')}
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)
|
{cpu_usages[cameras[camera]['pid']]?.['cpu'] || '- '}% |
{cpu_usages[cameras[camera]['pid']]?.['mem'] || '- '}% |
))}
)}
System stats update automatically every {config.mqtt.stats_interval} seconds.
)}
);
}