# hs.tangent

Tangent Control Surface Extension

API Version: TUBE Version 3.2 - TIPC Rev 4 (22nd February 2017)

This plugin allows Hammerspoon to communicate with Tangent's range of panels, such as their Element, Virtual Element Apps, Wave, Ripple and any future panels.

The Tangent Unified Bridge Engine (TUBE) is made up of two software elements, the Mapper and the Hub. The Hub communicates with your application via the TUBE Inter Process Communications (TIPC). TIPC is a standardised protocol to allow any application that supports it to communicate with any current and future panels produced by Tangent via the TUBE Hub.

You can download the Tangent Developer Support Pack & Tangent Hub Installer for Mac here.

This extension was thrown together by Chris Hocking, then dramatically improved by David Peterson for CommandPost.


# API Overview

Constants - Useful values which cannot be changed

  • action
  • fromHub
  • panelType
  • parameter
  • toHub

Variables - Configurable values

  • automaticallySendApplicationDefinition
  • ipAddress
  • port

Functions - API calls offered directly by the extension

  • callback
  • connect
  • connected
  • disconnect
  • isTangentHubInstalled
  • send
  • sendAllChange
  • sendApplicationDefinition
  • sendDisplayText
  • sendHighlightControl
  • sendIndicateControl
  • sendMenuString
  • sendModeValue
  • sendPanelConnectionStatesRequest
  • sendParameterValue
  • sendRenameControl
  • sendUnmanagedDisplayWrite
  • sendUnmanagedPanelCapabilitiesRequest
  • setLogLevel

# API Documentation

# Constants

# action

Signature hs.tangent.reserved.action -> table
Type Constant
Description Definitions for reserved action IDs.
Notes
  • alt - toggles the 'ALT' function.
  • nextKnobBank - switches to the next knob bank.
  • prevKnobBank - switches to the previous knob bank.
  • nextButtonBank - switches to the next button bank.
  • prevBasketBank - switches to the previous button bank.
  • nextTrackerballBank - switches to the next trackerball bank.
  • prevTrackerballBank - switches to the previous trackerball bank.
  • nextMode - switches to the next mode.
  • prevMode - switches to the previous mode.
  • goToMode - switches to the specified mode, requiring a Argument with the mode ID.
  • toggleJogShuttle - toggles jog/shuttle mode.
  • toggleMouseEmulation - toggles mouse emulation.
  • fakeKeypress - generates a keypress, requiring an Argument with the key code.
  • showHUD - shows the HUD on screen.
  • goToKnobBank - goes to the specific knob bank, requiring an Argument with the bank number.
  • goToButtonBank - goes to the specific button bank, requiring an Argument with the bank number.
  • goToTrackerballBank - goes to the specific trackerball bank, requiring an Argument with the bank number.
Source extensions/tangent/tangent.lua line 109

# fromHub

Signature hs.tangent.fromHub -> table
Type Constant
Description Definitions for IPC Commands from the HUB to Hammerspoon.
Notes
  • connected - a connection is established with the Hub.
  • disconnected - the connection is dropped with the Hub.
  • initiateComms - sent when the Hub wants to initiate communications.
  • parameterChange - a parameter was incremented.
  • parameterReset - a parameter was reset.
  • parameterValueRequest - the Hub wants the current value of the parameter.
  • menuChange - The menu was changed, +1 or -1.
  • menuReset - The menu was reset.
  • menuStringRequest - The application should send a menuString with the current value.
  • actionOn - An action button was pressed.
  • actionOff - An action button was released.
  • modeChange - The current mode was changed.
  • transport - The transport.
  • unmanagedPanelCapabilities - Send by the Hub to advertise an unmanaged panel.
  • unmanagedButtonDown - A button on an unmanaged panel was pressed.
  • unmanagedButtonUp - A button on an unmanaged panel was released.
  • unmanagedEncoderChange - An encoder (dial/wheel) on an unmanaged panel changed.
  • unmanagedDisplayRefresh - Triggered when an unmanaged panel's display needs to update.
  • panelConnectionState - A panel's connection state changed.
Source extensions/tangent/tangent.lua line 37

# panelType

Signature hs.tangent.panelType -> table
Type Constant
Description Tangent Panel Types.
Notes None
Source extensions/tangent/tangent.lua line 169

# parameter

Signature hs.tangent.reserved.parameter -> table
Type Constant
Description A table of reserved parameter IDs.
Notes
  • transportRing - transport ring.
  • fakeKeypress - sends a fake keypress.
Source extensions/tangent/tangent.lua line 152

# toHub

Signature hs.tangent.toHub -> table
Type Constant
Description Definitions for IPC Commands from Hammerspoon to the HUB.
Notes None
Source extensions/tangent/tangent.lua line 90

# Variables

# automaticallySendApplicationDefinition

Signature hs.tangent.automaticallySendApplicationDefinition -> boolean
Type Variable
Description Automatically send the "Application Definition" response. Defaults to true.
Notes None
Source extensions/tangent/tangent.lua line 1008

# ipAddress

Signature hs.tangent.ipAddress -> number
Type Variable
Description IP Address that the Tangent Hub is located at. Defaults to 127.0.0.1.
Notes None
Source extensions/tangent/tangent.lua line 998

# port

Signature hs.tangent.port -> number
Type Variable
Description The port that Tangent Hub monitors. Defaults to 64246.
Notes None
Source extensions/tangent/tangent.lua line 1003

# Functions

# callback

Signature hs.tangent.callback() -> boolean
Type Function
Description Sets a callback when new messages are received.
Parameters
  • callbackFn - a function to set as the callback for hs.tangent. If the value provided is nil, any currently existing callback function is removed.
Returns
  • true if successful otherwise false
Notes
  • Full documentation for the Tangent API can be downloaded here.
  • The callback function should expect 1 argument and should not return anything.
  • The 1 argument will be a table, which can contain one or many commands. Each command is it's own table with the following contents:
  • id - the message ID of the incoming message
  • metadata - A table of data for the Tangent command (see below).
  • The metadata table will return the following, depending on the id for the callback:
  • connected - Connection to Tangent Hub successfully established.
  • disconnected - The connection to Tangent Hub was dropped.
  • initiateComms - Initiates communication between the Hub and the application.
  • protocolRev - The revision number of the protocol.
  • numPanels - The number of panels connected.
  • panels
  • panelID - The ID of the panel.
  • panelType - The type of panel connected.
  • data - The raw data from the Tangent Hub
  • parameterChange - Requests that the application increment a parameter.
  • paramID - The ID value of the parameter.
  • increment - The incremental value which should be applied to the parameter.
  • parameterReset - Requests that the application changes a parameter to its reset value.
  • paramID - The ID value of the parameter.
  • parameterValueRequest - Requests that the application sends a ParameterValue (0x82) command to the Hub.
  • paramID - The ID value of the parameter.
  • menuChange - Requests the application change a menu index by +1 or -1.
  • menuID - The ID value of the menu.
  • increment - The incremental amount by which the menu index should be changed which will always be an integer value of +1 or -1.
  • menuReset - Requests that the application changes a menu to its reset value.
  • menuID - The ID value of the menu.
  • menuStringRequest - Requests that the application sends a MenuString (0x83) command to the Hub.
  • menuID - The ID value of the menu.
  • actionOn - Requests that the application performs the specified action.
  • actionID - The ID value of the action.
  • modeChange - Requests that the application changes to the specified mode.
  • modeID - The ID value of the mode.
  • transport - Requests the application to move the currently active transport.
  • jogValue - The number of jog steps to move the transport.
  • shuttleValue - An incremental value to add to the shuttle speed.
  • actionOff - Requests that the application cancels the specified action.
  • actionID - The ID value of the action.
  • unmanagedPanelCapabilities - Only used when working in Unmanaged panel mode. Sent in response to a UnmanagedPanelCapabilitiesRequest (0xA0) command.
  • panelID - The ID of the panel as reported in the InitiateComms command.
  • numButtons - The number of buttons on the panel.
  • numEncoders - The number of encoders on the panel.
  • numDisplays - The number of displays on the panel.
  • numDisplayLines - The number of lines for each display on the panel.
  • numDisplayChars - The number of characters on each line of each display on the panel.
  • unmanagedButtonDown - Only used when working in Unmanaged panel mode. Issued when a button has been pressed.
  • panelID - The ID of the panel as reported in the InitiateComms command.
  • buttonID - The hardware ID of the button
  • unmanagedButtonUp - Only used when working in Unmanaged panel mode. Issued when a button has been released.
  • panelID - The ID of the panel as reported in the InitiateComms command.
  • buttonID - The hardware ID of the button.
  • unmanagedEncoderChange - Only used when working in Unmanaged panel mode. Issued when an encoder has been moved.
  • panelID - The ID of the panel as reported in the InitiateComms command.
  • paramID - The hardware ID of the encoder.
  • increment - The incremental value.
  • unmanagedDisplayRefresh - Only used when working in Unmanaged panel mode. Issued when a panel has been connected or the focus of the panel has been returned to your application.
  • panelID - The ID of the panel as reported in the InitiateComms command.
  • panelConnectionState
  • panelID - The ID of the panel as reported in the InitiateComms command.
  • state - The connected state of the panel, true if connected, false if disconnected.
Examples None
Source extensions/tangent/tangent.lua line 1044

# connect

Signature hs.tangent.connect(applicationName, systemPath[, userPath]) -> boolean, errorMessage
Type Function
Description Connects to the Tangent Hub.
Parameters
  • applicationName - Your application name as a string
  • systemPath - A string containing the absolute path of the directory that contains the Controls and Default Map XML files.
  • [userPath] - An optional string containing the absolute path of the directory that contains the User’s Default Map XML files.
Returns
  • success - true on success, otherwise nil
  • errorMessage - The error messages as a string or nil if success is true.
Notes None
Examples None
Source extensions/tangent/tangent.lua line 1726

# connected

Signature hs.tangent.connected() -> boolean
Type Function
Description Checks to see whether or not you're successfully connected to the Tangent Hub.
Parameters
  • None
Returns
  • true if connected, otherwise false
Notes None
Examples None
Source extensions/tangent/tangent.lua line 1128

# disconnect

Signature hs.tangent.disconnect() -> none
Type Function
Description Disconnects from the Tangent Hub.
Parameters
  • None
Returns
  • None
Notes None
Examples None
Source extensions/tangent/tangent.lua line 1657

# isTangentHubInstalled

Signature hs.tangent.isTangentHubInstalled() -> boolean
Type Function
Description Checks to see whether or not the Tangent Hub software is installed.
Parameters
  • None
Returns
  • true if Tangent Hub is installed otherwise false.
Notes None
Examples None
Source extensions/tangent/tangent.lua line 1027

# send

Signature hs.tangent.send(byteString) -> boolean, string
Type Function
Description Sends a "bytestring" message to the Tangent Hub.
Parameters
  • byteString - The string of bytes to send to tangent.
Returns
  • success - true if connected, otherwise false
  • errorMessage - An error message if an error occurs, as a string
Notes
  • This should be a full encoded string for the command you want to send, withouth the leading 'size' section, which the function will calculate automatically.
  • In general, you should use the more specific functions that package the command for you, such as sendParameterValue(...). This function can be used to send a message that this API doesn't yet support.
  • Full documentation for the Tangent API can be downloaded here.
Examples None
Source extensions/tangent/tangent.lua line 1141

# sendAllChange

Signature hs.tangent.sendAllChange() -> boolean, string
Type Function
Description Tells the Hub that a large number of software-controls have changed.
Parameters
  • None
Returns
  • true if successful, or false and an error message if not.
Notes
  • The Hub responds by requesting all the current values of software-controls it is currently controlling.
Examples None
Source extensions/tangent/tangent.lua line 1295

# sendApplicationDefinition

Signature hs.tangent.sendApplicationDefinition([appName, systemPath, userPath]) -> boolean, string
Type Function
Description Sends the application details to the Tangent Hub.
Parameters
  • appName - The human-readable name of the application.
  • systemPath - A string containing the absolute path of the directory that contains the Controls and Default Map XML files (Path String)
  • userPath - A string containing the absolute path of the directory that contains the User’s Default Map XML files (Path String)
Returns
  • true if successful, false and an error message if there was a problem.
Notes
  • If no details are provided the ones stored in the module are used.
Examples None
Source extensions/tangent/tangent.lua line 1168

# sendDisplayText

Signature hs.tangent.sendDisplayText(messages[, doubleHeight]) -> boolean, string
Type Function
Description Updates the Hub with a number of character strings that will be displayed on connected panels if there is space.
Parameters
  • messages - A list of messages to send.
  • doubleHeight - An optional list of booleans indicating if the corresponding message is double-height.
Returns
  • true if successful, or false and an error message if not.
Notes
  • Strings may either be 32 character, single height or 16 character double-height. They will be displayed in the order received; the first string displayed at the top of the display.
  • If a string is not defined as double-height then it will occupy the next line.
  • If a string is defined as double-height then it will occupy the next 2 lines.
  • The maximum number of lines which will be used by the application must be indicated in the Controls XML file.
  • Text which exceeds 32 (single-height) or 16 (double-height) characters will be truncated.
  • If all text is single-height, the doubleHeight table can be omitted.
Examples
  • lua</li><li>hs.tangent.sendDisplayText(</li><li> { "Single Height", "Double Height" }, {false, true}</li><li>)
Source extensions/tangent/tangent.lua line 1342

# sendHighlightControl

Signature hs.tangent.sendHighlightControl(targetID, active) -> boolean, string
Type Function
Description Highlights the control on any panel where this feature is available.
Parameters
  • targetID - The id of any application defined Parameter, Menu, Action or Mode (Unsigned Int)
  • active - If true, the control is highlighted, otherwise it is not.
Returns
  • true if sent successfully, false and an error message if no.
Notes
  • When applied to Modes, buttons which are mapped to the reserved "Go To Mode" action for this particular mode will highlight.
Examples None
Source extensions/tangent/tangent.lua line 1544

# sendIndicateControl

Signature hs.tangent.sendIndicateControl(targetID, indicated) -> boolean, string
Type Function
Description Sets the Indicator of the control on any panel where this feature is available.
Parameters
  • targetID - The id of any application defined Parameter, Menu, Action or Mode
  • active - If true, the control is indicated, otherwise it is not.
Returns
  • true if sent successfully, false and an error message if no.
Notes
  • This indicator is driven by the atDefault argument for Parameters and Menus. This command therefore only applies to controls mapped to Actions and Modes.
  • When applied to Modes, buttons which are mapped to the reserved "Go To Mode" action for this particular mode will have their indicator set.
Examples None
Source extensions/tangent/tangent.lua line 1574

# sendMenuString

Signature hs.tangent.sendMenuString(menuID, value[, atDefault]) -> boolean, string
Type Function
Description Updates the Hub with a menu value.
Parameters
  • menuID - The ID value of the menu (Unsigned Int)
  • value - The current ‘value’ of the parameter represented as a string
  • atDefault - if true the value represents the default. Otherwise false.
Returns
  • true if successful, or false and an error message if not.
Notes
  • The Hub then updates the displays of any panels which are currently showing the menu.
  • If a value of nil is sent then the Hub will not attempt to display a value for the menu. However the atDefault flag will still be recognised.
Examples None
Source extensions/tangent/tangent.lua line 1256

# sendModeValue

Signature hs.tangent.sendModeValue(modeID) -> boolean, string
Type Function
Description Updates the Hub with a mode value.
Parameters
  • modeID - The ID value of the mode (Unsigned Int)
Returns
  • true if successful, or false and an error message if not.
Notes
  • The Hub then changes mode and requests all the current values of software-controls it is controlling.
Examples None
Source extensions/tangent/tangent.lua line 1315

# sendPanelConnectionStatesRequest

Signature hs.tangent.sendPanelConnectionStatesRequest())
Type Function
Description Requests the Hub to respond with a sequence of PanelConnectionState (0x35) commands to report the connected/disconnected status of each configured panel
Parameters
  • None
Returns
  • true if sent successfully, false and an error message if not.
Notes
  • A single request may result in multiple state responses.
Examples None
Source extensions/tangent/tangent.lua line 1607

# sendParameterValue

Signature hs.tangent.sendParameterValue(paramID, value[, atDefault]) -> boolean, string
Type Function
Description Updates the Hub with a parameter value.
Parameters
  • paramID - The ID value of the parameter (Unsigned Int)
  • value - The current value of the parameter (Float)
  • atDefault - if true the value represents the default. Defaults to false.
Returns
  • true if successful, or false and an error message if not.
Notes
  • The Hub then updates the displays of any panels which are currently showing the parameter value.
Examples None
Source extensions/tangent/tangent.lua line 1218

# sendRenameControl

Signature hs.tangent.sendRenameControl(targetID, newName) -> boolean, string
Type Function
Description Renames a control dynamically.
Parameters
  • targetID - The id of any application defined Parameter, Menu, Action or Mode (Unsigned Int)
  • newName - The new name to apply.
Returns
  • true if successful, false and an error message if not.
Notes
  • The string supplied will replace the normal text which has been derived from the Controls XML file.
  • To remove any existing replacement name set newName to "", this will remove any renaming and return the system to the normal display text
  • When applied to Modes, the string displayed on buttons which mapped to the reserved "Go To Mode" action for this particular mode will also change.
Examples None
Source extensions/tangent/tangent.lua line 1507

# sendUnmanagedDisplayWrite

Signature hs.tangent.sendUnmanagedDisplayWrite(panelID, displayID, lineNum, pos, message) -> boolean, string
Type Function
Description Updates the Hub with text that will be displayed on a specific panel at the given line and starting position where supported by the panel capabilities.
Parameters
  • panelID - The ID of the panel as reported in the InitiateComms command (Unsigned Int)
  • displayID - The ID of the display to be written to (Unsigned Int)
  • lineNum - The line number of the display to be written to with 1 as the top line (Unsigned Int)
  • pos - The position on the line to start writing from with 1 as the first column (Unsigned Int)
  • message - A line of text (Character String)
Returns
  • true if successful, or false and an error message if not.
Notes
  • Only used when working in Unmanaged panel mode.
  • If the most significant bit of any individual text character in message is set it will be displayed as inversed with dark text on a light background.
Examples None
Source extensions/tangent/tangent.lua line 1452

# sendUnmanagedPanelCapabilitiesRequest

Signature hs.tangent.sendUnmanagedPanelCapabilitiesRequest(panelID) -> boolean, string
Type Function
Description Requests the Hub to respond with an UnmanagedPanelCapabilities (0x30) command.
Parameters
  • panelID - The ID of the panel as reported in the InitiateComms command (Unsigned Int)
Returns
  • true if successful, or false and an error message if not.
Notes
  • Only used when working in Unmanaged panel mode
Examples None
Source extensions/tangent/tangent.lua line 1425

# setLogLevel

Signature hs.tangent.setLogLevel(loglevel) -> none
Type Function
Description Sets the Log Level.
Parameters
  • loglevel - can be 'nothing', 'error', 'warning', 'info', 'debug', or 'verbose'; or a corresponding number between 0 and 5
Returns
  • None
Notes None
Examples None
Source extensions/tangent/tangent.lua line 1013