=====Plugin API: File Structure=====
====Folder Name====
An Xtension plugin is a folder or a bundle. The name must end with the “.isf” suffix so that XTension will recognize the folder or bundle as a plugin. The name should be unique and follow something like a bundle naming convention. So don’t just name your plugin “insteon.isf” as thats the built in XTension plugin naming convention. XTension reserves all non-bundle naming plugin names. While the exact layout of the names is up to you you should use a path that contains your name or company name and then the plugin type so that the file can be easily recognized as to what it is by a user and also that it will always be unique. “james_insteon.isf” or “james.insteon.isf” are all acceptable.
====Minimum Requirements====
At the very least the plugin folder must contain the info.json file that describes the plugin and the units that it will create and the main script file or executable that will be executed and passed the setup info from XTension. You can also include any other support files or python includes that are necessary for your plugin to run.
====Python Requirements====
At this time the plugin support files will only run in python 2.7. Python 2.7 is included in OSX so this is the best language to use as it won’t require that you embed the entire python 3 runtime into the plugin or require the user to install python 3 first.
If your plugin needs python modules that are not available by default on OSX best practice is to include them alongside the plugin files. You can usually do this by making a copy of the needed library into the plugin folder. I would recommend using pip to install the package onto your development mac. Then going to python’s site packages folder and getting the installed folder from there. You’ll find the site packets folder on OSX in: /Library/Python/2.7/site-packages any modules you have installed will be there. Only the actual module named folder is necessary to be copied. You will not need the distribution info or the .egg files or other support folders. Not all plugins folders are obvious from their names however, and some create more than one folder. It’s best to look at the folder before and after doing the module install so that you are sure what you need to copy. Once the files are copied to the plugin folder use pip to uninstall them properly from the system and make sure that your plugin still runs.
Please verify that the licenses of any modules you are including allow you to do so.
Lastly for Python you should pre-compile your python scripts so that you can include both the .py and .pyc files. This makes sure that the plugin folder doesn’t actually change it’s contents when you run it. If we are able to code sign a plugin file and python creates that file in the folder after it’s signed and verified then that will break the code signature and could result in a message from OSX about the application being corrupt or damaged.
===XTension Finds New Plugins===
Plugin installation is discussed on the [[http://machomeautomation.com/doku.php/plugins#installing_and_un-installing_plugins|first page of the plugin docs]].
It is not necessary to quit and restart XTension to have it discover new plugins. The plugin search locations are rescanned whenever the New Interface dialog is opened so your new plugin should be available in the list as soon as it’s in one of those locations and the user opens the window to create a new interface. If a New Interface dialog is already open it’s popup is not refreshed and would need to be closed and re-opened in order to have the new plugin be listed.
During development it may be necessary to open the edit interface dialog to get changes to a plugins info.json file to be reloaded.
====XTension Standard Python Includes====
XTension provides 2 python files that will be necessary for any plugin. If your plugin requires a specific version of the plugin includes you can simply copy them into the same folder with your application. Or to save space you can load them from inside the XTension app via the following code. If changes are ever made to the existing include files that could potentially break previous plugins I will increment the version and continue to include both versions inside XTension. You can link to the “current” version or to a specific version in your plugin code.
Upon launch XTension will create a file in it’s ~/Documents/XTension\ Support folder that contains the full path to the folder inside of XTension that contains the required modules. You can load this at the start of your plugin and include the files before starting up the connection to XTension. You can see the example plugin file for this or use the source below:
#
# Importing Necessary XTension Connection Modules
#
# normally you can just include this small block of code as is unless you need to control
# specifically which plugin module version you need to include
#
# import the current version of the XTension python plugin modules by setting our path to the
# contents of the helper file in the XTension Support folder
# if you have had to make changes to the xtension support modules or wish to guarente that
# a specific version is included with your plugin then you may instead include the 2 support
# files in the same folder with your application. You would comment out the following up
# until the instructions below for how to include them in that case.
# doing it this way does guarente that you're using the versions that are most compatible
# with the currently running XTension version however and so this is recommended. If there
# are any changes to the higher level interface to XTension that would potentially cause
# problems for a plugin then the previous version will be preserved and you can just change the
# link to go direct and not through /current
#
from os.path import expanduser
userHomePath = expanduser( '~')
del expanduser
# XTension will always create this file in the XTension Support folder when it starts up
# with a path to the python support files that we need to add to the search path so
# this program can load them.
pluginLocationFile = open( userHomePath + '/Documents/XTension Support/.python_include_path.txt', 'r')
if pluginLocationFile.mode == 'r':
pluginLocationPath = pluginLocationFile.read()
pluginLocationFile.close
else:
print( "Error opening the XTension Plugin Includes path file, cannot continue")
sys.exit()
#
# the pluginLocationPath will need either a specific version number or /current appended
# as the path is to the folder that contains the different version folders. To access
# the current most recent version as included in the currently running XTension append "/current"
# to access a specific version append that something like "/1.2"
#
pluginLocationPath += "/current"
sys.path.append( pluginLocationPath )
from xtension_plugin.xtension_constants import *
from xtension_plugin.xtension_plugin import *
====Custom Script Handlers====
Just like the user can send custom commands to the plugin via the tell xUnit “name” to doAPluginFunction() your plugin code can send a command to execute a handler in the interface or unit’s On script. In order to make these easier for the user to insert properly you can add any number of them to the “Insert...” toolbar item in the Edit Script window. They will be added to the list of XTension defaults when editing the On script of a plugin unit.
Create a text file that contains the handler definition for AppleScript and enough comments to describe what it does and how to use it. Then include a structure similar to this in the unit definition portion of the info.json file. You can include any number of handler definitions for units or for the Interface script.
At this moment only AppleScript handlers are supported, but in the future if we adopt other languages there will be the opportunity to include specific include information for those as well.
An example of what you might include in the info.json file. This is from the VeraUI7 plugin:
"appleScriptHandlers”:[
{"handler":"centralScene",
"name":"Central Scene Handler",
"desc":"Button index and gesture type will be sent to this handler.",
"file":"centralscene_handler_applescript.txt"}
]
since the AppleScriptHandlers is an array you can include any number of handlers there. The key “file” should contain the name of the text file that contains the handler prototype.
To add the same for the Edit Interface Script dialog include that same structure but at the root level of the JSON file rather than inside a unit definition.
====Icon Support====
If your plugin includes a folder named “Icons” then those icons will be loaded along with your plugin and be made available as unit icons inside the application. You can include custom icon images for your units in this way. Use the defaultOnIcon and defaultOffIcon keys into the info,json file to assign any icons as the default.
Icon file format should be png with a mask though jpeg and gif files are also supported.
Note, that this is unimplemented as of XTension 9.4.8.\\
\\
Previous:[[:plugins|]] | NEXT:[[:plugins:02_infojson|]]
====History====
* 7/6/2018 updated for plugin API 2.0