Announcements
Autodesk Community will be read-only between April 26 and April 27 as we complete essential maintenance. We will remove this banner once completed. Thanks for your understanding

Palette Communication Failure: Python->JS (sendInfoToHTML) Messages Not Received by JS Handler

samaksh_khandelwal
Community Visitor Community Visitor
106 Views
0 Replies
Message 1 of 1

Palette Communication Failure: Python->JS (sendInfoToHTML) Messages Not Received by JS Handler

samaksh_khandelwal
Community Visitor
Community Visitor

I am developing an Add-In that uses a standard HTML Palette (adsk.core.Palettes.add) for user interaction. The Add-In requires bi-directional communication:

  1. JavaScript -> Python: Sending user actions/data from the palette JS to the Python backend using window.adsk.fusionSendData(action, data).

  2. Python -> JavaScript: Sending status updates, results, or commands from the Python backend to the palette JS using palette.sendInfoToHTML(action, data).

While developing, I've encountered a persistent issue where communication from Python to JavaScript appears to be broken or unreliable. Messages sent using palette.sendInfoToHTML from Python are logged as completing successfully on the Python side, but the corresponding window.fusionJavaScriptHandler.handle function in JavaScript is never invoked for these messages.

Interestingly, communication from JavaScript to Python seems partially functional, although I sometimes observe duplicate events or spurious 'response' events being received by my Python HTMLEventHandler.notify method immediately after a valid event from JavaScript.

The primary symptom, however, is the failure of Python-to-JavaScript messaging, preventing UI updates, status reporting, and result display within the palette.

To isolate the issue, I created a minimal test Add-In:

Observed Behavior with Minimal Test:

  • Python receives the html_ready signal successfully.

  • Python attempts to send py_ack_ready back to JS - Python logs show sendInfoToHTML completed, but JS logs/UI never show receipt of py_ack_ready.

  • Clicking "Send PING" successfully sends ping from JS to Python. Python logs receipt.

  • Python attempts to send pong back to JS - Python logs show sendInfoToHTML completed, but JS logs/UI never show receipt of pong.

Could this indicate a potential issue with the palette.sendInfoToHTML -> window.fusionJavaScriptHandler.handle communication bridge in this version of Fusion 360 ( installed March 25 2025 ) on Mac? 

 

Thank you for any assistance.

 

<!DOCTYPE html>
<html>
<head><title>Minimal Test</title></head>
<body>
    <h3>Minimal Test</h3>
    <button id="pingButton">Send PING</button>
    <p>Status: <span id="status">Loading...</span></p>
    <p>Py Response: <span id="response">N/A</span></p>
    <script>
        const statusElem = document.getElementById('status');
        const responseElem = document.getElementById('response');
        function logJs(msg) { console.log(`JS: ${msg}`); statusElem.textContent = msg; }

        if (window.fusionJavaScriptHandler) {
             if (!window.fusionJavaScriptHandler.isMinimalHandlerAssigned_XYZ) {
                logJs("Assigning JS handler...");
                window.fusionJavaScriptHandler.handle = function (action, dataStr) {
                    logJs(`Handler called! Action: ${action}`); // *** THIS LOG IS NOT APPEARING for 'pong' or 'py_ack_ready' ***
                    responseElem.textContent = `Action=${action}, Data=${dataStr}`;
                };
                window.fusionJavaScriptHandler.isMinimalHandlerAssigned_XYZ = true;
                logJs("JS Handler assigned.");
                try {
                    logJs("Sending 'html_ready'...");
                    window.adsk.fusionSendData('html_ready', '{}'); // Signal Python
                    logJs("'html_ready' sent.");
                } catch (e) { logJs("Error sending 'html_ready'"); console.error(e); }
            }
        } else { logJs("CRITICAL: fusionJavaScriptHandler not found!"); }

        document.getElementById('pingButton').addEventListener('click', () => {
            logJs("Ping clicked. Sending 'ping'...");
            try {
                 window.adsk.fusionSendData('ping', '{}');
                 logJs("'ping' sent.");
            } catch (e) { logJs("Error sending 'ping'"); console.error(e); }
        });
        logJs("Script loaded.");
    </script>
</body>
</html>


##################### PYTHON STARTS HERE  #############


import adsk.core
import adsk.fusion
import traceback
import json

_app = None
_ui = None
_handlers = []
_palette = None
_palette_id = 'minimal'
_html_is_ready = False

def log_py(message): print(f"PY LOG: {message}")

def send_to_js_minimal(action, data={}):
    global _palette, _html_is_ready
    if not _html_is_ready:
        log_py(f"PY: HTML not ready, discarding {action}")
        return
    if _palette:
        try:
            payload_str = json.dumps(data)
            log_py(f"PY: Attempting sendInfoToHTML: Action='{action}'")
            _palette.sendInfoToHTML(action, payload_str)
            log_py(f"PY: sendInfoToHTML completed for '{action}'.")
        except Exception as e:
            log_py(f"PY ERROR sending '{action}': {e}")
            log_py(traceback.format_exc())
    else: log_py("PY ERROR: Palette object lost.")

class MinimalHTMLEventHandler(adsk.core.HTMLEventHandler):
    def __init__(self): super().__init__()
    def notify(self, args: adsk.core.HTMLEventArgs):
        global _html_is_ready
        action = "ERR"; data = "ERR"
        try:
            action = args.action; data = args.data
            log_py(f"PY Received: Action='{action}', Data='{data[:50]}...'")

            if action == 'html_ready':
                log_py("PY: HTML is ready!")
                _html_is_ready = True
                # Attempt to send an immediate response after ready
                send_to_js_minimal('py_ack_ready', {'status': 'Python Acknowledged Ready'})
                return

            if action == 'ping':
                 log_py("PY: Received PING, sending PONG...")
                 send_to_js_minimal('pong', {'reply': 'PONG from Python'})

            # Ignore spurious response if it occurs
            if action == 'response':
                 log_py("PY: Ignoring spurious 'response'.")
                 return

        except Exception as e:
            log_py(f"PY ERROR in notify for action '{action}': {e}")
            log_py(traceback.format_exc())

def run(context):
    global _ui, _app, _palette, _handlers, _html_is_ready
    try:
        _html_is_ready = False # Reset flag
        _app = adsk.core.Application.get(); _ui = _app.userInterface; _handlers = []
        log_py("Minimal Add-In Starting...")
        palettes = _ui.palettes; _palette = palettes.itemById(_palette_id)
        if _palette: _palette.deleteMe(); _palette = None # Force recreation
        _palette = palettes.add(_palette_id, 'Minimal Test', 'resources/test_palette.html', True, True, True, 300, 200)
        if not _palette: log_py("PY ERROR: Failed to create palette."); return
        onHTMLEvent = MinimalHTMLEventHandler(); _palette.incomingFromHTML.add(onHTMLEvent); _handlers.append(onHTMLEvent)
        _palette.isVisible = True
        log_py("Minimal Add-In Running. Waiting for html_ready...")
    except Exception as e: log_py(f"PY ERROR during run: {e}"); log_py(traceback.format_exc())

def stop(context):
    global _ui, _handlers, _palette, _palette_id, _html_is_ready
    log_py("Minimal Add-In Stopping...")
    _html_is_ready = False
    if _ui:
         palette = _ui.palettes.itemById(_palette_id)
         if palette: palette.deleteMe()
    _handlers = []; _palette = None; log_py("Minimal Add-In Stopped.")

 

0 Likes
107 Views
0 Replies
Replies (0)