Merge branch 'onewire_detect' into dev_environment
This commit is contained in:
commit
ff5d90a635
15 changed files with 256 additions and 15 deletions
4
package-lock.json
generated
4
package-lock.json
generated
|
|
@ -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#staging",
|
"protobuf-ts": "git+https://gitlab+deploy-token-50627:hv8mB4WkyvtjBpJKU1rN@gitlab.com/brandx/protobuf-ts.git#dev",
|
||||||
"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#c65c13a8eb98331c6648e401219debf8c9adc657",
|
"resolved": "git+https://gitlab+deploy-token-50627:hv8mB4WkyvtjBpJKU1rN@gitlab.com/brandx/protobuf-ts.git#b230f4b2779d21ca7b502798b1472f667f8bbdc0",
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"protobufjs": "^6.8.8"
|
"protobufjs": "^6.8.8"
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -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>
|
||||||
|
|
|
||||||
|
|
@ -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,7 +33,8 @@ 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();
|
||||||
|
|
@ -40,8 +43,8 @@ export default function DeviceScannedComponents(props: Props){
|
||||||
const [openDialog, setOpenDialog] = useState(false);
|
const [openDialog, setOpenDialog] = 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 +79,7 @@ export default function DeviceScannedComponents(props: Props){
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
setValidComponentAddresses(valid)
|
setValidI2CComponentAddresses(valid)
|
||||||
},[scannedI2C])
|
},[scannedI2C])
|
||||||
|
|
||||||
const stepper = () => {
|
const stepper = () => {
|
||||||
|
|
@ -200,6 +203,7 @@ export default function DeviceScannedComponents(props: Props){
|
||||||
})
|
})
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
console.log(cloneList)
|
||||||
setComponents(cloneList)
|
setComponents(cloneList)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -225,7 +229,7 @@ export default function DeviceScannedComponents(props: Props){
|
||||||
</Typography>
|
</Typography>
|
||||||
<Button variant="contained" color="primary" onClick={()=>{removeScan(scannedI2C.key)}}>Clear Scan</Button>
|
<Button variant="contained" color="primary" onClick={()=>{removeScan(scannedI2C.key)}}>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[]>()}/>
|
||||||
)
|
)
|
||||||
|
|
@ -242,6 +246,38 @@ export default function DeviceScannedComponents(props: Props){
|
||||||
}
|
}
|
||||||
</React.Fragment>
|
</React.Fragment>
|
||||||
}
|
}
|
||||||
|
{scannedOneWire.length > 0 &&
|
||||||
|
<Box marginTop={10}>
|
||||||
|
<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} padding={2} paddingBottom={0}>
|
||||||
|
<Box display="flex" justifyContent="space-between">
|
||||||
|
<Typography>Port: {portLabel}</Typography>
|
||||||
|
<Button variant="contained" color="primary" onClick={()=>{
|
||||||
|
removeScan(scan.key)
|
||||||
|
}}>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>
|
||||||
</Box>
|
</Box>
|
||||||
|
|
|
||||||
85
src/device/autoDetect/OneWire/PortComponent.tsx
Normal file
85
src/device/autoDetect/OneWire/PortComponent.tsx
Normal file
|
|
@ -0,0 +1,85 @@
|
||||||
|
import { Box, Checkbox, MenuItem, TextField, Tooltip } from "@mui/material"
|
||||||
|
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("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 [subtypeMap, setSubtypeMap] = useState<Map<string, number>>(new Map())
|
||||||
|
const [subtypeOptions, setSubtypeOptions] = useState<Subtype[]>([])
|
||||||
|
const [added, setAdded] = useState(false)
|
||||||
|
|
||||||
|
useEffect(()=>{
|
||||||
|
// setSelectedSubtype(compData.subtype)
|
||||||
|
let validSubtypes: Subtype[] = []
|
||||||
|
let subMap: Map<string, number> = new Map()
|
||||||
|
let subVal: string = "none"
|
||||||
|
getSubtypes(compData.type).forEach(option => {
|
||||||
|
if(compData.subtype === option.key || compData.subtype === 0){
|
||||||
|
validSubtypes.push(option)
|
||||||
|
if(subVal === "none"){
|
||||||
|
subVal = option.friendlyName
|
||||||
|
}
|
||||||
|
}
|
||||||
|
subMap.set(option.friendlyName, option.key)
|
||||||
|
})
|
||||||
|
setSubtypeOptions(validSubtypes)
|
||||||
|
setSubtypeMap(subMap)
|
||||||
|
setSubtypeVal(subVal)
|
||||||
|
},[compData])
|
||||||
|
|
||||||
|
const subtypeSelector = () => {
|
||||||
|
return (
|
||||||
|
<TextField
|
||||||
|
value={subtypeVal}
|
||||||
|
disabled={added}
|
||||||
|
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={"none"}>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)
|
||||||
|
}}
|
||||||
|
/>
|
||||||
|
}
|
||||||
|
/>
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
return (
|
||||||
|
<React.Fragment>
|
||||||
|
<Box>
|
||||||
|
{getFriendlyName(compData.type)}
|
||||||
|
Cable ID: {compData.cableId}
|
||||||
|
Number of nodes: {compData.nodeCount}
|
||||||
|
{subtypeOptions.length < 2 ? subtypeVal : subtypeSelector()}
|
||||||
|
{selectCompCheckbox()}
|
||||||
|
</Box>
|
||||||
|
</React.Fragment>
|
||||||
|
)
|
||||||
|
}
|
||||||
54
src/device/autoDetect/OneWire/ScannedOneWirePort.tsx
Normal file
54
src/device/autoDetect/OneWire/ScannedOneWirePort.tsx
Normal file
|
|
@ -0,0 +1,54 @@
|
||||||
|
import { Box, MenuItem, TextField } 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.map((compData, i) => {
|
||||||
|
return (
|
||||||
|
<PortComponent key={i} compData={compData} componentSelect={(checked, component) => {
|
||||||
|
componentSelected(checked, component)
|
||||||
|
}}/>
|
||||||
|
)
|
||||||
|
})}
|
||||||
|
</React.Fragment>
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
@ -48,6 +48,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.8",
|
||||||
|
v2CellGreen: "N/A",
|
||||||
|
v2WifiBlue: "2.1.8",
|
||||||
|
v2CellBlue: "2.1.8",
|
||||||
|
v2EthBlue: "2.1.8"
|
||||||
|
}
|
||||||
]
|
]
|
||||||
]);
|
]);
|
||||||
export class Device {
|
export class Device {
|
||||||
|
|
|
||||||
|
|
@ -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){
|
||||||
|
setScannedAddresses(pond.ListFoundComponentsResponse.fromObject(resp.data).foundComponents ?? undefined)
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
.catch(err => {
|
.catch(err => {
|
||||||
|
|
@ -252,7 +253,9 @@ export default function DevicePage() {
|
||||||
let id: quack.IComponentID = quack.ComponentID.fromObject({
|
let id: quack.IComponentID = quack.ComponentID.fromObject({
|
||||||
type: c.settings.type,
|
type: c.settings.type,
|
||||||
addressType: c.settings.addressType,
|
addressType: c.settings.addressType,
|
||||||
address: c.settings.address
|
address: c.settings.address,
|
||||||
|
expansionLine: c.settings.expansionLine,
|
||||||
|
muxLine: c.settings.muxLine
|
||||||
});
|
});
|
||||||
let filteredInteractions = interactions.filter(interaction => {
|
let filteredInteractions = interactions.filter(interaction => {
|
||||||
let isSource = false;
|
let isSource = false;
|
||||||
|
|
@ -430,8 +433,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}
|
||||||
|
|
|
||||||
|
|
@ -15,7 +15,9 @@ export function sameComponentID(
|
||||||
const sameType: boolean = id1.type === id2.type;
|
const sameType: boolean = id1.type === id2.type;
|
||||||
const sameAddressType: boolean = id1.addressType === id2.addressType;
|
const sameAddressType: boolean = id1.addressType === id2.addressType;
|
||||||
const sameAddress: boolean = (!id1.address && !id2.address) || id1.address === id2.address;
|
const sameAddress: boolean = (!id1.address && !id2.address) || id1.address === id2.address;
|
||||||
return sameType && sameAddressType && sameAddress;
|
const sameExpansion: boolean = (!id1.expansionLine && !id2.expansionLine) || id1.expansionLine === id2.expansionLine;
|
||||||
|
const sameMux: boolean = (!id1.muxLine && !id2.muxLine) || id1.muxLine === id2.muxLine;
|
||||||
|
return sameType && sameAddressType && sameAddress && sameExpansion && sameMux;
|
||||||
}
|
}
|
||||||
|
|
||||||
export function getComponentIDString(component?: Component): string {
|
export function getComponentIDString(component?: Component): string {
|
||||||
|
|
|
||||||
|
|
@ -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 {
|
||||||
|
|
|
||||||
|
|
@ -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: [],
|
||||||
|
|
|
||||||
|
|
@ -213,7 +213,7 @@ export function dragerGasDongle(subtype: number = 0): ComponentTypeExtension {
|
||||||
smoothingAverages,
|
smoothingAverages,
|
||||||
filters
|
filters
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
chartData = simpleLineChartData(
|
chartData = simpleLineChartData(
|
||||||
quack.ComponentType.COMPONENT_TYPE_DRAGER_GAS_DONGLE,
|
quack.ComponentType.COMPONENT_TYPE_DRAGER_GAS_DONGLE,
|
||||||
|
|
|
||||||
|
|
@ -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: [],
|
||||||
|
|
|
||||||
|
|
@ -63,6 +63,11 @@ const subtypes = [
|
||||||
key: quack.BooleanOutputSubtype.BOOLEAN_OUTPUT_SUBTYPE_EXHAUST_FAN,
|
key: quack.BooleanOutputSubtype.BOOLEAN_OUTPUT_SUBTYPE_EXHAUST_FAN,
|
||||||
value: "BOOLEAN_OUTPUT_SUBTYPE_FAN",
|
value: "BOOLEAN_OUTPUT_SUBTYPE_FAN",
|
||||||
friendlyName: "Exhaust Fan"
|
friendlyName: "Exhaust Fan"
|
||||||
|
} as Subtype,
|
||||||
|
{
|
||||||
|
key: quack.BooleanOutputSubtype.BOOLEAN_OUTPUT_SUBTYPE_ALARM,
|
||||||
|
value: "BOOLEAN_OUTPUT_SUBTYPE_ALARM",
|
||||||
|
friendlyName: "Alarm"
|
||||||
} as Subtype
|
} as Subtype
|
||||||
];
|
];
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -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: [],
|
||||||
|
|
|
||||||
|
|
@ -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>;
|
||||||
|
|
@ -962,6 +963,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
|
||||||
|
|
@ -1035,6 +1049,7 @@ export default function DeviceProvider(props: PropsWithChildren<Props>) {
|
||||||
updateComponentPreferences,
|
updateComponentPreferences,
|
||||||
listDeviceComponentPreferences,
|
listDeviceComponentPreferences,
|
||||||
detectI2C,
|
detectI2C,
|
||||||
|
detectOneWire,
|
||||||
listFoundComponents,
|
listFoundComponents,
|
||||||
removeFoundComponents
|
removeFoundComponents
|
||||||
}}>
|
}}>
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue