diff --git a/package.json b/package.json index 7e99bea8..e9ac63df 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "meshtastic-web", - "version": "2.2.10-0", + "version": "2.2.12-0", "type": "module", "description": "Meshtastic web client", "license": "GPL-3.0-only", diff --git a/src/components/PageComponents/ModuleConfig/DetectionSensor.tsx b/src/components/PageComponents/ModuleConfig/DetectionSensor.tsx new file mode 100644 index 00000000..28b26209 --- /dev/null +++ b/src/components/PageComponents/ModuleConfig/DetectionSensor.tsx @@ -0,0 +1,117 @@ +import { useDevice } from "@app/core/stores/deviceStore.js"; +import type { DetectionSensorValidation } from "@app/validation/moduleConfig/detectionSensor.js"; +import { DynamicForm } from "@components/Form/DynamicForm.js"; +import { Protobuf } from "@meshtastic/meshtasticjs"; + +export const DetectionSensor = (): JSX.Element => { + const { moduleConfig, setWorkingModuleConfig } = useDevice(); + + const onSubmit = (data: DetectionSensorValidation) => { + setWorkingModuleConfig( + new Protobuf.ModuleConfig({ + payloadVariant: { + case: "detectionSensor", + value: data, + }, + }), + ); + }; + + return ( + + onSubmit={onSubmit} + defaultValues={moduleConfig.detectionSensor} + fieldGroups={[ + { + label: "Detection Sensor Settings", + description: "Settings for the Detection Sensor module", + fields: [ + { + type: "toggle", + name: "enabled", + label: "Enabled", + description: "Enable or disable Detection Sensor Module", + }, + { + type: "number", + name: "minimumBroadcastSecs", + label: "Minimum Broadcast Seconds", + description: "The interval in seconds of how often we can send a message to the mesh when a state change is detected", + disabledBy: [ + { + fieldName: "enabled", + }, + ], + }, + { + type: "number", + name: "stateBroadcastSecs", + label: "State Broadcast Seconds", + description: "The interval in seconds of how often we should send a message to the mesh with the current state regardless of changes", + disabledBy: [ + { + fieldName: "enabled", + }, + ], + }, + { + type: "toggle", + name: "sendBell", + label: "Send Bell", + description: "Send ASCII bell with alert message", + disabledBy: [ + { + fieldName: "enabled", + }, + ], + }, + { + type: "text", + name: "name", + label: "Friendly Name", + description: "Used to format the message sent to mesh, max 20 Characters", + disabledBy: [ + { + fieldName: "enabled", + }, + ], + }, + { + type: "number", + name: "monitorPin", + label: "Monitor Pin", + description: "The GPIO pin to monitor for state changes", + disabledBy: [ + { + fieldName: "enabled", + }, + ], + }, + { + type: "toggle", + name: "detectionTriggeredHigh", + label: "Detection Triggered High", + description: "Whether or not the GPIO pin state detection is triggered on HIGH (1), otherwise LOW (0)", + disabledBy: [ + { + fieldName: "enabled", + }, + ], + }, + { + type: "toggle", + name: "usePullup", + label: "Use Pullup", + description: "Whether or not use INPUT_PULLUP mode for GPIO pin", + disabledBy: [ + { + fieldName: "enabled", + }, + ], + }, + ], + }, + ]} + /> + ); +}; diff --git a/src/core/stores/deviceStore.ts b/src/core/stores/deviceStore.ts index f5478260..92f95bbf 100644 --- a/src/core/stores/deviceStore.ts +++ b/src/core/stores/deviceStore.ts @@ -185,6 +185,9 @@ export const useDeviceStore = create((set, get) => ({ if (device) { switch (config.payloadVariant.case) { + case "detectionSensor": + device.moduleConfig.detectionSensor = config.payloadVariant.value; + break; case "mqtt": device.moduleConfig.mqtt = config.payloadVariant.value; break; diff --git a/src/pages/Config/ModuleConfig.tsx b/src/pages/Config/ModuleConfig.tsx index f10e34a9..6d7a5979 100644 --- a/src/pages/Config/ModuleConfig.tsx +++ b/src/pages/Config/ModuleConfig.tsx @@ -1,3 +1,4 @@ +import { DetectionSensor } from "@app/components/PageComponents/ModuleConfig/DetectionSensor.js"; import { Audio } from "@components/PageComponents/ModuleConfig/Audio.js"; import { CannedMessage } from "@components/PageComponents/ModuleConfig/CannedMessage.js"; import { ExternalNotification } from "@components/PageComponents/ModuleConfig/ExternalNotification.js"; @@ -47,6 +48,10 @@ export const ModuleConfig = (): JSX.Element => { label: "Audio", element: Audio, }, + { + label: "Detection Sensor", + element: DetectionSensor, + }, ]; return ( diff --git a/src/validation/moduleConfig/detectionSensor.ts b/src/validation/moduleConfig/detectionSensor.ts new file mode 100644 index 00000000..3c5e93c4 --- /dev/null +++ b/src/validation/moduleConfig/detectionSensor.ts @@ -0,0 +1,35 @@ +import { IsBoolean, IsInt, Length } from "class-validator"; + +import type { Protobuf } from "@meshtastic/meshtasticjs"; + +export class DetectionSensorValidation + implements + Omit< + Protobuf.ModuleConfig_DetectionSensorConfig, + keyof Protobuf.native.Message + > +{ + @IsBoolean() + enabled: boolean; + + @IsInt() + minimumBroadcastSecs: number; + + @IsInt() + stateBroadcastSecs: number; + + @IsBoolean() + sendBell: boolean; + + @Length(0, 20) + name: string; + + @IsInt() + monitorPin: number; + + @IsBoolean() + detectionTriggeredHigh: boolean; + + @IsBoolean() + usePullup: boolean; +}