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';
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 });
let paths = '';
config.cameras[camera].ffmpeg.inputs.forEach((input) => {
if (paths) {
paths += ',';
paths += input.path;
} else {
paths = input.path;
}
});
const response = await axios.get('ffprobe', {
params: {
paths,
},
});
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 () => {
await window.navigator.clipboard.writeText(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 () => {
await window.navigator.clipboard.writeText(JSON.stringify(state.vaifp, null, 2));
setState({ ...state, vainfo: '', showVainfo: false });
};
return (
System {service.version}
{state.showFfprobe && (
)}
{state.showVainfo && (
)}
{!detectors ? (
) : (
Detectors
{detectorNames.map((detector) => (
{detector}
P-ID |
Detection Start |
Inference Speed |
{detectors[detector]['pid']} |
{detectors[detector]['detection_start']} |
{detectors[detector]['inference_speed']} |
))}
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
{cameraNames.map((camera) => (
{camera.replaceAll('_', ' ')}
Process |
P-ID |
fps |
Cpu % |
Memory % |
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']}% |
ffmpeg |
{cameras[camera]['ffmpeg_pid']} |
{cameras[camera]['camera_fps']} |
{cpu_usages[cameras[camera]['ffmpeg_pid']]['cpu']}% |
{cpu_usages[cameras[camera]['ffmpeg_pid']]['mem']}% |
))}
System stats update automatically every {config.mqtt.stats_interval} seconds.
)}
);
}