made the react components to display the card for scanned components
This commit is contained in:
parent
f5bc230fb6
commit
751b39d345
14 changed files with 311 additions and 26 deletions
|
|
@ -26,7 +26,8 @@ import {
|
|||
import { GetDeviceProductIcon, GetDeviceProductLabel } from "products/DeviceProduct";
|
||||
import { pond } from "protobuf-ts/pond";
|
||||
import { quack } from "protobuf-ts/quack";
|
||||
import { useComponentAPI, useGlobalState, useSnackbar } from "providers";
|
||||
import { useComponentAPI, useDeviceAPI, useGlobalState, useSnackbar } from "providers";
|
||||
|
||||
import React, { useState } from "react";
|
||||
import DeviceSVG, { PortInformation } from "./deviceSVG";
|
||||
import { makeStyles } from "@mui/styles";
|
||||
|
|
@ -83,6 +84,8 @@ export default function DeviceWizard(props: Props) {
|
|||
);
|
||||
const classes = useStyles();
|
||||
const [selectedPort, setSelectedPort] = useState<PortInformation>();
|
||||
const deviceAPI = useDeviceAPI()
|
||||
const { openSnack } = useSnackbar()
|
||||
//const [addressType, setAddressType] = useState<quack.AddressType>(quack.AddressType.ADDRESS_TYPE_CONFIGURABLE_PIN_ARRAY);
|
||||
|
||||
const wizardMenu = () => {
|
||||
|
|
@ -118,6 +121,22 @@ export default function DeviceWizard(props: Props) {
|
|||
</MenuItem>
|
||||
</Tooltip>
|
||||
)}
|
||||
{selectedPort && selectedPort.addressType === quack.AddressType.ADDRESS_TYPE_I2C && device.featureSupported("detectI2C") && (
|
||||
<Tooltip title="Used to tell the Device to scan its I2C port for any plugged in sensors">
|
||||
<MenuItem
|
||||
key={"scanI2C"}
|
||||
onClick={() => {
|
||||
deviceAPI.detectI2C(device.id())
|
||||
.then(resp => {
|
||||
openSnack("Device will scan port on next check-in")
|
||||
}).catch(err => {
|
||||
openSnack("Command failed to send to device")
|
||||
})
|
||||
}}>
|
||||
Scan Port
|
||||
</MenuItem>
|
||||
</Tooltip>
|
||||
)}
|
||||
{portComponents.length > 0 && (
|
||||
<List>
|
||||
<ListSubheader>Current Components</ListSubheader>
|
||||
|
|
|
|||
93
src/device/autoDetect/DeviceScannedComponents.tsx
Normal file
93
src/device/autoDetect/DeviceScannedComponents.tsx
Normal file
|
|
@ -0,0 +1,93 @@
|
|||
import { Box, Card, DialogContent, FormControlLabel, Radio, RadioGroup, Step, StepLabel, Stepper } from "@mui/material";
|
||||
import { cloneDeep } from "lodash";
|
||||
import { getSubtypes, Subtype } from "pbHelpers/ComponentType";
|
||||
import { pond, quack } from "protobuf-ts/pond";
|
||||
import React from "react";
|
||||
import { useEffect, useState } from "react";
|
||||
import ScannedI2C from "./ScannedI2C";
|
||||
import ComponentForm from "component/ComponentForm";
|
||||
import { Component, Device } from "models";
|
||||
|
||||
interface Props {
|
||||
scannedComponents: pond.ComponentAddressMap
|
||||
device: Device
|
||||
}
|
||||
|
||||
interface CompStep {
|
||||
label: string;
|
||||
completed?: boolean;
|
||||
}
|
||||
|
||||
export default function DeviceScannedComponents(props: Props){
|
||||
const {scannedComponents, device} = props
|
||||
const [scannedI2C, setScannedI2C] = useState<pond.DetectI2C>()
|
||||
const [components, setComponents] = useState<Component[]>([])
|
||||
const [steps, setSteps] = useState<CompStep[]>([]);
|
||||
const [currentStep, setCurrentStep] = useState(0)
|
||||
const [settingsValid, setSettingsValid] = useState(false);
|
||||
|
||||
useEffect(()=>{
|
||||
if (scannedComponents.i2c) setScannedI2C(scannedComponents.i2c)
|
||||
},[scannedComponents])
|
||||
|
||||
useEffect(() => {
|
||||
let steps: CompStep[] = []
|
||||
components.forEach(comp => {
|
||||
steps.push({
|
||||
label: comp.name(),
|
||||
completed: false
|
||||
})
|
||||
})
|
||||
},[components])
|
||||
|
||||
const stepper = () => {
|
||||
return (
|
||||
<Stepper nonLinear activeStep={currentStep} style={{ width: "100%" }}>
|
||||
{steps.map(compStep => {
|
||||
const labelProps: {
|
||||
optional?: React.ReactNode;
|
||||
} = {};
|
||||
return (
|
||||
<Step key={compStep.label} completed={compStep.completed}>
|
||||
<StepLabel {...labelProps}>{compStep.label}</StepLabel>
|
||||
</Step>
|
||||
);
|
||||
})}
|
||||
</Stepper>
|
||||
);
|
||||
};
|
||||
|
||||
const addComponentContent = () => {
|
||||
return (
|
||||
<DialogContent>
|
||||
{stepper()}
|
||||
<ComponentForm
|
||||
component={components[currentStep]}
|
||||
canEdit
|
||||
device={device}
|
||||
componentChanged={(component, isValid) => {
|
||||
components[currentStep].settings = component.settings;
|
||||
setSettingsValid(isValid);
|
||||
}}
|
||||
/>
|
||||
</DialogContent>
|
||||
);
|
||||
};
|
||||
|
||||
|
||||
|
||||
return (
|
||||
<Card>
|
||||
{scannedI2C &&
|
||||
<React.Fragment>
|
||||
<Box>I2C Components Found</Box>
|
||||
{scannedI2C?.settings?.foundAddresses.map((addr, index) => {
|
||||
return (
|
||||
<ScannedI2C key={index} decimalAddress={addr} deviceProduct={device.settings.product} updateComponentList={()=>{}} />
|
||||
)
|
||||
})}
|
||||
</React.Fragment>
|
||||
}
|
||||
</Card>
|
||||
)
|
||||
}
|
||||
107
src/device/autoDetect/ScannedI2C.tsx
Normal file
107
src/device/autoDetect/ScannedI2C.tsx
Normal file
|
|
@ -0,0 +1,107 @@
|
|||
import { Box, Button, FormControlLabel, MenuItem, Radio, RadioGroup, TextField } from "@mui/material";
|
||||
import { getAddressTypes, getFriendlyName, getSubtypes, Subtype } from "pbHelpers/ComponentType";
|
||||
import { GetProductAvailability } from "products/DeviceProduct";
|
||||
import { pond } from "protobuf-ts/pond";
|
||||
import { quack } from "protobuf-ts/quack";
|
||||
import { useEffect, useState } from "react";
|
||||
|
||||
interface Props {
|
||||
decimalAddress: number
|
||||
deviceProduct: pond.DeviceProduct
|
||||
updateComponentList: () => void
|
||||
}
|
||||
|
||||
export default function ScannedI2C(props: Props){
|
||||
const {decimalAddress, deviceProduct} = props
|
||||
const [types, setTypes] = useState<quack.ComponentType[]>([])
|
||||
const [subtypeOptions, setSubtypeOptions] = useState<Array<Subtype>>([])
|
||||
const [selectedType, setSelectedType] = useState<quack.ComponentType>(quack.ComponentType.COMPONENT_TYPE_INVALID)
|
||||
const [selectedSubtype, setSelectedSubtype] = useState(0)
|
||||
|
||||
useEffect(()=>{
|
||||
//convert the address to hex
|
||||
let hexAddress = parseInt(decimalAddress.toString(16))
|
||||
hexAddress = 0x2a //hardcoding for testing
|
||||
let types: quack.ComponentType[] = []
|
||||
//find what component types use that address
|
||||
let productAvailability = GetProductAvailability(deviceProduct)
|
||||
if(productAvailability){
|
||||
let i2cMap = productAvailability.get(quack.AddressType.ADDRESS_TYPE_I2C)
|
||||
if(i2cMap){
|
||||
i2cMap.forEach((val, key) => {
|
||||
let addresses = val as number[] ?? []
|
||||
if(addresses.length > 0 && addresses.includes(hexAddress)){
|
||||
types.push(key)
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
||||
//this if can be taken out if we dont want to select the first component type by default
|
||||
if(types.length > 0) {
|
||||
setSelectedType(types[0])
|
||||
buildSubtypeOptions(types[0])
|
||||
}
|
||||
setTypes(types)
|
||||
},[decimalAddress, deviceProduct])
|
||||
|
||||
const buildSubtypeOptions = (compType: quack.ComponentType) => {
|
||||
let subtypes = getSubtypes(compType)
|
||||
let validSub: Subtype[] = []
|
||||
//have to exclude subtypes that are not I2C
|
||||
subtypes.forEach((sub,i) => {
|
||||
let addrTypes = getAddressTypes(compType, sub.key)
|
||||
if (addrTypes.includes(quack.AddressType.ADDRESS_TYPE_I2C)){
|
||||
validSub.push(sub)
|
||||
}
|
||||
})
|
||||
//set the selected on to be the first in the valid selection
|
||||
if(validSub.length > 0){
|
||||
setSelectedSubtype(validSub[0].key)
|
||||
}
|
||||
setSubtypeOptions(validSub)
|
||||
}
|
||||
|
||||
|
||||
|
||||
return (
|
||||
<Box>
|
||||
Sensor 1
|
||||
<RadioGroup
|
||||
value={selectedType}
|
||||
onChange={(_, value) => {
|
||||
console.log(value)
|
||||
let v = parseInt(value)
|
||||
if (!isNaN(v)){
|
||||
buildSubtypeOptions(v)
|
||||
}
|
||||
}}>
|
||||
{types.map((type, i) => {
|
||||
return (
|
||||
<FormControlLabel
|
||||
key={i}
|
||||
value={type}
|
||||
control={<Radio />}
|
||||
label={getFriendlyName(type)}
|
||||
/>
|
||||
)
|
||||
})}
|
||||
</RadioGroup>
|
||||
{subtypeOptions.length > 0 &&
|
||||
<TextField
|
||||
value={selectedSubtype}
|
||||
fullWidth
|
||||
onChange={(event)=>{
|
||||
let val = +event.target.value
|
||||
console.log(event.target.value)
|
||||
setSelectedSubtype(val)
|
||||
}}
|
||||
select>
|
||||
{subtypeOptions.map(s => (
|
||||
<MenuItem value={s.key}>{s.friendlyName}</MenuItem>
|
||||
))}
|
||||
</TextField>
|
||||
}
|
||||
<Button>Add Components</Button>
|
||||
</Box>
|
||||
)
|
||||
}
|
||||
Loading…
Add table
Add a link
Reference in a new issue