Table of Contents
Do It Yourself
This page is about the new DIY plugin which replaced the original DIY plugin in XTension 9.4.31. The original plugin is deprecated and will be removed completely in a current version. Please try your DIY interfaces with the new plugin and let me know if there are any issues. See the section below on converting from the legacy DIY plugin, there are some minor differences in the initial setup and configuration. The legacy plugins original documentation has been moved here,
The DIY plugin provides a way to easily connect to a device that does not have a specific plugin yet. The DIY plugin will provide a pipe to either a TCP socket on a remote device or a serial port connected directly to the XTension machine via a USB/Serial adaptor or Bluetooth Serial Port. Use the Send Data verb to write data to the device and receive its response in the Plugin script’s Data Available event.
To create a new DIY plugin instance visit the Interfaces window and click the New Interface button. Select “DIY Interface” from the Device popup. At the moment both this new plugin and the original DIY plugin are included in the XTension default package of plugins so be sure to select the “DIY Interface” that shows a version of at least 2.0b1 and not the one entitled “DIY Scripted Interface”. Please do not create new interfaces based on the original plugin as it will be removed in a future version of XTension and will not be included in the Catalina package.
Port Selection: The DIY plugin can talk directly to a serial port or make an outgoing connection to a TCP socket. There is also the option in the Port popup to listen for incoming connections. This is not implemented in the current beta version of the new plugin. If this is something you would find useful sooner please let me know and I will move it up the priorities list. Most network to serial adaptors such as the wiznet card can be run in either server mode meaning that we would connect to it which is how you must do it at the moment, or in client mode where it would connect to us. To allow this is the purpose of the incoming connection support and will be implemented in a future version. Make sure not to set a wiznet card to “mixed” mode as after you are disconnected for a while it will stop listening for you to reconnect and instead start trying to connect to you. This means that when you do reconnect it will not accept the connection.
Serial Ports: If you select a serial port you need to setup the necessary properties of the port such as baud and handshaking that might be necessary here. Most devices will connect at whatever baud it is built for but with the default other settings of no parity, no handshaking, 8 data bits and 1 stop bits.
There is a very old specification that allowed 1.5 stop bits. This is not supported on the Mac’s hardware at all and so I did not include it in the stop bits popup. If you need this it is possible that it will work if you set the stop bits to 2. This is what the hardware would do under the hood if you tried to set it to 1.5 anyway, so it is worth a try.
The Turnon RTS and Turnon DTR checkboxes will keep those handshaking lines turned on for the entire time the port is open. This is not compatible with a device that uses handshaking (though most do not) but it may be necessary for some smaller boxes who use these lines to power the opti-isolators for the serial data level converters that they use. If you have a device that will not communicate when all the other settings are correct try turning on these lines and it may wake up. The state of these lines can also be controlled with the scripting commands to setrts and setdtr see the scripting commands section below for more info on using those.
The Baud popup contains the standard list of baud rates that most or all USB/Serial adaptors support. It is possible to open the port with a non-standard baud rate if your USB/Serial adaptor supports this. At the moment there is no interface in XTension to setting a non-standard baud rate but if this is something you need please let me know and it can be added.
If you need to send a “Break” to the serial port see the SendBreak command below in the scripting commands section.
It is possible to read the state of the RI and CD line from the serial adaptor. At the moment there is no support for this in the plugin. If this is something you need to do please drop me an email and I will add supporting it to the list.
If the underlying hardware supports it it may be possible to properly talk to and configure an RS485 connection. As of this release there is no support for this in the plugin. If it is something that would be useful to you I can move the supporting of it up the priorities list. Please let me know. If you simply need an RS485 connection for something most USB/485 adaptors will handle most of the settings by default that may work just fine. The interface in XTension would only be necessary if these defaults did not work and you needed to change the drive level of the lines, the delay before tx/rx or the loopback settings.
TCP Connections: If you select an outgoing TCP connection you’ll see an additional section of the interface to enter the remote address and port of the device you wish to connect to. The Connection will be opened when the interface is enabled in XTension and held open until the interface is disabled or until XTension is quit. The Serial Port Settings are ignored when connected via a TCP socket. If you’re using a network to serial adaptor such as a Wiznet card or other the serial port settings are usually part of the configuration of that device. There is a protocol for sending these settings through the data connection so that I could implement this for them if needed. I am not aware of any devices that actually support this at the moment, but if it is something you need please let me know and I can look into implementing it.
If you are connecting to a TCP/Serial device that supports RFC2217 then it may be possible to set the port settings over the TCP connection. As of the current plugin release there is no support for this protocol but if it is something that would be useful to you please let me know and I will bump it up the priorities list. I’d also like to know what device you are connecting to as I’m not currently aware of very many that support this.
Parsing a data stream can be difficult and fraught with danger, especially if you are attempting to do it in AppleScript. The plugin has some rudimentary settings that can help in packetizing incoming data so that your Data Available or Binary Data Available events as documented below are more likely to contain the full packet and only one packet at a time.
If you are connecting to a true serial port the port will be flushed after opening so you should not receive a potentially large chunk of truncated garbage from the port buffers. This cannot be done for a TCP connection that will be up to the device you’re connecting to.
NOTE in the original DIY plugin these settings were not available in the initial plugin configuration and required that you use the Set Parsing Params verb in the init handler of the interface script to set them as the port was opened. You can still use the verb to change the options later if need be, but the state during the initial command
Send the data as soon as it is received:
This would be the default selection. At any seemingly random time while receiving data the system may choose to tell the plugin that there is data available to read on the port. The data is then read and the Data Available events will be called with whatever is there. It may be a single byte, a truncated packet or many packets stuck together. You can manage this in the scripting if you wish. This is the fastest way to get data into the script.
Fixed length packets:
If your device always sends the same length of packet you can use the fixed length packet parser. The port is opened and it will read until it receives the requested number of bytes and then pass those off as a single Data Available event to your script.
Wait for more data until:
The port is opened and the plugin will wait until some data is available. As soon as at least a single byte is available it will begin buffering any other data received until the number of milliseconds you specified has run out and then that buffer will be sent to your Data Available event.
Split data on terminator
This is arguably the most useful of the parsing options. Many simple ascii protocols will terminate each packet with a carriage return or newline character or something similar. At this moment you can enter any simple character string into the field and include this short list of special characters:
So to split on a carriage return line feed pair you would enter “\r\n” into the terminator field.
If you need other special characters or can imagine other ways that pre-parsing could be improved to be more helpful please let me know and I can add those.
At any point you can call the Set Parsing Params verb to change the parsing options. Though this is not necessary anymore as it was with the original DIY plugin.
To create the script that will receive the data received and parsed by the plugin use the Edit script button on the Edit Interface window. The initial script will appear with templates for all the available events that the plugin will call into your script.
There are 2 different formats of the DataAvailable event depending on the kind of data that is being sent. For simple ASCII or text protocols you can use the simpler version.
In AppleScript the handler would look like:
on dataAvailable( theDataAsString, theDataAsBytes) write log “DIY Interface Received: “ & theDataAsString end dataAvailable
This handler will pass you the data as a simple string, and also as an AppleScript list of the bytes received as numbers. This simplifies many parsing jobs as it is difficult in AppleScript to convert between characters and bytes.
If you are dealing with binary data then it may not be possible for AppleScript to send you the data as a string in the above example. If that is the case then you’ll see an error in the XTension log such as “unable to make data into specified type” or something similar whenever the plugin is trying to execute the Data Available event. If this happens then you need to use instead the binaryDataAvailable which does not attempt to turn the binary data into a text string but will instead only pass you an AppleScript list of bytes as individual numbers.
on binaryDataAvailable( theDataAsBytes) set s to “received “ & length of theDataAsBytes & “ bytes: " repeat with thisNumber in theDataAsBytes set s to s & (thisNumber as text) & “ " end repeat write log s end binaryDataAvailable
Sending data to the port is accomplished with the Send Data verb. The documentation on that page is extensive of how to send everything from simple text to individual bytes to specifically formatted multi-byte numerical values of the various C standards.
If you are sending the data from inside the Interface script that also contains your Data Available event then you can leave off the interface parameter of the Send Data verb. You can send data to the port from any other script or any other unit but in that case you must specify the interface parameter.
Working with Binary Data
Working with binary data in AppleScript is difficult. XTension provides many helper functions that can make it easier or just possible to do so. See the Bitwise: Manipulating bits in AppleScript portion of the AppleScript dictionary for more information.
Sending commands from units
It is now possible for the DIY script to receive events when a unit assigned to your DIY interface changes state. The following handlers are also defined and documented further in the template script that loads when you create a new DIY interface.
on SendOn( theUnitAddress) ... end SendOn
if you turn on a unit that is assigned to the DIY interface this handler in the scrip twill be called, it will pass you the address that you assigned to the unit and you can take any action you need to in order to send an on for that address via the SendData verb.
on SendOff( theUnitAddress) ... end SendOff
similarly when a unit assigned to this interface is turned off this event will be called
on SendValue( theUnitAddress, theValue) ... end SendValue
and lastly if it is a dimmable unit being set to a new value this event will be called in your DIY script. theValue is the Future Value that the unit is being requested to. You can change that value via the change future value verb. If you need to know the current value of the unit you can use ThisUnit to get the name of the current unit and use that and the value of verb to find out what it was previous to this command. This is useful if you need to calculate the difference between the 2 as some devices do rather than send an absolute value.
The value of the unit in the database is not updated until after these handlers return.
Additional Scripting Commands
In addition to the Send Data and Set Parsing Parameters verbs verbs the new plugin supports some additional scripting commands that are used differently inside a 'tell xInterface “name of interface” to doSomething()”
For some serial devices it may be necessary to send a “break” A break on the serial port was used by some devices as a synchronization method or a way to reset a conversation. It is still part of the DMX protocol. A break is really just a longer than appropriate holding of the data line at the mark voltage, the interface interprets this as a breaking of the standard data flow and it can be read by the controller and passed on to the software. You use the SendBreak command along with a floating point number of the number or fraction of seconds you wish to hold the port in this break state. The plugin will pause while the port is in the break state and not attempt to send any more data until it has expired. You do not have to add delay or pause statements to account for it.
To send a 500ms break you would use something like:
tell xInterface “name of the DIY interface” to sendBreak( 0.5)
Or if inside the Interface’s script you could use the (thisInterface) value like:
tell xInterface (thisInterface) to sendBreak( 0.5)
Pass a boolean to the command to set or clear the RTS pin on the fly. The initial state of this should be set in the Edit Interface dialog but you can change change it after the fact using this command. If the device requires handshaking and you have that turned on and are not trying to manage it yourself you may break that by calling this, or depending on the serial interface it may refuse to actually make any changes at all. This is probably most useful when handshaking is set to none or xonxoff.
tell xInterface “name of interface” to setRTS( true) tell xInterface “name of interface” to setRTS( false)
Identical to the above SetRTS command and with the same warnings about hardware flow control except that it controls the state of the DTR line.
tell xInterface “name of interface” to setDTR( true) tell xInterface “name of interface” to setDTR( false)
Converting from the Original DIY Plugin
In general the new plugin should work and handle your data identically to the old version. Please test this and let me know if there are any problems. Of all the plugins this may be the most difficult to test since there are so many wildly different use cases.
The conversion is not destructive and if you have problems you can immediately go back to the original plugin.
- Disable the interface in the Interfaces list window
- Edit the original interface.
- Change the selection in the popup from “DIY Scripted Interface” to “DIY Interface” which will also show a version of at least 2.0b1 in the popup.
- Add the proper parsing settings to the Edit Interface dialog as these can now be set at startup without needing the call to that in the init method. You can comment that call out with the new interface if you set the settings in the edit dialog. The verb is still supported however and will work as before.
If you need to revert simply change the Device popup back to the original plugin and re-enable it.
- The original DIY plugin documentation is preserved and contains a much more detailed use case and demo code than on this page. Please have a look there for more information.
- The initial DIY plugin was part of XTension since the early 2000s.
- The new API2.0 DIY plugin replaced the original in XTension version 9.4.31 in June of 2020.