User Tools

Site Tools


pluginapi:xtensionclass

XTension Class: Managing Units

Your pipe for all communications to and from XTension is the XTension class. It has many helper functions to find the Unit class you’re looking for or to maintain the Interface in XTension. You can set callbacks for commands from XTension.

It also hosts an xData object that contains all the settings and info in your Edit Unit dialog where you can access this or set and change the User settings. This database is kept in sync with the values in the host program database so any changes made there will momentarily be synced to the plugin instance.

Before you interact with the XTension you must create an instance of the XTension class. Set any callbacks that you wish to have ready when the initial connection is made, and then call the startup() function. That will open the pipe to XTension, connect this plugin to it’s appropriate interface instance in XTension and get all it’s settings and any Units assigned to this interface. At that point the startup call will return and the class is ready to use. You can also check the class property “ready” after calling startup() to verify that everything has completely properly and the data structures and indexes are ready to use.

The simplest startup of the XTension pipe would be just:

  XTension = cXTension()
  XTension.startup()

Making Unit Subclasses

This references creating a class in the plugin to represent the Unit in XTension. This is not for creating new Units in XTension that will be covered later.

The XTension class maintains an index of xUnit subclasses that represent all the Units assigned to your interface. By default XTension will create an instance of it’s own xUnit parent class. It is often useful to subclass that to add the custm functionality that your Unit type will require. There are 2 ways to have a subclass be indexed instead of the default Unit parent class.

During the initial connection with XTension these will be called for every Unit currently assigned to this interface. Later if new Units are added to the interface either by the User or by sending the new unit command from the plugin these will also be called for that newly received data. That is why you must set this callback before calling the startup() function as by the time it has returned you’ve already received the database from XTension and it will be too late to make different subclasses for them.

onMakeNewUnit

You can register an “onMakeNewUnit” callback with XTension. This will be called whenever XTension receives a Unit from XTension that is not already indexed. It will pass you the xData object from the XTension database and based on the unit “tag” you can create and setup the appropriate Unit subclass and return it from the call. If no class, or if a None is returned from this call then XTension will create the default xUnit subclass for this Unit.

In this example the tag values are constants and should hold the same values as the entires in the unit definition declaration in the info,json file. All units must have a tag in order to be associated with their specific internal subclasses and interfaces and so forth as well as to maintain unique indexing paths. This also assumes you have created 2 subclasses of the xtUnit class called “wsTempUnit” and “wsRainUnit“

# these from “deviceTypes” block of the info.json file
tagTemperatureUnit          = “jamie.weatherslam.temperature”
tagRainUnit                 = “jamie.weatherslam.rain”
 
 
def makeNewUnit( theData):
  thisDeviceTag = theData.get( xtUnitKeyTag)
 
  if thisDeviceTag == tagTemperatureUnit:
    return wsTempUnit( theData)
  elif thisDeviceTag == tagRainUnit:
    return wsRainUnit( theData)
 
 
# MAIN
 
# create xtension interface class
XTension = cXTension()
 
# add our callback to make new units
XTension.onMakeNewUnit = makeNewUnit
 
 
# startup the connection
XTension.startup()

The second method to create Unit subclasses is to register individual creator methods with XTension keyed to the tag values. These will be called when XTension encounters a new Unit definition from XTension that is not already indexed in the plugin. Note that you must pass the xData object passed to your callback through to the creator of the new unit class in order for it to fill in it’s data and be useful.

# these from “deviceTypes” block of the info.json file
tagTemperatureUnit          = “jamie.weatherslam.temperature”
tagRainUnit                 = “jamie.weatherslam.rain”
 
def makeTempUnit( theData):
  theNewUnit = wsTempUnit( theData)
  # do any other custom setup on the class as needed
  return theNewUnit
 
def makeRainUnit( theData):
  theNewUnit = wsRainUnit( theData)
  # do any other custom setup on the class as needed
  return theNewUnit
 
 
# MAIN
 
# create the XTension subclass
XTension = cXTension()
 
# register our unit creation callbacks via the Tag
XTension.addUnitCreator( tagTemperatureUnit, makeTempUnit)
XTension.addUnitCreator( tagRainUnit, makeRainUnit)
 
# now startup the pipe
XTension.startup()

Getting Unit Class References

XTension maintains a couple of different indexes of the xtUnit subclasses that you can query to get the Unit you need. For example if you are writing a weather station plugin you might have defined a Unit type in the info.json file to hold temperature readings. Your receiver class in the plugin receives a new reading from the weather station for this Unit. In that data packet is also the unique address you’re using as Unit addresses and you know it’s a temperature reading so you know to use the tag that you defined for temperature Units. Using those two bits of information you can ask the XTension class for the xtUnit subclass with the tag of tagTempUnit and the Address of whatever was received. It will return the subclass to you if it exists or None if it does not exist. If you are going to automatically create Units in XTension then upon discovering that the return from this was None you should send the command to create the Unit.

Get Unit From Address:

This is the most common method for getting a unit reference in order to send it some updated data.

XTension.getUnitFromAddress( theTagConstant, theUnitAddress) returns an xtUnit subclass or None if the Unit does not exist.

alternatively you can also use keyword parameters and pass “tag” and “address” named parameters:

XTension.getUnitFromAddress( tag = theTagConstant, address = theUnitAddress)
myUnit = XTension.getUnitFromAddress( tag = tagTempUnit, address = uniqueAddressFromReceivedCommand)

Note that this function is also in the class as “getUnitWithAddress” as I kept typing the wrong one so I added both.

Get Unit From Name:

Units must have unique names and so they can also be pulled from the index by their Name. This is the name that the user has assigned to the Unit and it may have changed or change at any moment if the User decides to do so. To get to individual Units without knowing their tag and address you should generally use their Unique ID which is also indexed. See below

XTension.getUnitFromName( theName) returns an xtUnit subclass or None if no Unit is found.
myUnit = XTension.getUnitFromAddress( “Deck Temperature”)

Note that this function is also in the class as “getUnitWithName” as I never could remember the correct name so I added both.

Get Unit Ignoring Tag

If it is necessary to find a Unit where the Address is known but the Unit Tag/Type is not you, can use the getUnitIgnoringTag function. This will only return a single Unit so it will only be useful if you know that your Unit address is unique among all the Units assigned to this interface regardless of the Tag. If no unit is found None is returned

XTension.getUnitIgnoringTag( “the unit addres”) returns an xtUnit subclass or None if not found
myUnit = XTension.getUnitIgnoringTag( “gh4487”)

Get Unit Ignoring Address

It is possible that you will only have a single Unit of a particular tag type. If the Address is not know, or was assigned with auto since the address woudl not actually be important in this instance, you can use this command. It will return the first Unit with that tag. It returns only a single Unit and will stop searching as soon as it finds the tag.

XTension.getUnitIgnoringAddress( theUnitTag) returns an xtUnit subclass or None
myUnit = XTension.getUnitIgnoringAddress( “my unit tag”)

Get Units With Tags

Returns a list of all the Units with the tag or tags passed. You may pass a single tag or a list like object with more than one. If no Units are found this will return an empty list.

XTension.getUnitsWithTags( theUnitTagOfInterest) returns a list of Units or an empty list if not found
allTempHumUnits = XTension.getUnitsWithTags( [tagTempUnit, tagHumUnit])

Get Unit From Id

It is also possible to look up a Unit by it’s Unique Id. This is what is normally used in XTension to keep track of unit references so that if addresses or names change the Units are still where they were put initially.

XTension.getUnitFromId( theUniqueId) returns an xtUnit subclass or None if not found
myUnit = XTension.getUnitFromId( “12345667789”)

The Unit Index Dictionary

You may also directly access the dictionaries of Units in the XTension class. You should not alter this in any way except through the helper functions that will add or remove Units from them. If you or the user deletes a Unit it will be removed from all the indexes automatically.

XTension maintains 3 dictionaries as indexes of the currently assigned units.

XTension.unitIndexByAddress this is probably the least useful as the keys are concatenations of the tag and address so that units can be looked up by the regular getUnitFromAddress call.

XTension.unitIndexById keyed by the unique ID of the Unit subclass. Every Unit has a UniqueId property in the database.

XTension.unitIndexByName these values may change at any time if the User or other function changes the name of a Unit.


Next: XTension Class: Working With Settings

pluginapi/xtensionclass.txt · Last modified: 2023/06/11 16:07 by James Sentman