From bb230b06bdd99e9c05d1c59a929fb6fbc09ab4f0 Mon Sep 17 00:00:00 2001 From: Sophia Beluli Date: Wed, 28 Aug 2024 14:25:27 -0400 Subject: [PATCH 1/4] add machine status component --- .../MachineStatus/AlarmDescriptionIcon.tsx | 60 ++++++++++ .../MachineStatus/MachineStatus.tsx | 107 ++++++++++++++++++ .../components/MachineStatus/UnlockButton.tsx | 69 +++++++++++ .../definitions/interfaces/machine_status.ts | 14 +++ src/app/src/definitions/types.ts | 2 + 5 files changed, 252 insertions(+) create mode 100644 src/app/src/components/MachineStatus/AlarmDescriptionIcon.tsx create mode 100644 src/app/src/components/MachineStatus/MachineStatus.tsx create mode 100644 src/app/src/components/MachineStatus/UnlockButton.tsx create mode 100644 src/app/src/definitions/interfaces/machine_status.ts diff --git a/src/app/src/components/MachineStatus/AlarmDescriptionIcon.tsx b/src/app/src/components/MachineStatus/AlarmDescriptionIcon.tsx new file mode 100644 index 000000000..125b4cc68 --- /dev/null +++ b/src/app/src/components/MachineStatus/AlarmDescriptionIcon.tsx @@ -0,0 +1,60 @@ +/* + * Copyright (C) 2021 Sienci Labs Inc. + * + * This file is part of gSender. + * + * gSender is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, under version 3 of the License. + * + * gSender is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with gSender. If not, see . + * + * Contact for information regarding this program and its license + * can be sent through gSender@sienci.com or mailed to the main office + * of Sienci Labs Inc. in Waterloo, Ontario, Canada. + * + */ + +import get from 'lodash/get'; +import { store as reduxStore } from '../../store/redux'; +import { GRBLHAL } from '../../constants'; +import { GRBL_HAL_ALARMS } from '../../../../server/controllers/Grblhal/constants'; +import { GRBL_ALARMS } from '../../../../server/controllers/Grbl/constants'; +import { Tooltip, TooltipContent, TooltipProvider, TooltipTrigger } from '../shadcn/Tooltip'; +import { ALARM_CODE } from '../../definitions/types'; + +const getCodeDescription = (code: number | 'Homing' = 1): string => { + const controllerType: string = get(reduxStore.getState(), 'controller.type'); + const ALARMS = controllerType === GRBLHAL ? GRBL_HAL_ALARMS : GRBL_ALARMS; + const alarm = ALARMS.find(alarm => alarm.code === code); + if (alarm) { + return alarm.description; + } + return 'Invalid alarm code - no matching description found'; +}; + +const AlarmDescriptionIcon = ({ code = 1 }: { code: ALARM_CODE }) => { + const alarmDescription = getCodeDescription(code); + return ( + + + +
+ +
+
+ + {alarmDescription} + +
+
+ ); +}; + +export default AlarmDescriptionIcon; diff --git a/src/app/src/components/MachineStatus/MachineStatus.tsx b/src/app/src/components/MachineStatus/MachineStatus.tsx new file mode 100644 index 000000000..20d10ae90 --- /dev/null +++ b/src/app/src/components/MachineStatus/MachineStatus.tsx @@ -0,0 +1,107 @@ +/* + * Copyright (C) 2021 Sienci Labs Inc. + * + * This file is part of gSender. + * + * gSender is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, under version 3 of the License. + * + * gSender is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with gSender. If not, see . + * + * Contact for information regarding this program and its license + * can be sent through gSender@sienci.com or mailed to the main office + * of Sienci Labs Inc. in Waterloo, Ontario, Canada. + * + */ + +import { connect } from 'react-redux'; +import cx from 'classnames'; +import get from 'lodash/get'; +import controller from '../../lib/controller'; +import AlarmDescriptionIcon from './AlarmDescriptionIcon'; +import UnlockButton from './UnlockButton'; +import { MachineStatusProps } from '../../definitions/interfaces/machine_status'; +import { GRBL_ACTIVE_STATE_ALARM, GRBL_ACTIVE_STATE_HOME, GRBL_ACTIVE_STATE_IDLE, GRBL_ACTIVE_STATE_RUN } from '../../constants'; + +/** + * Control Area component displaying machine status + * @param {Object} state Default state given from parent component + * @param {Object} actions Actions object given from parent component + */ +const MachineStatus: React.FC = ({ alarmCode, activeState, isConnected }) => { + const unlock = (): void => { + if ( + alarmCode === 1 || + alarmCode === 2 || + alarmCode === 10 || + alarmCode === 14 || + alarmCode === 17 + ) { + controller.command('reset:limit'); + return; + } else if (alarmCode === 'Homing' || alarmCode === 11) { + controller.command('homing'); + return; + } + controller.command('unlock'); + } + + /** + * Function to output the machine state based on multiple conditions + */ + const machineStateRender = (): React.ReactElement => { + return ( +
+ { + isConnected && activeState ? ( + <> +
+ { + activeState === GRBL_ACTIVE_STATE_ALARM ? ( +
+ {activeState} ({alarmCode}) +
+ ) : ( +
{activeState}
+ ) + } +
+ + ) :
Disconnected
+ } + { activeState === GRBL_ACTIVE_STATE_ALARM && } +
+ ) + }; + + return ( +
+
+ {machineStateRender()} +
+
+ ); +} + +export default connect((store) => { + const $22 = get(store, 'controller.settings.settings.$22', '0'); + const alarmCode = get(store, 'controller.state.status.alarmCode'); + const activeState = get(store, 'controller.state.status.activeState'); + const isConnected = get(store, 'connection.isConnected'); + return { + $22, + alarmCode, + activeState, + isConnected + }; +})(MachineStatus); diff --git a/src/app/src/components/MachineStatus/UnlockButton.tsx b/src/app/src/components/MachineStatus/UnlockButton.tsx new file mode 100644 index 000000000..84e515390 --- /dev/null +++ b/src/app/src/components/MachineStatus/UnlockButton.tsx @@ -0,0 +1,69 @@ +/* + * Copyright (C) 2021 Sienci Labs Inc. + * + * This file is part of gSender. + * + * gSender is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, under version 3 of the License. + * + * gSender is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with gSender. If not, see . + * + * Contact for information regarding this program and its license + * can be sent through gSender@sienci.com or mailed to the main office + * of Sienci Labs Inc. in Waterloo, Ontario, Canada. + * + */ + +import React from 'react'; +import cx from 'classnames'; + +import { GRBL_ACTIVE_STATE_ALARM, GRBL_ACTIVE_STATE_HOLD } from '../../constants'; +import { UnlockProps } from '../../definitions/interfaces/machine_status'; + + +const UnlockButton: React.FC = ({ activeState, alarmCode, onClick }) => { + const getButtonText = (): string => { + if (activeState === GRBL_ACTIVE_STATE_HOLD) { + return 'Cycle Start'; + } else if (alarmCode === 11) { + return 'Click to Run Homing'; + } + return 'Click to Unlock Machine'; + }; + + return ( +
+ +
+ ); +}; + +export default UnlockButton; diff --git a/src/app/src/definitions/interfaces/machine_status.ts b/src/app/src/definitions/interfaces/machine_status.ts new file mode 100644 index 000000000..5d2a1ac25 --- /dev/null +++ b/src/app/src/definitions/interfaces/machine_status.ts @@ -0,0 +1,14 @@ +import { MouseEventHandler } from "react" +import { ALARM_CODE, GRBL_ACTIVE_STATES_T } from "../types" + +export interface MachineStatusProps { + alarmCode: ALARM_CODE, + activeState: GRBL_ACTIVE_STATES_T, + isConnected: boolean +}; + +export interface UnlockProps { + activeState: GRBL_ACTIVE_STATES_T, + alarmCode: ALARM_CODE, + onClick: MouseEventHandler, +} \ No newline at end of file diff --git a/src/app/src/definitions/types.ts b/src/app/src/definitions/types.ts index 56ff9f1c6..bee83ab5f 100644 --- a/src/app/src/definitions/types.ts +++ b/src/app/src/definitions/types.ts @@ -89,3 +89,5 @@ export type TOOL = number; export type FirmwareSetting = { [key: `$${number}`]: string; }; + +export type ALARM_CODE = number | 'Homing'; From d90618521f4d55f68802deeb6363530760ae26b8 Mon Sep 17 00:00:00 2001 From: Sophia Beluli Date: Tue, 3 Sep 2024 16:44:53 -0400 Subject: [PATCH 2/4] add machine status --- .../MachineStatus/MachineStatus.tsx | 107 ------------- src/app/src/components/shadcn/Tooltip.tsx | 2 +- .../MachineStatus/AlarmDescriptionIcon.tsx | 9 +- .../features/MachineStatus/MachineStatus.tsx | 141 ++++++++++++++++++ .../MachineStatus/UnlockButton.tsx | 12 +- .../src/features/MachineStatus/definitions.ts | 1 + src/app/src/workspace/TopBar/index.tsx | 4 +- 7 files changed, 160 insertions(+), 116 deletions(-) delete mode 100644 src/app/src/components/MachineStatus/MachineStatus.tsx rename src/app/src/{components => features}/MachineStatus/AlarmDescriptionIcon.tsx (84%) create mode 100644 src/app/src/features/MachineStatus/MachineStatus.tsx rename src/app/src/{components => features}/MachineStatus/UnlockButton.tsx (86%) create mode 100644 src/app/src/features/MachineStatus/definitions.ts diff --git a/src/app/src/components/MachineStatus/MachineStatus.tsx b/src/app/src/components/MachineStatus/MachineStatus.tsx deleted file mode 100644 index 20d10ae90..000000000 --- a/src/app/src/components/MachineStatus/MachineStatus.tsx +++ /dev/null @@ -1,107 +0,0 @@ -/* - * Copyright (C) 2021 Sienci Labs Inc. - * - * This file is part of gSender. - * - * gSender is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, under version 3 of the License. - * - * gSender is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with gSender. If not, see . - * - * Contact for information regarding this program and its license - * can be sent through gSender@sienci.com or mailed to the main office - * of Sienci Labs Inc. in Waterloo, Ontario, Canada. - * - */ - -import { connect } from 'react-redux'; -import cx from 'classnames'; -import get from 'lodash/get'; -import controller from '../../lib/controller'; -import AlarmDescriptionIcon from './AlarmDescriptionIcon'; -import UnlockButton from './UnlockButton'; -import { MachineStatusProps } from '../../definitions/interfaces/machine_status'; -import { GRBL_ACTIVE_STATE_ALARM, GRBL_ACTIVE_STATE_HOME, GRBL_ACTIVE_STATE_IDLE, GRBL_ACTIVE_STATE_RUN } from '../../constants'; - -/** - * Control Area component displaying machine status - * @param {Object} state Default state given from parent component - * @param {Object} actions Actions object given from parent component - */ -const MachineStatus: React.FC = ({ alarmCode, activeState, isConnected }) => { - const unlock = (): void => { - if ( - alarmCode === 1 || - alarmCode === 2 || - alarmCode === 10 || - alarmCode === 14 || - alarmCode === 17 - ) { - controller.command('reset:limit'); - return; - } else if (alarmCode === 'Homing' || alarmCode === 11) { - controller.command('homing'); - return; - } - controller.command('unlock'); - } - - /** - * Function to output the machine state based on multiple conditions - */ - const machineStateRender = (): React.ReactElement => { - return ( -
- { - isConnected && activeState ? ( - <> -
- { - activeState === GRBL_ACTIVE_STATE_ALARM ? ( -
- {activeState} ({alarmCode}) -
- ) : ( -
{activeState}
- ) - } -
- - ) :
Disconnected
- } - { activeState === GRBL_ACTIVE_STATE_ALARM && } -
- ) - }; - - return ( -
-
- {machineStateRender()} -
-
- ); -} - -export default connect((store) => { - const $22 = get(store, 'controller.settings.settings.$22', '0'); - const alarmCode = get(store, 'controller.state.status.alarmCode'); - const activeState = get(store, 'controller.state.status.activeState'); - const isConnected = get(store, 'connection.isConnected'); - return { - $22, - alarmCode, - activeState, - isConnected - }; -})(MachineStatus); diff --git a/src/app/src/components/shadcn/Tooltip.tsx b/src/app/src/components/shadcn/Tooltip.tsx index 20028e30f..ee073cf3d 100644 --- a/src/app/src/components/shadcn/Tooltip.tsx +++ b/src/app/src/components/shadcn/Tooltip.tsx @@ -21,7 +21,7 @@ const TooltipContent = React.forwardRef< ref={ref} sideOffset={sideOffset} className={cx( - "z-50 overflow-hidden rounded-md border bg-popover px-3 py-1.5 text-sm text-popover-foreground shadow-md animate-in fade-in-0 zoom-in-95 data-[state=closed]:animate-out data-[state=closed]:fade-out-0 data-[state=closed]:zoom-out-95 data-[side=bottom]:slide-in-from-top-2 data-[side=left]:slide-in-from-right-2 data-[side=right]:slide-in-from-left-2 data-[side=top]:slide-in-from-bottom-2", + "bg-gray-700 overflow-hidden rounded-md border bg-popover px-3 py-1.5 text-sm text-popover-foreground shadow-md animate-in fade-in-0 zoom-in-95 data-[state=closed]:animate-out data-[state=closed]:fade-out-0 data-[state=closed]:zoom-out-95 data-[side=bottom]:slide-in-from-top-2 data-[side=left]:slide-in-from-right-2 data-[side=right]:slide-in-from-left-2 data-[side=top]:slide-in-from-bottom-2", className )} {...props} diff --git a/src/app/src/components/MachineStatus/AlarmDescriptionIcon.tsx b/src/app/src/features/MachineStatus/AlarmDescriptionIcon.tsx similarity index 84% rename from src/app/src/components/MachineStatus/AlarmDescriptionIcon.tsx rename to src/app/src/features/MachineStatus/AlarmDescriptionIcon.tsx index 125b4cc68..902d140e6 100644 --- a/src/app/src/components/MachineStatus/AlarmDescriptionIcon.tsx +++ b/src/app/src/features/MachineStatus/AlarmDescriptionIcon.tsx @@ -22,12 +22,13 @@ */ import get from 'lodash/get'; +import cx from 'classnames'; import { store as reduxStore } from '../../store/redux'; import { GRBLHAL } from '../../constants'; import { GRBL_HAL_ALARMS } from '../../../../server/controllers/Grblhal/constants'; import { GRBL_ALARMS } from '../../../../server/controllers/Grbl/constants'; -import { Tooltip, TooltipContent, TooltipProvider, TooltipTrigger } from '../shadcn/Tooltip'; -import { ALARM_CODE } from '../../definitions/types'; +import { Tooltip, TooltipContent, TooltipProvider, TooltipTrigger } from 'components/shadcn/Tooltip'; +import { ALARM_CODE } from './definitions'; const getCodeDescription = (code: number | 'Homing' = 1): string => { const controllerType: string = get(reduxStore.getState(), 'controller.type'); @@ -45,8 +46,8 @@ const AlarmDescriptionIcon = ({ code = 1 }: { code: ALARM_CODE }) => { -
- +
+
diff --git a/src/app/src/features/MachineStatus/MachineStatus.tsx b/src/app/src/features/MachineStatus/MachineStatus.tsx new file mode 100644 index 000000000..0e496aadb --- /dev/null +++ b/src/app/src/features/MachineStatus/MachineStatus.tsx @@ -0,0 +1,141 @@ +/* + * Copyright (C) 2021 Sienci Labs Inc. + * + * This file is part of gSender. + * + * gSender is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, under version 3 of the License. + * + * gSender is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with gSender. If not, see . + * + * Contact for information regarding this program and its license + * can be sent through gSender@sienci.com or mailed to the main office + * of Sienci Labs Inc. in Waterloo, Ontario, Canada. + * + */ + +import { connect } from 'react-redux'; +import cx from 'classnames'; +import get from 'lodash/get'; +import controller from '../../lib/controller'; +import AlarmDescriptionIcon from './AlarmDescriptionIcon'; +import UnlockButton from './UnlockButton'; +import { GRBL_ACTIVE_STATE_ALARM, GRBL_ACTIVE_STATE_CHECK, GRBL_ACTIVE_STATE_HOLD, GRBL_ACTIVE_STATE_HOME, GRBL_ACTIVE_STATE_IDLE, GRBL_ACTIVE_STATE_JOG, GRBL_ACTIVE_STATE_RUN } from '../../constants'; +import { GRBL_ACTIVE_STATES_T } from 'definitions/general'; +import { ALARM_CODE } from './definitions'; + +interface MachineStatusProps { + alarmCode: ALARM_CODE, + activeState: GRBL_ACTIVE_STATES_T, + isConnected: boolean, +}; + +interface Message { + [key: GRBL_ACTIVE_STATES_T]: string +} + +/** + * Control Area component displaying machine status + * @param {Object} state Default state given from parent component + * @param {Object} actions Actions object given from parent component + */ +const MachineStatus: React.FC = ({ activeState, alarmCode, isConnected }) => { + console.log(activeState); + + const unlock = (): void => { + if ( + alarmCode === 1 || + alarmCode === 2 || + alarmCode === 10 || + alarmCode === 14 || + alarmCode === 17 + ) { + controller.command('reset:limit'); + return; + } else if (alarmCode === 'Homing' || alarmCode === 11) { + controller.command('homing'); + return; + } + controller.command('unlock'); + } + + /** + * Function to output the machine state based on multiple conditions + */ + const machineStateRender = (): React.ReactElement => { + const message: Message = { + Idle: 'Idle', + Run: 'Running', + Hold: 'Hold', + Jog: 'Jogging', + Check: 'Check', + Home: 'Homing', + Sleep: 'Sleep', + Alarm: 'Alarm', + Disconnected: 'Disconnected', + }; + + return ( +
+
+ { + isConnected && activeState ? ( + <> + { + activeState === GRBL_ACTIVE_STATE_ALARM ? ( +
+
{activeState}
+
+
+ ) : ( + {message[activeState]} + ) + } + + ) :

Disconnected

+ } +
+
+ { activeState === GRBL_ACTIVE_STATE_ALARM && } +
+
+ ) + }; + + return ( + // calc = half of width + sidebar width +
{/*className="grid grid-cols-[2fr_2fr_2fr]">*/} + {machineStateRender()} +
+ ); +} + +export default connect((store) => { + const $22 = get(store, 'controller.settings.settings.$22', '0'); + const alarmCode = get(store, 'controller.state.status.alarmCode'); + const activeState = get(store, 'controller.state.status.activeState'); + const isConnected = get(store, 'connection.isConnected'); + return { + $22, + alarmCode, + activeState, + isConnected + }; +})(MachineStatus); diff --git a/src/app/src/components/MachineStatus/UnlockButton.tsx b/src/app/src/features/MachineStatus/UnlockButton.tsx similarity index 86% rename from src/app/src/components/MachineStatus/UnlockButton.tsx rename to src/app/src/features/MachineStatus/UnlockButton.tsx index 84e515390..52150d4ce 100644 --- a/src/app/src/components/MachineStatus/UnlockButton.tsx +++ b/src/app/src/features/MachineStatus/UnlockButton.tsx @@ -21,12 +21,18 @@ * */ -import React from 'react'; +import React, { MouseEventHandler } from 'react'; import cx from 'classnames'; import { GRBL_ACTIVE_STATE_ALARM, GRBL_ACTIVE_STATE_HOLD } from '../../constants'; -import { UnlockProps } from '../../definitions/interfaces/machine_status'; +import { GRBL_ACTIVE_STATES_T } from 'definitions/general'; +import { ALARM_CODE } from './definitions'; +export interface UnlockProps { + activeState: GRBL_ACTIVE_STATES_T, + alarmCode: ALARM_CODE, + onClick: MouseEventHandler, +}; const UnlockButton: React.FC = ({ activeState, alarmCode, onClick }) => { const getButtonText = (): string => { @@ -43,7 +49,7 @@ const UnlockButton: React.FC = ({ activeState, alarmCode, onClick }
- { activeState === GRBL_ACTIVE_STATE_ALARM && } + { (activeState === GRBL_ACTIVE_STATE_ALARM || activeState === GRBL_ACTIVE_STATE_HOLD) && }
) diff --git a/src/app/src/features/MachineStatus/UnlockButton.tsx b/src/app/src/features/MachineStatus/UnlockButton.tsx index 52150d4ce..07a04cb2a 100644 --- a/src/app/src/features/MachineStatus/UnlockButton.tsx +++ b/src/app/src/features/MachineStatus/UnlockButton.tsx @@ -24,7 +24,7 @@ import React, { MouseEventHandler } from 'react'; import cx from 'classnames'; -import { GRBL_ACTIVE_STATE_ALARM, GRBL_ACTIVE_STATE_HOLD } from '../../constants'; +import { GRBL_ACTIVE_STATE_ALARM } from '../../constants'; import { GRBL_ACTIVE_STATES_T } from 'definitions/general'; import { ALARM_CODE } from './definitions'; @@ -36,9 +36,7 @@ export interface UnlockProps { const UnlockButton: React.FC = ({ activeState, alarmCode, onClick }) => { const getButtonText = (): string => { - if (activeState === GRBL_ACTIVE_STATE_HOLD) { - return 'Cycle Start'; - } else if (alarmCode === 11) { + if (alarmCode === 11) { return 'Click to Run Homing'; } return 'Click to Unlock Machine'; @@ -49,10 +47,11 @@ const UnlockButton: React.FC = ({ activeState, alarmCode, onClick }