diff --git a/src/app/providers/CameraSettingsProvider.tsx b/src/app/providers/CameraSettingsProvider.tsx index f33ee72..1877a38 100644 --- a/src/app/providers/CameraSettingsProvider.tsx +++ b/src/app/providers/CameraSettingsProvider.tsx @@ -1,9 +1,50 @@ import { CameraSettingsContext } from "../context/CameraSettingsContext"; -import { useReducer, type ReactNode } from "react"; +import { useEffect, useReducer, type ReactNode } from "react"; import { initialState, cameraSettingsReducer } from "../reducers/cameraSettingsReducer"; +import { useCameraController } from "../../features/setup/hooks/useCameraControlConfig"; const CameraSettingsProvider = ({ children }: { children: ReactNode }) => { const [state, dispatch] = useReducer(cameraSettingsReducer, initialState); + const { cameraControllerQuery } = useCameraController(); + + useEffect(() => { + if (cameraControllerQuery?.data) { + console.log(cameraControllerQuery?.data); + const currentCameraControlMode = cameraControllerQuery.data.propOperationMode.value.toLowerCase(); + const currentAutoMaxGain = cameraControllerQuery.data.propAutoModeMaxGain.value; + const currentAutoMinShutter = cameraControllerQuery.data.propAutoModeMinShutter.value; + const currentAutoMaxShutter = cameraControllerQuery.data.propAutoModeMaxShutter.value; + const currentExposureCompensation = cameraControllerQuery.data.propAutoModeExposureCompensation.value; + + const currentManualFixShutter = cameraControllerQuery.data.propManualModeShutter.value; + const currentManualFixGain = cameraControllerQuery.data.propManualModeFixGain.value; + const currentManualFixIris = cameraControllerQuery.data.propManualModeFixIris.value; + + console.log({ + currentCameraControlMode, + currentManualFixShutter, + currentManualFixGain, + currentManualFixIris, + }); + dispatch({ + type: "SET_CAMERA_CONTROLS", + payload: { + cameraControlMode: currentCameraControlMode, + auto: { + maxGain: currentAutoMaxGain, + minShutter: currentAutoMinShutter, + maxShutter: currentAutoMaxShutter, + exposureCompensation: currentExposureCompensation, + }, + manual: { + fixShutter: currentManualFixShutter, + fixGain: currentManualFixGain, + fixIris: currentManualFixIris, + }, + }, + }); + } + }, [cameraControllerQuery.data]); return {children}; }; diff --git a/src/app/reducers/cameraSettingsReducer.ts b/src/app/reducers/cameraSettingsReducer.ts index d62654d..5bd19d6 100644 --- a/src/app/reducers/cameraSettingsReducer.ts +++ b/src/app/reducers/cameraSettingsReducer.ts @@ -4,6 +4,11 @@ export const initialState: CameraSettings = { cameraMode: 0, mode: 0, imageSize: { width: 1280, height: 960 }, + cameraControls: { + cameraControlMode: "auto", + auto: { minShutter: "1/100", maxShutter: "1/1000", maxGain: "0dB", exposureCompensation: "EC:off" }, + manual: { fixShutter: "1/100", fixGain: "0dB", fixIris: "F2.0" }, + }, regionPainter: { paintmode: "painter", paintedCells: new Map(), @@ -50,6 +55,12 @@ export const cameraSettingsReducer = (state: CameraSettings, action: CameraSetti selectedRegionIndex: action.payload, }, }; + + case "SET_CAMERA_CONTROLS": + return { + ...state, + cameraControls: action.payload, + }; default: return state; } diff --git a/src/features/setup/components/cameraControls/CameraControls.tsx b/src/features/setup/components/cameraControls/CameraControls.tsx index 24dcc53..b745e11 100644 --- a/src/features/setup/components/cameraControls/CameraControls.tsx +++ b/src/features/setup/components/cameraControls/CameraControls.tsx @@ -1,24 +1,276 @@ -import { Formik, Form } from "formik"; -import type { CameraSettings } from "../../../../utils/types"; +import { Formik, Form, Field } from "formik"; +import type { CameraSettings, CameraSettingsAction } from "../../../../utils/types"; +import { useCameraController } from "../../hooks/useCameraControlConfig"; type CameraControlProps = { - state: CameraSettings; + state: CameraSettings["cameraControls"]; + dispatch: React.Dispatch; }; -const CameraControls = ({ state }: CameraControlProps) => { +const CameraControls = ({ state, dispatch }: CameraControlProps) => { + const { cameraControllerMutation } = useCameraController(); console.log(state); - const initialValues = {}; - - const handleSumbit = (values: { test?: string }) => { - console.log(values); + const initialValues = { + cameraMode: state.cameraControlMode === "auto" ? "auto" : "manual", + auto: { + minShutter: state.auto.minShutter, + maxShutter: state.auto.maxShutter, + maxGain: state.auto.maxGain, + exposureCompensation: state.auto.exposureCompensation, + }, + manual: { + fixShutter: state.manual.fixShutter, + fixGain: state.manual.fixGain, + fixIris: state.manual.fixIris, + }, }; + + const handleSumbit = (values: { + cameraMode: string; + auto: typeof initialValues.auto; + manual: typeof initialValues.manual; + }) => { + cameraControllerMutation.mutate({ + cameraControlMode: values.cameraMode as "auto" | "manual", + auto: values.auto, + manual: values.manual, + }); + dispatch({ + type: "SET_CAMERA_CONTROLS", + payload: { + cameraControlMode: values.cameraMode as "auto" | "manual", + auto: values.auto, + manual: values.manual, + }, + }); + }; + return ( - - - - Save Settings - - + + {({ values }) => ( + + Controls + + + + Auto + + + + + + Manual + + + + + {values.cameraMode === "auto" && ( + + + Shutter Speed + + + + Min Shutter: + + + 1/100 + 1/120 + 1/250 + 1/500 + 1/1000 + 1/2000 + 1/5000 + 1/10000 + + + + + Max Shutter: + + + 1/500 + 1/1000 + 1/2000 + 1/5000 + 1/10000 + + + + + + + Gain + + + + Max Gain: + + + 0dB + 2dB + 4dB + 6dB + + 10dB + 12dB + 16dB + 18dB + 20dB + 24dB + + + + + + + Exposure + + + + Exposure Compensation: + + + EC:off + EC:0 + EC:1 + EC:2 + EC:3 + EC:4 + EC:5 + EC:6 + EC:7 + EC:8 + EC:9 + EC:10 + EC:11 + EC:12 + EC:13 + EC:14 + + + + + + )} + {values.cameraMode === "manual" && ( + + + Shutter Speed + + + + Fix Shutter: + + + 1/100 + 1/120 + 1/250 + 1/500 + 1/1000 + 1/2000 + 1/5000 + + + + + + + Gain + + + + Fix Gain: + + + 0dB + 2dB + 4dB + 6dB + 8dB + 10dB + 12dB + 16dB + 18dB + 20dB + 24dB + + + + + + + Iris + + + + Fix Iris: + + + F1.4 + F2.0 + F2.8 + F4.0 + F5.6 + F8.0 + F11.0 + F16.0 + + + + + + )} + + Save Settings + + + )} ); }; diff --git a/src/features/setup/components/cameraSetup/CameraSetup.tsx b/src/features/setup/components/cameraSetup/CameraSetup.tsx index a82291d..7bd2a5e 100644 --- a/src/features/setup/components/cameraSetup/CameraSetup.tsx +++ b/src/features/setup/components/cameraSetup/CameraSetup.tsx @@ -25,7 +25,7 @@ const CameraSetup = () => { Advanced - + diff --git a/src/features/setup/hooks/useCameraControlConfig.ts b/src/features/setup/hooks/useCameraControlConfig.ts new file mode 100644 index 0000000..b9247b6 --- /dev/null +++ b/src/features/setup/hooks/useCameraControlConfig.ts @@ -0,0 +1,60 @@ +import { useQuery, useMutation } from "@tanstack/react-query"; +import { cambase } from "../../../app/config"; +import type { CameraSettings } from "../../../utils/types"; + +const fetchCameraControllerConfig = async () => { + const response = await fetch(`${cambase}/api/fetch-config?id=Colour--camera-control-widget-config`); + if (!response.ok) throw new Error("Cannot reach camera controller endpoint"); + return response.json(); +}; + +const updateCameraControllerConfig = async (config: CameraSettings["cameraControls"]) => { + if (!config) return; + + const fields = []; + if (config.cameraControlMode === "auto") { + fields.push( + { name: "propOperationMode", value: "Auto" }, + { name: "propAutoModeMaxGain", value: config.auto.maxGain }, + { name: "propAutoModeMinShutter", value: config.auto.minShutter }, + { name: "propAutoModeMaxShutter", value: config.auto.maxShutter }, + { name: "propAutoModeExposureCompensation", value: config.auto.exposureCompensation }, + ); + } else if (config.cameraControlMode === "manual") { + fields.push( + { name: "propOperationMode", value: "Manual" }, + { name: "propManualModeShutter", value: config.manual.fixShutter }, + { name: "propManualModeFixGain", value: config.manual.fixGain }, + { name: "propManualModeFixIris", value: config.manual.fixIris }, + ); + } + + const data = { + id: "Colour--camera-control-widget-config", + fields: fields, + }; + const response = await fetch(`${cambase}/api/update-config`, { + method: "POST", + headers: { + "Content-Type": "application/json", + }, + body: JSON.stringify(data), + }); + if (!response.ok) throw new Error("Cannot reach camera controller endpoint"); + console.log(response); + return response.json(); +}; + +export const useCameraController = () => { + const cameraControllerQuery = useQuery({ + queryKey: ["getcameraConfig"], + queryFn: fetchCameraControllerConfig, + }); + + const cameraControllerMutation = useMutation({ + mutationKey: ["updateCameraConfig"], + mutationFn: (config: CameraSettings["cameraControls"]) => updateCameraControllerConfig(config), + }); + + return { cameraControllerQuery, cameraControllerMutation }; +}; diff --git a/src/utils/types.ts b/src/utils/types.ts index cd170a4..dfd8a3d 100644 --- a/src/utils/types.ts +++ b/src/utils/types.ts @@ -66,6 +66,20 @@ export type CameraSettings = { cameraMode: number; mode: number; imageSize: { width: number; height: number }; + cameraControls: { + cameraControlMode: "auto" | "manual"; + auto: { + minShutter: string; + maxShutter: string; + maxGain: string; + exposureCompensation: string; + }; + manual: { + fixShutter: string; + fixGain: string; + fixIris: string; + }; + }; regionPainter: { paintmode: "painter" | "eraser"; paintedCells: Map; @@ -90,7 +104,11 @@ export type CameraSettingsAction = type: "SET_REGION_PAINTMODE"; payload: "painter" | "eraser"; } - | { type: "SET_SELECTED_REGION_INDEX"; payload: number }; + | { type: "SET_SELECTED_REGION_INDEX"; payload: number } + | { + type: "SET_CAMERA_CONTROLS"; + payload: CameraSettings["cameraControls"]; + }; export type CameraStatus = { id: string;