Merge branch 'onewire_detect' into staging_environment

This commit is contained in:
csawatzky 2025-12-15 16:33:54 -06:00
commit a7fee2f76d
13 changed files with 380 additions and 24 deletions

4
package-lock.json generated
View file

@ -42,7 +42,7 @@
"mui-tel-input": "^7.0.0", "mui-tel-input": "^7.0.0",
"notistack": "^3.0.1", "notistack": "^3.0.1",
"openweathermap-ts": "^1.2.10", "openweathermap-ts": "^1.2.10",
"protobuf-ts": "git+https://gitlab+deploy-token-50627:hv8mB4WkyvtjBpJKU1rN@gitlab.com/brandx/protobuf-ts.git#master", "protobuf-ts": "git+https://gitlab+deploy-token-50627:hv8mB4WkyvtjBpJKU1rN@gitlab.com/brandx/protobuf-ts.git#staging",
"query-string": "^9.2.1", "query-string": "^9.2.1",
"react": "^18.3.1", "react": "^18.3.1",
"react-beautiful-dnd": "^13.1.1", "react-beautiful-dnd": "^13.1.1",
@ -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#c08965a296f2cd0799472fd8b163186cf6885d4c", "resolved": "git+https://gitlab+deploy-token-50627:hv8mB4WkyvtjBpJKU1rN@gitlab.com/brandx/protobuf-ts.git#3f647071f211c4552c2acc23a8ecabb6904a4156",
"dependencies": { "dependencies": {
"protobufjs": "^6.8.8" "protobufjs": "^6.8.8"
} }

View file

@ -54,7 +54,7 @@
"mui-tel-input": "^7.0.0", "mui-tel-input": "^7.0.0",
"notistack": "^3.0.1", "notistack": "^3.0.1",
"openweathermap-ts": "^1.2.10", "openweathermap-ts": "^1.2.10",
"protobuf-ts": "git+https://gitlab+deploy-token-50627:hv8mB4WkyvtjBpJKU1rN@gitlab.com/brandx/protobuf-ts.git#master", "protobuf-ts": "git+https://gitlab+deploy-token-50627:hv8mB4WkyvtjBpJKU1rN@gitlab.com/brandx/protobuf-ts.git#staging",
"query-string": "^9.2.1", "query-string": "^9.2.1",
"react": "^18.3.1", "react": "^18.3.1",
"react-beautiful-dnd": "^13.1.1", "react-beautiful-dnd": "^13.1.1",

View file

@ -141,6 +141,28 @@ export default function DeviceWizard(props: Props) {
</MenuItem> </MenuItem>
</Tooltip> </Tooltip>
)} )}
{selectedPort &&
selectedPort.addressType === quack.AddressType.ADDRESS_TYPE_CONFIGURABLE_PIN_ARRAY &&
device.featureSupported("detectOneWire") &&
selectedPort.autoDetectable && (
<Tooltip title="Used to tell the Device to scan this port for any plugged in sensors">
<MenuItem
key={"scanOneWire"}
disabled={scanInProgress || buttonClicked}
onClick={() => {
setButtonClicked(true)
console.log(selectedPort)
deviceAPI.detectOneWire(device.id(), selectedPort.address)
.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 && ( {portComponents.length > 0 && (
<List> <List>
<ListSubheader>Current Components</ListSubheader> <ListSubheader>Current Components</ListSubheader>

View file

@ -7,9 +7,11 @@ import { useEffect, useState } from "react";
import ScannedI2C from "./ScannedI2C"; import ScannedI2C from "./ScannedI2C";
import ComponentForm from "component/ComponentForm"; import ComponentForm from "component/ComponentForm";
import { Component, Device } from "models"; import { Component, Device } from "models";
import { DeviceAvailabilityMap, OffsetAvailabilityMap } from "pbHelpers/DeviceAvailability"; import { DeviceAvailabilityMap, FindAvailablePositions, OffsetAvailabilityMap } from "pbHelpers/DeviceAvailability";
import ResponsiveDialog from "common/ResponsiveDialog"; import ResponsiveDialog from "common/ResponsiveDialog";
import { useComponentAPI, useDeviceAPI, useSnackbar } from "hooks"; import { useComponentAPI, useDeviceAPI, useSnackbar } from "hooks";
import { ConfigurablePin } from "pbHelpers/AddressTypes";
import ScannedOneWirePort from "./OneWire/ScannedOneWirePort";
interface Props { interface Props {
scannedComponents: pond.ComponentAddressMap scannedComponents: pond.ComponentAddressMap
@ -31,17 +33,19 @@ export default function DeviceScannedComponents(props: Props){
const compAPI = useComponentAPI(); const compAPI = useComponentAPI();
const deviceAPI = useDeviceAPI() const deviceAPI = useDeviceAPI()
const [scannedI2C, setScannedI2C] = useState<pond.DetectI2C>() //the unmodified scan of addresses const [scannedI2C, setScannedI2C] = useState<pond.DetectI2C>() //the unmodified scan of addresses
const [validCompAddresses, setValidComponentAddresses] = useState<quack.AddressData[]>([]) //the filtered array of address data const [scannedOneWire, setScannedOneWire] = useState<pond.DetectOneWire[]>([])
const [validI2CCompAddresses, setValidI2CComponentAddresses] = useState<quack.AddressData[]>([]) //the filtered array of address data
const [components, setComponents] = useState<Component[]>([]) const [components, setComponents] = useState<Component[]>([])
const [steps, setSteps] = useState<CompStep[]>([]); const [steps, setSteps] = useState<CompStep[]>([]);
const { error, success } = useSnackbar(); const { error, success } = useSnackbar();
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(()=>{
//console.log(scannedComponents)
if (scannedComponents.i2c) setScannedI2C(scannedComponents.i2c) if (scannedComponents.i2c) setScannedI2C(scannedComponents.i2c)
if (scannedComponents.oneWire) setScannedOneWire(scannedComponents.oneWire)
//makes the array empty for testing //makes the array empty for testing
// if (scannedComponents.i2c) { // if (scannedComponents.i2c) {
// let clone = cloneDeep(scannedComponents.i2c) // let clone = cloneDeep(scannedComponents.i2c)
@ -76,7 +80,7 @@ export default function DeviceScannedComponents(props: Props){
} }
}) })
} }
setValidComponentAddresses(valid) setValidI2CComponentAddresses(valid)
},[scannedI2C]) },[scannedI2C])
const stepper = () => { const stepper = () => {
@ -200,11 +204,12 @@ export default function DeviceScannedComponents(props: Props){
}) })
}) })
} }
console.log(cloneList)
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 => {
@ -212,20 +217,51 @@ export default function DeviceScannedComponents(props: Props){
}) })
} }
const removeAllScans = () => {
deviceAPI.removeAllFoundComponents(device.settings.deviceId)
.then(resp => {
console.log("Cleared all scans")
refreshCallback()
}).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()
setClearOpen(false)
}}>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>
{validCompAddresses.length > 0 ? validCompAddresses.map((addr, index) => { {validI2CCompAddresses.length > 0 ? validI2CCompAddresses.map((addr, index) => {
return ( return (
<ScannedI2C key={index} sensorNum={index+1} addressData={addr} deviceProduct={device.settings.product} componentSelectionCallback={componentSelection} availablePositions={availablePositions.get(quack.AddressType.ADDRESS_TYPE_I2C) ?? new Map<quack.ComponentType, number[]>()}/> <ScannedI2C key={index} sensorNum={index+1} addressData={addr} deviceProduct={device.settings.product} componentSelectionCallback={componentSelection} availablePositions={availablePositions.get(quack.AddressType.ADDRESS_TYPE_I2C) ?? new Map<quack.ComponentType, number[]>()}/>
) )
@ -240,7 +276,39 @@ export default function DeviceScannedComponents(props: Props){
</Typography> </Typography>
</Box> </Box>
} }
</React.Fragment> </Box>
}
{scannedOneWire.length > 0 &&
<Box>
<Box justifyContent="space-between" display="flex">
<Typography sx={{fontWeight: 650}}>
Pin Port Sensors
</Typography>
</Box>
{scannedOneWire.map((scan,i) => {
let map = FindAvailablePositions([], device.settings.product).availability.get(quack.AddressType.ADDRESS_TYPE_CONFIGURABLE_PIN_ARRAY)
let portAddress = scan.settings?.oneWireData?.port
let portLabel = ""
map?.forEach(entry => {
let pin = entry as ConfigurablePin
if (pin.address && pin.address === portAddress) {
portLabel = pin.label
}
})
return(
<Box key={i} paddingX={2}>
<Box display="flex" justifyContent="space-between" alignItems={"center"}>
<Typography>Port: {portLabel}</Typography>
<Button variant="contained" color="primary" onClick={()=>{
removeScan(scan.key, pond.ObjectType.OBJECT_TYPE_DETECT_ONEWIRE)
}}>Clear Port Scan</Button>
</Box>
<ScannedOneWirePort scan={scan} componentSelectionCallback={componentSelection}/>
</Box>
)
})}
</Box>
} }
<Box display="flex" flexDirection="row-reverse" marginTop={2}> <Box display="flex" flexDirection="row-reverse" marginTop={2}>
<Button disabled={components.length === 0} variant="contained" color="primary" onClick={()=>{setOpenDialog(true)}}>Add Components</Button> <Button disabled={components.length === 0} variant="contained" color="primary" onClick={()=>{setOpenDialog(true)}}>Add Components</Button>

View file

@ -0,0 +1,150 @@
import { Box, Checkbox, Grid2, MenuItem, TextField, Tooltip, Typography } from "@mui/material"
import { useMobile } from "hooks"
import { getFriendlyName, getSubtypes, Subtype } from "pbHelpers/ComponentType"
import { quack } from "protobuf-ts/quack"
import React, { useEffect, useState } from "react"
interface Props {
compData: quack.OneWireComponentData
componentSelect: (selected: boolean, componentData: quack.OneWireComponentData) => void
}
export default function PortComponent(props: Props){
const {compData, componentSelect} = props
// const [selectedSubtype, setSelectedSubtype] = useState<number>(0)
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 [subtypeOptions, setSubtypeOptions] = useState<Subtype[]>([])
const [added, setAdded] = useState(false)
const isMobile = useMobile()
useEffect(()=>{
// setSelectedSubtype(compData.subtype)
let validSubtypes: Subtype[] = []
let subMap: Map<string, number> = new Map()
let subVal: string = "no subtype"
getSubtypes(compData.type).forEach(option => {
if(compData.subtype === option.key || compData.subtype === 0){
validSubtypes.push(option)
if(subVal === "no subtype"){
subVal = option.friendlyName
}
}
subMap.set(option.friendlyName, option.key)
})
setSubtypeOptions(validSubtypes)
setSubtypeMap(subMap)
setSubtypeVal(subVal)
},[compData])
const subtypeSelector = () => {
return (
<TextField
value={subtypeVal}
disabled={added}
fullWidth
onChange={(event) => {
setSubtypeVal(event.target.value)
// setSelectedSubtype(subtypeMap.get(event.target.value) ?? 0)
compData.subtype = subtypeMap.get(event.target.value) ?? 0
}}
select>
<MenuItem key={-1} value={"no subtype"}>Select the Component Subtype</MenuItem>
{subtypeOptions.map((s, i) => (
<MenuItem key={i} value={s.friendlyName}>{s.friendlyName}</MenuItem>
))}
</TextField>
)
}
const selectCompCheckbox = () => {
return (
<Tooltip
title="Add to list to be added to the device"
children={
<Checkbox
value={added}
onChange={(_, checked) => {
setAdded(checked)
componentSelect(checked, compData)
}}
/>
}
/>
)
}
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 (
<React.Fragment>
{isMobile ? mobileDisplay() : desktopDisplay()}
</React.Fragment>
)
}

View file

@ -0,0 +1,57 @@
import { Box, MenuItem, TextField, Typography } from "@mui/material"
import { extension, getFriendlyName, getSubtypes, Subtype } from "pbHelpers/ComponentType"
import { pond } from "protobuf-ts/pond"
import { quack } from "protobuf-ts/quack"
import React, { useEffect, useState } from "react"
import PortComponent from "./PortComponent"
import { Component } from "models"
interface Props {
scan: pond.DetectOneWire
componentSelectionCallback: (newComponents: Component[], checked: boolean) => void
}
export default function ScannedOneWirePort(props: Props){
const {scan, componentSelectionCallback} = props
const [portComponents, setPortComponents] = useState<quack.OneWireComponentData[]>([])
useEffect(()=>{
setPortComponents(scan.settings?.oneWireData?.components ?? [])
},[scan])
const componentSelected = (checked: boolean, componentData: quack.OneWireComponentData) => {
let newComponents: Component[] = []
//use the component data to create a new Component
//build a component with given information and defaults for the rest
let primaryComponent = Component.create()
primaryComponent.settings.type = componentData.type
primaryComponent.settings.subtype = componentData.subtype
primaryComponent.settings.address = scan.settings?.oneWireData?.port ?? 0
primaryComponent.settings.addressType = quack.AddressType.ADDRESS_TYPE_CONFIGURABLE_PIN_ARRAY
primaryComponent.settings.name = getFriendlyName(componentData.type, componentData.subtype)
//need to check if the component is chainable, meaning the address type will reflect the cable id
let ext = extension(componentData.type, componentData.subtype)
if(ext.isChainable){
primaryComponent.settings.addressType = componentData.cableId + 8
}
newComponents.push(primaryComponent)
componentSelectionCallback(newComponents, checked)
}
return (
<React.Fragment>
{portComponents.length > 0 ? portComponents.map((compData, i) => {
return (
<PortComponent key={i} compData={compData} componentSelect={(checked, component) => {
componentSelected(checked, component)
}}/>
)
}):
<Box>
<Typography>No Components Found</Typography>
</Box>}
</React.Fragment>
)
}

View file

@ -64,6 +64,21 @@ const featureVersions: Map<string, FeatureVersionByPlatform> = new Map([
v2CellBlue: "2.1.7", v2CellBlue: "2.1.7",
v2EthBlue: "2.1.7" v2EthBlue: "2.1.7"
} }
],[
"detectOneWire",
{
photon: "N/A",
electron: "N/A",
v2Wifi: "N/A",
v2Cell: "N/A",
v2WifiS3: "N/A",
v2CellS3: "N/A",
v2CellBlack: "2.1.10",
v2CellGreen: "N/A",
v2WifiBlue: "2.1.10",
v2CellBlue: "2.1.10",
v2EthBlue: "2.1.10"
}
] ]
]); ]);
export class Device { export class Device {

View file

@ -1,4 +1,4 @@
import { Button, Card, Divider, List, ListItem, Typography } from "@mui/material"; import { Box, Button, Card, Divider, List, ListItem, Typography } from "@mui/material";
import Grid from '@mui/material/Grid2'; import Grid from '@mui/material/Grid2';
import { Component, Device, Interaction, User } from "models"; import { Component, Device, Interaction, User } from "models";
import { getContextKeys, getContextTypes } from "pbHelpers/Context"; import { getContextKeys, getContextTypes } from "pbHelpers/Context";
@ -169,8 +169,9 @@ export default function DevicePage() {
const loadPortScan = () => { const loadPortScan = () => {
deviceAPI.listFoundComponents(parseInt(deviceID)) deviceAPI.listFoundComponents(parseInt(deviceID))
.then(resp => { .then(resp => {
if (resp.data.foundComponents?.i2c){ console.log(resp.data)
setScannedAddresses(resp.data.foundComponents ?? undefined) if (resp.data.foundComponents?.i2c || resp.data.foundComponents?.oneWire){
setScannedAddresses(pond.ListFoundComponentsResponse.fromObject(resp.data).foundComponents ?? undefined)
} }
}) })
.catch(err => { .catch(err => {
@ -411,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
@ -432,8 +442,8 @@ export default function DevicePage() {
refreshCallback={loadDevice} refreshCallback={loadDevice}
/> />
</Grid> </Grid>
{scannedAddresses && {(scannedAddresses?.i2c || scannedAddresses?.oneWire) &&
<Grid size={{ xs: 6, sm: 6, lg: 4, xl: 4 }}> <Grid size={{ xs: 6, sm: 6, lg: 8, xl: 8 }}>
<DeviceScannedComponents <DeviceScannedComponents
scannedComponents={scannedAddresses} scannedComponents={scannedAddresses}
device={device} device={device}

View file

@ -168,6 +168,7 @@ export interface ComponentTypeExtension {
//if the map does not exist then just use the array from the device availability, //if the map does not exist then just use the array from the device availability,
//if the map does exist filter the availability after claims to find matching address between them and use that //if the map does exist filter the availability after claims to find matching address between them and use that
subtypeI2CMap?: Map<number, number[]> subtypeI2CMap?: Map<number, number[]>
isChainable?: boolean
} }
export interface Summary { export interface Summary {

View file

@ -68,6 +68,7 @@ export function CapacitorCable(subtype: number = 0): ComponentTypeExtension {
isSource: true, isSource: true,
isArray: true, isArray: true,
isCalibratable: false, isCalibratable: false,
isChainable: true,
addressTypes: addressTypes, addressTypes: addressTypes,
interactionResultTypes: [], interactionResultTypes: [],
states: [], states: [],

View file

@ -176,6 +176,7 @@ export function GrainCable(subtype: number = 0): ComponentTypeExtension {
isSource: true, isSource: true,
isArray: true, isArray: true,
isCalibratable: false, isCalibratable: false,
isChainable: true,
addressTypes: [quack.AddressType.ADDRESS_TYPE_CONFIGURABLE_PIN_ARRAY, quack.AddressType.ADDRESS_TYPE_I2C], addressTypes: [quack.AddressType.ADDRESS_TYPE_CONFIGURABLE_PIN_ARRAY, quack.AddressType.ADDRESS_TYPE_I2C],
interactionResultTypes: [], interactionResultTypes: [],
states: [], states: [],

View file

@ -64,6 +64,7 @@ export function PressureCable(subtype: number = 0): ComponentTypeExtension {
isArray: true, isArray: true,
hasFan: true, hasFan: true,
isCalibratable: false, isCalibratable: false,
isChainable: true,
addressTypes: [quack.AddressType.ADDRESS_TYPE_CONFIGURABLE_PIN_ARRAY], addressTypes: [quack.AddressType.ADDRESS_TYPE_CONFIGURABLE_PIN_ARRAY],
interactionResultTypes: [], interactionResultTypes: [],
states: [], states: [],

View file

@ -23,6 +23,7 @@ export interface IDeviceAPIContext {
) => Promise<AxiosResponse<pond.GetDevicePageDataResponse>>; ) => Promise<AxiosResponse<pond.GetDevicePageDataResponse>>;
getMulti: (ids: number[] | string[], otherTeam?: string) => Promise<AxiosResponse<pond.GetMultiDeviceResponse>>; getMulti: (ids: number[] | string[], otherTeam?: string) => Promise<AxiosResponse<pond.GetMultiDeviceResponse>>;
detectI2C: (id: number, otherTeam?: string) => Promise<AxiosResponse<pond.DetectI2CResponse>>; detectI2C: (id: number, otherTeam?: string) => Promise<AxiosResponse<pond.DetectI2CResponse>>;
detectOneWire: (id: number, port: number, otherTeam?: string) => Promise<AxiosResponse<pond.DetectOneWireResponse>>
listFoundComponents: (id: number, otherTeam?: string) => Promise<AxiosResponse<pond.ListFoundComponentsResponse>> listFoundComponents: (id: number, otherTeam?: string) => Promise<AxiosResponse<pond.ListFoundComponentsResponse>>
getGeoJson: (id: number | string, demo?: boolean, otherTeam?: string) => Promise<any>; getGeoJson: (id: number | string, demo?: boolean, otherTeam?: string) => Promise<any>;
getMultiGeoJson: (ids: number[] | string[], otherTeam?: string) => Promise<any>; getMultiGeoJson: (ids: number[] | string[], otherTeam?: string) => Promise<any>;
@ -148,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);
@ -962,6 +964,19 @@ export default function DeviceProvider(props: PropsWithChildren<Props>) {
}) })
} }
const detectOneWire = (id: number, port: number, otherTeam?: string) => {
let url = "/devices/" + id + "/detectOneWire?port=" + port;
const view = otherTeam ? otherTeam : as
if(view) url = url + "?as=" + view
return new Promise<AxiosResponse<pond.DetectOneWireResponse>>((resolve, reject) => {
put<pond.DetectOneWireResponse>(pondURL(url)).then(resp => {
return resolve(resp)
}).catch(err => {
return reject(err)
})
})
}
const listFoundComponents = (id: number, otherTeam?: string) => { const listFoundComponents = (id: number, otherTeam?: string) => {
let url = "/devices/" + id + "/listScannedComponents"; let url = "/devices/" + id + "/listScannedComponents";
const view = otherTeam ? otherTeam : as const view = otherTeam ? otherTeam : as
@ -975,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)
@ -988,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={{
@ -1035,8 +1063,10 @@ export default function DeviceProvider(props: PropsWithChildren<Props>) {
updateComponentPreferences, updateComponentPreferences,
listDeviceComponentPreferences, listDeviceComponentPreferences,
detectI2C, detectI2C,
detectOneWire,
listFoundComponents, listFoundComponents,
removeFoundComponents removeFoundComponents,
removeAllFoundComponents
}}> }}>
{children} {children}
</DeviceAPIContext.Provider> </DeviceAPIContext.Provider>