Error when calling sendInfoToHTML

mycad2016D8W4P
Enthusiast

Error when calling sendInfoToHTML

mycad2016D8W4P
Enthusiast
Enthusiast

I met an error when calling sendInfoToHTML.

 

Here is my code:

 

import adsk.core, adsk.fusion, traceback

myPalette = 'myPalette'

# global set of event handlers to keep them referenced for the duration of the command
handlers = []
ui = None

def run(context):
    ui = None
    try:
        app = adsk.core.Application.get()
        global ui
        ui = app.userInterface
            
        palette = ui.palettes.itemById(myPalette)
        if palette:
            palette.deleteMe()
            
        palette = ui.palettes.add(myPalette, 'My Palette', 'palette.html', True, True, True, 300, 200)

        # Dock the palette to the right side of Fusion window.
        palette.dockingState = adsk.core.PaletteDockingStates.PaletteDockStateRight
        
        palette.sendInfoToHTML('send', 'some info')
    except:
        if ui:
            ui.messageBox('AddIn Start Failed: {}'.format(traceback.format_exc()))

def stop(context):
    ui = None
    try:
        app = adsk.core.Application.get()
        ui = app.userInterface
            
        palette = ui.palettes.itemById(myPalette)
        if palette:
            palette.deleteMe()
    except:
        if ui:
            ui.messageBox('AddIn Stop Failed: {}'.format(traceback.format_exc()))
<!DOCTYPE html>
<html>
    <head>
    </head>
    <body>
        <p id='p1'>Click the button below or use the "Send info to HTML" command in the ADD-INS panel.</p>
        <button type='button' onclick='sendInfoToFusion()'>Click to send info to Fusion</button> 
        <br /><br />
    </body>
    <script>
        function sendInfoToFusion(){
            var args = {
                arg1 : "Sample argument 1",
                arg2 : "Sample argument 2"
            };
            adsk.fusionSendData('send', JSON.stringify(args));
        }

        window.fusionJavaScriptHandler = {handle: function(action, data){
            try {
                if (action == 'send') {
					// Update a paragraph with the data passed in.
					document.getElementById('p1').innerHTML = data;
				}
				else if (action == 'debugger') {
                    debugger;
				}
				else {
					return 'Unexpected command type: ' + action;
                }
            } catch (e) {
                console.log(e);
                console.log('exception caught with command: ' + action + ', data: ' + data);
            }
            return 'OK';
        }};
    </script>
</html>
0 Likes
Reply
529 Views
3 Replies
Replies (3)

marshaltu
Autodesk
Autodesk

Hello,

 

It should be timing issue. The html wasn't loaded completely when you sent data to it. One approach would be to do that asynchronously by worker thread and custom event. The sample I posted in the following thread will demo how to create a worker thread and use custom event.

 

https://forums.autodesk.com/t5/fusion-360-api-and-scripts/can-t-get-javascript-add-in-to-communicate...

 

Thanks,

Marshal



Marshal Tu
Fusion Developer
>
0 Likes

mycad2016D8W4P
Enthusiast
Enthusiast

Thanks. The approach could work but a little complicated. The code in bold below still got the error.

 

import adsk.core, adsk.fusion, traceback, json, threading, random

commandIdOnQAT = 'demoCommandOnQAT'
myPalette = 'myPalette'

# global set of event handlers to keep them referenced for the duration of the command
handlers = []
ui = None
stopFlag = None
myCustomEvent = 'MyCustomEventId'
customEvent = None


# The event handler that responds to the custom event being fired.
class ThreadEventHandler(adsk.core.CustomEventHandler):
    def __init__(self):
        super().__init__()
    def notify(self, args):
        try:
            # Make sure a command isn't running before changes are made.
            if ui.activeCommand != 'SelectCommand':
                ui.commandDefinitions.itemById('SelectCommand').execute()
            
            palette = ui.palettes.itemById(myPalette)
            cmds = []
            for cmd in ui.commandDefinitions:
                cmds.append({'name': cmd.name})
            data = json.dumps(cmds)
            palette.sendInfoToHTML('send', data)
            #palette.sendInfoToHTML('send', 'some info')
        except:
            if ui:
                ui.messageBox('Failed:\n{}'.format(traceback.format_exc()))


# The class for the new thread.
class MyThread(threading.Thread):
    def __init__(self, event):
        threading.Thread.__init__(self)
        self.stopped = event

    def run(self):
        # Every five seconds fire a custom event, passing a random number.
        while not self.stopped.wait(1):
            args = {'Length': random.randint(1, 15)}
            app = adsk.core.Application.get()
            app.fireCustomEvent(myCustomEvent, json.dumps(args))
            stopFlag.set()
            
def run(context):
    ui = None
    try:
        app = adsk.core.Application.get()
        global ui
        ui = app.userInterface
            
        palette = ui.palettes.itemById(myPalette)
        if palette:
            palette.deleteMe()
            
        palette = ui.palettes.add(myPalette, 'My Palette', 'palette.html', True, True, True, 300, 200)

        # Dock the palette to the right side of Fusion window.
        palette.dockingState = adsk.core.PaletteDockingStates.PaletteDockStateRight
        
        #palette.sendInfoToHTML('send', 'test')
        
        # Register the custom event and connect the handler.
        global customEvent
        customEvent = app.registerCustomEvent(myCustomEvent)
        onThreadEvent = ThreadEventHandler()
        customEvent.add(onThreadEvent)
        handlers.append(onThreadEvent)

        # Create a new thread for the other processing.        
        global stopFlag        
        stopFlag = threading.Event()
        myThread = MyThread(stopFlag)
        myThread.start()
    except:
        if ui:
            ui.messageBox('AddIn Start Failed: {}'.format(traceback.format_exc()))

def stop(context):
    ui = None
    try:
        app = adsk.core.Application.get()
        ui = app.userInterface
        
        if handlers.count:
            customEvent.remove(handlers[0])
        stopFlag.set() 
        app.unregisterCustomEvent(myCustomEvent)
        ui.messageBox('Stop addin')
        
        palette = ui.palettes.itemById(myPalette)
        if palette:
            palette.deleteMe()
    except:
        if ui:
            ui.messageBox('AddIn Stop Failed: {}'.format(traceback.format_exc()))
0 Likes

marshaltu
Autodesk
Autodesk

Hello,

 

It looked there was an issue to handle single quote and double quote during sending data to html in the API. We will fix the issue. Meanwhile the workaround for you would be to encode data before sending it and decode it after receiving it.

 

import adsk.core, adsk.fusion, traceback, json, threading, random, base64

commandIdOnQAT = 'demoCommandOnQAT'
myPalette = 'myPalette'

# global set of event handlers to keep them referenced for the duration of the command
handlers = []
ui = None
stopFlag = None
myCustomEvent = 'MyCustomEventId'
customEvent = None


# The event handler that responds to the custom event being fired.
class ThreadEventHandler(adsk.core.CustomEventHandler):
    def __init__(self):
        super().__init__()
    def notify(self, args):
        try:
            # Make sure a command isn't running before changes are made.
            if ui.activeCommand != 'SelectCommand':
                ui.commandDefinitions.itemById('SelectCommand').execute()
            
            palette = ui.palettes.itemById(myPalette)
            cmds = []
            for cmd in ui.commandDefinitions:
                cmds.append({'name': cmd.name})
            data = json.dumps(cmds)
            encoded_str = base64.b64encode(data.encode(errors='ignore'))
            data = encoded_str.decode(encoding='utf-8')
            palette.sendInfoToHTML('send', data)
            #palette.sendInfoToHTML('send', 'some info')
        except:
            if ui:
                ui.messageBox('Failed:\n{}'.format(traceback.format_exc()))
<!DOCTYPE html>
<html>
    <head>
    </head>
    <body>
        <p id='p1'>Click the button below or use the "Send info to HTML" command in the ADD-INS panel.</p>
        <button type='button' onclick='sendInfoToFusion()'>Click to send info to Fusion</button> 
        <br /><br />
    </body>
    <script>
        function sendInfoToFusion(){
            var args = {
                arg1 : "Sample argument 1",
                arg2 : "Sample argument 2"
            };
            adsk.fusionSendData('send', JSON.stringify(args));
        }

        window.fusionJavaScriptHandler = {handle: function(action, data){
            try {
                if (action == 'send') {
					// Update a paragraph with the data passed in.
					document.getElementById('p1').innerHTML = window.atob(data);
				}
				else if (action == 'debugger') {
                    debugger;
				}
				else {
					return 'Unexpected command type: ' + action;
                }
            } catch (e) {
                console.log(e);
                console.log('exception caught with command: ' + action + ', data: ' + data);
            }
            return 'OK';
        }};
    </script>
</html>

 

Thanks,

Marshal 



Marshal Tu
Fusion Developer
>
0 Likes