import { useEffect, useState } from 'react'; import { Card, CardContent, SvgIcon, IconButton, List, ListItem, ListItemText, Box, Dialog, DialogActions, DialogContent, DialogContentText, DialogTitle, TextField, Button, Backdrop, } from '@mui/material'; import ArrowRightIcon from '@heroicons/react/24/solid/ArrowRightIcon'; import CircularProgress from '@mui/material/CircularProgress'; import PlayCircle from '@heroicons/react/24/outline/PlayCircleIcon' import PlusCircleIcon from '@heroicons/react/24/outline/PlusCircleIcon'; import Pencil from "@heroicons/react/24/outline/PencilIcon" import ArrowUturnLeftIcon from '@heroicons/react/24/outline/ArrowUturnLeftIcon' import XMarkIcon from '@heroicons/react/24/outline/XMarkIcon'; import { useRouter } from 'next/router'; import TrashIcon from '@heroicons/react/24/outline/TrashIcon'; import PlayCircleIcon from '@heroicons/react/24/outline/PlayCircleIcon'; /* OBJ_READ_ONLY (0) OBJ_ADD_DELETE (1) OBJ_ADD_ONLY (2) OBJ_DELETE_ONLY (3) */ const ObjAccessType = { ReadOnly: 0, AddDelete: 1, AddOnly: 2, DeleteOnly:3, } const ParamAccessType = { ReadOnly: 0, ReadWrite: 1, WriteOnly: 2, } const ParamValueType = { Unknown: 0, Base64: 1, Boolean: 2, DateTime: 3, Decimal: 4, HexBinary: 5, Int: 6, Long: 7, String: 8, UnisgnedInt: 9, UnsignedLong: 10, } //TODO: refact all of this mess const addDeviceObj = async(obj, setShowLoading, router, updateDeviceParameters) => { console.log("AddDeviceObj => obj = ", obj) let raw = JSON.stringify( { "allow_partial": true, "create_objs": [ { "obj_path": obj, //TODO: create queue and create new obj with parameters // "param_settings": [ // { // "param": "Alias", // "value": "test", // "required": true // } // ] } ] } ) 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 (await fetch(`${process.env.NEXT_PUBLIC_REST_ENDPOINT}/device/${router.query.id[0]}/any/add`, requestOptions)) if (result.status != 200) { if (result.status === 401){ router.push("/auth/login") } setShowLoading(false) throw new Error('Please check your email and password'); }else{ setShowLoading(false) console.log(result.json()) updateDeviceParameters(obj+"*.") } } const deleteDeviceObj = async(obj, setShowLoading, router, updateDeviceParameters) => { console.log("deleteDeviceObj => obj = ", obj) let raw = JSON.stringify( { "allow_partial": true, "obj_paths": [ obj ] } ) 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 (await fetch(`${process.env.NEXT_PUBLIC_REST_ENDPOINT}/device/${router.query.id[0]}/any/del`, requestOptions)) if (result.status != 200) { if (result.status === 401){ router.push("/auth/login") } setShowLoading(false) throw new Error('Please check your email and password'); }else{ setShowLoading(false) console.log(result.json()) let paths = obj.split(".") console.log("paths:",paths) let pathsToJump = 2 if (paths[paths.length -2] == "*"){ pathsToJump = 3 } paths.splice(paths.length - pathsToJump, pathsToJump) let pathToFetch = paths.join(".") updateDeviceParameters(pathToFetch) } } function ShowPath({x,updateDeviceParameters,setShowLoading, router}) { // console.log(x) // console.log("x.supported_obj_path:", x.supported_obj_path) // console.log("x.access:", x.access) if(x.supported_obj_path != "Device."){ if (x.access === ObjAccessType.ReadOnly || x.access === undefined){ return ( { console.log("x.supported_obj_path:",x.supported_obj_path) let supported_obj_path = x.supported_obj_path.replaceAll("{i}.","*.") updateDeviceParameters(supported_obj_path) }}> ) }else if (x.access === ObjAccessType.AddDelete){ console.log("addDelete") return (
addDeviceObj( x.supported_obj_path.replace("{i}.",""), setShowLoading, router, updateDeviceParameters)}> { console.log("x.supported_obj_path:",x.supported_obj_path) let supported_obj_path = x.supported_obj_path.replaceAll("{i}.","*.") updateDeviceParameters(supported_obj_path) }}>
) }else if (x.access === ObjAccessType.AddOnly){ return addDeviceObj(x.supported_obj_path.replace("{i}.",""), setShowLoading, router, updateDeviceParameters)}> } } return <> } function ShowParamsWithValues({ x, deviceParametersValue, setOpen, setParameter, setParameterValue, deviceParameters, setShowLoading, router, updateDeviceParameters, deviceCommands, openCommandDialog }) { console.log("HEY jow:", deviceParametersValue) let paths = x.supported_obj_path.split(".") const showDialog = (param, paramvalue) => { setParameter(param); if (paramvalue == "\"\"") { setParameterValue("") }else{ setParameterValue(paramvalue); } setOpen(true); } if(paths[paths.length -2] == "{i}"){ return Object.keys(deviceParametersValue).map((paramKey, h)=>{ console.log("deviceParametersValue:", deviceParametersValue) console.log("paramKey:", paramKey) console.log("deviceParameters.req_obj_results[0].supported_objs[h]?.access:", deviceParameters.req_obj_results[0].supported_objs[h]?.access) let obj = deviceParameters.req_obj_results[0].supported_objs[0] let access = obj?.access return ( ObjAccessType.ReadOnly && { deleteDeviceObj( paramKey, setShowLoading, router, updateDeviceParameters ) }}> } > {paramKey}} sx={{fontWeight:'bold'}} /> {deviceParametersValue[paramKey].length > 0 ? deviceParametersValue[paramKey].map((param, i) => { return ( {Object.values(param)[0].value} {Object.values(param)[0].access > ParamAccessType.ReadOnly && { showDialog( paramKey+Object.keys(param)[0], Object.values(param)[0].value) } }> } } > ) }):<>} { deviceCommands && Object.keys(deviceCommands).map(commando =>{ console.log("Comando:", commando) return } > }) } ) }) }else{ return ( <> {x.supported_params && x.supported_params.map((y, index)=>{ return ( {deviceParametersValue[y.param_name].value} {deviceParametersValue[y.param_name].access > ParamAccessType.ReadOnly && { showDialog( x.supported_obj_path + y.param_name, deviceParametersValue[y.param_name].value) } }> } } > ) })} { deviceCommands && Object.keys(deviceCommands).map(commando =>{ console.log("Comando:", commando) return } > }) } ) } } export const DevicesDiscovery = () => { const router = useRouter() const [deviceCommands, setDeviceCommands] = useState({}) const [deviceParameters, setDeviceParameters] = useState(null) const [parameter, setParameter] = useState(null) const [parameterValue, setParameterValue] = useState(null) const [parameterValueChange, setParameterValueChange] = useState(null) const [deviceParametersValue, setDeviceParametersValue] = useState({}) const [open, setOpen] = useState(false) const [errorModal, setErrorModal] = useState(false) const [errorModalText, setErrorModalText] = useState("") 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) => { let content = await getDeviceParameters(raw) setDeviceParameters(content) //initDeviceCommands(content) } const getDeviceParameters = async (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 }; let result = await (await fetch(`${process.env.NEXT_PUBLIC_REST_ENDPOINT}/device/${router.query.id[0]}/any/parameters`, requestOptions)) if (result.status != 200) { if (result.status === 401){ router.push("/auth/login") } console.log('Please check your email and password'); }else { return result.json() } } /* const getDeviceParameterInstances = async (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 }; let result = await (await fetch(`${process.env.NEXT_PUBLIC_REST_ENDPOINT}/device/${router.query.id[0]}/any/instances`, requestOptions)) if (result.status != 200) { throw new Error('Please check your email and password'); }else if (result.status === 401){ router.push("/auth/login") }else{ return result.json() } }*/ useEffect(()=> { initialize( JSON.stringify({ "obj_paths": ["Device."], "first_level_only" : true, "return_commands" : true, "return_events" : true, "return_params" : true }) ); },[]) //Together with showParameters, this function renders all the device parameters the device supports //but you must set req with first_level_only property to false // const showPathParameters = (pathParamsList) => { // return pathParamsList.map((x,i)=>{ // return( // // // // // // ) // }) // } // Multi instance not used, found better way to get values // const updateDeviceParametersMultiInstance = async (param) =>{ // console.log("UpdateDeviceParametersMultiInstance => param = ", param) // let raw = JSON.stringify({ // "obj_paths": [param], // "first_level_only" : true, // "return_commands" : true, // "return_events" : true, // "return_params" : true // }) // let response = await getDeviceParameterInstances(raw) // console.log("response:", response) // let instancesToGet = [] // if (response.req_path_results[0].curr_insts) { // let supportedParams = response.req_path_results[0].curr_insts // let instances = () => { // for (let i =0; i < supportedParams.length ;i++){ // instancesToGet.push(supportedParams[i].instantiated_obj_path) // } // } // instances() // }else{ // instancesToGet.push(response.req_path_results[0].requested_path) // } // let rawInP = JSON.stringify({ // "obj_paths": instancesToGet, // "first_level_only" : true, // "return_commands" : true, // "return_events" : true, // "return_params" : true // }) // let resultParams = await getDeviceParameters(rawInP) // console.log("result params:", resultParams) // setDeviceParameters(resultParams) // let paramsToFetch = [] // console.log("parameters to fetch: ", paramsToFetch) // let rawV = JSON.stringify({ // "param_paths": paramsToFetch, // "max_depth": 1 // }) // let resultValues = await getDeviceParametersValue(rawV) // console.log("result values:", resultValues) // let rawP = JSON.stringify({ // "obj_paths": paramsToFetch, // "first_level_only" : true, // "return_commands" : true, // "return_events" : true, // "return_params" : true // }) // let resultParams = await getDeviceParameters(rawP) // console.log("result params:", resultParams) // let values = {} // let setvalues = () => {resultValues.req_path_results.map((x)=>{ // // let path = x.requested_path.split(".") // // let param = path[path.length -1] // if (!x.resolved_path_results){ // return // } // x.resolved_path_results.map((y)=> { // }) // // Object.keys(x.resolved_path_results[0].result_params).forEach((key, index) =>{ // // values[key] = x.resolved_path_results[0].result_params[key] // // }) // return values // })} // setvalues() // console.log("values:",values) // setDeviceParameters(resultParams) // setDeviceParametersValue(values) // } const updateDeviceParameters = async (param) => { console.log("UpdateDeviceParameters => param = ", param) let raw = JSON.stringify({ "obj_paths": [param], "first_level_only" : true, "return_commands" : true, "return_events" : true, "return_params" : true }) let content = await getDeviceParameters(raw) console.log("content:",content) let paramsInfo = {} let commandsInfo = {} 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 paramsToFetch = [] for (let i =0; i < supportedParams.length ;i++){ let supported_obj_path = content.req_obj_results[0].supported_objs[0].supported_obj_path.replaceAll("{i}","*") let param = supportedParams[i] paramsToFetch.push(supported_obj_path+param.param_name) paramsInfo[param.param_name] = { "value_change":param["value_change"], "value_type":param["value_type"], "access": param["access"], "value": "-", } } if (supportedCommands === undefined){ return paramsToFetch } for(let i =0; i < supportedCommands.length; i++){ let command = supportedCommands[i] commandsInfo[command.command_name] = { "type":command["command_type"] } } return paramsToFetch } if (supportedParams !== undefined) { const fetchparameters = parametersToFetch() console.log("parameters to fetch: ", fetchparameters) raw = JSON.stringify({ "param_paths": fetchparameters, "max_depth": 1 }) let result = await getDeviceParametersValue(raw) console.log("result:", result) console.log("/-------------------------------------------------------/") let values = {} let commands = {} console.log("VALUES:",values) result.req_path_results.map((x)=>{ if (!x.resolved_path_results){ values[x.requested_path] = {} setDeviceParametersValue(values) return } let paths = x.requested_path.split(".") if(paths[paths.length -2] == "*"){ x.resolved_path_results.map(y=>{ // console.log(y.result_params) // console.log(y.resolved_path) let key = Object.keys(y.result_params)[0] // console.log(key) // console.log(paramsInfo[key].value) // console.log(paramsInfo[key]) // console.log(y.result_params[key]) // console.log({[key]:paramsInfo[key]}) console.log("Take a look here mate: ",{...paramsInfo[key], value: y.result_params[key]}) if (!values[y.resolved_path]){ values[y.resolved_path] = [] } if (!commands[y.resolved_path]){ commands[y.resolved_path] = [] } if (y.result_params[key] == ""){ y.result_params[key] = "\"\"" } values[y.resolved_path].push({[key]:{...paramsInfo[key], value: y.result_params[key]}}) }) }else{ Object.keys(x.resolved_path_results[0].result_params).forEach((key, index) =>{ if (x.resolved_path_results[0].result_params[key] != ""){ paramsInfo[key].value = x.resolved_path_results[0].result_params[key] }else{ paramsInfo[key].value = "\"\"" } values = paramsInfo }) } console.log("values:", values) setDeviceParametersValue(values) console.log("commands:", commandsInfo) setDeviceCommands(commandsInfo) }) console.log("/-------------------------------------------------------/") setDeviceParameters(content) }else{ console.log("fixme") setDeviceParameters(content) } } const getDeviceParametersValue = async (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 }; let result = await (await fetch(`${process.env.NEXT_PUBLIC_REST_ENDPOINT}/device/${router.query.id[0]}/any/get`, requestOptions)) if (result.status != 200) { if (result.status === 401){ router.push("/auth/login") } throw new Error('Please check your email and password'); }else if (result.status === 401){ router.push("/auth/login") }else{ return result.json() } } function isInteger(value) { return /^\d+$/.test(value); } const inputjow = () => { if (inputArgsValue === ""){ return {"":""} }else{ return inputArgsValue } } const showParameters = () => { return deviceParameters.req_obj_results.map((a,b)=>{ return a.supported_objs.map((x,i)=> { let supported_obj_path = x.supported_obj_path.split(".") let supportedObjPath = "" supported_obj_path.map((x,i)=>{ if(i !== supported_obj_path.length -2){ supportedObjPath = supportedObjPath + x + "." } }) let req_obj_path = a.req_obj_path.split(".") let reqObjPath = "" req_obj_path.map((x,i)=>{ if(i !== req_obj_path.length -2){ reqObjPath = reqObjPath + x + "." } }) // console.log("reqObjPath:", reqObjPath) // console.log("supportedObjPath:", supportedObjPath) let paramName = x.supported_obj_path if (supportedObjPath != "Device.."){ if (supportedObjPath == reqObjPath){ paramName = a.req_obj_path } } return ( { let supported_obj_path = x.supported_obj_path.replaceAll("{i}.","*.") let paths = supported_obj_path.split(".") console.log("paths:",paths) let pathsToJump = 2 if (paths[paths.length -2] == "*"){ pathsToJump = 3 } paths.splice(paths.length - pathsToJump, pathsToJump) let pathToFetch = paths.join(".") updateDeviceParameters(pathToFetch) } }> : } sx={{ boxShadow: 'rgba(149, 157, 165, 0.2) 0px 0px 5px;' }} > {paramName}} sx={{fontWeight:'bold'}} /> { x.supported_params && } { x.supported_commands && Object.keys(deviceCommands).length == 0 && x.supported_commands.map((y)=>{ return { setDeviceCommandToExecute( { [x.supported_obj_path+y.command_name]: {"input_arg_names": [ y.input_arg_names ] } } ) setOpenCommandDialog(true) }}> } > }) } { x.supported_events && x.supported_events.map((y)=>{ return }) } ) }) }) } return ( deviceParameters ? {showParameters()} {parameter} setParameterValueChange(e.target.value)} /> Response { setErrorModalText("") setErrorModal(false) }}> < XMarkIcon/>
                        {errorModalText}
                    
{deviceCommandToExecute && {Object.keys(deviceCommandToExecute)[0]} {deviceCommandToExecute[Object.keys(deviceCommandToExecute)[0]].input_arg_names[0]!=undefined && Input Arguments: } {deviceCommandToExecute[Object.keys(deviceCommandToExecute)[0]].input_arg_names[0] !=undefined && deviceCommandToExecute[Object.keys(deviceCommandToExecute)[0]].input_arg_names?.map(arg => { return {setInputArgsValue(prevState=>{ return {...prevState, [arg] : e.target.value} })}} onClick={()=>{console.log(deviceCommandToExecute)}} value={inputArgsValue[arg]} /> })} } theme.zIndex.drawer + 1, overflow: 'hidden' }} open={showLoading} >
: ) };