import { Box, Button, Checkbox, FormControlLabel, Grid2, MenuItem, Radio, RadioGroup, TextField, Tooltip, Typography } from "@mui/material"; import { Component } from "models"; import { getAddressTypes, getFriendlyName, GetSecondaryComponents, getSubtypes, Subtype } from "pbHelpers/ComponentType"; import { ComponentAvailabilityMap, DevicePositions } from "pbHelpers/DeviceAvailability"; import { GetProductAvailability } from "products/DeviceProduct"; import { pond } from "protobuf-ts/pond"; import { quack } from "protobuf-ts/quack"; import React, { useEffect, useState } from "react"; interface Props { addressData: quack.AddressData deviceProduct: pond.DeviceProduct componentSelectionCallback: (component: Component[], checked: boolean) => void availablePositions: DevicePositions sensorNum?: number } export default function ScannedI2C(props: Props){ const {addressData, deviceProduct, componentSelectionCallback, availablePositions, sensorNum} = props const [types, setTypes] = useState([]) const [subtypeOptions, setSubtypeOptions] = useState>([]) const [selectedPrimaryType, setSelectedPrimaryType] = useState(quack.ComponentType.COMPONENT_TYPE_INVALID) const [selectedPrimarySubtype, setSelectedPrimarySubtype] = useState(0) const [added, setAdded] = useState(false) const [addressInUse, setAddressInUse] = useState(false) useEffect(()=>{ let types: quack.ComponentType[] = [] //find what component types use that address, this is different than the available positions passed in //this is meant to get all possibilities according to product type and the given address, availablePositions is the restriction of what is available 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(addressData.address)){ 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) { setSelectedPrimaryType(types[0]) buildSubtypeOptions(types[0]) checkAddressAvailable(types[0]) } setTypes(types) },[addressData, 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){ setSelectedPrimarySubtype(validSub[0].key) } setSubtypeOptions(validSub) } const checkAddressAvailable = (compType: quack.ComponentType) => { let i2cMap = availablePositions as ComponentAvailabilityMap let compAddresses = i2cMap.get(compType) ?? [] if (!compAddresses.includes(addressData.address)){ setAddressInUse(true) }else{ setAddressInUse(false) } } const componentSelected = (event: React.ChangeEvent, checked: boolean) => { let toAdd: Component[] = [] setAdded(checked) //build a component with given information and defaults for the rest let primaryComponent = Component.create() primaryComponent.settings.type = selectedPrimaryType primaryComponent.settings.subtype = selectedPrimarySubtype primaryComponent.settings.addressType = quack.AddressType.ADDRESS_TYPE_I2C primaryComponent.settings.address = addressData.address primaryComponent.settings.expansionLine = addressData.expansionLine primaryComponent.settings.muxLine = addressData.muxLine primaryComponent.settings.name = getFriendlyName(selectedPrimaryType, selectedPrimarySubtype) toAdd.push(primaryComponent) GetSecondaryComponents(selectedPrimaryType, selectedPrimarySubtype).forEach(secComp => { let component = Component.create() component.settings = secComp toAdd.push(component) }) //return the component and the checked status to the parent componentSelectionCallback(toAdd, checked) } return ( {sensorNum && Sensor {sensorNum}} {addressData.expansionLine !== 0 && "Expansion Line: " + addressData.expansionLine} {/* may also want to specify the mux line, not sure if the sensors will have a mux line though */} {types.length > 0 ? { let v = parseInt(value) if (!isNaN(v)){ buildSubtypeOptions(v) checkAddressAvailable(v) } }}> {types.map((type, i) => { return ( } label={getFriendlyName(type)} /> ) })} {subtypeOptions.length > 0 && { let val = +event.target.value setSelectedPrimarySubtype(val) }} select> {subtypeOptions.map(s => ( {s.friendlyName} ))} } } /> : Sensor Not Supported By Product } ) }