frontend/src/bin/BinControllerDisplay.tsx

168 lines
No EOL
4.9 KiB
TypeScript

import { Component } from "models"
import React, { useEffect, useState } from "react"
import { makeStyles } from "@mui/styles";
import { Box, Button, DialogActions, DialogContent, DialogTitle, Typography } from "@mui/material";
import AerationFanIcon from "products/AgIcons/AerationFanIcon";
import { quack } from "protobuf-ts/quack";
import { useComponentAPI, useMobile, useSnackbar } from "hooks";
import ButtonGroup from "common/ButtonGroup";
import ObjectHeaterIcon from "products/Construction/ObjectHeaterIcon";
import ResponsiveDialog from "common/ResponsiveDialog";
interface Props {
deviceID: number
component: Component
currentState?: boolean
}
const useStyles = makeStyles(() => {
return ({
controllerDisplay: {
display: "flex",
justifyContent: "space-between",
paddingLeft: 5,
paddingRight: 5
},
})
})
export default function BinControllerDisplay(props: Props) {
const {component, deviceID, currentState} = props
const [controllerState, setControllerState] = useState(0)
const [openDialog, setOpenDialog] = useState(false)
const [newOutputState, setNewOutputState] = useState(0)
const {openSnack} = useSnackbar()
const componentAPI = useComponentAPI()
const isMobile = useMobile()
const classes = useStyles()
useEffect(()=>{
setControllerState(component.settings.defaultOutputState)
},[component])
const controllerIcon = () => {
if(component.subType() === quack.BooleanOutputSubtype.BOOLEAN_OUTPUT_SUBTYPE_HEATER){
return <ObjectHeaterIcon />
}else{
return <AerationFanIcon />
}
}
const setController = () => {
let newSettings = component.settings
newSettings.defaultOutputState = newOutputState
componentAPI.update(deviceID, newSettings).then(resp => {
openSnack("Updated controllers output state")
setControllerState(newOutputState)
}).catch(err => {
openSnack("There was a problem updating the controller")
}).finally(() => {
setOpenDialog(false)
})
}
const controllerDialog = () => {
return (
<ResponsiveDialog open={openDialog} onClose={() => {setOpenDialog(false)}}>
<DialogTitle>Set Controller State</DialogTitle>
<DialogContent>
This Action will change the output state of the controller
</DialogContent>
<DialogActions>
<Button onClick={()=>{setOpenDialog(false)}}>Cancel</Button>
<Button onClick={()=>{setController()}} variant="contained" color="primary">Confirm</Button>
</DialogActions>
</ResponsiveDialog>
)
}
const componentOn = () => {
if(currentState){
return currentState
}else{
let state = false
component.status.lastGoodMeasurement.forEach(um => {
if(um.type === quack.MeasurementType.MEASUREMENT_TYPE_BOOLEAN){
if(um.values.length > 0){
let readings = um.values
if(readings[readings.length-1].values.length > 0){
let nodes = readings[readings.length-1].values
if (nodes[nodes.length -1] === 1){
state = true
}
}
}
}
})
return state
}
}
return (
<React.Fragment>
{controllerDialog()}
<Box className={classes.controllerDisplay} key={component.key()} marginTop={1} marginBottom={1}>
<Box display="flex" marginY="auto">
<Box margin="auto">
{controllerIcon()}
</Box>
<Typography
align="center"
style={{
marginBottom: "auto",
marginTop: "auto",
paddingLeft: 5,
fontSize: isMobile ? "0.85rem" : "1.0rem",
fontWeight: 650
}}>
{component.name()}
</Typography>
</Box>
<Box display="flex">
<ButtonGroup
buttons={[
{
title: "Auto",
function: () => {
setNewOutputState(0)
setOpenDialog(true)
}
},
{
title: "On",
function: () => {
setNewOutputState(1)
setOpenDialog(true)
}
},
{
title: "Off",
function: () => {
setNewOutputState(2)
setOpenDialog(true)
}
}
]}
toggledButtons={[controllerState]}
toggle
/>
<Typography
style={{
minWidth: 30,
marginLeft: "10px",
marginBottom: "auto",
marginTop: "auto",
fontSize: isMobile ? "0.85rem" : "1.0rem",
fontWeight: 650,
color: componentOn() ? "green" : "orange"
}}>
{componentOn() ? "ON" : "OFF"}
</Typography>
</Box>
</Box>
</React.Fragment>
)
}