User Tools

Site Tools


pluginapi:xtensionclasssettings

XTension Class: Working With Settings

The XTension class holds a reference to an xData object that is kept in sync with the database in XTension. In this database are all the settings from XTension and some other useful information bits that you can access. It is possible to set values into this for local persistent storage but do so via the set xtension data commands below and not by directly accessing the data class.

At any point you can see everything in the settings being passed to the plugin by right clicking on the interface in the interface list window while holding down the option key. That exposes more debug choices in the menu. Then select “log debug data” and the entirety of the data stored for that interface will be written to the log in key=value pairs.

In addition to any data that XTension adds or is part of the non-dynamic interface all of your user interface keys setup in the dynamic interface portion of the interface setup will be here. You’ll want to create constants for the keys you used when setting it up via the Interface Builder so that you can pull the values out as needed. An additional feature of the xData class is that you can subscribe to specific keys and get a callback just before their value is changed when syncing from XTension.

For more info on getting a callback when a setting value has changed see the forthcoming documentation on the xData object.

Accessing your info.json File:

The entirety of your info.json file is loaded by the plugin at startup and is available to you, This is loaded when you init the XTension class and can be accessed through the dictionary at XTension.info This is loaded directly from the JSON and so is a standard python keyed dictionary and NOT an xData class.

 ThisPluginDescription = XTension.info[ “Desc”]

So keep in mind that there is no reason to limit the contents of the info.json file to just what is required or used by XTension. If there are some structures that you would like to put there and retrieve once the program is running thats fine. You cannot write back to the info.json file however.

Info Available at the Class Level

Some data points from the settings and info.json file are made available at the class level because they are so often used. Here are some of the properties you’ll find useful in the XTension class that you do not need to read from the info file or the settings data object.

debugMode boolean - will be true if additional logging is requested
if XTension.debugMode:
  XTension.writeLog( “lots more info!”)
ready Boolean - Set to true after the initial connection and the reception of our Settings and Units. If this is ever false then something has gone badly wrong and the plugin should assume it does not have a valid connection to XTension.
isShuttingDown Boolean - Normally false, this is set to true if XTension has asked this plugin instance to shut down and quit. You can check this value in a loop for instance so that you stop looping when XTension wants us to quit. You can also add a command handler for the shutdown command to get an event when we must quit. XTension will either immediately force you to quit, or wait up to 30 seconds for all it’s plugin instances to exit cleanly if the user has selected that in the preferences.

If you wish to shut everything down inside of the plugin for whatever reason, like forcing a brand new plugin instance to be created to try to get that USB device again, you can use the call to doShutdown() takes no parameters, works like XTension.doShutdown() all the normal shutdown subscribers will be called and the isShuttingDown set to true. When the plugin quits it will be an unrequested quit, so XTension will wait 5 seconds or so and start to try to restart the plugin as a clean instance.
interfaceName String - The name the user has set for this interface. This is available in the XTension class as soon as it has received it’s settings data and will be kept up to date if the user changes the name of the interface. Useful when creating new units so that you can give them a name that links them with this interface for the user to find more easily. Also can be added to log messages or other informational displays.
  XTension.writeLog( f’my interface name is: {XTension.interfaceName})
interfaceId String - a unique string that will not change for this interface instance. Is useful if you need to save data specifically related to this interface into units that might be shared via multiple interfaces or otherwise need something that will always be unique to this isntance of a plugin. This should be treated as an opaque string. At the moment it’s numerical but might change to a true UUID in the future.
  XTension.writeLog( f’This Interfaces Unique ID is: {XTension.uniqueId})
rootDatabaseId String - Assigned when a new database is created in XTension. This is not persistent or connected to the serial number. It is just a unique ID that the database has so that if you need something to delineate between different XTension installs possibly on the same network you can use this.
XTension.writeLog( f’The Unique ID of this database is: {XTension.rootDatabaseId})

Keys into the Settings Object

Much more data is available in the xData object at XTension.settings which is all the user interface data along with many useful things added by the program itself to aid your plugin in finding things that might be helpful and knowing about other user settings that might affect what you do. Most of these will have keys defined in the xtension_constants.py file.

You can get any value with the .get() function of the xData object. This is not the same as the overridden regular dictionary accessor that powerers the [] selector. Do not use the regular doctionary selector. Use the .get method.

Pass the key to the get method and an optional second parameter that is the default if there is no key by that name. If the default is not specified and there is no key None is returned.

myValue = XTension.settings.get( myKeyAsSetupInInterfaceBuilder, “some default to return”)
xtKeyXTensionBuild ‘build' Integer - The build number of XTension currently running. This is like our “vers” data from the info.json file. It will only ever increase and it is the easiest way to check to see if a newer version of XTension than the previous one is running.
XTension.settings.get( xtKeyXTensionBuild)
xtKeyCertificatePath ‘CertPath’ String - if you need to use the XTension created self signed certificate or even possibly a signed certificate the user has installed the path to the currently valid one will be at this key.
xtKeyDatabasePath ‘databasePath’ String - the path to the currently active database. If you need to create a folder to load user provided info or images or data or a place that is safe to store info that is valid across all your plugin instances this is where to create that folder.
xtKeyFolderPath ‘isf’ String the full path to the folder you are running out of. You should not make any changes to your folders structure while running as this will break the code signing and the Mac will think that the application has been damaged or that it’s infected with malware. This is for loading external resources that you might not be able to get from a relative path for whatever reason. If you need to write information beyond what can be stored in the XTension.settings object please create a folder in the database via the xtKeyDatabasePath that is some descriptive name concatenated with your plugin unique ID so that it does not overlap any other instances of the plugin running.
xtkeyLocalAddress ‘localAddress’ String the local IP address that XTension thinks the machine is running on. People with very complex networking setups with VPNs or separate subnets for IOT devices and so forth can find themselves with incoming connections that do not work properly as the system does not know what interface to bind the port to. This tells you what XTension thinks is the main interface of the machine if needed. Of course an interface can be provided to the user to ask what interface to bind to if that turns out to be necessary for someone.
xtKeyLongWeekdayNames ‘longDayNames’ String, a comma separated list of the days of the week. Sometimes the localization in python can be wrong or incomplete so if you need full length day names for displays or messages you can pull the correct one out of this value.
longDayNames = Sunday,Monday,Tuesday,Wednesday,Thursday,Friday,Saturday
xtKeyShortWeekdayNames ’shortDayNames’ String a comma separated list of the days of the ween in abbreviated format. Sometimes the localization of python can be wrong or incomplete so if you need abbreviated weekday names you can use this list.
shortDayNames = Sun,Mon,Tue,Wed,Thu,Fri,Sat
xtKeyOnColor ‘onColor’ String - A comma separated string of 4 values for R. G. B and Alpha as set in the XTension preferences for the default On color to use in the program. Note that this may be overridden by the individual units in their on/off color settings.
onColor = 255,0,0,0
xtKeyOffColor ‘offColor’ String - You know, like your jokes… A comma separate string of 4 values for R, G, B and Alpha as set in the XTension preferences for the default Off color. Note that this may be overridden by individual units in their own on/off color settings.
offColor=0,210,15,0
xtCommandSetRunState ‘runState’ Enumerated String - Note that this is a “command” constant, but is also used as the key to the current value. You set this via the setRunState command. Do not set this value manually. It will contain one of the keys
  * xtRunStateOK     = ‘ok’   # shows the green dot in all displays, all is working OK
  * xtRunStateError  = ‘err’  # shows the yellow dot in all displays, there is an error, but we are attempting to recover
  * xtRunStateFail   = ‘fail’ # shows the red dot in all displays, this is an error that is unlikely to be able to be recovered from, ie: entered wrong password.
xtKeySupportFolderPath ’supportFolder’ The path to the XTension Support folder. The database and other resources live in this folder. If the application is installed in the Applications folder then this will be in the Documents folder. If the App is placed elsewhere this may be in the parent folder that also holds the app.
xtKeyUse24HourTime ‘use24hourtime’ Boolean - Due to potential difficulties with python localization it can be difficult to properly format a time for the User with their default computer preferences. If this is set to true then the default settings on the computer say to use a 24 hour time format, otherwise use a 12 hour format.

Connection and Port Settings

If you’re using the default port or outgoing/incoming address portions of the UI in XTension then these values can also be read out of the settings object.

xtKeyPortName

The xtKeyPortName is the key that holds the serial port name, or one of other constants that will point to the fact that incoming or outgoing tcp has been selected. This can be read from the settings with something similar to:

portName = XTension.settings.get( xtKeyPortName, xtKeyPortNameNone)

The current valid constants that may be returned are:

xtPortNameNone - The “None” value was selected for the port, or no port has been selected at all.
xtPortNameOutgoingTCP - An outgoing connection has been selected, you can get the address and port info with the keys below.
xtPortNameListen - A listening server has been requested. The Port will be placed in the same xtRemotePort key that us used for the outgoing TCP.

If the portName is not one of those constants, or if you have disabled those portions of the port selection system with the keys above, then this will contain the name of the serial port that has been selected. The name will be just the system name for the port and not the entire path as needed by the Python serial library. To turn it into a valid string to pass to serial.Serial() use something like this:

serialPortPath = f’/dev/tty.{XTension.settings.get( xtKeyPortName)}'

which will make it valid for passing as the port parameter to serial.Serial()

Outgoing TCP Keys

If an outgoing TCP connection is selected then the portName key above will match the xtPortNameOutgoingTCP constant. The address they have entered and the port will be available via the keys:

xtKeyRemotePort - Contains the port to connect to. This may be a string or if set from default a number so please do an explicit conversion to integer before sending it to a Socket.
workPort = int( XTension.settings.get( xtKeyRemotePort, 80)
xtKeyRemoteAddress - Contains the IP address or DNS name that the user has entered into the Address field.
workAddress = XTension.settings.get( xtKeyRemoteAddress, “127.0.0.1”)

Listening Connection Keys

Many serial to ethernet adaptors and other devices you may wish to connect to do not listen for incoming connections, but will want to be configured to make a connection to your machine. If that is the case the User make select Incoming as the connection method. In which case they UI will ask them for the port to listen on. It will be stored in the same key xtKeyRemotePort that is used for the port for an outgoing connection.

xtKeyRemotePort - Contains the port to listen on. This may be a string if set by the user or a number if set from defaults so make sure to do an explicit cast to an integer before trying to pass it to the socket.
listenPort = int( XTension.settings.get( xtKeyRemotePort, 5089)

All Dynamic Interface Keys

When you create a dynamic interface at the top level of the info.json file you must assign string keys to all the fields and controls. To get to that information from your plugin use the key and access them from the settings object just like any of the above. They will be stored at the root level of the settings.

Assuming you created an interface with a text field and the key set to “jamie.weatherslam.hello” and then created a constant in the plugin where keyHelloMessage was also set to “jamie.weatherslam.hello” then you could get the user setting for that field from the plugin like this:

myHelloMessage = XTension.settings.get( keyHelloMessage, “Hello World!”)

Saving Data In the Settings Data Store

You can also send new values or change values stored in the XTension.settings object. Make sure to use proper path names for the values so that they dont interfere with any XTension constants. The command to set data updates the local data store and then sends a message to XTension asking it to set the same value in the database for this Interface. You can save data with any key in any simple data format, strings, integers, floats and dates. For more complex structures please convert to JSON or some other formatting method and save them as a string, knowing you have to load them from JSON to get the data back out again.

Any data that you set in this way will be updated locally in your plugin immediately and sent to XTension where it will be saved in the persistent storage of the database for this interface. There are no limits placed on the length of keys or value strings however keep in mind that any info you save here must be written to disk and transferred back and forth between XTension and the plugin while being stored in memory and so forth. Make sure that none of your data structures can grow over time without a mechanism to clean them up. See also the next section on manually removing or adding keyed values from the database.

setXTensionData( key, value) - key must be a string, value can be strings, numbers, or datetime objects.
XTension.setXTensionData( “jamie.weatherslam.hello”, “Greetings to all world leaders!”)

Manually Removing and Adding Database Entries

As of this moment there is not a helper command in the plugin API to delete keys from the Interface database object. There is for managing data at the Unit level. If this is something that you need please let me know it can be implemented.

There are scripting commands in XTension to do this however. For testing you can set keyed values and delete keyed values via the single line apple script command line window in the app.

To Manually Delete A Keyed Value:
tell xInterface “name of your plugin instance” to xtremovedata( “your key”)
To Manually Set A Keyed Value:
tell xInterface “name of your plugin instance” to xtsetdata( “your key”)

Those 2 commands can also be sent to a Unit class in the same way but telling the xUnit object with the proper name.

Next: XTension Class: Helper Functions

pluginapi/xtensionclasssettings.txt · Last modified: 2023/06/12 15:04 by James Sentman