I'm trying to create a very simple Vision component with some event scripting.
I've got the component working but am trying to figure out how to populate the Event Description and Event Object Properties at the bottom of the scripting window.
I'm using an ActionAdapter to try to help me out by setting up a default script and populating the metadata, and I think what I'm probably missing is the ActionAdapter.setBuilderInfo()) method, but since it just takes a Map<String, Object> I'm really not sure what I need to supply to it to make it work as expected, or if this is even the right approach.
Anyone have any insight to offer to help me get this populated with information that would help my end users know what they're getting with these events?
Mine is pretty similar, or at least I can't see the difference, but how does it get the event description and event object parameters? Mine are still empty as in the screenshot.
So one key difference is that I diverted from the standard convention for the add/remove/get listener methods. After reviewing the docs I saw an overload that takes those method names, so I've changed it to this, but still no dice.
So that worked for the event description, and I thought I could easily figure out the parameter section from there, but I've tried a couple things and it's not obvious to me.
Do you know what magic key might fill out the Event Object Properties?
There's no dynamic way to add new event object properties, in a supported manner.
If you hold your nose... com.inductiveautomation.factorypmi.designer.eventhandling.ActionConfigPanel#EVENT_OBJECTS is a package-private hashmap String to String[].
If you got a reference to that field, you could add your own key/value (e.g. eventReceived as the key, your list of possible parameters for all of these events as the value). Then add keys in the format eventobj.eventReceived.property=My event object parameter, and things, again, might work. Your different events will all be assumed to receive the same parameters.
Agreed. I could put it on the books, but honestly I don't think it's going to buy you much compared to the "hold your nose" approach. I would consider your approach "safe" for the foreseeable future; we're pretty unlikely to refactor something this fundamental to Vision at this stage of the game; if we ever do, we'll surely replace it with an actual API.
For those who may be interested in this topic, here's the relevant code to do this unsupported thing that you should only do as a last resort.
This goes in the DesignerHook class; I put it in the onStartup() method. This implies that you've declared a dependency on the Vision module..
var visionSdk = (VisionDesignerInterface) context.getModule(VisionDesignerInterface.VISION_MODULE_ID);
// If the Vision module is installed, add our component to the palette
if (visionSdk != null) {
var palette = visionSdk.getPalette();
var group = palette.addGroup("Your Custom Components");
group.addPaletteItem(new JavaBeanPaletteItem(YourComponent.class));
try {
var actionConfigPanelClass = Class.forName("com.inductiveautomation.factorypmi.designer.eventhandling.ActionConfigPanel");
var eventObjectsField = actionConfigPanelClass.getDeclaredField("EVENT_OBJECTS");
boolean accessibility = eventObjectsField.canAccess(null);
eventObjectsField.setAccessible(true);
var eventObjects = (Map<String, String[]>) eventObjectsField.get(actionConfigPanelClass);
if (!eventObjects.containsKey("eventReceived")) {
eventObjects.put("eventReceived", new String[]{"source", "eventName", "eventData"});
}
eventObjectsField.setAccessible(accessibility);
} catch (Exception e) {
e.printStackTrace();
}
}