implemented device statistics

This commit is contained in:
Carter 2025-01-27 10:36:54 -06:00
parent 0076f2d208
commit 3a000b0094
8 changed files with 276 additions and 111 deletions

View file

@ -1,5 +1,4 @@
import {
CircularProgress,
Dialog,
DialogContent,
DialogTitle,
@ -20,9 +19,8 @@ import TagSettings from "common/TagSettings";
import { Device, Tag } from "models";
import { filterByTag } from "pbHelpers/Tag";
import { useDeviceAPI, useSnackbar, useTagAPI } from "providers";
import React, { useEffect, useRef, useState } from "react";
import React, { useEffect, useState } from "react";
import { pond } from "protobuf-ts/pond";
import { getContextKeys, getContextTypes } from "pbHelpers/Context";
const useStyles = makeStyles((_theme: Theme) => {
return ({
@ -137,14 +135,14 @@ export default function DeviceTags(props: DeviceTagsProps) {
// const [{ tags }] = useGlobalState();
const tagAPI = useTagAPI()
const [tags, setTags] = useState<Tag[]>([])
const [loading, setLoading] = useState(false)
// const [loading, setLoading] = useState(false)
const deviceAPI = useDeviceAPI();
const { error } = useSnackbar();
const [deviceTags, setDeviceTags] = useState<string[]>(device.status.tagKeys);
const previousDeviceRef = useRef(device);
// const previousDeviceRef = useRef(device);
const loadTags = () => {
setLoading(true)
// setLoading(true)
tagAPI.listTags().then(resp => {
let newTags: Tag[] = [];
resp.data.tags.forEach((tag: pond.Tag) => {
@ -152,12 +150,11 @@ export default function DeviceTags(props: DeviceTagsProps) {
})
setTags(newTags)
}).finally(() => {
setLoading(false)
// setLoading(false)
})
}
useEffect(() => {
console.log(props.tags)
let newTags: string[] = []
props.tags.forEach(tag => {
if (tag.settings) newTags.push(tag.settings?.key)
@ -169,34 +166,6 @@ export default function DeviceTags(props: DeviceTagsProps) {
loadTags()
}, [])
// useEffect(() => {
// // if (previousDeviceRef.current !== device) {
// let keys = getContextKeys()
// keys.push(device.id().toString())
// let types = getContextTypes()
// types.push("device")
// setDeviceTags(device.status.tagKeys);
// previousDeviceRef.current = device;
// tagAPI.listTags(
// undefined,
// undefined,
// undefined,
// undefined,
// undefined,
// undefined,
// keys,
// types,
// ).then(resp => {
// // console.log(resp.data)
// let newTagKeys: string[] = []
// resp.data.tags.forEach((tag: any) => {
// newTagKeys.push(tag.settings.key)
// })
// setDeviceTags(newTagKeys)
// })
// // }
// }, [device]);
const addTag = (tag: Tag) => {
if (!deviceTags.some(dt => dt === tag.key())) {
deviceAPI

View file

@ -0,0 +1,140 @@
import {
AutoAwesomeMosaic,
Battery20,
Check,
CheckCircle,
PermScanWifi,
} from "@mui/icons-material";
import { Card, Grid2, Typography, useTheme } from "@mui/material";
import { blue, green, purple, red } from "@mui/material/colors";
import CircleGraphIcon from "common/CircleGraphIcon";
import { getContextKeys, getContextTypes } from "pbHelpers/Context";
import { pond } from "protobuf-ts/pond";
import { useDeviceAPI } from "providers";
import { useEffect, useState } from "react";
interface Props {}
export default function DevicesSummary(props: Props) {
const deviceAPI = useDeviceAPI()
const theme = useTheme()
const [stats, setStats] = useState<pond.DeviceStatistics>(pond.DeviceStatistics.create())
const [loadingStats, setLoadingStats] = useState(false)
const loadDeviceStatistics = () => {
setLoadingStats(true)
deviceAPI.statistics(
getContextKeys(),
getContextTypes()
).then(resp => {
let stats = pond.DeviceStatistics.fromObject(resp.data.stats)
setStats(stats)
}).finally(() => {
setLoadingStats(false)
})
}
useEffect(() => {
loadDeviceStatistics()
}, [])
const getPercent = (devices: number) => {
const ratio = devices/stats.total
return ratio*100
}
return (
<Grid2 container spacing={1} marginBlock={1} >
<Grid2 size={{xs: 6, sm: 3}}>
<Card sx={{ padding: 1 }}>
<Grid2 container spacing={1} justifyContent={"center"} alignItems={"center"} >
<Grid2>
<CircleGraphIcon
sx={{ marginRight: 1, marginLeft: 1 }}
progress={100}
color={"info"}
icon={<AutoAwesomeMosaic />}
/>
</Grid2>
<Grid2 marginRight={1}>
<Typography variant="h6" >
{stats.total} Devices
</Typography>
<Typography variant="subtitle2" color="textSecondary">
Total
</Typography>
</Grid2>
</Grid2>
</Card>
</Grid2>
<Grid2 size={{xs: 6, sm: 3}}>
<Card sx={{ padding: 1 }}>
<Grid2 container spacing={1} justifyContent={"center"} alignItems={"center"} >
<Grid2>
<CircleGraphIcon
sx={{ marginRight: 1, marginLeft: 1 }}
progress={getPercent(stats.active)}
color={"success"}
icon={<Check />}
/>
</Grid2>
<Grid2 marginRight={1}>
<Typography variant="h6" >
{stats.active} Devices
</Typography>
<Typography variant="subtitle2" color="textSecondary">
Active
</Typography>
</Grid2>
</Grid2>
</Card>
</Grid2>
<Grid2 size={{xs: 6, sm: 3}}>
<Card sx={{ padding: 1 }}>
<Grid2 container spacing={1} justifyContent={"center"} alignItems={"center"} >
<Grid2>
<CircleGraphIcon
sx={{ marginRight: 1, marginLeft: 1 }}
progress={getPercent(stats.warning)}
color="warning"
icon={<Battery20 />}
/>
</Grid2>
<Grid2 marginRight={1}>
<Typography variant="h6" >
{stats.warning} Devices
</Typography>
<Typography variant="subtitle2" color="textSecondary">
Low Power
</Typography>
</Grid2>
</Grid2>
</Card>
</Grid2>
<Grid2 size={{xs: 6, sm: 3}}>
<Card sx={{ padding: 1 }}>
<Grid2 container spacing={1} justifyContent={"center"} alignItems={"center"} >
<Grid2>
<CircleGraphIcon
sx={{ marginRight: 1, marginLeft: 1 }}
progress={100}
color={green[50]}
icon={<PermScanWifi />}
/>
</Grid2>
<Grid2 marginRight={1}>
<Typography variant="h6" >
{stats.offline} Devices
</Typography>
<Typography variant="subtitle2" color="textSecondary">
Offline
</Typography>
</Grid2>
</Grid2>
</Card>
</Grid2>
</Grid2>
)
}