@adcops/autocore-react 3.1.1 → 3.3.2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/additional-docs/react_performance_notes.md +94 -0
- package/dist/components/AutoCoreDevPanel.d.ts.map +1 -1
- package/dist/components/AutoCoreDevPanel.js +1 -1
- package/dist/components/FileList.d.ts.map +1 -1
- package/dist/components/FileList.js +1 -1
- package/dist/components/FileSelect.d.ts.map +1 -1
- package/dist/components/FileSelect.js +1 -1
- package/dist/core/AutoCoreTagContext.d.ts +59 -185
- package/dist/core/AutoCoreTagContext.d.ts.map +1 -1
- package/dist/core/AutoCoreTagContext.js +1 -1
- package/dist/core/AutoCoreTagTypes.d.ts +127 -6
- package/dist/core/AutoCoreTagTypes.d.ts.map +1 -1
- package/dist/core/CoreStreamTypes.d.ts +345 -0
- package/dist/core/CoreStreamTypes.d.ts.map +1 -0
- package/dist/core/CoreStreamTypes.js +1 -0
- package/dist/core/EventEmitterContext.d.ts +91 -473
- package/dist/core/EventEmitterContext.d.ts.map +1 -1
- package/dist/core/EventEmitterContext.js +1 -1
- package/dist/hooks/adsHooks.d.ts.map +1 -1
- package/dist/hooks/adsHooks.js +1 -1
- package/dist/hooks/commandHooks.d.ts +3 -3
- package/dist/hooks/commandHooks.d.ts.map +1 -1
- package/dist/hooks/commandHooks.js +1 -1
- package/dist/hooks/useAutoCoreTag.js +1 -1
- package/dist/hub/CommandMessage.d.ts +18 -9
- package/dist/hub/CommandMessage.d.ts.map +1 -1
- package/dist/hub/CommandMessage.js +1 -1
- package/dist/hub/DebugPanel.d.ts +31 -0
- package/dist/hub/DebugPanel.d.ts.map +1 -0
- package/dist/hub/DebugPanel.js +1 -0
- package/dist/hub/HubBase.d.ts +83 -129
- package/dist/hub/HubBase.d.ts.map +1 -1
- package/dist/hub/HubBase.js +1 -1
- package/dist/hub/HubSimulate.d.ts +41 -8
- package/dist/hub/HubSimulate.d.ts.map +1 -1
- package/dist/hub/HubSimulate.js +1 -1
- package/dist/hub/HubTauri.d.ts +24 -60
- package/dist/hub/HubTauri.d.ts.map +1 -1
- package/dist/hub/HubTauri.js +1 -1
- package/dist/hub/HubWebSocket.d.ts +33 -17
- package/dist/hub/HubWebSocket.d.ts.map +1 -1
- package/dist/hub/HubWebSocket.js +1 -1
- package/dist/hub/debug.d.ts +23 -0
- package/dist/hub/debug.d.ts.map +1 -0
- package/dist/hub/debug.js +1 -0
- package/dist/hub/index.d.ts +19 -4
- package/dist/hub/index.d.ts.map +1 -1
- package/dist/hub/index.js +1 -1
- package/package.json +4 -4
- package/src/components/AutoCoreDevPanel.tsx +14 -11
- package/src/components/FileList.tsx +5 -4
- package/src/components/FileSelect.tsx +2 -1
- package/src/core/ActionMode.ts +1 -1
- package/src/core/AutoCoreTagContext.tsx +247 -330
- package/src/core/AutoCoreTagTypes.ts +236 -104
- package/src/core/CoreStreamTypes.ts +512 -0
- package/src/core/EventEmitterContext.tsx +182 -520
- package/src/core/IndicatorButtonState.ts +1 -1
- package/src/core/hoc.tsx +1 -1
- package/src/hooks/adsHooks.tsx +21 -22
- package/src/hooks/commandHooks.tsx +23 -19
- package/src/hooks/index.ts +1 -1
- package/src/hooks/useAutoCoreTag.ts +2 -2
- package/src/hooks/useScaledValue.tsx +1 -1
- package/src/hub/CommandMessage.ts +71 -19
- package/src/hub/DebugPanel.ts +280 -0
- package/src/hub/HubBase.ts +147 -223
- package/src/hub/HubSimulate.ts +93 -24
- package/src/hub/HubTauri.ts +87 -96
- package/src/hub/HubWebSocket.ts +118 -140
- package/src/hub/debug.ts +211 -0
- package/src/hub/index.ts +49 -39
- package/docs/.nojekyll +0 -1
- package/docs/assets/hierarchy.js +0 -1
- package/docs/assets/highlight.css +0 -134
- package/docs/assets/icons.js +0 -18
- package/docs/assets/icons.svg +0 -1
- package/docs/assets/main.js +0 -60
- package/docs/assets/navigation.js +0 -1
- package/docs/assets/search.js +0 -1
- package/docs/assets/style.css +0 -1633
- package/docs/classes/components_CodeEditor.CodeEditor.html +0 -135
- package/docs/classes/components_Indicator.Indicator.html +0 -122
- package/docs/classes/components_IndicatorRect.IndicatorRect.html +0 -121
- package/docs/classes/components_JogPanel.JogPanel.html +0 -136
- package/docs/classes/components_Lamp.Lamp.html +0 -122
- package/docs/classes/components_OskDialog.OskDialog.html +0 -125
- package/docs/classes/components_TextInput.TextInput.html +0 -125
- package/docs/classes/components_ValueDisplay.ValueDisplay.html +0 -148
- package/docs/classes/components_ValueIndicator.ValueIndicator.html +0 -126
- package/docs/classes/core_ValueSimulator.ValueSimulator.html +0 -51
- package/docs/classes/hub_HubBase.HubBase.html +0 -106
- package/docs/classes/hub_HubSimulate.HubSimulate.html +0 -75
- package/docs/classes/hub_HubTauri.HubTauri.html +0 -93
- package/docs/classes/hub_HubWebSocket.HubWebSocket.html +0 -112
- package/docs/documents/core_AutoCoreTagContext.AutoCoreTagContext.html +0 -148
- package/docs/enums/components_JogPanel.JogDistanceAction.html +0 -5
- package/docs/enums/components_JogPanel.JogPanelAction.html +0 -18
- package/docs/enums/components_JogPanel.JogSpeedAction.html +0 -5
- package/docs/enums/core_ActionMode.ActionMode.html +0 -6
- package/docs/enums/core_IndicatorColor.IndicatorColor.html +0 -23
- package/docs/functions/assets.BlocklyLogo.html +0 -1
- package/docs/functions/assets.Distance.html +0 -1
- package/docs/functions/assets.JogLong.html +0 -1
- package/docs/functions/assets.JogMedium.html +0 -1
- package/docs/functions/assets.JogShort.html +0 -1
- package/docs/functions/assets.PythonLogo.html +0 -1
- package/docs/functions/assets.Rotation3D.html +0 -1
- package/docs/functions/assets.RotationCcw.html +0 -1
- package/docs/functions/assets.RotationCcwA.html +0 -1
- package/docs/functions/assets.RotationCcwB.html +0 -1
- package/docs/functions/assets.RotationCcwC.html +0 -1
- package/docs/functions/assets.RotationCw.html +0 -1
- package/docs/functions/assets.RotationCwA.html +0 -1
- package/docs/functions/assets.RotationCwB.html +0 -1
- package/docs/functions/assets.RotationCwC.html +0 -1
- package/docs/functions/assets.Run.html +0 -1
- package/docs/functions/assets.Speed.html +0 -1
- package/docs/functions/assets.SpeedFast.html +0 -1
- package/docs/functions/assets.SpeedMedium.html +0 -1
- package/docs/functions/assets.SpeedNone.html +0 -1
- package/docs/functions/assets.SpeedSlow.html +0 -1
- package/docs/functions/assets.Walk.html +0 -1
- package/docs/functions/components_BlocklyEditor.createCustomToolbox.html +0 -6
- package/docs/functions/core_UniqueId.UniqueId.html +0 -9
- package/docs/functions/core_hoc.hocAddSubscription.html +0 -6
- package/docs/functions/hooks_adsHooks.useAdsRegisterSymbols.html +0 -16
- package/docs/functions/hooks_adsHooks.useAdsTapValue.html +0 -8
- package/docs/functions/hooks_adsHooks.useAdsWriteScaledValue.html +0 -18
- package/docs/functions/hooks_adsHooks.useAdsWriteValue.html +0 -9
- package/docs/functions/hooks_commandHooks.useRegisterSymbols.html +0 -16
- package/docs/functions/hooks_commandHooks.useTapValue.html +0 -10
- package/docs/functions/hooks_commandHooks.useWriteScaledValue.html +0 -18
- package/docs/functions/hooks_commandHooks.useWriteValue.html +0 -11
- package/docs/functions/hooks_useAutoCoreTag.ts.makeAutoCoreTagHooks.html +0 -12
- package/docs/functions/hooks_useScaledValue.useScaledValue.html +0 -18
- package/docs/functions/hub.createHub.html +0 -3
- package/docs/hierarchy.html +0 -1
- package/docs/index.html +0 -148
- package/docs/interfaces/components_IndicatorButton.IndicatorButtonProps.html +0 -654
- package/docs/interfaces/components_IndicatorRect.IndicatorRectProps.html +0 -37
- package/docs/interfaces/components_JogPanel.JogPanelButtonDefinition.html +0 -5
- package/docs/interfaces/components_ToggleGroup.ToggleGroupProps.html +0 -644
- package/docs/interfaces/core_AutoCoreTagTypes.BaseContextValue.html +0 -12
- package/docs/interfaces/core_AutoCoreTagTypes.ScaleConfig.html +0 -13
- package/docs/interfaces/core_EventEmitterContext.Action.html +0 -8
- package/docs/interfaces/core_EventEmitterContext.EventEmitterContextType.html +0 -33
- package/docs/interfaces/core_EventEmitterContext.State.html +0 -8
- package/docs/interfaces/core_EventEmitterContext.Subscription.html +0 -6
- package/docs/interfaces/core_IndicatorButtonState.IndicatorButtonState.html +0 -10
- package/docs/interfaces/core_PositionContext.IPositionContext.html +0 -17
- package/docs/interfaces/hub_CommandMessage.CommandMessage.html +0 -6
- package/docs/interfaces/hub_CommandMessage.CommandMessageResult.html +0 -4
- package/docs/modules/assets.html +0 -1
- package/docs/modules/assets_BlocklyLogo.html +0 -1
- package/docs/modules/assets_Distance.html +0 -1
- package/docs/modules/assets_JogLong.html +0 -1
- package/docs/modules/assets_JogMedium.html +0 -1
- package/docs/modules/assets_JogShort.html +0 -1
- package/docs/modules/assets_PythonLogo.html +0 -1
- package/docs/modules/assets_Rotation3D.html +0 -1
- package/docs/modules/assets_RotationCcw.html +0 -1
- package/docs/modules/assets_RotationCcwA.html +0 -1
- package/docs/modules/assets_RotationCcwB.html +0 -1
- package/docs/modules/assets_RotationCcwC.html +0 -1
- package/docs/modules/assets_RotationCw.html +0 -1
- package/docs/modules/assets_RotationCwA.html +0 -1
- package/docs/modules/assets_RotationCwB.html +0 -1
- package/docs/modules/assets_RotationCwC.html +0 -1
- package/docs/modules/assets_Run.html +0 -1
- package/docs/modules/assets_Speed.html +0 -1
- package/docs/modules/assets_SpeedFast.html +0 -1
- package/docs/modules/assets_SpeedMedium.html +0 -1
- package/docs/modules/assets_SpeedNone.html +0 -1
- package/docs/modules/assets_SpeedSlow.html +0 -1
- package/docs/modules/assets_Walk.html +0 -1
- package/docs/modules/components_AutoCoreDevPanel.html +0 -20
- package/docs/modules/components_BlocklyEditor.html +0 -1
- package/docs/modules/components_CodeEditor.html +0 -1
- package/docs/modules/components_FileList.html +0 -1
- package/docs/modules/components_FileSelect.html +0 -1
- package/docs/modules/components_FitText.html +0 -1
- package/docs/modules/components_Indicator.html +0 -1
- package/docs/modules/components_IndicatorButton.html +0 -1
- package/docs/modules/components_IndicatorRect.html +0 -1
- package/docs/modules/components_JogPanel.html +0 -1
- package/docs/modules/components_Lamp.html +0 -1
- package/docs/modules/components_Osk.html +0 -1
- package/docs/modules/components_OskDialog.html +0 -1
- package/docs/modules/components_ProgressBarWithValue.html +0 -1
- package/docs/modules/components_TextInput.html +0 -1
- package/docs/modules/components_ToggleGroup.html +0 -1
- package/docs/modules/components_ValueDisplay.html +0 -1
- package/docs/modules/components_ValueIndicator.html +0 -1
- package/docs/modules/components_ValueInput.html +0 -1
- package/docs/modules/core_ActionMode.html +0 -1
- package/docs/modules/core_AutoCoreTagContext.html +0 -11
- package/docs/modules/core_AutoCoreTagTypes.html +0 -1
- package/docs/modules/core_EventEmitterContext.html +0 -53
- package/docs/modules/core_IndicatorButtonState.html +0 -1
- package/docs/modules/core_IndicatorColor.html +0 -1
- package/docs/modules/core_MaskPatterns.html +0 -1
- package/docs/modules/core_NumerableTypes.html +0 -1
- package/docs/modules/core_PositionContext.html +0 -1
- package/docs/modules/core_UniqueId.html +0 -1
- package/docs/modules/core_ValueSimulator.html +0 -1
- package/docs/modules/core_hoc.html +0 -1
- package/docs/modules/hooks.html +0 -1
- package/docs/modules/hooks_adsHooks.html +0 -1
- package/docs/modules/hooks_commandHooks.html +0 -1
- package/docs/modules/hooks_useAutoCoreTag.ts.html +0 -52
- package/docs/modules/hooks_useScaledValue.html +0 -1
- package/docs/modules/hub.html +0 -1
- package/docs/modules/hub_CommandMessage.html +0 -1
- package/docs/modules/hub_HubBase.html +0 -1
- package/docs/modules/hub_HubSimulate.html +0 -1
- package/docs/modules/hub_HubTauri.html +0 -1
- package/docs/modules/hub_HubWebSocket.html +0 -1
- package/docs/modules.html +0 -23
- package/docs/types/components_IndicatorButton.IndicatorButtonOptionsType.html +0 -1
- package/docs/types/core_AutoCoreTagTypes.ExtractByTag.html +0 -2
- package/docs/types/core_AutoCoreTagTypes.PrimitiveKind.html +0 -1
- package/docs/types/core_AutoCoreTagTypes.TagConfig.html +0 -16
- package/docs/types/core_AutoCoreTagTypes.TagValueMap.html +0 -1
- package/docs/types/core_AutoCoreTagTypes.TagValueOf.html +0 -1
- package/docs/types/core_EventEmitterContext.EmitterDispatchFunction.html +0 -3
- package/docs/types/core_EventEmitterContext.EmitterSubscribeFunction.html +0 -3
- package/docs/types/core_EventEmitterContext.EmitterUnsubscribeFunction.html +0 -3
- package/docs/types/core_NumerableTypes.NumerableFormatOptions.html +0 -4
- package/docs/types/core_hoc.HocAddSubscriptionProps.html +0 -6
- package/docs/variables/components_AutoCoreDevPanel.AutoCoreDevPanel.html +0 -43
- package/docs/variables/components_BlocklyEditor.BlocklyEditor.html +0 -13
- package/docs/variables/components_BlocklyEditor.StandardToolbox.html +0 -1
- package/docs/variables/components_FileList.FileList.html +0 -23
- package/docs/variables/components_FileSelect.FileSelect.html +0 -1
- package/docs/variables/components_FitText.FitText.html +0 -4
- package/docs/variables/components_IndicatorButton.IndicatorButton.html +0 -1
- package/docs/variables/components_JogPanel.DefaultLinearJogButtons.html +0 -2
- package/docs/variables/components_JogPanel.DefaultRotationJogButtons.html +0 -2
- package/docs/variables/components_Osk.Osk.html +0 -1
- package/docs/variables/components_ProgressBarWithValue.ProgressBarWithValue.html +0 -1
- package/docs/variables/components_ToggleGroup.ToggleGroup.html +0 -1
- package/docs/variables/components_ValueInput.ValueInput.html +0 -4
- package/docs/variables/core_AutoCoreTagContext.AutoCoreTagContext.html +0 -1
- package/docs/variables/core_AutoCoreTagContext.AutoCoreTagProvider.html +0 -7
- package/docs/variables/core_EventEmitterContext.EventEmitterContext.html +0 -64
- package/docs/variables/core_EventEmitterContext.EventEmitterProvider.html +0 -10
- package/docs/variables/core_MaskPatterns.PrimeReactMaskPatterns.html +0 -14
- package/docs/variables/core_MaskPatterns.RegExMaskPatterns.html +0 -15
- package/docs/variables/core_PositionContext.DimensionsContext.html +0 -6
- package/docs/variables/hooks_useScaledValue.kMillimeters2Inches.html +0 -2
- package/docs/variables/hooks_useScaledValue.kNewtons2Pounds.html +0 -2
package/src/core/hoc.tsx
CHANGED
package/src/hooks/adsHooks.tsx
CHANGED
|
@@ -2,7 +2,7 @@
|
|
|
2
2
|
* Copyright (C) 2024 Automated Design Corp.. All Rights Reserved.
|
|
3
3
|
* Created Date: 2024-04-26 09:04:40
|
|
4
4
|
* -----
|
|
5
|
-
* Last Modified:
|
|
5
|
+
* Last Modified: 2026-01-29 09:33:22
|
|
6
6
|
* -----
|
|
7
7
|
*
|
|
8
8
|
*/
|
|
@@ -11,6 +11,7 @@
|
|
|
11
11
|
|
|
12
12
|
import { useContext, useRef, useEffect, useCallback } from 'react';
|
|
13
13
|
import { EventEmitterContext } from '../core/EventEmitterContext';
|
|
14
|
+
import { MessageType } from '../hub/CommandMessage';
|
|
14
15
|
|
|
15
16
|
|
|
16
17
|
/**
|
|
@@ -70,8 +71,8 @@ export const useAdsRegisterSymbols = (
|
|
|
70
71
|
const registerAndSubscribe = async () => {
|
|
71
72
|
for (const [key, symbolName] of Object.entries(symbols)) {
|
|
72
73
|
try {
|
|
73
|
-
const invokeOptions = options[key] ? { symbol_name: symbolName, options
|
|
74
|
-
await invoke("ADS",
|
|
74
|
+
const invokeOptions = options[key] ? { symbol_name: symbolName, options: options[key] } : { symbol_name: symbolName };
|
|
75
|
+
await invoke("ADS.register_symbol", MessageType.Request, invokeOptions);
|
|
75
76
|
|
|
76
77
|
//console.log(`Subscribe... ADS/${symbolName}`);
|
|
77
78
|
const subscriptionId = subscribe(`ADS/${symbolName}`, (data) => {
|
|
@@ -87,7 +88,7 @@ export const useAdsRegisterSymbols = (
|
|
|
87
88
|
console.error(`Failed to register symbol ${symbolName}: ${err}`);
|
|
88
89
|
}
|
|
89
90
|
}
|
|
90
|
-
await invoke("ADS",
|
|
91
|
+
await invoke("ADS.refresh", MessageType.Request, {});
|
|
91
92
|
};
|
|
92
93
|
|
|
93
94
|
if (!isConnected() ) {
|
|
@@ -152,14 +153,13 @@ export const useAdsRegisterSymbols = (
|
|
|
152
153
|
* };
|
|
153
154
|
*/
|
|
154
155
|
export function useAdsWriteValue(symbolName: string) {
|
|
155
|
-
const {
|
|
156
|
-
const domain = "ADS";
|
|
157
|
-
const fname = "write_value";
|
|
156
|
+
const { write } = useContext(EventEmitterContext);
|
|
158
157
|
|
|
159
158
|
// Return a function that takes a value and sends it to the backend
|
|
160
|
-
return async (value: object | boolean | number | string
|
|
159
|
+
return async (value: object | boolean | number | string) => {
|
|
161
160
|
try {
|
|
162
|
-
|
|
161
|
+
// Use FQDN topic: ADS.symbolName
|
|
162
|
+
await write(`ADS.${symbolName}`, value);
|
|
163
163
|
} catch (err) {
|
|
164
164
|
console.error(`Error writing tag ${symbolName}: ${err}`);
|
|
165
165
|
}
|
|
@@ -220,23 +220,22 @@ export function useAdsWriteValue(symbolName: string) {
|
|
|
220
220
|
* dynamically if needed, for instance, based on user selection or other external configurations.
|
|
221
221
|
*/
|
|
222
222
|
export function useAdsWriteScaledValue(symbolName: string, scale: number, offset: number) {
|
|
223
|
-
const {
|
|
224
|
-
|
|
225
|
-
const fname = "write_value";
|
|
226
|
-
|
|
223
|
+
const { write } = useContext(EventEmitterContext);
|
|
224
|
+
|
|
227
225
|
return useCallback(async (value: number) => {
|
|
228
226
|
|
|
229
|
-
// In autocore-react, we
|
|
227
|
+
// In autocore-react, we multiply to scale incoming values,
|
|
230
228
|
// divide to scale outgoing values.
|
|
231
229
|
// This is an OUTGOING value, so we divide.
|
|
232
230
|
|
|
233
|
-
const scaledValue = (value - offset) / scale;
|
|
231
|
+
const scaledValue = (value - offset) / scale;
|
|
234
232
|
try {
|
|
235
|
-
|
|
233
|
+
// Use FQDN topic: ADS.symbolName
|
|
234
|
+
await write(`ADS.${symbolName}`, scaledValue);
|
|
236
235
|
} catch (err) {
|
|
237
236
|
console.error(`Error writing scaled value to tag ${symbolName}: ${err}`);
|
|
238
237
|
}
|
|
239
|
-
}, [symbolName, scale, offset,
|
|
238
|
+
}, [symbolName, scale, offset, write]);
|
|
240
239
|
}
|
|
241
240
|
|
|
242
241
|
|
|
@@ -271,15 +270,15 @@ export function useAdsWriteScaledValue(symbolName: string, scale: number, offset
|
|
|
271
270
|
* ```
|
|
272
271
|
*/
|
|
273
272
|
export function useAdsTapValue(symbolName: string): () => Promise<void> {
|
|
274
|
-
const {
|
|
275
|
-
const domain = "ADS";
|
|
276
|
-
const fname = "write_value";
|
|
273
|
+
const { write } = useContext(EventEmitterContext);
|
|
277
274
|
|
|
278
275
|
return async () => {
|
|
279
276
|
try {
|
|
280
|
-
|
|
277
|
+
// Use FQDN topic: ADS.symbolName
|
|
278
|
+
const topic = `ADS.${symbolName}`;
|
|
279
|
+
await write(topic, true);
|
|
281
280
|
await sleep(300); // Sleep for 300ms before writing false
|
|
282
|
-
await
|
|
281
|
+
await write(topic, false);
|
|
283
282
|
} catch (err) {
|
|
284
283
|
console.error(`Error handling tap action for ${symbolName}: ${err}`);
|
|
285
284
|
}
|
|
@@ -2,7 +2,7 @@
|
|
|
2
2
|
* Copyright (C) 2025 Automated Design Corp. All Rights Reserved.
|
|
3
3
|
* Created Date: 2025-03-31 06:38:50
|
|
4
4
|
* -----
|
|
5
|
-
* Last Modified:
|
|
5
|
+
* Last Modified: 2026-01-29 09:33:28
|
|
6
6
|
* -----
|
|
7
7
|
*
|
|
8
8
|
*/
|
|
@@ -14,6 +14,7 @@
|
|
|
14
14
|
|
|
15
15
|
import { useContext, useRef, useEffect, useCallback } from 'react';
|
|
16
16
|
import { EventEmitterContext } from '../core/EventEmitterContext';
|
|
17
|
+
import { MessageType } from '../hub/CommandMessage';
|
|
17
18
|
|
|
18
19
|
|
|
19
20
|
/**
|
|
@@ -90,9 +91,8 @@ export const useRegisterSymbols = (
|
|
|
90
91
|
subscriptions.current.push(subscriptionId);
|
|
91
92
|
|
|
92
93
|
// Refresh on a topic is the same as a read_value, except the response is broadcasted.
|
|
93
|
-
//
|
|
94
|
-
|
|
95
|
-
await invoke(domain, "refresh", {'topic' : `${symbolName}`});
|
|
94
|
+
// Use FQDN topic: domain.symbolName
|
|
95
|
+
await invoke(`${domain}.${symbolName}`, MessageType.Request, { action: "refresh" });
|
|
96
96
|
|
|
97
97
|
} catch (err) {
|
|
98
98
|
console.error(`Failed to register symbol ${symbolName}: ${err}`);
|
|
@@ -165,13 +165,14 @@ export const useRegisterSymbols = (
|
|
|
165
165
|
* );
|
|
166
166
|
* };
|
|
167
167
|
*/
|
|
168
|
-
export function useWriteValue(domain
|
|
169
|
-
const {
|
|
168
|
+
export function useWriteValue(domain: string, symbolName: string) {
|
|
169
|
+
const { write } = useContext(EventEmitterContext);
|
|
170
170
|
|
|
171
171
|
// Return a function that takes a value and sends it to the backend
|
|
172
|
-
return async (value: object | boolean | number | string
|
|
172
|
+
return async (value: object | boolean | number | string) => {
|
|
173
173
|
try {
|
|
174
|
-
|
|
174
|
+
// Use FQDN topic: domain.symbolName
|
|
175
|
+
await write(`${domain}.${symbolName}`, value);
|
|
175
176
|
} catch (err) {
|
|
176
177
|
console.error(`Error writing tag ${symbolName}: ${err}`);
|
|
177
178
|
}
|
|
@@ -231,22 +232,23 @@ export function useWriteValue(domain : string, symbolName: string, fname : strin
|
|
|
231
232
|
* converts it to millimeters using the current `scale`, and writes the result to a backend symbol. The `scale` and `offset` can be adjusted
|
|
232
233
|
* dynamically if needed, for instance, based on user selection or other external configurations.
|
|
233
234
|
*/
|
|
234
|
-
export function useWriteScaledValue(domain
|
|
235
|
-
const {
|
|
236
|
-
|
|
235
|
+
export function useWriteScaledValue(domain: string, symbolName: string, scale: number, offset: number) {
|
|
236
|
+
const { write } = useContext(EventEmitterContext);
|
|
237
|
+
|
|
237
238
|
return useCallback(async (value: number) => {
|
|
238
239
|
|
|
239
|
-
// In autocore-react, we
|
|
240
|
+
// In autocore-react, we multiply to scale incoming values,
|
|
240
241
|
// divide to scale outgoing values.
|
|
241
242
|
// This is an OUTGOING value, so we divide.
|
|
242
243
|
|
|
243
|
-
const scaledValue = (value - offset) / scale;
|
|
244
|
+
const scaledValue = (value - offset) / scale;
|
|
244
245
|
try {
|
|
245
|
-
|
|
246
|
+
// Use FQDN topic: domain.symbolName
|
|
247
|
+
await write(`${domain}.${symbolName}`, scaledValue);
|
|
246
248
|
} catch (err) {
|
|
247
249
|
console.error(`Error writing scaled value to tag ${symbolName}: ${err}`);
|
|
248
250
|
}
|
|
249
|
-
}, [symbolName, scale, offset,
|
|
251
|
+
}, [domain, symbolName, scale, offset, write]);
|
|
250
252
|
}
|
|
251
253
|
|
|
252
254
|
|
|
@@ -280,14 +282,16 @@ export function useWriteScaledValue(domain : string, symbolName: string, scale:
|
|
|
280
282
|
* };
|
|
281
283
|
* ```
|
|
282
284
|
*/
|
|
283
|
-
export function useTapValue(domain
|
|
284
|
-
const {
|
|
285
|
+
export function useTapValue(domain: string, symbolName: string): () => Promise<void> {
|
|
286
|
+
const { write } = useContext(EventEmitterContext);
|
|
285
287
|
|
|
286
288
|
return async () => {
|
|
287
289
|
try {
|
|
288
|
-
|
|
290
|
+
// Use FQDN topic: domain.symbolName
|
|
291
|
+
const topic = `${domain}.${symbolName}`;
|
|
292
|
+
await write(topic, true);
|
|
289
293
|
await sleep(300); // Sleep for 300ms before writing false
|
|
290
|
-
await
|
|
294
|
+
await write(topic, false);
|
|
291
295
|
} catch (err) {
|
|
292
296
|
console.error(`Error handling tap action for ${symbolName}: ${err}`);
|
|
293
297
|
}
|
package/src/hooks/index.ts
CHANGED
|
@@ -2,7 +2,7 @@
|
|
|
2
2
|
* Copyright (C) 2025 Automated Design Corp.. All Rights Reserved.
|
|
3
3
|
* Created Date: 2025-09-05 08:03:32
|
|
4
4
|
* -----
|
|
5
|
-
* Last Modified:
|
|
5
|
+
* Last Modified: 2026-01-29 09:33:40
|
|
6
6
|
* -----
|
|
7
7
|
*
|
|
8
8
|
*/
|
|
@@ -24,7 +24,7 @@ export function makeAutoCoreTagHooks<Spec extends readonly TagConfig[]>(
|
|
|
24
24
|
type TagNames = keyof VMap & string;
|
|
25
25
|
|
|
26
26
|
const findCfg = (tagName: string) =>
|
|
27
|
-
tags.find(t => t.
|
|
27
|
+
tags.find(t => t.fqdn === tagName) as (Spec[number] | undefined);
|
|
28
28
|
|
|
29
29
|
/**
|
|
30
30
|
* Access a single tag by name.
|
|
@@ -2,36 +2,88 @@
|
|
|
2
2
|
* Copyright (C) 2024 Automated Design Corp.. All Rights Reserved.
|
|
3
3
|
* Created Date: 2024-04-24 11:47:13
|
|
4
4
|
* -----
|
|
5
|
-
* Last Modified:
|
|
5
|
+
* Last Modified: 2026-01-29 09:33:54
|
|
6
6
|
* -----
|
|
7
7
|
*
|
|
8
8
|
*/
|
|
9
9
|
|
|
10
10
|
|
|
11
|
+
// Replaced by a flattened CommandMessage
|
|
12
|
+
// /// The result portion of a CommandMessage. The server will
|
|
13
|
+
// /// place the result of a command in this portion of the message.
|
|
14
|
+
// export interface CommandMessageResult {
|
|
15
|
+
// /// The JSON object of the result.
|
|
16
|
+
// data: any;
|
|
17
|
+
// /// If true, the command was processed successfully.
|
|
18
|
+
// success : boolean,
|
|
19
|
+
// /// If success is false, this should contain a corresponding error message.
|
|
20
|
+
// error_message: string;
|
|
21
|
+
// }
|
|
11
22
|
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
///
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
23
|
+
|
|
24
|
+
export enum MessageType {
|
|
25
|
+
/// Invalid or no operation. Used for keepalive/ping.
|
|
26
|
+
NoOp = 0,
|
|
27
|
+
|
|
28
|
+
/// Response to a previous request.
|
|
29
|
+
Response = 1,
|
|
30
|
+
|
|
31
|
+
/// Read request - module should return data for the specified topic.
|
|
32
|
+
Read = 2,
|
|
33
|
+
|
|
34
|
+
/// Write request - module should store the provided data.
|
|
35
|
+
Write = 3,
|
|
36
|
+
|
|
37
|
+
/// Subscribe to updates on a topic.
|
|
38
|
+
Subscribe = 4,
|
|
39
|
+
|
|
40
|
+
/// Unsubscribe from a topic.
|
|
41
|
+
Unsubscribe = 5,
|
|
42
|
+
|
|
43
|
+
/// Broadcast message (unsolicited push from module to server or vice versa).
|
|
44
|
+
Broadcast = 6,
|
|
45
|
+
|
|
46
|
+
/// Heartbeat/keepalive message.
|
|
47
|
+
Heartbeat = 7,
|
|
48
|
+
|
|
49
|
+
/// Control message (initialize, finalize, configuration).
|
|
50
|
+
Control = 8,
|
|
51
|
+
|
|
52
|
+
/// Generic request - module parses topic to determine action.
|
|
53
|
+
Request = 10,
|
|
21
54
|
}
|
|
22
55
|
|
|
56
|
+
|
|
57
|
+
|
|
23
58
|
/// CommandMessage is the object passed between the client and server for making requests and
|
|
24
59
|
/// responses.
|
|
25
60
|
export interface CommandMessage {
|
|
26
61
|
/// An id to identify the request. The request ID is managed by the client and will be reflected back.
|
|
27
62
|
/// The server will never change the request ID.
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
///
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
///
|
|
36
|
-
|
|
63
|
+
transaction_id: number;
|
|
64
|
+
|
|
65
|
+
/// Timestamp in milliseconds since UNIX epoch.
|
|
66
|
+
/// Set automatically on message creation.
|
|
67
|
+
timecode: number,
|
|
68
|
+
|
|
69
|
+
|
|
70
|
+
/// Fully-qualified topic name (FQDN).
|
|
71
|
+
/// Format: "domain.subtopic.path" e.g., "ads.plc1.GM.stData"
|
|
72
|
+
topic: string;
|
|
73
|
+
|
|
74
|
+
/// The type/purpose of this message.
|
|
75
|
+
message_type: MessageType,
|
|
76
|
+
|
|
77
|
+
/// The payload data.
|
|
78
|
+
/// - For requests: arguments/parameters
|
|
79
|
+
/// - For responses: result data
|
|
80
|
+
data?: any;
|
|
81
|
+
|
|
82
|
+
|
|
83
|
+
/// Whether the operation was successful (for responses).
|
|
84
|
+
success: boolean,
|
|
85
|
+
|
|
86
|
+
/// Error message if the operation failed (for responses).
|
|
87
|
+
error_message: string,
|
|
88
|
+
|
|
37
89
|
}
|
|
@@ -0,0 +1,280 @@
|
|
|
1
|
+
/*
|
|
2
|
+
* Copyright (C) 2026 Automated Design Corp. All Rights Reserved.
|
|
3
|
+
*
|
|
4
|
+
* DebugPanel - Injects a visible debug panel directly into the DOM
|
|
5
|
+
*
|
|
6
|
+
* This bypasses React entirely to show real-time debug info about
|
|
7
|
+
* WebSocket connections and Hub instances.
|
|
8
|
+
*/
|
|
9
|
+
|
|
10
|
+
console.log("[DebugPanel.ts] Module loading...");
|
|
11
|
+
|
|
12
|
+
interface DebugLog {
|
|
13
|
+
time: string;
|
|
14
|
+
type: "info" | "warn" | "error" | "send" | "recv";
|
|
15
|
+
source: string;
|
|
16
|
+
message: string;
|
|
17
|
+
}
|
|
18
|
+
|
|
19
|
+
class DebugPanel {
|
|
20
|
+
private container: HTMLDivElement | null = null;
|
|
21
|
+
private logContainer: HTMLDivElement | null = null;
|
|
22
|
+
private statsContainer: HTMLDivElement | null = null;
|
|
23
|
+
private logs: DebugLog[] = [];
|
|
24
|
+
private maxLogs = 100;
|
|
25
|
+
|
|
26
|
+
// Stats
|
|
27
|
+
private stats = {
|
|
28
|
+
hubInstancesCreated: 0,
|
|
29
|
+
connectCalls: 0,
|
|
30
|
+
wsOpened: 0,
|
|
31
|
+
wsClosed: 0,
|
|
32
|
+
wsErrors: 0,
|
|
33
|
+
messagesSent: 0,
|
|
34
|
+
messagesReceived: 0,
|
|
35
|
+
currentState: "unknown",
|
|
36
|
+
};
|
|
37
|
+
|
|
38
|
+
constructor() {
|
|
39
|
+
this.injectPanel();
|
|
40
|
+
this.log("info", "DebugPanel", "Debug panel initialized");
|
|
41
|
+
}
|
|
42
|
+
|
|
43
|
+
private injectPanel(): void {
|
|
44
|
+
// Check for existing panel and remove it (handles HMR/StrictMode)
|
|
45
|
+
const existing = document.getElementById("autocore-debug-panel");
|
|
46
|
+
if (existing) {
|
|
47
|
+
existing.remove();
|
|
48
|
+
}
|
|
49
|
+
|
|
50
|
+
// Create container
|
|
51
|
+
this.container = document.createElement("div");
|
|
52
|
+
this.container.id = "autocore-debug-panel";
|
|
53
|
+
this.container.innerHTML = `
|
|
54
|
+
<style>
|
|
55
|
+
#autocore-debug-panel {
|
|
56
|
+
position: fixed;
|
|
57
|
+
bottom: 10px;
|
|
58
|
+
right: 10px;
|
|
59
|
+
width: 400px;
|
|
60
|
+
max-height: 300px;
|
|
61
|
+
background: rgba(0, 0, 0, 0.9);
|
|
62
|
+
color: #0f0;
|
|
63
|
+
font-family: monospace;
|
|
64
|
+
font-size: 11px;
|
|
65
|
+
border: 1px solid #0f0;
|
|
66
|
+
border-radius: 4px;
|
|
67
|
+
z-index: 99999;
|
|
68
|
+
overflow: hidden;
|
|
69
|
+
}
|
|
70
|
+
#autocore-debug-panel .header {
|
|
71
|
+
background: #0f0;
|
|
72
|
+
color: #000;
|
|
73
|
+
padding: 4px 8px;
|
|
74
|
+
font-weight: bold;
|
|
75
|
+
cursor: pointer;
|
|
76
|
+
display: flex;
|
|
77
|
+
justify-content: space-between;
|
|
78
|
+
}
|
|
79
|
+
#autocore-debug-panel .stats {
|
|
80
|
+
padding: 4px 8px;
|
|
81
|
+
border-bottom: 1px solid #0f0;
|
|
82
|
+
display: grid;
|
|
83
|
+
grid-template-columns: 1fr 1fr;
|
|
84
|
+
gap: 2px;
|
|
85
|
+
}
|
|
86
|
+
#autocore-debug-panel .stats span {
|
|
87
|
+
color: #fff;
|
|
88
|
+
}
|
|
89
|
+
#autocore-debug-panel .stats .value {
|
|
90
|
+
color: #ff0;
|
|
91
|
+
}
|
|
92
|
+
#autocore-debug-panel .logs {
|
|
93
|
+
max-height: 180px;
|
|
94
|
+
overflow-y: auto;
|
|
95
|
+
padding: 4px;
|
|
96
|
+
}
|
|
97
|
+
#autocore-debug-panel .log-entry {
|
|
98
|
+
margin: 1px 0;
|
|
99
|
+
white-space: nowrap;
|
|
100
|
+
overflow: hidden;
|
|
101
|
+
text-overflow: ellipsis;
|
|
102
|
+
}
|
|
103
|
+
#autocore-debug-panel .log-entry.info { color: #888; }
|
|
104
|
+
#autocore-debug-panel .log-entry.warn { color: #fa0; }
|
|
105
|
+
#autocore-debug-panel .log-entry.error { color: #f44; }
|
|
106
|
+
#autocore-debug-panel .log-entry.send { color: #4f4; }
|
|
107
|
+
#autocore-debug-panel .log-entry.recv { color: #44f; }
|
|
108
|
+
#autocore-debug-panel .state-connected { color: #4f4 !important; }
|
|
109
|
+
#autocore-debug-panel .state-disconnected { color: #f44 !important; }
|
|
110
|
+
#autocore-debug-panel .state-connecting { color: #fa0 !important; }
|
|
111
|
+
</style>
|
|
112
|
+
<div class="header">
|
|
113
|
+
<span>AutoCore Debug</span>
|
|
114
|
+
<span id="debug-toggle">[_]</span>
|
|
115
|
+
</div>
|
|
116
|
+
<div id="debug-content">
|
|
117
|
+
<div class="stats" id="debug-stats"></div>
|
|
118
|
+
<div class="logs" id="debug-logs"></div>
|
|
119
|
+
</div>
|
|
120
|
+
`;
|
|
121
|
+
|
|
122
|
+
// Wait for DOM ready
|
|
123
|
+
if (document.body) {
|
|
124
|
+
document.body.appendChild(this.container);
|
|
125
|
+
this.setupElements();
|
|
126
|
+
} else {
|
|
127
|
+
document.addEventListener("DOMContentLoaded", () => {
|
|
128
|
+
document.body.appendChild(this.container!);
|
|
129
|
+
this.setupElements();
|
|
130
|
+
});
|
|
131
|
+
}
|
|
132
|
+
}
|
|
133
|
+
|
|
134
|
+
private setupElements(): void {
|
|
135
|
+
this.statsContainer = document.getElementById("debug-stats") as HTMLDivElement;
|
|
136
|
+
this.logContainer = document.getElementById("debug-logs") as HTMLDivElement;
|
|
137
|
+
|
|
138
|
+
// Toggle button
|
|
139
|
+
const toggle = document.getElementById("debug-toggle");
|
|
140
|
+
const content = document.getElementById("debug-content");
|
|
141
|
+
toggle?.addEventListener("click", () => {
|
|
142
|
+
if (content) {
|
|
143
|
+
content.style.display = content.style.display === "none" ? "block" : "none";
|
|
144
|
+
toggle.textContent = content.style.display === "none" ? "[+]" : "[_]";
|
|
145
|
+
}
|
|
146
|
+
});
|
|
147
|
+
|
|
148
|
+
this.updateStats();
|
|
149
|
+
}
|
|
150
|
+
|
|
151
|
+
private updateStats(): void {
|
|
152
|
+
if (!this.statsContainer) return;
|
|
153
|
+
|
|
154
|
+
const stateClass =
|
|
155
|
+
this.stats.currentState === "OPEN"
|
|
156
|
+
? "state-connected"
|
|
157
|
+
: this.stats.currentState === "CONNECTING"
|
|
158
|
+
? "state-connecting"
|
|
159
|
+
: "state-disconnected";
|
|
160
|
+
|
|
161
|
+
this.statsContainer.innerHTML = `
|
|
162
|
+
<div><span>Hub Instances:</span> <span class="value">${this.stats.hubInstancesCreated}</span></div>
|
|
163
|
+
<div><span>connect() calls:</span> <span class="value">${this.stats.connectCalls}</span></div>
|
|
164
|
+
<div><span>WS Opened:</span> <span class="value">${this.stats.wsOpened}</span></div>
|
|
165
|
+
<div><span>WS Closed:</span> <span class="value">${this.stats.wsClosed}</span></div>
|
|
166
|
+
<div><span>WS Errors:</span> <span class="value">${this.stats.wsErrors}</span></div>
|
|
167
|
+
<div><span>Msgs Sent:</span> <span class="value">${this.stats.messagesSent}</span></div>
|
|
168
|
+
<div><span>Msgs Recv:</span> <span class="value">${this.stats.messagesReceived}</span></div>
|
|
169
|
+
<div><span>WS State:</span> <span class="value ${stateClass}">${this.stats.currentState}</span></div>
|
|
170
|
+
`;
|
|
171
|
+
}
|
|
172
|
+
|
|
173
|
+
log(type: DebugLog["type"], source: string, message: string): void {
|
|
174
|
+
const time = new Date().toTimeString().slice(0, 8);
|
|
175
|
+
const entry: DebugLog = { time, type, source, message };
|
|
176
|
+
|
|
177
|
+
this.logs.push(entry);
|
|
178
|
+
if (this.logs.length > this.maxLogs) {
|
|
179
|
+
this.logs.shift();
|
|
180
|
+
}
|
|
181
|
+
|
|
182
|
+
// Also log to console
|
|
183
|
+
const prefix = `[${time}] [${source}]`;
|
|
184
|
+
switch (type) {
|
|
185
|
+
case "error":
|
|
186
|
+
console.error(prefix, message);
|
|
187
|
+
break;
|
|
188
|
+
case "warn":
|
|
189
|
+
console.warn(prefix, message);
|
|
190
|
+
break;
|
|
191
|
+
default:
|
|
192
|
+
console.log(prefix, message);
|
|
193
|
+
}
|
|
194
|
+
|
|
195
|
+
this.renderLogs();
|
|
196
|
+
}
|
|
197
|
+
|
|
198
|
+
private renderLogs(): void {
|
|
199
|
+
if (!this.logContainer) return;
|
|
200
|
+
|
|
201
|
+
this.logContainer.innerHTML = this.logs
|
|
202
|
+
.slice(-50) // Show last 50
|
|
203
|
+
.map(
|
|
204
|
+
(log) =>
|
|
205
|
+
`<div class="log-entry ${log.type}">[${log.time}] ${log.source}: ${log.message}</div>`
|
|
206
|
+
)
|
|
207
|
+
.join("");
|
|
208
|
+
|
|
209
|
+
// Auto-scroll to bottom
|
|
210
|
+
this.logContainer.scrollTop = this.logContainer.scrollHeight;
|
|
211
|
+
}
|
|
212
|
+
|
|
213
|
+
// Stat update methods
|
|
214
|
+
hubCreated(): void {
|
|
215
|
+
this.stats.hubInstancesCreated++;
|
|
216
|
+
this.log("warn", "Hub", `NEW INSTANCE CREATED (total: ${this.stats.hubInstancesCreated})`);
|
|
217
|
+
this.updateStats();
|
|
218
|
+
}
|
|
219
|
+
|
|
220
|
+
connectCalled(socketState: string): void {
|
|
221
|
+
this.stats.connectCalls++;
|
|
222
|
+
this.stats.currentState = socketState;
|
|
223
|
+
this.log("info", "Hub", `connect() called (socket state: ${socketState})`);
|
|
224
|
+
this.updateStats();
|
|
225
|
+
}
|
|
226
|
+
|
|
227
|
+
wsOpened(url: string): void {
|
|
228
|
+
this.stats.wsOpened++;
|
|
229
|
+
this.stats.currentState = "OPEN";
|
|
230
|
+
this.log("info", "WS", `OPENED: ${url}`);
|
|
231
|
+
this.updateStats();
|
|
232
|
+
}
|
|
233
|
+
|
|
234
|
+
wsClosed(code: number, reason: string): void {
|
|
235
|
+
this.stats.wsClosed++;
|
|
236
|
+
this.stats.currentState = "CLOSED";
|
|
237
|
+
this.log("warn", "WS", `CLOSED: code=${code}, reason=${reason}`);
|
|
238
|
+
this.updateStats();
|
|
239
|
+
}
|
|
240
|
+
|
|
241
|
+
wsError(error: string): void {
|
|
242
|
+
this.stats.wsErrors++;
|
|
243
|
+
this.log("error", "WS", `ERROR: ${error}`);
|
|
244
|
+
this.updateStats();
|
|
245
|
+
}
|
|
246
|
+
|
|
247
|
+
messageSent(type: string, command: string, requestId: number): void {
|
|
248
|
+
this.stats.messagesSent++;
|
|
249
|
+
this.log("send", "WS", `>>> ${type}/${command} (id=${requestId})`);
|
|
250
|
+
this.updateStats();
|
|
251
|
+
}
|
|
252
|
+
|
|
253
|
+
messageReceived(type: string, command: string, requestId?: number): void {
|
|
254
|
+
this.stats.messagesReceived++;
|
|
255
|
+
this.log("recv", "WS", `<<< ${type}/${command} (id=${requestId ?? "none"})`);
|
|
256
|
+
this.updateStats();
|
|
257
|
+
}
|
|
258
|
+
|
|
259
|
+
updateState(state: string): void {
|
|
260
|
+
this.stats.currentState = state;
|
|
261
|
+
this.updateStats();
|
|
262
|
+
}
|
|
263
|
+
}
|
|
264
|
+
|
|
265
|
+
// Create singleton and expose globally
|
|
266
|
+
let debugPanel: DebugPanel | null = null;
|
|
267
|
+
|
|
268
|
+
export function getDebugPanel(): DebugPanel {
|
|
269
|
+
if (!debugPanel) {
|
|
270
|
+
debugPanel = new DebugPanel();
|
|
271
|
+
// Expose globally for console access
|
|
272
|
+
(window as any).__AUTOCORE_DEBUG_PANEL__ = debugPanel;
|
|
273
|
+
}
|
|
274
|
+
return debugPanel;
|
|
275
|
+
}
|
|
276
|
+
|
|
277
|
+
// Auto-initialize on import
|
|
278
|
+
getDebugPanel();
|
|
279
|
+
|
|
280
|
+
export default getDebugPanel;
|