mirror of
https://github.com/blakeblackshear/frigate.git
synced 2026-02-10 21:25:24 +03:00
Show camera storage usage
This commit is contained in:
parent
76b805eba1
commit
f25b329909
@ -137,14 +137,8 @@ type StorageGraphProps = {
|
|||||||
graphId: string;
|
graphId: string;
|
||||||
used: number;
|
used: number;
|
||||||
total: number;
|
total: number;
|
||||||
data: ApexAxisChartSeries;
|
|
||||||
};
|
};
|
||||||
export function StorageGraph({
|
export function StorageGraph({ graphId, used, total }: StorageGraphProps) {
|
||||||
graphId,
|
|
||||||
used,
|
|
||||||
total,
|
|
||||||
data,
|
|
||||||
}: StorageGraphProps) {
|
|
||||||
const { theme, systemTheme } = useTheme();
|
const { theme, systemTheme } = useTheme();
|
||||||
|
|
||||||
const options = useMemo(() => {
|
const options = useMemo(() => {
|
||||||
@ -225,7 +219,14 @@ export function StorageGraph({
|
|||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div className="h-5 rounded-md overflow-hidden">
|
<div className="h-5 rounded-md overflow-hidden">
|
||||||
<Chart type="bar" options={options} series={data} height="100%" />
|
<Chart
|
||||||
|
type="bar"
|
||||||
|
options={options}
|
||||||
|
series={[
|
||||||
|
{ data: [{ x: "storage", y: Math.round((used / total) * 100) }] },
|
||||||
|
]}
|
||||||
|
height="100%"
|
||||||
|
/>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
);
|
);
|
||||||
|
|||||||
@ -71,12 +71,7 @@ function System() {
|
|||||||
setLastUpdated={setLastUpdated}
|
setLastUpdated={setLastUpdated}
|
||||||
/>
|
/>
|
||||||
)}
|
)}
|
||||||
{page == "storage" && (
|
{page == "storage" && <StorageMetrics setLastUpdated={setLastUpdated} />}
|
||||||
<StorageMetrics
|
|
||||||
lastUpdated={lastUpdated}
|
|
||||||
setLastUpdated={setLastUpdated}
|
|
||||||
/>
|
|
||||||
)}
|
|
||||||
</div>
|
</div>
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|||||||
@ -1,4 +1,5 @@
|
|||||||
import { StorageGraph } from "@/components/graph/SystemGraph";
|
import { StorageGraph } from "@/components/graph/SystemGraph";
|
||||||
|
import { FrigateStats } from "@/types/stats";
|
||||||
import { useMemo } from "react";
|
import { useMemo } from "react";
|
||||||
import useSWR from "swr";
|
import useSWR from "swr";
|
||||||
|
|
||||||
@ -11,30 +12,32 @@ type CameraStorage = {
|
|||||||
};
|
};
|
||||||
|
|
||||||
type StorageMetricsProps = {
|
type StorageMetricsProps = {
|
||||||
lastUpdated: number;
|
|
||||||
setLastUpdated: (last: number) => void;
|
setLastUpdated: (last: number) => void;
|
||||||
};
|
};
|
||||||
export default function StorageMetrics({
|
export default function StorageMetrics({
|
||||||
lastUpdated,
|
|
||||||
setLastUpdated,
|
setLastUpdated,
|
||||||
}: StorageMetricsProps) {
|
}: StorageMetricsProps) {
|
||||||
const { data: storage } = useSWR<CameraStorage>("recordings/storage");
|
const { data: cameraStorage } = useSWR<CameraStorage>("recordings/storage");
|
||||||
|
const { data: stats } = useSWR<FrigateStats>("stats");
|
||||||
|
|
||||||
const totalStorage = useMemo(() => {
|
const totalStorage = useMemo(() => {
|
||||||
if (!storage) {
|
if (!cameraStorage || !stats) {
|
||||||
return undefined;
|
return undefined;
|
||||||
}
|
}
|
||||||
|
|
||||||
const totalStorage = {
|
const totalStorage = {
|
||||||
total: 0,
|
used: 0,
|
||||||
|
total: stats.service.storage["/media/frigate/recordings"]["total"],
|
||||||
};
|
};
|
||||||
|
|
||||||
Object.values(storage).forEach((cam) => (totalStorage.total += cam.usage));
|
Object.values(cameraStorage).forEach(
|
||||||
|
(cam) => (totalStorage.used += cam.usage),
|
||||||
|
);
|
||||||
|
setLastUpdated(Date.now() / 1000);
|
||||||
return totalStorage;
|
return totalStorage;
|
||||||
}, [storage]);
|
}, [cameraStorage, stats, setLastUpdated]);
|
||||||
|
|
||||||
if (!totalStorage) {
|
if (!cameraStorage || !stats || !totalStorage) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -48,11 +51,41 @@ export default function StorageMetrics({
|
|||||||
<div className="mb-5">Recordings</div>
|
<div className="mb-5">Recordings</div>
|
||||||
<StorageGraph
|
<StorageGraph
|
||||||
graphId="general-recordings"
|
graphId="general-recordings"
|
||||||
used={1000000}
|
used={totalStorage.used}
|
||||||
total={5000000}
|
total={totalStorage.total}
|
||||||
data={[{ name: "Recordings", data: [{ x: "Recordings", y: 25 }] }]}
|
|
||||||
/>
|
/>
|
||||||
</div>
|
</div>
|
||||||
|
<div className="p-2.5 bg-primary rounded-2xl flex-col">
|
||||||
|
<div className="mb-5">/tmp/cache</div>
|
||||||
|
<StorageGraph
|
||||||
|
graphId="general-cache"
|
||||||
|
used={stats.service.storage["/tmp/cache"]["used"]}
|
||||||
|
total={stats.service.storage["/tmp/cache"]["total"]}
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
|
<div className="p-2.5 bg-primary rounded-2xl flex-col">
|
||||||
|
<div className="mb-5">/dev/shm</div>
|
||||||
|
<StorageGraph
|
||||||
|
graphId="general-shared-memory"
|
||||||
|
used={stats.service.storage["/dev/shm"]["used"]}
|
||||||
|
total={stats.service.storage["/dev/shm"]["total"]}
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div className="mt-4 text-muted-foreground text-sm font-medium">
|
||||||
|
Camera Storage
|
||||||
|
</div>
|
||||||
|
<div className="mt-4 grid grid-cols-1 sm:grid-cols-3 gap-2">
|
||||||
|
{Object.keys(cameraStorage).map((camera) => (
|
||||||
|
<div className="p-2.5 bg-primary rounded-2xl flex-col">
|
||||||
|
<div className="mb-5 capitalize">{camera.replaceAll("_", " ")}</div>
|
||||||
|
<StorageGraph
|
||||||
|
graphId={`${camera}-storage`}
|
||||||
|
used={cameraStorage[camera].usage}
|
||||||
|
total={totalStorage.used}
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
|
))}
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
);
|
);
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user