Merge branch 'onewire_detect' into dev_environment
This commit is contained in:
commit
25bce682ad
7 changed files with 154 additions and 34 deletions
2
package-lock.json
generated
2
package-lock.json
generated
|
|
@ -10953,7 +10953,7 @@
|
||||||
},
|
},
|
||||||
"node_modules/protobuf-ts": {
|
"node_modules/protobuf-ts": {
|
||||||
"version": "1.0.0",
|
"version": "1.0.0",
|
||||||
"resolved": "git+https://gitlab+deploy-token-50627:hv8mB4WkyvtjBpJKU1rN@gitlab.com/brandx/protobuf-ts.git#b230f4b2779d21ca7b502798b1472f667f8bbdc0",
|
"resolved": "git+https://gitlab+deploy-token-50627:hv8mB4WkyvtjBpJKU1rN@gitlab.com/brandx/protobuf-ts.git#873cef415993fc91a18e8b3ff80cdc6531f4e78d",
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"protobufjs": "^6.8.8"
|
"protobufjs": "^6.8.8"
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -142,8 +142,8 @@ export default function DeviceWizard(props: Props) {
|
||||||
</Tooltip>
|
</Tooltip>
|
||||||
)}
|
)}
|
||||||
{selectedPort &&
|
{selectedPort &&
|
||||||
// selectedPort.addressType === quack.AddressType.ADDRESS_TYPE_CONFIGURABLE_PIN_ARRAY &&
|
selectedPort.addressType === quack.AddressType.ADDRESS_TYPE_CONFIGURABLE_PIN_ARRAY &&
|
||||||
// device.featureSupported("detectOneWire") &&
|
device.featureSupported("detectOneWire") &&
|
||||||
selectedPort.autoDetectable && (
|
selectedPort.autoDetectable && (
|
||||||
<Tooltip title="Used to tell the Device to scan this port for any plugged in sensors">
|
<Tooltip title="Used to tell the Device to scan this port for any plugged in sensors">
|
||||||
<MenuItem
|
<MenuItem
|
||||||
|
|
|
||||||
|
|
@ -41,6 +41,7 @@ export default function DeviceScannedComponents(props: Props){
|
||||||
const [currentStep, setCurrentStep] = useState(0)
|
const [currentStep, setCurrentStep] = useState(0)
|
||||||
const [settingsValid, setSettingsValid] = useState(false);
|
const [settingsValid, setSettingsValid] = useState(false);
|
||||||
const [openDialog, setOpenDialog] = useState(false);
|
const [openDialog, setOpenDialog] = useState(false);
|
||||||
|
const [clearOpen, setClearOpen] = useState(false);
|
||||||
|
|
||||||
useEffect(()=>{
|
useEffect(()=>{
|
||||||
if (scannedComponents.i2c) setScannedI2C(scannedComponents.i2c)
|
if (scannedComponents.i2c) setScannedI2C(scannedComponents.i2c)
|
||||||
|
|
@ -207,8 +208,8 @@ export default function DeviceScannedComponents(props: Props){
|
||||||
setComponents(cloneList)
|
setComponents(cloneList)
|
||||||
}
|
}
|
||||||
|
|
||||||
const removeScan = (key: string) => {
|
const removeScan = (key: string, type: pond.ObjectType) => {
|
||||||
deviceAPI.removeFoundComponents(device.settings.deviceId, key)
|
deviceAPI.removeFoundComponents(device.settings.deviceId, key, type)
|
||||||
.then(resp => {
|
.then(resp => {
|
||||||
console.log("Cleared this scan")
|
console.log("Cleared this scan")
|
||||||
}).catch(err => {
|
}).catch(err => {
|
||||||
|
|
@ -216,18 +217,45 @@ export default function DeviceScannedComponents(props: Props){
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const removeAllScans = () => {
|
||||||
|
deviceAPI.removeAllFoundComponents(device.settings.deviceId)
|
||||||
|
.then(resp => {
|
||||||
|
console.log("Cleared all scans")
|
||||||
|
}).catch(err => {
|
||||||
|
console.log("There was a problem clearing scans")
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
const clearWarning = () => {
|
||||||
|
return (
|
||||||
|
<ResponsiveDialog open={clearOpen} onClose={()=>{setClearOpen(false)}}>
|
||||||
|
<DialogTitle>Clear All Scans</DialogTitle>
|
||||||
|
<DialogContent>This action will clear all scans for this device.</DialogContent>
|
||||||
|
<DialogActions>
|
||||||
|
<Button variant="contained" onClick={()=>{setClearOpen(false)}}>Close</Button>
|
||||||
|
<Button variant="contained" color="primary" onClick={()=>{removeAllScans()}}>Continue</Button>
|
||||||
|
</DialogActions>
|
||||||
|
</ResponsiveDialog>
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<React.Fragment>
|
<React.Fragment>
|
||||||
|
{clearWarning()}
|
||||||
<Card raised sx={{padding: 1}}>
|
<Card raised sx={{padding: 1}}>
|
||||||
|
<Box display="flex" flexDirection="row" justifyContent="space-between" alignItems="center">
|
||||||
|
<Typography sx={{fontWeight: 650, fontSize: 25}}>Sensor Scan</Typography>
|
||||||
|
<Button variant="contained" color="primary" onClick={()=>{setClearOpen(true)}}>Clear</Button>
|
||||||
|
</Box>
|
||||||
{scannedI2C !== undefined &&
|
{scannedI2C !== undefined &&
|
||||||
<React.Fragment>
|
<Box marginBottom={5}>
|
||||||
<Box justifyContent="space-between" display="flex">
|
<Box justifyContent="space-between" display="flex">
|
||||||
<Typography sx={{fontWeight: 650}}>
|
<Typography sx={{fontWeight: 650}}>
|
||||||
I2C Sensors
|
I2C Sensors
|
||||||
</Typography>
|
</Typography>
|
||||||
<Button variant="contained" color="primary" onClick={()=>{removeScan(scannedI2C.key)}}>Clear Scan</Button>
|
<Button variant="contained" color="primary" onClick={()=>{removeScan(scannedI2C.key, pond.ObjectType.OBJECT_TYPE_DETECT_I2C)}}>Clear Scan</Button>
|
||||||
</Box>
|
</Box>
|
||||||
{validI2CCompAddresses.length > 0 ? validI2CCompAddresses.map((addr, index) => {
|
{validI2CCompAddresses.length > 0 ? validI2CCompAddresses.map((addr, index) => {
|
||||||
return (
|
return (
|
||||||
|
|
@ -244,10 +272,10 @@ export default function DeviceScannedComponents(props: Props){
|
||||||
</Typography>
|
</Typography>
|
||||||
</Box>
|
</Box>
|
||||||
}
|
}
|
||||||
</React.Fragment>
|
</Box>
|
||||||
}
|
}
|
||||||
{scannedOneWire.length > 0 &&
|
{scannedOneWire.length > 0 &&
|
||||||
<Box marginTop={10}>
|
<Box>
|
||||||
<Box justifyContent="space-between" display="flex">
|
<Box justifyContent="space-between" display="flex">
|
||||||
<Typography sx={{fontWeight: 650}}>
|
<Typography sx={{fontWeight: 650}}>
|
||||||
Pin Port Sensors
|
Pin Port Sensors
|
||||||
|
|
@ -265,11 +293,11 @@ export default function DeviceScannedComponents(props: Props){
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
return(
|
return(
|
||||||
<Box key={i} padding={2} paddingBottom={0}>
|
<Box key={i} paddingX={2}>
|
||||||
<Box display="flex" justifyContent="space-between">
|
<Box display="flex" justifyContent="space-between" alignItems={"center"}>
|
||||||
<Typography>Port: {portLabel}</Typography>
|
<Typography>Port: {portLabel}</Typography>
|
||||||
<Button variant="contained" color="primary" onClick={()=>{
|
<Button variant="contained" color="primary" onClick={()=>{
|
||||||
removeScan(scan.key)
|
removeScan(scan.key, pond.ObjectType.OBJECT_TYPE_DETECT_ONEWIRE)
|
||||||
}}>Clear Port Scan</Button>
|
}}>Clear Port Scan</Button>
|
||||||
</Box>
|
</Box>
|
||||||
<ScannedOneWirePort scan={scan} componentSelectionCallback={componentSelection}/>
|
<ScannedOneWirePort scan={scan} componentSelectionCallback={componentSelection}/>
|
||||||
|
|
|
||||||
|
|
@ -1,4 +1,5 @@
|
||||||
import { Box, Checkbox, MenuItem, TextField, Tooltip } from "@mui/material"
|
import { Box, Checkbox, Grid2, MenuItem, TextField, Tooltip, Typography } from "@mui/material"
|
||||||
|
import { useMobile } from "hooks"
|
||||||
import { getFriendlyName, getSubtypes, Subtype } from "pbHelpers/ComponentType"
|
import { getFriendlyName, getSubtypes, Subtype } from "pbHelpers/ComponentType"
|
||||||
import { quack } from "protobuf-ts/quack"
|
import { quack } from "protobuf-ts/quack"
|
||||||
import React, { useEffect, useState } from "react"
|
import React, { useEffect, useState } from "react"
|
||||||
|
|
@ -11,20 +12,21 @@ interface Props {
|
||||||
export default function PortComponent(props: Props){
|
export default function PortComponent(props: Props){
|
||||||
const {compData, componentSelect} = props
|
const {compData, componentSelect} = props
|
||||||
// const [selectedSubtype, setSelectedSubtype] = useState<number>(0)
|
// const [selectedSubtype, setSelectedSubtype] = useState<number>(0)
|
||||||
const [subtypeVal, setSubtypeVal] = useState("none")//note that this is the friendly name and not the key or the value because it needs to be different from the other alias options
|
const [subtypeVal, setSubtypeVal] = useState("no subtype")//note that this is the friendly name and not the key or the value because it needs to be different from the other alias options
|
||||||
const [subtypeMap, setSubtypeMap] = useState<Map<string, number>>(new Map())
|
const [subtypeMap, setSubtypeMap] = useState<Map<string, number>>(new Map())
|
||||||
const [subtypeOptions, setSubtypeOptions] = useState<Subtype[]>([])
|
const [subtypeOptions, setSubtypeOptions] = useState<Subtype[]>([])
|
||||||
const [added, setAdded] = useState(false)
|
const [added, setAdded] = useState(false)
|
||||||
|
const isMobile = useMobile()
|
||||||
|
|
||||||
useEffect(()=>{
|
useEffect(()=>{
|
||||||
// setSelectedSubtype(compData.subtype)
|
// setSelectedSubtype(compData.subtype)
|
||||||
let validSubtypes: Subtype[] = []
|
let validSubtypes: Subtype[] = []
|
||||||
let subMap: Map<string, number> = new Map()
|
let subMap: Map<string, number> = new Map()
|
||||||
let subVal: string = "none"
|
let subVal: string = "no subtype"
|
||||||
getSubtypes(compData.type).forEach(option => {
|
getSubtypes(compData.type).forEach(option => {
|
||||||
if(compData.subtype === option.key || compData.subtype === 0){
|
if(compData.subtype === option.key || compData.subtype === 0){
|
||||||
validSubtypes.push(option)
|
validSubtypes.push(option)
|
||||||
if(subVal === "none"){
|
if(subVal === "no subtype"){
|
||||||
subVal = option.friendlyName
|
subVal = option.friendlyName
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -40,13 +42,14 @@ export default function PortComponent(props: Props){
|
||||||
<TextField
|
<TextField
|
||||||
value={subtypeVal}
|
value={subtypeVal}
|
||||||
disabled={added}
|
disabled={added}
|
||||||
|
fullWidth
|
||||||
onChange={(event) => {
|
onChange={(event) => {
|
||||||
setSubtypeVal(event.target.value)
|
setSubtypeVal(event.target.value)
|
||||||
// setSelectedSubtype(subtypeMap.get(event.target.value) ?? 0)
|
// setSelectedSubtype(subtypeMap.get(event.target.value) ?? 0)
|
||||||
compData.subtype = subtypeMap.get(event.target.value) ?? 0
|
compData.subtype = subtypeMap.get(event.target.value) ?? 0
|
||||||
}}
|
}}
|
||||||
select>
|
select>
|
||||||
<MenuItem key={-1} value={"none"}>Select the Component Subtype</MenuItem>
|
<MenuItem key={-1} value={"no subtype"}>Select the Component Subtype</MenuItem>
|
||||||
{subtypeOptions.map((s, i) => (
|
{subtypeOptions.map((s, i) => (
|
||||||
<MenuItem key={i} value={s.friendlyName}>{s.friendlyName}</MenuItem>
|
<MenuItem key={i} value={s.friendlyName}>{s.friendlyName}</MenuItem>
|
||||||
))}
|
))}
|
||||||
|
|
@ -71,15 +74,77 @@ export default function PortComponent(props: Props){
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const desktopDisplay = () => {
|
||||||
|
return (
|
||||||
|
<Box padding={2}>
|
||||||
|
<Grid2 container spacing={2} direction="row" wrap="nowrap" alignContent="center" alignItems="center" justifyContent="space-between">
|
||||||
|
<Grid2 size={3}>
|
||||||
|
<Typography>
|
||||||
|
{getFriendlyName(compData.type)}
|
||||||
|
</Typography>
|
||||||
|
</Grid2>
|
||||||
|
<Grid2 size={3}>
|
||||||
|
{subtypeOptions.length < 2
|
||||||
|
?
|
||||||
|
<Typography>
|
||||||
|
{subtypeVal}
|
||||||
|
</Typography>
|
||||||
|
:
|
||||||
|
subtypeSelector()}
|
||||||
|
</Grid2>
|
||||||
|
<Grid2 size={2}>
|
||||||
|
<Typography>
|
||||||
|
Cable ID: {compData.cableId}
|
||||||
|
</Typography>
|
||||||
|
</Grid2>
|
||||||
|
<Grid2 size={2}>
|
||||||
|
<Typography>
|
||||||
|
Nodes: {compData.nodeCount}
|
||||||
|
</Typography>
|
||||||
|
</Grid2>
|
||||||
|
<Grid2 size={1}>
|
||||||
|
{selectCompCheckbox()}
|
||||||
|
</Grid2>
|
||||||
|
</Grid2>
|
||||||
|
</Box>
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
const mobileDisplay = () => {
|
||||||
|
return(
|
||||||
|
<Box padding={2}>
|
||||||
|
<Grid2 container spacing={2} direction="row" wrap="nowrap" alignContent="center" alignItems="center" justifyContent="space-between">
|
||||||
|
<Grid2 size={5}>
|
||||||
|
<Typography>
|
||||||
|
{getFriendlyName(compData.type)}
|
||||||
|
</Typography>
|
||||||
|
<Typography>
|
||||||
|
Cable ID: {compData.cableId}
|
||||||
|
</Typography>
|
||||||
|
<Typography>
|
||||||
|
Nodes: {compData.nodeCount}
|
||||||
|
</Typography>
|
||||||
|
</Grid2>
|
||||||
|
<Grid2 size={5}>
|
||||||
|
{subtypeOptions.length < 2
|
||||||
|
?
|
||||||
|
<Typography>
|
||||||
|
{subtypeVal}
|
||||||
|
</Typography>
|
||||||
|
:
|
||||||
|
subtypeSelector()}
|
||||||
|
</Grid2>
|
||||||
|
<Grid2 size={2}>
|
||||||
|
{selectCompCheckbox()}
|
||||||
|
</Grid2>
|
||||||
|
</Grid2>
|
||||||
|
</Box>
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<React.Fragment>
|
<React.Fragment>
|
||||||
<Box>
|
{isMobile ? mobileDisplay() : desktopDisplay()}
|
||||||
{getFriendlyName(compData.type)}
|
|
||||||
Cable ID: {compData.cableId}
|
|
||||||
Number of nodes: {compData.nodeCount}
|
|
||||||
{subtypeOptions.length < 2 ? subtypeVal : subtypeSelector()}
|
|
||||||
{selectCompCheckbox()}
|
|
||||||
</Box>
|
|
||||||
</React.Fragment>
|
</React.Fragment>
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
@ -1,4 +1,4 @@
|
||||||
import { Box, MenuItem, TextField } from "@mui/material"
|
import { Box, MenuItem, TextField, Typography } from "@mui/material"
|
||||||
import { extension, getFriendlyName, getSubtypes, Subtype } from "pbHelpers/ComponentType"
|
import { extension, getFriendlyName, getSubtypes, Subtype } from "pbHelpers/ComponentType"
|
||||||
import { pond } from "protobuf-ts/pond"
|
import { pond } from "protobuf-ts/pond"
|
||||||
import { quack } from "protobuf-ts/quack"
|
import { quack } from "protobuf-ts/quack"
|
||||||
|
|
@ -42,13 +42,16 @@ export default function ScannedOneWirePort(props: Props){
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<React.Fragment>
|
<React.Fragment>
|
||||||
{portComponents.map((compData, i) => {
|
{portComponents.length > 0 ? portComponents.map((compData, i) => {
|
||||||
return (
|
return (
|
||||||
<PortComponent key={i} compData={compData} componentSelect={(checked, component) => {
|
<PortComponent key={i} compData={compData} componentSelect={(checked, component) => {
|
||||||
componentSelected(checked, component)
|
componentSelected(checked, component)
|
||||||
}}/>
|
}}/>
|
||||||
)
|
)
|
||||||
})}
|
}):
|
||||||
|
<Box>
|
||||||
|
<Typography>No Components Found</Typography>
|
||||||
|
</Box>}
|
||||||
</React.Fragment>
|
</React.Fragment>
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
@ -170,7 +170,7 @@ export default function DevicePage() {
|
||||||
deviceAPI.listFoundComponents(parseInt(deviceID))
|
deviceAPI.listFoundComponents(parseInt(deviceID))
|
||||||
.then(resp => {
|
.then(resp => {
|
||||||
console.log(resp.data)
|
console.log(resp.data)
|
||||||
if (resp.data.foundComponents){
|
if (resp.data.foundComponents?.i2c || resp.data.foundComponents?.oneWire){
|
||||||
setScannedAddresses(pond.ListFoundComponentsResponse.fromObject(resp.data).foundComponents ?? undefined)
|
setScannedAddresses(pond.ListFoundComponentsResponse.fromObject(resp.data).foundComponents ?? undefined)
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
|
|
@ -412,7 +412,16 @@ export default function DevicePage() {
|
||||||
/>
|
/>
|
||||||
</Grid>
|
</Grid>
|
||||||
{/* add grid card here for I2C detected components */}
|
{/* add grid card here for I2C detected components */}
|
||||||
|
{(scannedAddresses?.i2c || scannedAddresses?.oneWire) &&
|
||||||
|
<Grid size={{ xs: 12 }}>
|
||||||
|
<DeviceScannedComponents
|
||||||
|
scannedComponents={scannedAddresses}
|
||||||
|
device={device}
|
||||||
|
availablePositions={availablePositions}
|
||||||
|
availableOffsets={availableOffsets}
|
||||||
|
refreshCallback={loadDevice}/>
|
||||||
|
</Grid>
|
||||||
|
}
|
||||||
{diagnosticComponents.map(comp => (
|
{diagnosticComponents.map(comp => (
|
||||||
<Grid size={{ xs: 12 }} key={comp.key()}>
|
<Grid size={{ xs: 12 }} key={comp.key()}>
|
||||||
<ComponentDiagnostics
|
<ComponentDiagnostics
|
||||||
|
|
|
||||||
|
|
@ -149,7 +149,8 @@ export interface IDeviceAPIContext {
|
||||||
keys?: string[],
|
keys?: string[],
|
||||||
types?: string[]
|
types?: string[]
|
||||||
) => Promise<any>;
|
) => Promise<any>;
|
||||||
removeFoundComponents: (id: number, key: string, otherTeam?: string) => Promise<AxiosResponse<pond.RemoveFoundComponentsResponse>>;
|
removeAllFoundComponents: (id: number,otherTeam?: string) => Promise<AxiosResponse<pond.RemoveAllFoundComponentsResponse>>;
|
||||||
|
removeFoundComponents: (id: number, key: string, type: pond.ObjectType, otherTeam?: string) => Promise<AxiosResponse<pond.RemoveFoundComponentsResponse>>;
|
||||||
}
|
}
|
||||||
|
|
||||||
export const DeviceAPIContext = createContext<IDeviceAPIContext>({} as IDeviceAPIContext);
|
export const DeviceAPIContext = createContext<IDeviceAPIContext>({} as IDeviceAPIContext);
|
||||||
|
|
@ -989,10 +990,10 @@ export default function DeviceProvider(props: PropsWithChildren<Props>) {
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
const removeFoundComponents = (id: number, key: string, otherTeam?: string) => {
|
const removeFoundComponents = (id: number, key: string, type: pond.ObjectType, otherTeam?: string) => {
|
||||||
let url = "/devices/" + id + "/removeFoundComponents/" + key;
|
let url = "/devices/" + id + "/removeFoundComponents/" + key + "?scanType=" + type;
|
||||||
const view = otherTeam ? otherTeam : as
|
const view = otherTeam ? otherTeam : as
|
||||||
if(view) url = url + "?as=" + view
|
if(view) url = url + "&as=" + view
|
||||||
return new Promise<AxiosResponse<pond.RemoveFoundComponentsResponse>>((resolve, reject) => {
|
return new Promise<AxiosResponse<pond.RemoveFoundComponentsResponse>>((resolve, reject) => {
|
||||||
del<pond.RemoveFoundComponentsResponse>(pondURL(url)).then(resp => {
|
del<pond.RemoveFoundComponentsResponse>(pondURL(url)).then(resp => {
|
||||||
return resolve(resp)
|
return resolve(resp)
|
||||||
|
|
@ -1002,6 +1003,19 @@ export default function DeviceProvider(props: PropsWithChildren<Props>) {
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const removeAllFoundComponents = (id: number, otherTeam?: string) => {
|
||||||
|
let url = "/devices/" + id + "/removeAllFoundComponents";
|
||||||
|
const view = otherTeam ? otherTeam : as
|
||||||
|
if(view) url = url + "?as=" + view
|
||||||
|
return new Promise<AxiosResponse<pond.RemoveAllFoundComponentsResponse>>((resolve, reject) => {
|
||||||
|
del<pond.RemoveAllFoundComponentsResponse>(pondURL(url)).then(resp => {
|
||||||
|
return resolve(resp)
|
||||||
|
}).catch(err => {
|
||||||
|
return reject(err)
|
||||||
|
})
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<DeviceAPIContext.Provider
|
<DeviceAPIContext.Provider
|
||||||
value={{
|
value={{
|
||||||
|
|
@ -1051,7 +1065,8 @@ export default function DeviceProvider(props: PropsWithChildren<Props>) {
|
||||||
detectI2C,
|
detectI2C,
|
||||||
detectOneWire,
|
detectOneWire,
|
||||||
listFoundComponents,
|
listFoundComponents,
|
||||||
removeFoundComponents
|
removeFoundComponents,
|
||||||
|
removeAllFoundComponents
|
||||||
}}>
|
}}>
|
||||||
{children}
|
{children}
|
||||||
</DeviceAPIContext.Provider>
|
</DeviceAPIContext.Provider>
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue