feat(frontend): device execute commands

This commit is contained in:
leandrofars 2023-11-06 00:30:56 -03:00
parent 221460763c
commit 926fcf25aa
2 changed files with 302 additions and 71 deletions

View File

@ -19,6 +19,7 @@ import {
} from '@mui/material'; } from '@mui/material';
import ArrowRightIcon from '@heroicons/react/24/solid/ArrowRightIcon'; import ArrowRightIcon from '@heroicons/react/24/solid/ArrowRightIcon';
import CircularProgress from '@mui/material/CircularProgress'; import CircularProgress from '@mui/material/CircularProgress';
import PlayCircle from '@heroicons/react/24/outline/PlayCircleIcon'
import PlusCircleIcon from '@heroicons/react/24/outline/PlusCircleIcon'; import PlusCircleIcon from '@heroicons/react/24/outline/PlusCircleIcon';
import Pencil from "@heroicons/react/24/outline/PencilIcon" import Pencil from "@heroicons/react/24/outline/PencilIcon"
import ArrowUturnLeftIcon from '@heroicons/react/24/outline/ArrowUturnLeftIcon' import ArrowUturnLeftIcon from '@heroicons/react/24/outline/ArrowUturnLeftIcon'
@ -26,6 +27,7 @@ import XMarkIcon from '@heroicons/react/24/outline/XMarkIcon';
import { useRouter } from 'next/router'; import { useRouter } from 'next/router';
import TrashIcon from '@heroicons/react/24/outline/TrashIcon'; import TrashIcon from '@heroicons/react/24/outline/TrashIcon';
import PlayCircleIcon from '@heroicons/react/24/outline/PlayCircleIcon';
/* /*
OBJ_READ_ONLY (0) OBJ_READ_ONLY (0)
@ -150,9 +152,9 @@ const deleteDeviceObj = async(obj, setShowLoading, router, updateDeviceParameter
} }
function ShowPath({x,updateDeviceParameters,setShowLoading, router}) { function ShowPath({x,updateDeviceParameters,setShowLoading, router}) {
console.log(x) // console.log(x)
console.log("x.supported_obj_path:", x.supported_obj_path) // console.log("x.supported_obj_path:", x.supported_obj_path)
console.log("x.access:", x.access) // console.log("x.access:", x.access)
if(x.supported_obj_path != "Device."){ if(x.supported_obj_path != "Device."){
if (x.access === ObjAccessType.ReadOnly || x.access === undefined){ if (x.access === ObjAccessType.ReadOnly || x.access === undefined){
return ( return (
@ -205,7 +207,8 @@ function ShowParamsWithValues({
setOpen, setParameter, setOpen, setParameter,
setParameterValue, deviceParameters, setParameterValue, deviceParameters,
setShowLoading, router, setShowLoading, router,
updateDeviceParameters updateDeviceParameters, deviceCommands,
openCommandDialog
}) { }) {
console.log("HEY jow:", deviceParametersValue) console.log("HEY jow:", deviceParametersValue)
let paths = x.supported_obj_path.split(".") let paths = x.supported_obj_path.split(".")
@ -297,11 +300,46 @@ function ShowParamsWithValues({
</List> </List>
) )
}):<></>} }):<></>}
{
deviceCommands &&
Object.keys(deviceCommands).map(commando =>{
console.log("Comando:", commando)
return <List
component="div"
disablePadding
dense={true}
key={commando}
>
<ListItem
key={commando}
divider={true}
sx={{
boxShadow: 'rgba(149, 157, 165, 0.2) 0px 0px 5px;',
pl: 4
}}
secondaryAction={
<IconButton>
<SvgIcon>
<PlayCircleIcon>
</PlayCircleIcon>
</SvgIcon>
</IconButton>
}
>
<ListItemText
primary={commando}
/>
</ListItem>
</List>
})
}
</List> </List>
) )
}) })
}else{ }else{
return x.supported_params.map((y, index)=>{ return (
<>
{x.supported_params && x.supported_params.map((y, index)=>{
return ( return (
<List <List
component="div" component="div"
@ -339,15 +377,52 @@ function ShowParamsWithValues({
primary={y.param_name} primary={y.param_name}
/> />
</ListItem> </ListItem>
</List>) </List>
)
})}
{
deviceCommands &&
Object.keys(deviceCommands).map(commando =>{
console.log("Comando:", commando)
return <List
component="div"
disablePadding
dense={true}
key={commando}
>
<ListItem
key={commando}
divider={true}
sx={{
boxShadow: 'rgba(149, 157, 165, 0.2) 0px 0px 5px;',
pl: 4
}}
secondaryAction={
<IconButton>
<SvgIcon>
<PlayCircleIcon>
</PlayCircleIcon>
</SvgIcon>
</IconButton>
}
>
<ListItemText
primary={commando}
/>
</ListItem>
</List>
}) })
} }
</>
)
}
} }
export const DevicesDiscovery = () => { export const DevicesDiscovery = () => {
const router = useRouter() const router = useRouter()
const [deviceCommands, setDeviceCommands] = useState({})
const [deviceParameters, setDeviceParameters] = useState(null) const [deviceParameters, setDeviceParameters] = useState(null)
const [parameter, setParameter] = useState(null) const [parameter, setParameter] = useState(null)
const [parameterValue, setParameterValue] = useState(null) const [parameterValue, setParameterValue] = useState(null)
@ -357,10 +432,35 @@ const [open, setOpen] = useState(false)
const [errorModal, setErrorModal] = useState(false) const [errorModal, setErrorModal] = useState(false)
const [errorModalText, setErrorModalText] = useState("") const [errorModalText, setErrorModalText] = useState("")
const [showLoading, setShowLoading] = useState(false) const [showLoading, setShowLoading] = useState(false)
const [openCommandDialog, setOpenCommandDialog] = useState(false)
const [deviceCommandToExecute, setDeviceCommandToExecute] = useState(null)
const [inputArgsValue, setInputArgsValue] = useState({})
// const initDeviceCommands = (content) => {
// let supportedCommands = content?.req_obj_results[0].supported_objs[0].supported_commands
// if (supportedCommands === undefined){
// return paramsToFetch
// }
// let commands = {}
// for(let i =0; i < supportedCommands.length; i++){
// let command = supportedCommands[i]
// commands[command.command_name] = {
// "type":command["command_type"]
// }
// }
// console.log("commands:", commands)
// setDeviceCommands(commands)
// }
const initialize = async (raw) => { const initialize = async (raw) => {
let content = await getDeviceParameters(raw) let content = await getDeviceParameters(raw)
setDeviceParameters(content) setDeviceParameters(content)
//initDeviceCommands(content)
} }
const getDeviceParameters = async (raw) =>{ const getDeviceParameters = async (raw) =>{
@ -377,14 +477,16 @@ const getDeviceParameters = async (raw) =>{
let result = await (await fetch(`${process.env.NEXT_PUBLIC_REST_ENPOINT}/device/${router.query.id[0]}/parameters`, requestOptions)) let result = await (await fetch(`${process.env.NEXT_PUBLIC_REST_ENPOINT}/device/${router.query.id[0]}/parameters`, requestOptions))
if (result.status != 200) { if (result.status != 200) {
throw new Error('Please check your email and password'); if (result.status === 401){
}else if (result.status === 401){
router.push("/auth/login") router.push("/auth/login")
}else{ }
console.log('Please check your email and password');
}else {
return result.json() return result.json()
} }
} }
/*
const getDeviceParameterInstances = async (raw) =>{ const getDeviceParameterInstances = async (raw) =>{
var myHeaders = new Headers(); var myHeaders = new Headers();
myHeaders.append("Content-Type", "application/json"); myHeaders.append("Content-Type", "application/json");
@ -405,8 +507,7 @@ const getDeviceParameterInstances = async (raw) =>{
}else{ }else{
return result.json() return result.json()
} }
} }*/
useEffect(()=> { useEffect(()=> {
@ -546,8 +647,11 @@ const getDeviceParameterInstances = async (raw) =>{
console.log("content:",content) console.log("content:",content)
let paramsInfo = {} let paramsInfo = {}
let commandsInfo = {}
let supportedParams = content.req_obj_results[0].supported_objs[0].supported_params let supportedParams = content.req_obj_results[0].supported_objs[0].supported_params
let supportedCommands = content.req_obj_results[0].supported_objs[0].supported_commands
let parametersToFetch = () => { let parametersToFetch = () => {
let paramsToFetch = [] let paramsToFetch = []
for (let i =0; i < supportedParams.length ;i++){ for (let i =0; i < supportedParams.length ;i++){
@ -557,23 +661,25 @@ const getDeviceParameterInstances = async (raw) =>{
paramsToFetch.push(supported_obj_path+param.param_name) paramsToFetch.push(supported_obj_path+param.param_name)
let paths = supported_obj_path.split(".")
if (paths[paths.length -2] !== "*"){
paramsInfo[param.param_name] = { paramsInfo[param.param_name] = {
"value_change":param["value_change"], "value_change":param["value_change"],
"value_type":param["value_type"], "value_type":param["value_type"],
"access": param["access"], "access": param["access"],
"value": "-", "value": "-",
} }
}else{ }
paramsInfo[param.param_name] = {
"value_change":param["value_change"], if (supportedCommands === undefined){
"value_type":param["value_type"], return paramsToFetch
"access": param["access"], }
"value":"-",
} for(let i =0; i < supportedCommands.length; i++){
let command = supportedCommands[i]
commandsInfo[command.command_name] = {
"type":command["command_type"]
} }
} }
return paramsToFetch return paramsToFetch
} }
@ -589,7 +695,10 @@ const getDeviceParameterInstances = async (raw) =>{
let result = await getDeviceParametersValue(raw) let result = await getDeviceParametersValue(raw)
console.log("result:", result) console.log("result:", result)
console.log("/-------------------------------------------------------/") console.log("/-------------------------------------------------------/")
let values = {} let values = {}
let commands = {}
console.log("VALUES:",values) console.log("VALUES:",values)
result.req_path_results.map((x)=>{ result.req_path_results.map((x)=>{
if (!x.resolved_path_results){ if (!x.resolved_path_results){
@ -601,21 +710,28 @@ const getDeviceParameterInstances = async (raw) =>{
let paths = x.requested_path.split(".") let paths = x.requested_path.split(".")
if(paths[paths.length -2] == "*"){ if(paths[paths.length -2] == "*"){
x.resolved_path_results.map(y=>{ x.resolved_path_results.map(y=>{
console.log(y.result_params) // console.log(y.result_params)
console.log(y.resolved_path) // console.log(y.resolved_path)
let key = Object.keys(y.result_params)[0] let key = Object.keys(y.result_params)[0]
console.log(key) // console.log(key)
console.log(paramsInfo[key].value) // console.log(paramsInfo[key].value)
console.log(paramsInfo[key]) // console.log(paramsInfo[key])
console.log(y.result_params[key]) // console.log(y.result_params[key])
console.log({[key]:paramsInfo[key]}) // console.log({[key]:paramsInfo[key]})
console.log("Take a look here mate: ",{...paramsInfo[key], value: y.result_params[key]}) console.log("Take a look here mate: ",{...paramsInfo[key], value: y.result_params[key]})
if (!values[y.resolved_path]){ if (!values[y.resolved_path]){
values[y.resolved_path] = [] values[y.resolved_path] = []
} }
if (!commands[y.resolved_path]){
commands[y.resolved_path] = []
}
if (y.result_params[key] == ""){ if (y.result_params[key] == ""){
y.result_params[key] = "\"\"" y.result_params[key] = "\"\""
} }
values[y.resolved_path].push({[key]:{...paramsInfo[key], value: y.result_params[key]}}) values[y.resolved_path].push({[key]:{...paramsInfo[key], value: y.result_params[key]}})
}) })
}else{ }else{
@ -629,8 +745,10 @@ const getDeviceParameterInstances = async (raw) =>{
}) })
} }
console.log(values) console.log("values:", values)
setDeviceParametersValue(values) setDeviceParametersValue(values)
console.log("commands:", commandsInfo)
setDeviceCommands(commandsInfo)
}) })
console.log("/-------------------------------------------------------/") console.log("/-------------------------------------------------------/")
@ -669,7 +787,16 @@ const getDeviceParameterInstances = async (raw) =>{
return /^\d+$/.test(value); return /^\d+$/.test(value);
} }
const inputjow = () => {
if (inputArgsValue === ""){
return {"":""}
}else{
return inputArgsValue
}
}
const showParameters = () => { const showParameters = () => {
return deviceParameters.req_obj_results.map((a,b)=>{ return deviceParameters.req_obj_results.map((a,b)=>{
return a.supported_objs.map((x,i)=> { return a.supported_objs.map((x,i)=> {
@ -741,7 +868,7 @@ const getDeviceParameterInstances = async (raw) =>{
sx={{fontWeight:'bold'}} sx={{fontWeight:'bold'}}
/> />
</ListItem> </ListItem>
{ x.supported_params && deviceParametersValue && { x.supported_params &&
<ShowParamsWithValues <ShowParamsWithValues
x={x} x={x}
deviceParametersValue={deviceParametersValue} deviceParametersValue={deviceParametersValue}
@ -752,15 +879,18 @@ const getDeviceParameterInstances = async (raw) =>{
setShowLoading={setShowLoading} setShowLoading={setShowLoading}
router={router} router={router}
updateDeviceParameters={updateDeviceParameters} updateDeviceParameters={updateDeviceParameters}
deviceCommands={deviceCommands}
openCommandDialog={openCommandDialog}
/> />
} }
{ x.supported_commands && { x.supported_commands && Object.keys(deviceCommands).length == 0 &&
x.supported_commands.map((y)=>{ x.supported_commands.map((y)=>{
return <List return <List
component="div" component="div"
disablePadding disablePadding
dense={true} dense={true}
key={y.command_name} key={y.command_name}
> >
<ListItem <ListItem
key={i} key={i}
@ -769,6 +899,26 @@ const getDeviceParameterInstances = async (raw) =>{
boxShadow: 'rgba(149, 157, 165, 0.2) 0px 0px 5px;', boxShadow: 'rgba(149, 157, 165, 0.2) 0px 0px 5px;',
pl: 4 pl: 4
}} }}
secondaryAction={
<IconButton onClick={()=> {
setDeviceCommandToExecute(
{
[x.supported_obj_path+y.command_name]:
{"input_arg_names":
[
y.input_arg_names
]
}
}
)
setOpenCommandDialog(true)
}}>
<SvgIcon>
<PlayCircleIcon >
</PlayCircleIcon>
</SvgIcon>
</IconButton>
}
> >
<ListItemText <ListItemText
primary={y.command_name} primary={y.command_name}
@ -925,12 +1075,11 @@ const getDeviceParameterInstances = async (raw) =>{
<Box display="flex" alignItems="center"> <Box display="flex" alignItems="center">
<Box flexGrow={1} >Response</Box> <Box flexGrow={1} >Response</Box>
<Box> <Box>
<IconButton > <IconButton onClick={()=>{
<SvgIcon
onClick={()=>{
setErrorModalText("") setErrorModalText("")
setErrorModal(false) setErrorModal(false)
}} }}>
<SvgIcon
> >
< XMarkIcon/> < XMarkIcon/>
</SvgIcon> </SvgIcon>
@ -952,6 +1101,88 @@ const getDeviceParameterInstances = async (raw) =>{
}}>OK</Button> }}>OK</Button>
</DialogActions> </DialogActions>
</Dialog> </Dialog>
{deviceCommandToExecute && <Dialog open={openCommandDialog}
slotProps={{ backdrop: { style: { backgroundColor: 'rgba(255,255,255,0.5)' } } }}
fullWidth={ true }
maxWidth={"md"}
scroll={"paper"}
aria-labelledby="scroll-dialog-title"
aria-describedby="scroll-dialog-description"
>
<DialogTitle id="scroll-dialog-title">
{Object.keys(deviceCommandToExecute)[0]}
</DialogTitle>
<DialogContent dividers={scroll === 'paper'}>
{deviceCommandToExecute[Object.keys(deviceCommandToExecute)[0]].input_arg_names[0]!=undefined && <DialogContentText id="scroll-dialog-description" tabIndex={-1}>
Input Arguments:
</DialogContentText>}
{deviceCommandToExecute[Object.keys(deviceCommandToExecute)[0]].input_arg_names[0] !=undefined &&
deviceCommandToExecute[Object.keys(deviceCommandToExecute)[0]].input_arg_names?.map(arg => {
return <TextField
autoFocus
margin="dense"
id={arg}
label={arg}
type="text"
onChange={(e)=> {setInputArgsValue(prevState=>{
return {...prevState, [arg] : e.target.value}
})}}
onClick={()=>{console.log(deviceCommandToExecute)}}
value={inputArgsValue[arg]}
/>
})}
</DialogContent>
<DialogActions>
<Button onClick={()=>{
setInputArgsValue("")
setDeviceCommandToExecute(null)
setOpenCommandDialog(false)
}}>Cancel</Button>
<Button onClick={async ()=>{
let raw = JSON.stringify(
{
"command": Object.keys(deviceCommandToExecute)[0],
"input_args": inputjow(),
"send_resp": true
}
)
console.log("deviceOperate => obj = ", raw)
var myHeaders = new Headers();
myHeaders.append("Content-Type", "application/json");
myHeaders.append("Authorization", localStorage.getItem("token"));
var requestOptions = {
method: 'PUT',
headers: myHeaders,
redirect: 'follow',
body: raw
};
setShowLoading(true)
let result = await fetch(`${process.env.NEXT_PUBLIC_REST_ENPOINT}/device/${router.query.id[0]}/operate`, requestOptions)
let content = await result.json()
if (result.status != 200) {
setShowLoading(false)
if (result.status === 401){
router.push("/auth/login")
}
setInputArgsValue("")
setDeviceCommandToExecute(null)
setOpenCommandDialog(false)
setShowLoading(false)
}else{
setInputArgsValue("")
setDeviceCommandToExecute(null)
setOpenCommandDialog(false)
setShowLoading(false)
if (content.operation_results[0].OperationResp.CmdFailure != undefined){
setErrorModalText(JSON.stringify(content, null, 2))
setErrorModal(true)
return
}
}
}}>Apply</Button>
</DialogActions>
</Dialog>}
<Backdrop <Backdrop
sx={{ sx={{
color: '#fff', color: '#fff',

View File

@ -99,7 +99,7 @@ export const OverviewLatestOrders = (props) => {
<TableCell> <TableCell>
<SvgIcon <SvgIcon
fontSize="small" fontSize="small"
sx={{cursor:'pointer'}} sx={{cursor: order.Status !== 2 && 'pointer'}}
onClick={()=>{ onClick={()=>{
if (order.Status !== 2){ if (order.Status !== 2){
router.push("devices/"+order.SN+"/discovery") router.push("devices/"+order.SN+"/discovery")