User Tools

Site Tools


pluginapi:infounits

Info.json: Unit Definition

It is not required that a plugin implement any Unit definitions. If this is left out then you will not be able to create any Units associated with the plugin instance. If this is present then when creating a new Unit and assigning the new unit to this plugin instance these unit types will be available in the edit unit window to select from. This is also where you would include any custom interfaces for the specific Edit Unit window or the 2 different sizes of specific control windows.

The deviceTypes block is a list of json dictionaries each with the keys necessary to describe a kind of Unit the plugin will use. All the below keys are to be used inside a dictionary in the list of “deviceTypes”

An example of what a unit definition block in the info.json file might look like:

“deviceTypes”:[
    {“name”:”Mantle Heating Element”, 
      “tag”:”jamie.chemcontrol.heater1”, 
      “info”:”shows the state of the heater and allows for manual control"
    },
    {“name”:”separator”},
    {“name”:”Mantle Temperature Setpoint”, 
      “tag”:”jamie.chemcontrol.setpoint”, 
      “info”:”The goal temperature of the mantle”, 
      “dimmable”:true,
      “suffix”:”°”,
      “format”:”#.##”.
       "editControls":[
         {"type":"groupbox","text":"Temperature:","bounds":[0,0,547,211]},
         {"key":"","type":"label","text":"Temperature Format:","align":"left","bounds":[20,36,138,20]},
         {"type":"popup","key":"xt.tempformat","action":"",
           "options":[["°F","f",true],["°C","c"]],
           "bounds":[170,35,80,20]
          }
        ]
     },
    {“name”:”Current Mantle Temperature”, 
      “tag”:”jamie.chemcontrol.temp”, 
      “info”:”the current measured temperature”,
      “dimmable”:true, 
      “receiveonly”:true, 
      “ignoreclicks”:true, 
      “hasQuery”:true,
      “suffix”:”°”,
      “format”:”#.##"
     }
]

This defines 3 Units each with a unique tag which is required and used internally for indexing and re-assigning this unit type popup and controlling which unit subclass you create in your plugin and so forth.

The popup is not sorted and will be presented in the order that you put them into the deviceTypes list. You can also add an entry with the name set to “separator” and no other settings to create a standard line separator in the popup. This can be useful to block different types of Unuits together when it makes more sense than just putting them all in alphabetical order. You can see a separator in the example above.

Required Keys:

name String - The name of this type of Unit. This is how the user will select the unit type from the popup when creating a new unit and how it will be displayed in the device type field of the unit list windows.
“name”:”Mantle Heating Element, Stage 1”,
tag String - The unique “tag” for this unit type. These must be unique in the entirty of XTension. This is the same idea as the tag that is required in the root level of the info.json file that is unique for this plugin. XTension reserves all tags starting with “xt.” it is recommended to use something like a path that has your name or company, the plugin device and then something that describes the unit. There is no length restriction on the tag but don’t get too creative. They do not necessarily need to be human readable with full sentences just something so that when debugging you can look at this value and know what it is.
“tag”:”jamie.chemcontrol.heater”,
info String - A short description also displayed when the unit type is selected in the Edit Unit dialog. This space is not dynamically sized so your description will get cut off if too long.
“info”:”Controls the state of the heater”,

Unit Behavior Keys:

These keys are not required and are not permanent for the Unit. They can be edited at any time by the user or set programattically from your plugin. These settings offer a default setup for the Unit when created by the User. If you create them automatically from inside your plugin you still need to include the appropriate keys for the behavior you wish.

hasQuery Boolean - defaults to false. If this is set then the interface will present an option to send a query where appropriate. If this is set then the contextual menu for the Unit in any list will also have an option to query the Unit.
“hasQuery”:true,
dimmable Boolean - defaults to false. With this set to true the Unit will be “dimmable” or just able to hold a numerical value. Without this the Unit will be discrete just being able to be turned on or off. Corresponds to the checkbox of the same name.
“dimmable”:true,
receiveonly Boolean - (note all lower case) defaults to false, if set to true then when the Unit is controlled in XTension it will not send any command to the plugin. This does not stop the user from controlling the Unit in XTension it just will not send any commands if you do. Corresponds to the checkbox of the same name on the Edit Unit dialog.
“receiveonly”:true,
ignoreclicks Boolean - (note all lower case) defaults to false. If this is set to true then the Unit’s interface will not easily allow the control of the Unit. For example the default control of a toggle control in list windows will just display the current value or on label rather than offer a control. The Unit may still be controlled through the advanced control windows or via a script. Usually you will want to combine both the receiveonly and ignoreclicks keys. Corresponds to the checkbox of the same name on the Edit Unit dialog.
“ignoreclicks”:true,
useMinMax Boolean - Sets or clears the checkbox of the same name in the Edit Unit dialog. Setting it to true enables the min and max values edit fields in the Advanced tab of the Edit Unit Dialog. Defaults to false. If a Unit receives a value or is controlled by the User or a script to a value over the max the max of the Unit will be set to the Max. if sending a command due to user or script action for a value above the max, only the max value will be sent, the same action is taken for the min value.
“useMinMax”:true,
min float - The value that will be filled into the Min value field if useMinMax is turned on. Defaults to 0.
“min”:15,
max float - The value that will be filled into the Max value field if useMinMax is turned on. Defaults to 100.
“max”: 275,
format String - The default value that will be inserted into the Format field in the Edit Unit dialog.
“format”:”#.##”,
suffix String - The default value that will be inserted into the suffix field on the display tab of the Edit Unit dialog.
“suffix”:”°F”,
allowColor Boolean - Defaults to false, if set to true then the standard color and color preset controls will be displayed for the Unit. May be combined with the allowColorTemp key below. Note that this setting cannot be changed by the User. There is no per-unit interface to this setting.
“allowColor”:true,
allowColorTemp Boolean - Defaults to false. If set to true then the standard color temperature and color preset controls will be displayed for the Unit. May be combined with the allowColor setting. Note that this setting cannot be changed by the user. There is no interface offered for this.
“allowColorTemp”:true,

Dimmable Type Selection:

There is a dimmable type popup for every dimmable unit that has options you can preset in the Unit definition section of the info.json file. The user can change this manually if they wish to. There are 3 valid settings: simple, simulated and smart. These are somewhat historical but can still have valid uses for modern units as they change the turn on behavior.

In general setting a unit to “dimmable” just means that it can accept a floating point value as opposed to a boolean value of on or off for a “discrete” or non-dimmable unit. For receive only devices like say a temperature sensor they should be set to dimmable but this setting would not matter as you do not send updates to a temperature sensor.

This also does not affect devices that never get sent an On command. For example an HVAC cooling setpoint makes no sense to send it an ON command so this setting will not affect it as this only changes the On command behavior and not the set value behavior which is what you would use for something like a thermostat.

Dimmable: Simple

In this case an ON command sends an On command to the plugin without any preset value or dim level or any other information. It assumes the device that has been sent the command will go to 100% and the value of the Unit in XTension will be set to 100% upon getting an ON through user interface or a script.

Dimmable: Simulated

The name is historical but the functionality is what most modern devices would expect. In this case XTension will keep track of the last value that it sent to the Unit and saves that as it’s preset value. When it next wants to send an On command it will also include this last preset value and assume the physical device that was controlled has returned to the last value it set. it’s up to the plugin to make use of the Value property of the On command and make sure this works properly or not. The last set color, color temperature and color mode are also sent in an On command. This should be the default of almost every lighting Unit.

Dimmable: Smart

This is entirely historical and should only be used if this behavior makes sense. This is from the age old time when some X10 devices were “smart” meaning that they would remember their last set value and return to that upon receiving an On command. If a Unit is set to this then when you tell it to turn on the value will NOT be included in the On command and XTension will assume the value of the unit has returned to what it remembers in it’s database as the preset value.

dimmableType Enumerated String - must be one of the following types: “simple”, “simulated” or “smart”
“dimmableType”:”simulated”,

Addressing Options:

Unit addressing internally to XTension is done by a path of information. The unique ID of the Interface/Plugin Instance that it is assigned to, then the “tag” that shows what type of unit it is, and finally the Address of the Unit as entered usually by the user in the Edit Unit dialog, or when automatically creating a Unit. On each interface only one Unit of each “tag” type can have the same address. There can only be 1 Unit of tag “mything.temperature” with the address of “1” but there can be an address of “1” for each type on that interface, a “mything.temperature” address “1”, a “mything.humidity” with address “1” an a “mything.lux” with address “1”.

It is not required to add any addressing information to the info.json file. If it is not specified then any new units the User creates will have the regular empty text field to fill in. Any Units you create automatically from the plugin are not affected and can have their addresses set any way you choose.

There are 2 values you can assign to the optional “address” key. If it is a JSON list of strings then the user will be presented with a popup menu with those options rather than an empty text field. This is only useful if there are a limited number of possibilities. It can also be the string “auto” in which case it will not be required that the User enter an address at all. When the Unit with an empty address is saved an automatically generated unique ID will be assigned to the Address and then the unit saved and indexed.

This last auto setting makes sense if the address is not really part of the system to find and work with the Unit inside the plugin. I have used this in places like for the Calendar plugin where the User may create any number of event search Units. It doesn’t make sense to force them to put the search string into the address or keep count of how many they are or something, so this lets them create any number of Units and not worry about it.

address String: “auto” - used when the User may create any number of units and a unique address would not be related to anything internal to the plugin where you would be looking the Unit up by address. Just walking the list of all the units of that type to process.
“address”:”auto”,


address JSON List of String - used where there are a limited number of selections for the Units to provide a popup menu rather than an empty address field.

“address”:[“1”, “2”, “3”, “4”, “5”, “6”],


or possibly something like:

“address”:[“UP”, “DOWN”, “LEFT”, “RIGHT”],

You can also add callbacks to the plugin by adding items to the contextual menu for the Unit. This is the same technique that you can use to add menu items to the contextual menu of the Interface itself. In this case the “menuHandlers” key is inside the deviceType dictionary rather than in the root of the info.json where they would be assigned to the Interface as a whole. Items added in this way are also given a button in the Advanced Controls (see dynamic interface section below) so the user can access these from the web remotes or via that mechanism as well as through the contextual menu. Note that there is no way to pass any information to plugin from these handlers. They are simply run with no parameters.

The data in this key is a json list of lists. Each of the inner lists has 2 items, first the name of the action as you wish it to appear in the menu, the human readable version, and the second is the name of the script handler callback that will be run when the user selects this.

Use the Unit parent class “addScriptHandler” command to register a callback to be run when that action name is run by the user.

“menuHandlers”:[[“Open The Door”, “openTheDoor”], [“Knock On the Door”, “knockOnTheDoor”], [“Run Away”, “runAway”], ...]

Dynamic Interfaces:

There are 3 places you can create dynamic interfaces specific to a Unit type inside these definitions. The most commonly used one is the “editControls” block in the example above. These controls are shown in the first tab of the Edit Unit Dialog. The Height is adjusted and the window is either resized or a scrollbar is displayed to the user if there is not enough space. While these can be generated by hand it would be much easier to use the Dynamic Interface Builder app.

The “Small Controls” window can be added to this with the key of “smallControls” and the “Advanced Controls” can be added to this with the key of “controls” These are the Popup controls that appear when you click on the icon of a Unit in any of the lists or displays.

The small controls and advanced controls may be toggled between by the user by clicking the disclosure triangle/carrot just below the name of the Unit in the popup. The same interface is shown in the application as well as created in the web remotes. The selection of small or advanced is remembered for the Unit and the same will be presented first the next time you open this window.

The Edit Unit Controls

The “editControls” key will be rendered on the first page of the Edit Unit dialog. The width of the control pane is fixed to 586px but the height can be anything reasonable. The Edit unit window will resize itself to accommodate the extra height and if there is not enough screen display room then a scrollbar will be presented to the user.

The dynamic content is placed below the Unit Scripts groupbox and runs to the bottom of the tab panel section which ends above the Cancel/Apply/Save buttons.

The spacing left right and top and bottom are taken care of by the program so when creating your interfaces in the Interface Builder app please use the entire window there. You can see in this example that I did not bring my group boxes all the way to the edge and so they do not line up properly with the rest of the windows content. I’ll be adding that to my list of stuff to get around to fixing momentarily…

This is generally the place you would put settings that need to be saved in the data object for this Unit. They will be available to your plugin via the UnitSubclass.data object which is an instance of the xData class. You can read and write to this as it will always be in sync with the database in XTension. You can also set callbacks to any of the keys you use or that are used by XTension to know when the User has changed those settings while the plugin is running. That information is documented in the xData documentation.

If the plugin is running you can also create buttons here that will send a scripting command event to the plugin. If you have a handler registered for the action name you define in the Interface Builder then it will be run and sent all the settings from the screen as a keyed dictionary. This way you can take into account any changes the user has made to any of the settings on the page, but also still access the currently live saved data in the xData class for the Unit. So it would be possible to have turn on, turn off buttons on this page, though it would be a very questionable design choice.

The Small Controls Window

An example of the small control window. By default this is what is in the window. Any controls you create with the “smallControls” tag will be added below the block/edit buttons but before the Done button. Note the disclosure triangle control just below the Unit Name on the right.

The controls segment width is limited to 200px. There is no height limit. The window in the interface builder app is already set to this width, do not change the width, but make it any height you need to in order to display the controls you wish to here.

In the appplication they are shown in a dark “hud” styled partially transparent window. Something similar is done in the Web Remote.

The Advanced Controls Window

An example of the Advanced Controls window from the Haiku Flans plugin. It offers more default controls and information as well as any of the dynamic elements you have added to the Unit type.

This window is slightly wider than the simple controls window. The dynamic controls portion has a fixed width of 272px. The controls will automatically be placed inside the grouping rectangle with the proper spacing on the sides. In the Interface Builder use the entire space to the edges of the window there as you do not have to honor the normal spacing, this will be done for you.

In this example the “requiresInterface” key has been turned on (this is a checkbox/switch setting in the Interface Builder) and since the interface these units are assigned to is not running or enabled at the moment you cannot change these settings. For changing settings that shoudli be saved when the interface is not running it’s generally the right thing to do to put those on the Edit Unit dynamic interface portion of the Edit Unit dialog and not here.


Next: interfacebuilder

pluginapi/infounits.txt · Last modified: 2023/06/11 14:29 by James Sentman