User Tools

Site Tools


transsecs_host:startup_trigger_host_recipesend_ui

Differences

This shows you the differences between two versions of the page.

Link to this comparison view

Both sides previous revisionPrevious revision
Next revision
Previous revision
transsecs_host:startup_trigger_host_recipesend_ui [2025/08/19 12:53] – amywtranssecs_host:startup_trigger_host_recipesend_ui [2025/08/21 11:49] (current) – amyw
Line 5: Line 5:
 It performs two key tasks: It performs two key tasks:
  
-  * Waits for the TransSECS Host controller to become available.   +  * Waits for the **TransSECS Host controller** to become available.   
-  * Sets up a **Connection Status Listener** that, once communications are established, prompts the user to choose a **PPID + file** and sends it to the tool using **S7F3 (RecipeSend)**.  +  * Sets up a **Connection Status Listener** that, once communications are established, launches a Swing-based **PPID + File selection UI** for recipe sending using **S7F3 (RecipeSend)**.  
  
-The script includes a **Swing-based popup window** for PPID and file selection. +The script includes a **Swing-based popup window** for entering a PPID and choosing a file.
- +
----+
  
 ===== Key Features ===== ===== Key Features =====
-  * **Swing UI**: Lets the user enter a PPID and select a file to send as a recipe.  +  * **Swing UI**: Lets the user enter a **PPID** and select a **file** to send as a recipe.  
   * **Background host discovery**: Uses a separate thread to wait until the host is ready.     * **Background host discovery**: Uses a separate thread to wait until the host is ready.  
-    - In deployment: host is usually ready immediately.   +    - In **SIM mode**: waits until the user toggles from SIM → LIVE.   
-    - In SIM mode: the thread waits until the user toggles SIM → LIVE.   +    - In **deployment mode**: usually connects quickly, but can be delayed if: 
-  * **Safe listener setup**: Adds a short delay before registering the listener, preventing race conditions in deployment.   +      * The tool is still initializing.   
-  * **Null-safe message bean lookup**: Ensures `RecipeSend` bean is available before sending.   +      * The tool is not reachable on the network.   
-  * **Robust error handling**: Uses `RuntimeException` instead of Nashorn `Error` to avoid Java `ClassCastException`.  +      * There are temporary communication issues.   
 +  * **Lightweight polling**: Checks every **50 ms**, with logging every 500 ms during the wait.   
 +  * **Connection-safe listener setup**: Adds a **1-second delay** before registering the listener to avoid race conditions during initialization.   
 +  * **Robust logging**: Provides clear feedback during wait, connection, timeout, and UI launch.   
 +  * **Thread-safe UI handling**: UI actions are executed via `SwingUtilities.invokeLater` to prevent Swing threading issues.
  
 ===== How It Works ===== ===== How It Works =====
 +At startup, a **background thread** is launched:
 +  * Repeatedly checks `TransSecsController.getSingleController()` until it returns a valid controller, or until a **5-second timeout** is reached.
 +  * Logs progress every **10 polling cycles (~500 ms)** while waiting.
 +  * Stops waiting and logs an error message after the timeout if no host is detected.
  
-At startup: a background thread begins waiting for TransSecsController.getSingleController() to return non-null.+Once the host is found: 
 +  * Waits **1 second** for the host and project to stabilize. 
 +  * Registers a **Connection Status Listener**.
  
-If in SIM mode: the loop continues until the user toggles to LIVE.+When the host reports **status = 0 (Connected)**: 
 +  * Launches the Swing **PPID + File** popup UI.   
 +  * Collects the user's **PPID** and reads the file into a byte array.   
 +  * Sends an **S7F3 RecipeSend** message with the selected PPID and file contents.
  
-If in deployment: host is found almost immediately.+If the host never becomes available: 
 +  * Logs a timeout message.   
 +  * Skips UI initialization to avoid errors.
  
-After discovery: waits 1 second for project initialization, then registers the Connection Status Listener. +{{:transsecs_host:screenshot_2025-08-18_103804.png?400|}}
- +
-On connection: when the host reports connection status 0 (operational), the script: +
- +
-Pops up the Swing UI. +
- +
-Collects PPID and file bytes. +
- +
-Sends an S7F3 RecipeSend message with the user’s inputs.+
  
 ===== Benefits ===== ===== Benefits =====
 +  * **Resilient in all environments**: Handles delays, network issues, and tool readiness problems gracefully.  
 +  * **Lightweight and efficient**: Uses non-blocking polling with minimal CPU usage.  
 +  * **Safe initialization**: Prevents null references and avoids premature listener setup.  
 +  * **User-friendly**:  
 +    - Clear log messages for troubleshooting.  
 +    - Safe and simple UI for recipe selection and transmission.
  
-Works seamlessly in both SIM and deployment modes. 
  
-No CPU churn (500 ms polling). 
  
-No premature null errors on deployment.+===== Full Code =====
  
-User-friendly: clear logs, safe cancel behavior, and popup UI for recipe send. +<code javascript>
- +
---- +
- +
-===== Full Code ===== +
-```javascript+
 // === Imports === // === Imports ===
 var TransSecsController      = Java.type("com.ergotech.transsecs.secs.TransSecsController"); var TransSecsController      = Java.type("com.ergotech.transsecs.secs.TransSecsController");
Line 82: Line 86:
 // We'll store our singleton UI+state under this key. // We'll store our singleton UI+state under this key.
 var KEY = "TransSECS.ScriptParamWindow"; var KEY = "TransSECS.ScriptParamWindow";
- 
  
 // --- Singleton state accessor --- // --- Singleton state accessor ---
Line 196: Line 199:
 } }
  
- +// --- Startup Trigger Main Loop --- 
-// --- Background host discovery --- +var r = new java.lang.Runnable() {    //Defines a background thread that will execute the startup logic.
-var r = new java.lang.Runnable() {+
     run: function() {     run: function() {
         var host = null;         var host = null;
         var count = 0;         var count = 0;
- +        while (host == null) {        //Polls the system every 50 ms to see if the TransSecsController (the Host object) has been created. 
-        // Wait until host is ready (deployment: quick; SIM: wait for toggle) +            Thread.sleep(50); 
-        while (host == null) { +            count++;                  // count and timeout check. Increments a counter each loop. After 100 iterations (≈ 5 seconds), stops waiting and logs a message that no host was found. 
-            Thread.sleep(500); +
-            count++;+
             host = TransSecsController.getSingleController();             host = TransSecsController.getSingleController();
- +            if (host == null && count % 10 == 0) {       //Every 10 loops (≈ 0.5 seconds), logs "Still waiting for host." for debugging/monitoring purposes. 
-            if (host == null && count % 10 == 0) { +                DataSource.logMessage("Startup Trigger: Still waiting for host."); 
-                DataSource.logMessage("Startup Trigger: Still waiting for host (toggle SIM→LIVE if needed)");+            } 
 +            if (count >= 100) { 
 +                DataSource.logMessage("Startup Trigger: Host did not connect after ~5 seconds. Stopping wait."); 
 +                break;
             }             }
         }         }
  
-        DataSource.logMessage("Startup Trigger: Host model " + host + " is ready after " + count + " checks."); +        if (host != null) {    //Once the host is found, it logs success and waits another 1 second to ensure the host is fully initialized. 
- +            DataSource.logMessage("Startup Trigger: Host model is ready."); 
-        // Delay: give project time to finish initialization +            Thread.sleep(1000); 
-        Thread.sleep(1000); +            host.addConnectionStatusListener(new ConnectionStatusListener() {   //Subscribes to connection status changes. When the status changes to 0 (connected), it triggers the UI builder (buildUI(host)) in the Swing UI thread. 
- +                connectionStatusChanged: function(connectionStatus, comment) { 
-        // Connection listener +                    if (connectionStatus == 0) { // Connected 
-        host.addConnectionStatusListener(new ConnectionStatusListener() { +                        SwingUtilities.invokeLater(function() {         //Ensures that the UI is built safely in the event dispatch thread, preventing concurrency issues. 
-            connectionStatusChanged: function(connectionStatus, comment) { +                            buildUI(host); 
-                DataSource.logMessage("ConnectionStatusListener: " + comment + " (" + connectionStatus + ")"); +                        });
-                if (connectionStatus == 0) { +
-                    try { +
-                        var h   = TransSecsController.getSingleController(); +
-                        var msg = h.getMessageBean("RecipeSend"); // or "S7F5" +
- +
-                        if (msg == null) { +
-                            DataSource.logMessage("ConnectionStatusListener: RecipeSend message bean not ready yet, skipping."); +
-                            return; +
-                        } +
- +
-                        var selection = requestParams().get(); +
-                        msg.setPPID(selection.get("ppid")); +
-                        msg.setPPBodyFormat(new SecsFormat10(selection.get("body"))); +
-                        msg.sendMessage(); +
- +
-                    } catch (e) { +
-                        print("Error in S7F3 handler script:\n" + e);+
                     }                     }
                 }                 }
-            } +            }); 
-        }); +            DataSource.logMessage("Startup Trigger: Connection Status Listener added."); 
- +        } else { 
-        DataSource.logMessage("Startup Trigger: Connection Status Listener added.");+            DataSource.logMessage("Startup Trigger: No host available after timeout. UI will not be shown."); 
 +        }
     }     }
 }; };
  
-// Start in a background thread (avoids blocking project load) +new Thread(r).start();   //Starts the thread to run this logic asynchronously so it does not block other operations. 
-new Thread(r).start();+</code> 
  
transsecs_host/startup_trigger_host_recipesend_ui.1755622417.txt.gz · Last modified: by amyw

Donate Powered by PHP Valid HTML5 Valid CSS Driven by DokuWiki