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 (
Last refreshed:
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'] || '- '}% |
GPU % | Memory % |
---|---|
{gpu_usages[gpu]['gpu']} | {gpu_usages[gpu]['mem']} |
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'] || '- '} | {(() => { if (cameras[camera]['pid'] && cameras[camera]['detection_enabled'] == 1) return ({cameras[camera]['detection_fps']} ({cameras[camera]['skipped_fps']} skipped) | ); else if (cameras[camera]['pid'] && cameras[camera]['detection_enabled'] == 0) returndisabled | ; return- | ; })()}{cpu_usages[cameras[camera]['pid']]?.['cpu'] || '- '}% | {cpu_usages[cameras[camera]['pid']]?.['mem'] || '- '}% |
System stats update automatically every {config.mqtt.stats_interval} seconds.