diff --git a/package-lock.json b/package-lock.json index e369745..a656312 100644 --- a/package-lock.json +++ b/package-lock.json @@ -42,7 +42,7 @@ "mui-tel-input": "^7.0.0", "notistack": "^3.0.1", "openweathermap-ts": "^1.2.10", - "protobuf-ts": "git+https://gitlab+deploy-token-50627:hv8mB4WkyvtjBpJKU1rN@gitlab.com/brandx/protobuf-ts.git#master", + "protobuf-ts": "git+https://gitlab+deploy-token-50627:hv8mB4WkyvtjBpJKU1rN@gitlab.com/brandx/protobuf-ts.git#staging", "react": "^18.3.1", "react-beautiful-dnd": "^13.1.1", "react-color": "^2.19.3", @@ -10864,7 +10864,7 @@ }, "node_modules/protobuf-ts": { "version": "1.0.0", - "resolved": "git+https://gitlab+deploy-token-50627:hv8mB4WkyvtjBpJKU1rN@gitlab.com/brandx/protobuf-ts.git#f8704561c094b208029340cdf2ce0c510ef1eb12", + "resolved": "git+https://gitlab+deploy-token-50627:hv8mB4WkyvtjBpJKU1rN@gitlab.com/brandx/protobuf-ts.git#cead0be8708fa2c6679c77ed38f51239341c4ed4", "dependencies": { "protobufjs": "^6.8.8" } diff --git a/package.json b/package.json index 8e3ebd3..5a32392 100644 --- a/package.json +++ b/package.json @@ -52,7 +52,7 @@ "mui-tel-input": "^7.0.0", "notistack": "^3.0.1", "openweathermap-ts": "^1.2.10", - "protobuf-ts": "git+https://gitlab+deploy-token-50627:hv8mB4WkyvtjBpJKU1rN@gitlab.com/brandx/protobuf-ts.git#master", + "protobuf-ts": "git+https://gitlab+deploy-token-50627:hv8mB4WkyvtjBpJKU1rN@gitlab.com/brandx/protobuf-ts.git#staging", "react": "^18.3.1", "react-beautiful-dnd": "^13.1.1", "react-color": "^2.19.3", diff --git a/src/common/StatusGas.tsx b/src/common/StatusGas.tsx new file mode 100644 index 0000000..b0ebb85 --- /dev/null +++ b/src/common/StatusGas.tsx @@ -0,0 +1,162 @@ +import { Box, Grid2, Theme, Tooltip, Typography } from "@mui/material"; +import { blue, deepOrange, green, grey, orange, teal } from "@mui/material/colors"; +import { makeStyles } from "@mui/styles"; +import { Device } from "models"; +import PulseBox from "./PulseBox"; +import { or } from "utils"; +import { useEffect, useState } from "react"; + +interface Props { + device: Device + // noDust?: boolean; + gasType: "co2" | "co" | "no2" | "o2" | "all" +} + +const useStyles = makeStyles((theme: Theme) => { + const lightMode = theme.palette?.mode === "light"; + return ({ + box: { + display: "inline-block", + borderRadius: "6px", + backgroundColor: lightMode ? "rgb(210, 210, 210)" : "rgb(50, 50, 50)", + padding: theme.spacing(0.75), + marginRight: "auto", + margin: theme.spacing(1), + width: theme.spacing(14), + height: theme.spacing(6), + }, + carouselContainer: { + position: 'relative', + height: '40px', + overflow: 'hidden', + textAlign: "center", + }, + carouselItem: { + opacity: 0, + transform: 'translateX(100%)', + transition: 'opacity 0.5s ease, transform 0.5s ease', + position: 'absolute', + width: '100%', + overflow: "hidden", + // height: '100%', + }, + active: { + opacity: 1, + transform: 'translateX(0)', + }, + inactive: { + transform: 'translateX(-100%)', + }, + }) +}) + +export default function StatusGas(props: Props) { + const { device, gasType } = props; + const classes = useStyles() + // console.log(noDust) + // const colors = or(device.status.sen5x?.overlays.map(overlay => overlay.color), []); + // const messages = or(device.status.sen5x?.overlays.map(overlay => overlay.message), []); + + // const [color, setColor] = useState(colors.length > 0 ? colors[0] : ""); + // const [, setColorIndex] = useState(0) + + // useEffect(() => { + // const interval = setInterval(() => { + // setColorIndex(prevIndex => { + // const newIndex = prevIndex >= colors.length - 1 ? 0 : prevIndex + 1; + // setColor(colors[newIndex]); // Use the new index here + // return newIndex; + // }); + // }, 7500); + + // return () => clearInterval(interval); + // }, []); + + // const [currentIndex, setCurrentIndex] = useState(0); + + // Auto-cycle through measurements every 5 seconds + // useEffect(() => { + // if (noDust) { + // setCurrentIndex(0) + // return + // } + // const interval = setInterval(() => { + // if (!noDust) setCurrentIndex((prevIndex) => (prevIndex + 1) % 2); + // setCurrentIndex((prevIndex) => (prevIndex + 1) % 2); + // }, 5000); + + // return () => clearInterval(interval); // Cleanup on unmount + // }, [noDust]); + + // const tooltip = () => { + // if (messages.length === 0) return null + // if (messages.length < 2) return ( + // messages[0] + // ) + // return ( + // + // + // + // Overlay Messages + // + // + // {messages.map((message, index) => { + // return ( + // + // + // + // {message} + // + // + // ) + // })} + // + // ) + // } + + const gasDisplay = () => { + if (gasType !== "all") { + return( + // + + + + + {gasType !== "o2" ? + + Gas: {device.status[gasType]?.ppm.toFixed(1)}ppm + + : + + Gas: {(device.status[gasType]?.ppm!/10000).toFixed(1)}% + + } + + + + Volt: {device.status[gasType]?.millivolts.toFixed(1)}mV + + + + + + // + ) + + } + } + + return ( + <> + {gasDisplay()} + + ) +} \ No newline at end of file diff --git a/src/common/StatusSen5x.tsx b/src/common/StatusSen5x.tsx index 8d32f35..288eb10 100644 --- a/src/common/StatusSen5x.tsx +++ b/src/common/StatusSen5x.tsx @@ -49,7 +49,7 @@ const useStyles = makeStyles((theme: Theme) => { }) }) -export default function StatusPlenum(props: Props) { +export default function StatusSen5x(props: Props) { const { device, noDust } = props; const classes = useStyles() // console.log(noDust) diff --git a/src/pages/Devices.tsx b/src/pages/Devices.tsx index a394d18..dcd2c1c 100644 --- a/src/pages/Devices.tsx +++ b/src/pages/Devices.tsx @@ -25,6 +25,7 @@ import moment from "moment"; import StatusPlenum from "common/StatusPlenum"; import StatusSen5x from "common/StatusSen5x"; import StatusDust from "common/StatusDust"; +import StatusGas from "common/StatusGas"; const useStyles = makeStyles((theme: Theme) => { return ({ @@ -101,6 +102,10 @@ export default function Devices() { const [isProvisionDialogOpen, setIsProvisionDialogOpen] = useState(false); const [hasPlenums, setHasPlenums] = useState(false) const [hasSen5x, setHasSen5x] = useState(false) + const [hasCo, setHasCo] = useState(false) + const [hasCo2, setHasCo2] = useState(false) + const [hasNo2, setHasNo2] = useState(false) + const [hasO2, setHasO2] = useState(false) const [groupsLoading, setGroupsLoading] = useState(false) const [groups, setGroups] = useState([]); @@ -264,6 +269,10 @@ export default function Devices() { resp.data.devices.forEach(device => { if (device.status?.plenum?.temperature) setHasPlenums(true) if (device.status?.sen5x?.temperature) setHasSen5x(true) + if (device.status?.o2) setHasO2(true) + if (device.status?.co) setHasCo(true) + if (device.status?.co2) setHasCo2(true) + if (device.status?.no2) setHasNo2(true) newDevices.push(Device.create(device)) }) setDevices(newDevices) @@ -311,6 +320,10 @@ export default function Devices() { return '/' + newSegments.join('/'); } + useEffect(() => { + console.log(devices) + }, [devices]) + const toDevice = (device: Device) => { let url = getGroup() ? insertGroupContext(getGroup().id().toString(), device.id().toString()) : "" if (url.length < 1) url = device.id().toString() @@ -440,6 +453,78 @@ export default function Devices() { } }) } + if (hasCo) { + columns.push({ + title: "CO", + render: (device: Device) => { + if (device.status.co) { + return ( + + + + ) + } else { + return ( + <> + ) + } + } + }) + } + if (hasCo2) { + columns.push({ + title: "CO2", + render: (device: Device) => { + if (device.status.co2) { + return ( + + + + ) + } else { + return ( + <> + ) + } + } + }) + } + if (hasNo2) { + columns.push({ + title: "NO2", + render: (device: Device) => { + if (device.status.no2) { + return ( + + + + ) + } else { + return ( + <> + ) + } + } + }) + } + if (hasCo2) { + columns.push({ + title: "O2", + render: (device: Device) => { + if (device.status.o2) { + return ( + + + + ) + } else { + return ( + <> + ) + } + } + }) + } return columns }