Last active
December 23, 2017 23:06
-
-
Save cmsj/89548c9ad9c9ef38d021fd2a1e697cd7 to your computer and use it in GitHub Desktop.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
hs.console.clearConsole() | |
local hubMessage = { | |
["INITIATE_COMMS"] = 0x01, | |
["PARAMETER_CHANGE"] = 0x02, | |
["PARAMETER_RESET"] = 0x03, | |
["PARAMETER_VALUE_REQUEST"] = 0x04, | |
["MENU_CHANGE"] = 0x05, | |
["MENU_RESET"] = 0x06, | |
["MENU_STRING_REQUEST"] = 0x07, | |
["ACTION_ON"] = 0x08, | |
["MODE_CHANGE"] = 0x09, | |
["TRANSPORT"] = 0x0A, | |
["ACTION_OFF"] = 0x0B, | |
["UNMANAGED_PANEL_CAPABILITIES"] = 0x30, | |
["UNMANAGED_BUTTON_DOWN"] = 0x31, | |
["UNMANAGED_BUTTON_UP"] = 0x32, | |
["UNMANAGED_ENCODER_CHANGE"] = 0x33, | |
["UNMANAGED_DISPLAY_REFRESH"] = 0x34, | |
["PANEL_CONNECTION_STATE"] = 0x35, | |
} | |
local appMessage = { | |
["APPLICATION_DEFINITION"] = 0x81, | |
["PARAMETER_VALUE"] = 0x82, | |
["MENU_STRING"] = 0x83, | |
["ALL_CHANGE"] = 0x84, | |
["MODE_VALUE"] = 0x85, | |
["DISPLAY_TEXT"] = 0x86, | |
["UNMANAGED_PANEL_CAPABILITIES_REQUEST"] = 0xA0, | |
["UNMANAGED_DISPLAY_WRITE"] = 0xA1, | |
["RENAME_CONTROL"] = 0xA2, | |
["HIGHLIGHT_CONTROL"] = 0xA3, | |
["INDICATE_CONTROL"] = 0xA4, | |
["REQUEST_PANEL_CONNECTION_STATES"] = 0xA5, | |
} | |
local panelType = { | |
["CP200-BK"] = 0x03, | |
["CP200-K"] = 0x04, | |
["CP200-TS"] = 0x05, | |
["CP200-S"] = 0x09, | |
["Wave"] = 0x0A, | |
["Element-Tk"] = 0x0C, | |
["Element-Mf"] = 0x0D, | |
["Element-Kb"] = 0x0E, | |
["Element-Bt"] = 0x0F, | |
["Ripple"] = 0x11, | |
} | |
local logger = require("hs.logger") | |
logger.defaultLogLevel = 'debug' | |
local log = logger.new("tangent") | |
local socket = require("hs.socket") | |
local utf8 = require("hs.utf8") | |
messageBuffer = {} | |
messageLength = 0 | |
messageCount = 0 | |
readBytesRemaining = 0 | |
function getPanelType(id) | |
for i,v in pairs(panelType) do | |
if id == v then | |
return i | |
end | |
end | |
end | |
function byteStringToNumber(str, offset, num_bytes) | |
assert(num_bytes >= 1 and num_bytes <= 4) | |
local x = 0 | |
for i = 1, num_bytes do | |
x = x * 0x0100 | |
x = x + math.fmod(string.byte(str, i + offset - 1) or 0, 0x0100) | |
end | |
return x | |
end | |
function numberToByteString(n) | |
local t = {} | |
local char = string.char | |
t[1] = char(n >> 24 & 0xFF) | |
t[2] = char(n >> 16 & 0xFF) | |
t[3] = char(n >> 08 & 0xFF) | |
t[4] = char(n >> 00 & 0xFF) | |
return table.concat(t) | |
end | |
function buildMessage(msgType, msgParts) | |
local byteString = numberToByteString(msgType) | |
for _,partValue in pairs(msgParts) do | |
byteString = byteString .. numberToByteString(#partValue) | |
byteString = byteString .. partValue | |
end | |
log.df("buildMessage constructed: "..utf8.hexDump(byteString)) | |
return byteString | |
end | |
function processHubCommand(data) | |
local id = byteStringToNumber(data, 1, 4) | |
if id == hubMessage["INITIATE_COMMS"] then | |
-- 0x01, <protocolRev>, <numPanels>, (<panelType>, <panelID>)... | |
log.df("InitiateComms (0x01) Triggered:") | |
local protocolRev = byteStringToNumber(data, 5, 4) | |
local numberOfPanels = byteStringToNumber(data, 9, 4) | |
log.df(" protocolRev: %s", protocolRev) | |
log.df(" numberOfPanels: %s", numberOfPanels) | |
local startNumber = 13 | |
for i=1, numberOfPanels do | |
local currentPanelType = byteStringToNumber(data, startNumber, 4) | |
startNumber = startNumber + 4 | |
local currentPanelID = byteStringToNumber(data, startNumber, 4) | |
startNumber = startNumber + 4 | |
log.df(" panelType: %s panelID: %s", getPanelType(currentPanelType), currentPanelID) | |
end | |
-- Respond with ApplicationDefinition (0x81): | |
log.df("Responding with ApplicationDefinition (0x81)") | |
local byteString = buildMessage(appMessage["APPLICATION_DEFINITION"], {"CommandPost", "/Users/cmsj", ""}) | |
tangentSocket:send(byteStringToNumber(#byteString)..byteString) | |
else | |
log.df("Unknown Reply: %s", hs.inspect(data)) | |
end | |
end | |
log.df("CONNECTING TO TANGENT HUB...") | |
tangentSocket = socket.new() | |
:setCallback(function(data, tag) | |
local hexDump = utf8.hexDump(data) | |
log.df("Received data: "..hexDump) | |
if readBytesRemaining == 0 then | |
-- Each message starts with an integer value indicating the number of bytes to follow | |
-- We don't have any bytes left to read of a previous message, so this must be the first 4 bytes | |
readBytesRemaining = byteStringToNumber(data, 1, 4) | |
log.df("New command received from hub, of length: "..readBytesRemaining) | |
hs.timer.doAfter(0.5, function() tangentSocket:read(readBytesRemaining) end) | |
else | |
-- We've read the rest of a command | |
readBytesRemaining = 0 | |
processHubCommand(data) | |
-- Get set up for the next command | |
hs.timer.doAfter(0.5, function() tangentSocket:read(4) end) | |
end | |
end) | |
:connect("127.0.0.1", 64246, function() | |
log.df("CONNECTION TO TANGENT HUB ESTABLISHED.") | |
end) | |
tangentSocket:read(4) -- Read the first 4 bytes, which will trigger the callback. |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
FYI: Line 126 should be:
tangentSocket:send(numberToByteString(#byteString)..byteString)
Apart from that works BRILLIANTLY! THANK YOU!!