From 0223354f54d5c7da6502523eadc724af3dd10299 Mon Sep 17 00:00:00 2001 From: csawatzky Date: Fri, 23 May 2025 11:22:32 -0600 Subject: [PATCH] re-added the product types and svgs for MiVent and Streamline --- src/device/deviceSVG.tsx | 931 ++++++++++++++++++++++ src/products/Bindapt/BindaptDescriber.ts | 32 + src/products/DeviceProduct.ts | 11 +- src/products/MiVent/MiVentAvailability.ts | 61 ++ src/products/MiVent/MiVentDescriber.ts | 29 + 5 files changed, 1062 insertions(+), 2 deletions(-) create mode 100644 src/products/MiVent/MiVentAvailability.ts create mode 100644 src/products/MiVent/MiVentDescriber.ts diff --git a/src/device/deviceSVG.tsx b/src/device/deviceSVG.tsx index d6399f7..e279268 100644 --- a/src/device/deviceSVG.tsx +++ b/src/device/deviceSVG.tsx @@ -5204,6 +5204,933 @@ export default function DeviceSVG(props: Props) { ); }; + const streamlineMonitorSVG = () => { + return ( + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + {/* buttons for port selection */} + {/* I2C PORTS */} + { + openMenu(e, { + address: 0, //address here is not important for I2C, the restrictions are per component not per port + addressType: quack.AddressType.ADDRESS_TYPE_I2C, + label: "1", + autoDetectable: false + }); + }} + className={classes.testButton} + id="button" + cx="20.5" + cy="44" + rx={buttonSize.rxLarge} + ry={buttonSize.ryLarge} + /> + {/* CONFIGURABLE PIN PORTS - Note input Ports 3 and 4 and all control ports are locked for the monitor */} + {/* PORT 1 */} + { + openMenu(e, { + address: 1, + addressType: quack.AddressType.ADDRESS_TYPE_CONFIGURABLE_PIN_ARRAY, + label: "1", + autoDetectable: true + }); + }} + className={classes.testButton} + id="button" + cx="20" + cy="80" + rx={buttonSize.rxLarge} + ry={buttonSize.ryLarge} + /> + {/* PORT 2 */} + { + openMenu(e, { + address: 2, + addressType: quack.AddressType.ADDRESS_TYPE_CONFIGURABLE_PIN_ARRAY, + label: "2", + autoDetectable: true + }); + }} + className={classes.testButton} + id="button" + cx="20.5" + cy="116" + rx={buttonSize.rxLarge} + ry={buttonSize.ryLarge} + /> + {/* PORT 3 */} + { + setLockOpen(true); + // openMenu(e, { + // address: 4, + // addressType: quack.AddressType.ADDRESS_TYPE_CONFIGURABLE_PIN_ARRAY, + // label: "3", + // autoDetectable: true + // }); + }} + className={classes.testButton} + id="button" + cx="21.5" + cy="153" + rx={buttonSize.rxLarge} + ry={buttonSize.ryLarge} + /> + {/* Port 4 */} + { + setLockOpen(true); + // openMenu(e, { + // address: 8, + // addressType: quack.AddressType.ADDRESS_TYPE_CONFIGURABLE_PIN_ARRAY, + // label: "3", + // autoDetectable: true + // }); + }} + className={classes.testButton} + id="button" + cx="21.5" + cy="189" + rx={buttonSize.rxLarge} + ry={buttonSize.ryLarge} + /> + {/* Controller ports - note these are all locked for monitor devices */} + {/* PORT C1 */} + { + setLockOpen(true); + // openMenu(e, { + // address: 2, + // addressType: quack.AddressType.ADDRESS_TYPE_CONFIGURABLE_PIN_ARRAY, + // label: "2", + // autoDetectable: true + // }); + }} + className={classes.testButton} + id="button" + cx="98" + cy="206" + rx={buttonSize.rxLarge} + ry={buttonSize.ryLarge} + /> + {/* PORT C2 */} + { + setLockOpen(true); + // openMenu(e, { + // address: 4, + // addressType: quack.AddressType.ADDRESS_TYPE_CONFIGURABLE_PIN_ARRAY, + // label: "3", + // autoDetectable: true + // }); + }} + className={classes.testButton} + id="button" + cx="140" + cy="206" + rx={buttonSize.rxLarge} + ry={buttonSize.ryLarge} + /> + {/* Port C3 */} + { + setLockOpen(true); + // openMenu(e, { + // address: 8, + // addressType: quack.AddressType.ADDRESS_TYPE_CONFIGURABLE_PIN_ARRAY, + // label: "3", + // autoDetectable: true + // }); + }} + className={classes.testButton} + id="button" + cx="182" + cy="206" + rx={buttonSize.rxLarge} + ry={buttonSize.ryLarge} + /> + + ); + }; + + const streamlineAutomateSVG = () => { + return ( + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + {/* buttons for port selection */} + {/* I2C PORTS */} + { + openMenu(e, { + address: 0, //address here is not important for I2C, the restrictions are per component not per port + addressType: quack.AddressType.ADDRESS_TYPE_I2C, + label: "1", + autoDetectable: false + }); + }} + className={classes.testButton} + id="button" + cx="17" + cy="44" + rx={buttonSize.rxLarge} + ry={buttonSize.ryLarge} + /> + {/* CONFIGURABLE PIN PORTS - Note input Ports 3 and 4 and all control ports are locked for the monitor */} + {/* PORT 1 */} + { + openMenu(e, { + address: 1, + addressType: quack.AddressType.ADDRESS_TYPE_CONFIGURABLE_PIN_ARRAY, + label: "1", + autoDetectable: true + }); + }} + className={classes.testButton} + id="button" + cx="17" + cy="80" + rx={buttonSize.rxLarge} + ry={buttonSize.ryLarge} + /> + {/* PORT 2 */} + { + openMenu(e, { + address: 2, + addressType: quack.AddressType.ADDRESS_TYPE_CONFIGURABLE_PIN_ARRAY, + label: "2", + autoDetectable: true + }); + }} + className={classes.testButton} + id="button" + cx="17" + cy="116" + rx={buttonSize.rxLarge} + ry={buttonSize.ryLarge} + /> + {/* PORT 3 */} + { + openMenu(e, { + address: 4, + addressType: quack.AddressType.ADDRESS_TYPE_CONFIGURABLE_PIN_ARRAY, + label: "3", + autoDetectable: true + }); + }} + className={classes.testButton} + id="button" + cx="17" + cy="152" + rx={buttonSize.rxLarge} + ry={buttonSize.ryLarge} + /> + {/* Port 4 */} + { + openMenu(e, { + address: 8, + addressType: quack.AddressType.ADDRESS_TYPE_CONFIGURABLE_PIN_ARRAY, + label: "4", + autoDetectable: true + }); + }} + className={classes.testButton} + id="button" + cx="17" + cy="188" + rx={buttonSize.rxLarge} + ry={buttonSize.ryLarge} + /> + {/* Controller ports - note these are all locked for monitor devices */} + {/* PORT C1 */} + { + openMenu(e, { + address: 2, + addressType: quack.AddressType.ADDRESS_TYPE_CONFIGURABLE_PIN_ARRAY, + label: "C1", + autoDetectable: true + }); + }} + className={classes.testButton} + id="button" + cx="95" + cy="207" + rx={buttonSize.rxLarge} + ry={buttonSize.ryLarge} + /> + {/* PORT C2 */} + { + openMenu(e, { + address: 4, + addressType: quack.AddressType.ADDRESS_TYPE_CONFIGURABLE_PIN_ARRAY, + label: "C2", + autoDetectable: true + }); + }} + className={classes.testButton} + id="button" + cx="138" + cy="207" + rx={buttonSize.rxLarge} + ry={buttonSize.ryLarge} + /> + {/* Port C3 */} + { + openMenu(e, { + address: 8, + addressType: quack.AddressType.ADDRESS_TYPE_CONFIGURABLE_PIN_ARRAY, + label: "C3", + autoDetectable: true + }); + }} + className={classes.testButton} + id="button" + cx="180" + cy="207" + rx={buttonSize.rxLarge} + ry={buttonSize.ryLarge} + /> + + ); + }; + const getProductSVG = () => { switch (device.settings.product) { case pond.DeviceProduct.DEVICE_PRODUCT_BINDAPT_PLUS_PRO: @@ -5232,6 +6159,10 @@ export default function DeviceSVG(props: Props) { return miVentSVG(); case pond.DeviceProduct.DEVICE_PRODUCT_MIVENT_V2: return miVentSVG(true); + case pond.DeviceProduct.DEVICE_PRODUCT_STREAMLINE_MONITOR: + return streamlineMonitorSVG(); + case pond.DeviceProduct.DEVICE_PRODUCT_STREAMLINE_AUTOMATE: + return streamlineAutomateSVG(); } }; diff --git a/src/products/Bindapt/BindaptDescriber.ts b/src/products/Bindapt/BindaptDescriber.ts index 2bb4b63..b7f39f3 100644 --- a/src/products/Bindapt/BindaptDescriber.ts +++ b/src/products/Bindapt/BindaptDescriber.ts @@ -191,6 +191,38 @@ export const BindaptV2Automate: DeviceProductDescriber = { // ]) }; +export const StreamlineMonitor: DeviceProductDescriber = { + product: pond.DeviceProduct.DEVICE_PRODUCT_STREAMLINE_MONITOR, + label: "Streamline Monitor", + icon: (_, theme?: "light" | "dark") => { + return theme === "light" ? BindaptPlusDarkIcon : BindaptPlusLightIcon; + }, + view: "controller", + tabs: getBindaptTabs(), + availability: BindaptV2MonitorAvailability + //TODO not sure what the default address map for these should be yet + // defaultAddressMap: new Map([ + // ["plenum", ["9-2-64"]], + // ["heatersFans", ["3-1-512"]] //refers to heaters and fans + // ]) +}; + +export const StreamlineAutomate: DeviceProductDescriber = { + product: pond.DeviceProduct.DEVICE_PRODUCT_STREAMLINE_AUTOMATE, + label: "Streamline Automate", + icon: (_, theme?: "light" | "dark") => { + return theme === "light" ? BindaptPlusDarkIcon : BindaptPlusLightIcon; + }, + view: "controller", + tabs: getBindaptTabs(), + availability: BindaptV2AutomateAvailability + //TODO not sure what the default address map for these should be yet + // defaultAddressMap: new Map([ + // ["plenum", ["9-2-64"]], + // ["heatersFans", ["3-1-512"]] //refers to heaters and fans + // ]) +}; + export function IsBindaptDevice(product?: pond.DeviceProduct): boolean { const bindaptProducts: pond.DeviceProduct[] = [ pond.DeviceProduct.DEVICE_PRODUCT_BINDAPT_MINI, diff --git a/src/products/DeviceProduct.ts b/src/products/DeviceProduct.ts index ce910ec..792be79 100644 --- a/src/products/DeviceProduct.ts +++ b/src/products/DeviceProduct.ts @@ -11,7 +11,9 @@ import { BindaptV2Automate, BinHalo, BinMonitor, - BinUltimate + BinUltimate, + StreamlineMonitor, + StreamlineAutomate } from "./Bindapt/BindaptDescriber"; import { NexusST } from "./Nexus/NexusDescriber"; import { MiPCAV2, OmniAir } from "./OmniAir/OmniAirDescriber"; @@ -19,6 +21,7 @@ import { ConfigurablePin } from "pbHelpers/AddressTypes"; import { useTheme } from "@mui/material"; import { Device } from "models"; import { or } from "utils"; +import { MiVent, MiVentV2 } from "./MiVent/MiVentDescriber"; export type ProductTab = "components" | "presets"; @@ -87,7 +90,11 @@ const DEVICE_PRODUCT_MAP = new Map([ [pond.DeviceProduct.DEVICE_PRODUCT_BINDAPT_PLUS_MOD, BindaptPlusMod], [pond.DeviceProduct.DEVICE_PRODUCT_BINDAPT_PLUS_PRO_MOD, BindaptPlusProMod], [pond.DeviceProduct.DEVICE_PRODUCT_BINDAPT_V2_MONITOR, BindaptV2Monitor], - [pond.DeviceProduct.DEVICE_PRODUCT_BINDAPT_V2_AUTOMATE, BindaptV2Automate] + [pond.DeviceProduct.DEVICE_PRODUCT_BINDAPT_V2_AUTOMATE, BindaptV2Automate], + [pond.DeviceProduct.DEVICE_PRODUCT_MIVENT, MiVent], + [pond.DeviceProduct.DEVICE_PRODUCT_MIVENT_V2, MiVentV2], + [pond.DeviceProduct.DEVICE_PRODUCT_STREAMLINE_MONITOR, StreamlineMonitor], + [pond.DeviceProduct.DEVICE_PRODUCT_STREAMLINE_AUTOMATE, StreamlineAutomate] ]); export function ListDeviceProductDescribers(): DeviceProductDescriber[] { diff --git a/src/products/MiVent/MiVentAvailability.ts b/src/products/MiVent/MiVentAvailability.ts new file mode 100644 index 0000000..4002627 --- /dev/null +++ b/src/products/MiVent/MiVentAvailability.ts @@ -0,0 +1,61 @@ +import { ConfigurablePin } from "pbHelpers/AddressTypes"; +import { DeviceAvailabilityMap, DevicePositions } from "pbHelpers/DeviceAvailability"; +import { quack } from "protobuf-ts/pond"; + +const MiVentV1Pins: ConfigurablePin[] = [ + { address: 4, label: "1" }, + { address: 8, label: "2" }, + { address: 16, label: "3" }, + { address: 512, label: "C1" }, + { address: 1024, label: "C2" } +]; + +export const MiVentV1Availability: DeviceAvailabilityMap = new Map< + quack.AddressType, + DevicePositions +>([ + [quack.AddressType.ADDRESS_TYPE_INVALID, []], + [quack.AddressType.ADDRESS_TYPE_CONFIGURABLE_PIN_ARRAY, MiVentV1Pins], + [ + quack.AddressType.ADDRESS_TYPE_I2C, + new Map([ + [quack.ComponentType.COMPONENT_TYPE_PRESSURE, [0x18]], + [quack.ComponentType.COMPONENT_TYPE_DHT, [0x40]], + [quack.ComponentType.COMPONENT_TYPE_SEN5X, [0x69]], + [quack.ComponentType.COMPONENT_TYPE_AIRFLOW, [0x2a]] + ]) + ], + [quack.AddressType.ADDRESS_TYPE_POWER, [0]], + [quack.AddressType.ADDRESS_TYPE_GPS, [0]], + [quack.AddressType.ADDRESS_TYPE_MODEM, [0]] +]); + +/*---V2 Stuff starts here---*/ + +const MiVentV2Pins: ConfigurablePin[] = [ + { address: 1, label: "1" }, + { address: 2, label: "2" }, + { address: 4, label: "3" }, + { address: 256, label: "L1" }, + { address: 512, label: "L2" } +]; + +export const MiVentV2Availability: DeviceAvailabilityMap = new Map< + quack.AddressType, + DevicePositions +>([ + [quack.AddressType.ADDRESS_TYPE_INVALID, []], + [quack.AddressType.ADDRESS_TYPE_CONFIGURABLE_PIN_ARRAY, MiVentV2Pins], + [ + quack.AddressType.ADDRESS_TYPE_I2C, + new Map([ + [quack.ComponentType.COMPONENT_TYPE_PRESSURE, [0x18]], + [quack.ComponentType.COMPONENT_TYPE_DHT, [0x40]], + [quack.ComponentType.COMPONENT_TYPE_SEN5X, [0x69]], + [quack.ComponentType.COMPONENT_TYPE_AIRFLOW, [0x2a]] + ]) + ], + [quack.AddressType.ADDRESS_TYPE_POWER, [0]], + [quack.AddressType.ADDRESS_TYPE_GPS, [0]], + [quack.AddressType.ADDRESS_TYPE_MODEM, [0]] +]); diff --git a/src/products/MiVent/MiVentDescriber.ts b/src/products/MiVent/MiVentDescriber.ts new file mode 100644 index 0000000..05592ec --- /dev/null +++ b/src/products/MiVent/MiVentDescriber.ts @@ -0,0 +1,29 @@ +import { DeviceProductDescriber } from "products/DeviceProduct"; +import { pond } from "protobuf-ts/pond"; +import DeviceDarkIcon from "assets/products/Ag/device 1.png"; +import DeviceLightIcon from "assets/products/Ag/device 2.png"; +import { MiVentV1Availability, MiVentV2Availability } from "./MiVentAvailability"; + +export const MiVent: DeviceProductDescriber = { + product: pond.DeviceProduct.DEVICE_PRODUCT_MIVENT, + label: "MiVent V1", + icon: (_, theme?: "light" | "dark") => { + return theme === "light" ? DeviceDarkIcon : DeviceLightIcon; + }, + view: "controller", + tabs: ["components"], + availability: MiVentV1Availability +}; + +/*---V2 Stuff starts here---*/ + +export const MiVentV2: DeviceProductDescriber = { + product: pond.DeviceProduct.DEVICE_PRODUCT_MIVENT_V2, + label: "MiVent V2", + icon: (_, theme?: "light" | "dark") => { + return theme === "light" ? DeviceDarkIcon : DeviceLightIcon; + }, + view: "controller", + tabs: ["components"], + availability: MiVentV2Availability +};