mirror of
https://github.com/jwetzell/q-sys-plugin-novastar.git
synced 2026-08-16 02:33:31 +00:00
838 lines
24 KiB
Plaintext
838 lines
24 KiB
Plaintext
-- Plugin for NovaStar Video Wall controllers
|
|
-- Built in Lua
|
|
|
|
-- Layout inspired by VideoHub plugin @ https://github.com/locimation/qsys-plugins
|
|
|
|
PluginInfo = {
|
|
Name = "NovaStar~VX4S/VX6S/ProHD/ProHDJr/MCTRL4K", -- The tilde here indicates folder structure in the Shematic Elements pane
|
|
Version = "0.1.0-master",
|
|
Id = "novastar.plugin.0.1.0-master",
|
|
Description = "Plugin for controlling NovaStar video wall controllers",
|
|
ShowDebug = true,
|
|
Author = "Joel Wetzell"
|
|
}
|
|
|
|
function GetPrettyName()
|
|
return "NovaStar Controller"
|
|
end
|
|
|
|
-- Once you've drawn your plugin in Designer, you can determine what colors you use a lot. Save yourself some time by putting them in a table, and then simply calling them later.
|
|
local Colors = {
|
|
White = {255, 255, 255},
|
|
Black = {0, 0, 0},
|
|
Red = {255, 0, 0},
|
|
Green = {0, 255, 0},
|
|
Blue = {0, 0, 255},
|
|
DarkGrey = {0x56,0x56,0x56},
|
|
|
|
LCD = { 0x02, 0x33, 0xb2 }
|
|
}
|
|
|
|
-- We can let users determine some of the plugin properties by exposing them here
|
|
-- While this function can be very useful, it is completely optional and not always needed.
|
|
-- If no Properties are set here, only the position and fill properties of your plugin will show in the Properties pane
|
|
function GetProperties()
|
|
props = {
|
|
{
|
|
Name = "IP Address",
|
|
Type = "string",
|
|
Value = "10.0.0.5"
|
|
},
|
|
{
|
|
Name = 'Model',
|
|
Type = 'enum',
|
|
Choices = { 'VX4S', 'VX4S_N', 'VX6S', 'PROHD', 'PROUHDJR', 'MCTRL4K' },
|
|
Value = 'VX4S'
|
|
}
|
|
}
|
|
return props
|
|
end
|
|
|
|
-- The below function is optional (like GetProperties() is), but it can allow further customization of what users can and can't do with your plugin.
|
|
-- In this example, when Model 1 is selected in the properties pane, the ability to modify some of the properties will be hidden, only allowing customization with Model 2
|
|
-- Another application of this is if you have different input/output types for different models, and want those properties to be dynamic in the Properties pane
|
|
function RectifyProperties(props)
|
|
return props
|
|
end
|
|
|
|
-- The below function is where you will populate the controls for your plugin.
|
|
function GetControls(props)
|
|
local controls = {
|
|
-- Source Inputs
|
|
{
|
|
Name = "IN1",
|
|
ControlType = "Button",
|
|
ButtonType = "Trigger"
|
|
},
|
|
{
|
|
Name = "IN2",
|
|
ControlType = "Button",
|
|
ButtonType = "Trigger"
|
|
},
|
|
{
|
|
Name = "IN3",
|
|
ControlType = "Button",
|
|
ButtonType = "Trigger"
|
|
},
|
|
{
|
|
Name = "IN4",
|
|
ControlType = "Button",
|
|
ButtonType = "Trigger"
|
|
},
|
|
{
|
|
Name = "IN5",
|
|
ControlType = "Button",
|
|
ButtonType = "Trigger"
|
|
},
|
|
{
|
|
Name = "IN6",
|
|
ControlType = "Button",
|
|
ButtonType = "Trigger"
|
|
},
|
|
{
|
|
Name = "IN7",
|
|
ControlType = "Button",
|
|
ButtonType = "Trigger"
|
|
},
|
|
{
|
|
Name = "IN8",
|
|
ControlType = "Button",
|
|
ButtonType = "Trigger"
|
|
},
|
|
{
|
|
Name = "IN9",
|
|
ControlType = "Button",
|
|
ButtonType = "Trigger"
|
|
},
|
|
{
|
|
Name = "IN0",
|
|
ControlType = "Button",
|
|
ButtonType = "Trigger"
|
|
},
|
|
--Brightness Knob
|
|
{
|
|
Name = "Brightness",
|
|
ControlType = "Knob",
|
|
ControlUnit = "Integer",
|
|
Min = 0,
|
|
Max = 255,
|
|
PinStyle = "Both",
|
|
UserPin = true
|
|
},
|
|
|
|
-- Test Pattern Buttons
|
|
{
|
|
Name = "TEST1",
|
|
ControlType = "Button",
|
|
ButtonType = "Trigger"
|
|
},
|
|
|
|
{
|
|
Name = "TEST2",
|
|
ControlType = "Button",
|
|
ButtonType = "Trigger"
|
|
},
|
|
{
|
|
Name = "TEST3",
|
|
ControlType = "Button",
|
|
ButtonType = "Trigger"
|
|
},
|
|
{
|
|
Name = "TEST4",
|
|
ControlType = "Button",
|
|
ButtonType = "Trigger"
|
|
},
|
|
{
|
|
Name = "TEST5",
|
|
ControlType = "Button",
|
|
ButtonType = "Trigger"
|
|
},
|
|
{
|
|
Name = "TEST6",
|
|
ControlType = "Button",
|
|
ButtonType = "Trigger"
|
|
},
|
|
{
|
|
Name = "TEST7",
|
|
ControlType = "Button",
|
|
ButtonType = "Trigger"
|
|
},
|
|
{
|
|
Name = "TEST8",
|
|
ControlType = "Button",
|
|
ButtonType = "Trigger"
|
|
},
|
|
{
|
|
Name = "TEST9",
|
|
ControlType = "Button",
|
|
ButtonType = "Trigger"
|
|
},
|
|
|
|
{
|
|
Name = "Status",
|
|
ControlType = "Indicator",
|
|
IndicatorType = "Status",
|
|
PinStyle = "Output",
|
|
UserPin = true
|
|
}
|
|
}
|
|
return controls
|
|
end
|
|
|
|
-- Variable holding Page Names for ease
|
|
local pagenames = {"System"}
|
|
|
|
function GetPages(props) -- This function allows you to populate pages in your plugin.
|
|
local pages = {}
|
|
table.insert(pages, {name = pagenames[1]})
|
|
return pages
|
|
end
|
|
|
|
function GetControlLayout(props)
|
|
local controls = {}
|
|
|
|
local rackSize = {1000, 120}
|
|
|
|
local inputPosition = {rackSize[1]*3/8,5}
|
|
local testPosition = {rackSize[1]*11/16,5}
|
|
|
|
local graphics = {
|
|
|
|
{ -- Outer box
|
|
Type = "GroupBox",
|
|
StrokeWidth = 1,
|
|
CornerRadius = 8,
|
|
Fill = Colors.Black,
|
|
StrokeColor = {0,0,0},
|
|
Size = rackSize,
|
|
Position = {0,0}
|
|
},
|
|
-- Inputs box
|
|
{
|
|
Type = "GroupBox",
|
|
Text = "INPUTS",
|
|
Color = Colors.White,
|
|
HTextAlign = "CENTER",
|
|
CornerRadius = 3,
|
|
Fill = Colors.Black,
|
|
StrokeColor = Colors.White,
|
|
StrokeWidth = 1,
|
|
Size = {250, rackSize[2] - 10},
|
|
Position = inputPosition
|
|
},
|
|
|
|
-- Test box
|
|
{
|
|
Type = "GroupBox",
|
|
Text = "TEST",
|
|
Color = Colors.White,
|
|
HTextAlign = "CENTER",
|
|
CornerRadius = 3,
|
|
Fill = Colors.Black,
|
|
StrokeColor = Colors.White,
|
|
StrokeWidth = 1,
|
|
Size = {250, rackSize[2] - 10},
|
|
Position = testPosition
|
|
},
|
|
-- NovaStar Text
|
|
{
|
|
Type = "Label",
|
|
Text = "NovaStar",
|
|
TextSize = 16,
|
|
HTextAlign = "Center",
|
|
IsBold = true,
|
|
Size = {150,16},
|
|
Color = Colors.White,
|
|
Position = {60, rackSize[2]*1/8}
|
|
}
|
|
|
|
}
|
|
|
|
controls['Brightness'] = {
|
|
Style="Knob",
|
|
Color = Colors.DarkGrey,
|
|
Fill = Colors.DarkGrey,
|
|
Size={rackSize[2]/2,rackSize[2]/2},
|
|
Position= {250, rackSize[2]*1/4}
|
|
}
|
|
|
|
local SourceButton = {
|
|
yStart = inputPosition[2] + 20,
|
|
Padding = 5
|
|
}
|
|
|
|
local TestButton = {
|
|
yStart = testPosition[2] + 20,
|
|
Padding = 5
|
|
}
|
|
|
|
SourceButton.Size = {(rackSize[2] - 30 - (SourceButton.Padding * 2))/2, (rackSize[2] - 30 - (SourceButton.Padding * 2))/2}
|
|
TestButton.Size = {(rackSize[2] - 30 - (TestButton.Padding * 2))/2, (rackSize[2] - 30 - (TestButton.Padding * 2))/2}
|
|
SourceButton.xStart = inputPosition[1] + ((250 - (((SourceButton.Size[1] * 5) + (SourceButton.Padding * 4))))/2)
|
|
TestButton.xStart = testPosition[1] + ((250 - (((TestButton.Size[1] * 5) + (TestButton.Padding * 4))))/2)
|
|
|
|
local TestLabels = {
|
|
"Red","Green","Blue","White","Horiz","Vert","Diag","Gray","Aging"
|
|
}
|
|
|
|
local InputLabels = {
|
|
VX4S = {
|
|
"DVI",
|
|
"HDMI",
|
|
"VGA1",
|
|
"VGA2",
|
|
"CVBS1",
|
|
"CVBS2",
|
|
"SDI",
|
|
"DP",
|
|
},
|
|
VX4S_N = {
|
|
"HDMI",
|
|
"DVI",
|
|
"VGA",
|
|
"",
|
|
"",
|
|
"CVBS",
|
|
"DP",
|
|
"SDI",
|
|
"",
|
|
"",
|
|
},
|
|
VX6S = {
|
|
"HDMI1",
|
|
"HDMI2",
|
|
"SDI1",
|
|
"SDI2",
|
|
"DVI1",
|
|
"DVI2",
|
|
"USB",
|
|
},
|
|
PROHD = {
|
|
"SDI",
|
|
"DVI",
|
|
"HDMI",
|
|
"DP",
|
|
"VGA",
|
|
"CVBS",
|
|
},
|
|
PROUHDJR = {
|
|
"SDI",
|
|
"DVI",
|
|
"HDMI",
|
|
"DP",
|
|
},
|
|
MCTRL4K = {
|
|
"DVI",
|
|
"HDMI",
|
|
"DP",
|
|
}
|
|
}
|
|
|
|
|
|
--First row of input buttons
|
|
controls['IN1'] = {
|
|
Style = "Button",
|
|
ButtonType = "Trigger",
|
|
Legend = InputLabels[props['Model'].Value][1] ~= nil and InputLabels[props['Model'].Value][1] or "1" ,
|
|
UnlinkOffColor = true,
|
|
OffColor = Colors.White,
|
|
Color = Colors.Red,
|
|
Position = {SourceButton.xStart, SourceButton.yStart},
|
|
Size = SourceButton.Size
|
|
}
|
|
|
|
controls['IN2'] = {
|
|
Style = "Button",
|
|
ButtonType = "Trigger",
|
|
Legend = InputLabels[props['Model'].Value][2] ~= nil and InputLabels[props['Model'].Value][2] or "2" ,
|
|
UnlinkOffColor = true,
|
|
OffColor = Colors.White,
|
|
Color = Colors.Red,
|
|
Position = {SourceButton.xStart + ((SourceButton.Size[1]+SourceButton.Padding)*1), SourceButton.yStart},
|
|
Size = SourceButton.Size
|
|
}
|
|
|
|
controls['IN3'] = {
|
|
Style = "Button",
|
|
ButtonType = "Trigger",
|
|
Legend = InputLabels[props['Model'].Value][3] ~= nil and InputLabels[props['Model'].Value][3] or "3" ,
|
|
UnlinkOffColor = true,
|
|
OffColor = Colors.White,
|
|
Color = Colors.Red,
|
|
Position = {SourceButton.xStart + ((SourceButton.Size[1]+SourceButton.Padding)*2),SourceButton.yStart},
|
|
Size = SourceButton.Size
|
|
}
|
|
|
|
controls['IN4'] = {
|
|
Style = "Button",
|
|
ButtonType = "Trigger",
|
|
Legend = InputLabels[props['Model'].Value][4] ~= nil and InputLabels[props['Model'].Value][4] or"4",
|
|
UnlinkOffColor = true,
|
|
OffColor = Colors.White,
|
|
Color = Colors.Red,
|
|
Position = {SourceButton.xStart + ((SourceButton.Size[1]+SourceButton.Padding)*3),SourceButton.yStart},
|
|
Size = SourceButton.Size
|
|
}
|
|
|
|
|
|
controls['IN5'] = {
|
|
Style = "Button",
|
|
ButtonType = "Trigger",
|
|
Legend = InputLabels[props['Model'].Value][5] ~= nil and InputLabels[props['Model'].Value][5] or"5",
|
|
UnlinkOffColor = true,
|
|
OffColor = Colors.White,
|
|
Color = Colors.Red,
|
|
Position = {SourceButton.xStart + ((SourceButton.Size[1]+SourceButton.Padding)*4),SourceButton.yStart},
|
|
Size = SourceButton.Size
|
|
}
|
|
|
|
--First row of test buttons
|
|
controls['TEST1'] = {
|
|
Style = "Button",
|
|
ButtonType = "Trigger",
|
|
Legend = TestLabels[1] ~= nil and TestLabels[1] or "1" ,
|
|
UnlinkOffColor = true,
|
|
OffColor = Colors.White,
|
|
Color = Colors.Red,
|
|
Position = {TestButton.xStart, TestButton.yStart},
|
|
Size = TestButton.Size
|
|
}
|
|
|
|
controls['TEST2'] = {
|
|
Style = "Button",
|
|
ButtonType = "Trigger",
|
|
Legend = TestLabels[2] ~= nil and TestLabels[2] or "2" ,
|
|
UnlinkOffColor = true,
|
|
OffColor = Colors.White,
|
|
Color = Colors.Red,
|
|
Position = {TestButton.xStart + ((TestButton.Size[1]+TestButton.Padding)*1), TestButton.yStart},
|
|
Size = TestButton.Size
|
|
}
|
|
|
|
controls['TEST3'] = {
|
|
Style = "Button",
|
|
ButtonType = "Trigger",
|
|
Legend = TestLabels[3] ~= nil and TestLabels[3] or "3" ,
|
|
UnlinkOffColor = true,
|
|
OffColor = Colors.White,
|
|
Color = Colors.Red,
|
|
Position = {TestButton.xStart + ((TestButton.Size[1]+TestButton.Padding)*2),TestButton.yStart},
|
|
Size = TestButton.Size
|
|
}
|
|
|
|
controls['TEST4'] = {
|
|
Style = "Button",
|
|
ButtonType = "Trigger",
|
|
Legend = TestLabels[4] ~= nil and TestLabels[4] or "4",
|
|
UnlinkOffColor = true,
|
|
OffColor = Colors.White,
|
|
Color = Colors.Red,
|
|
Position = {TestButton.xStart + ((TestButton.Size[1]+TestButton.Padding)*3),TestButton.yStart},
|
|
Size = TestButton.Size
|
|
}
|
|
|
|
|
|
controls['TEST5'] = {
|
|
Style = "Button",
|
|
ButtonType = "Trigger",
|
|
Legend = TestLabels[5] ~= nil and TestLabels[5] or "5",
|
|
UnlinkOffColor = true,
|
|
OffColor = Colors.White,
|
|
Color = Colors.Red,
|
|
Position = {TestButton.xStart + ((TestButton.Size[1]+TestButton.Padding)*4),TestButton.yStart},
|
|
Size = TestButton.Size
|
|
}
|
|
|
|
--bump down second row of buttons
|
|
SourceButton.yStart = SourceButton.yStart + SourceButton.Size[1] + (SourceButton.Padding/2)
|
|
TestButton.yStart = TestButton.yStart + TestButton.Size[1] + (TestButton.Padding/2)
|
|
|
|
--Second row of input buttons
|
|
controls['IN6'] = {
|
|
Style = "Button",
|
|
ButtonType = "Trigger",
|
|
Legend = InputLabels[props['Model'].Value][6] ~= nil and InputLabels[props['Model'].Value][6] or"6",
|
|
UnlinkOffColor = true,
|
|
OffColor = Colors.White,
|
|
Color = Colors.Red,
|
|
Position = {SourceButton.xStart,SourceButton.yStart},
|
|
Size = SourceButton.Size
|
|
}
|
|
|
|
controls['IN7'] = {
|
|
Style = "Button",
|
|
ButtonType = "Trigger",
|
|
Legend = InputLabels[props['Model'].Value][7] ~= nil and InputLabels[props['Model'].Value][7] or"7",
|
|
UnlinkOffColor = true,
|
|
OffColor = Colors.White,
|
|
Color = Colors.Red,
|
|
Position = {SourceButton.xStart + ((SourceButton.Size[1]+SourceButton.Padding)*1), SourceButton.yStart},
|
|
Size = SourceButton.Size
|
|
}
|
|
|
|
|
|
controls['IN8'] = {
|
|
Style = "Button",
|
|
ButtonType = "Trigger",
|
|
Legend = InputLabels[props['Model'].Value][8] ~= nil and InputLabels[props['Model'].Value][8] or"8",
|
|
UnlinkOffColor = true,
|
|
OffColor = Colors.White,
|
|
Color = Colors.Red,
|
|
Position = {SourceButton.xStart + ((SourceButton.Size[1]+SourceButton.Padding)*2),SourceButton.yStart},
|
|
Size = SourceButton.Size
|
|
}
|
|
|
|
controls['IN9'] = {
|
|
Style = "Button",
|
|
ButtonType = "Trigger",
|
|
Legend = InputLabels[props['Model'].Value][9] ~= nil and InputLabels[props['Model'].Value][9] or"9",
|
|
UnlinkOffColor = true,
|
|
OffColor = Colors.White,
|
|
Color = Colors.Red,
|
|
Position = {SourceButton.xStart + ((SourceButton.Size[1]+SourceButton.Padding)*3),SourceButton.yStart},
|
|
Size = SourceButton.Size
|
|
}
|
|
|
|
|
|
controls['IN0'] = {
|
|
Style = "Button",
|
|
ButtonType = "Trigger",
|
|
Legend = InputLabels[props['Model'].Value][10] ~= nil and InputLabels[props['Model'].Value][10] or"0",
|
|
UnlinkOffColor = true,
|
|
OffColor = Colors.White,
|
|
Color = Colors.Red,
|
|
Position = {SourceButton.xStart + ((SourceButton.Size[1]+SourceButton.Padding)*4),SourceButton.yStart},
|
|
Size = SourceButton.Size
|
|
}
|
|
|
|
--Second row of test buttons
|
|
controls['TEST6'] = {
|
|
Style = "Button",
|
|
ButtonType = "Trigger",
|
|
Legend = TestLabels[6] ~= nil and TestLabels[6] or "6",
|
|
UnlinkOffColor = true,
|
|
OffColor = Colors.White,
|
|
Color = Colors.Red,
|
|
Position = {TestButton.xStart,TestButton.yStart},
|
|
Size = TestButton.Size
|
|
}
|
|
|
|
controls['TEST7'] = {
|
|
Style = "Button",
|
|
ButtonType = "Trigger",
|
|
Legend = TestLabels[7] ~= nil and TestLabels[7] or "7",
|
|
UnlinkOffColor = true,
|
|
OffColor = Colors.White,
|
|
Color = Colors.Red,
|
|
Position = {TestButton.xStart + ((TestButton.Size[1]+TestButton.Padding)*1), TestButton.yStart},
|
|
Size = TestButton.Size
|
|
}
|
|
|
|
|
|
controls['TEST8'] = {
|
|
Style = "Button",
|
|
ButtonType = "Trigger",
|
|
Legend = TestLabels[8] ~= nil and TestLabels[8] or "8",
|
|
UnlinkOffColor = true,
|
|
OffColor = Colors.White,
|
|
Color = Colors.Red,
|
|
Position = {TestButton.xStart + ((TestButton.Size[1]+TestButton.Padding)*2),TestButton.yStart},
|
|
Size = TestButton.Size
|
|
}
|
|
|
|
controls['TEST9'] = {
|
|
Style = "Button",
|
|
ButtonType = "Trigger",
|
|
Legend = TestLabels[9] ~= nil and TestLabels[9] or "9",
|
|
UnlinkOffColor = true,
|
|
OffColor = Colors.White,
|
|
Color = Colors.Red,
|
|
Position = {TestButton.xStart + ((TestButton.Size[1]+TestButton.Padding)*3),TestButton.yStart},
|
|
Size = TestButton.Size
|
|
}
|
|
|
|
controls['Status'] = {
|
|
Style = "Text",
|
|
Color = Colors.LCD,
|
|
TextSize = 10,
|
|
UserPin = true,
|
|
PinStyle = "Output",
|
|
Size = {150,rackSize[2]/2},
|
|
Position = {60, rackSize[2]*1/4}
|
|
}
|
|
|
|
return controls, graphics
|
|
end
|
|
|
|
if (Controls) then
|
|
local NovaStar = {
|
|
socket = TcpSocket.New(),
|
|
setStatus = function (value, msg)
|
|
-- 0 = OK
|
|
-- 1 = Compromised
|
|
-- 2 = Fault
|
|
-- 3 = Not Present
|
|
-- 4 = Missing
|
|
-- 5 = Initializing
|
|
-- >5 = Fault
|
|
Controls['Status'].Value = value;
|
|
Controls['Status'].String = msg;
|
|
end,
|
|
Commands = {
|
|
Preamble = {0x55, 0xAA},
|
|
Connect = {0x00,0x00,0xFE,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x02,0x00,0x00,0x00,0x02,0x00,0x57,0x56},
|
|
Brightness = {0x00,0x00,0xFE,0xFF,0x01,0xFF,0xFF,0xFF,0x01,0x00,0x01,0x00,0x00,0x02,0x01,0x00},
|
|
TestPatterns = {
|
|
{0x00,0x80,0xFE,0x00,0x01,0x00,0xFF,0xFF,0x01,0x00,0x01,0x01,0x00,0x02,0x01,0x00,0x02,0xDA,0x58}, --Red
|
|
{0x00,0x80,0xFE,0x00,0x01,0x00,0xFF,0xFF,0x01,0x00,0x01,0x01,0x00,0x02,0x01,0x00,0x03,0xDB,0x58}, --Green
|
|
{0x00,0x80,0xFE,0x00,0x01,0x00,0xFF,0xFF,0x01,0x00,0x01,0x01,0x00,0x02,0x01,0x00,0x04,0xDC,0x58}, --Blue
|
|
{0x00,0x80,0xFE,0x00,0x01,0x00,0xFF,0xFF,0x01,0x00,0x01,0x01,0x00,0x02,0x01,0x00,0x05,0xDD,0x58}, --White
|
|
{0x00,0x80,0xFE,0x00,0x01,0x00,0xFF,0xFF,0x01,0x00,0x01,0x01,0x00,0x02,0x01,0x00,0x06,0xDE,0x58}, --Horizontal
|
|
{0x00,0x80,0xFE,0x00,0x01,0x00,0xFF,0xFF,0x01,0x00,0x01,0x01,0x00,0x02,0x01,0x00,0x07,0xDF,0x58}, --Vertical
|
|
{0x00,0x80,0xFE,0x00,0x01,0x00,0xFF,0xFF,0x01,0x00,0x01,0x01,0x00,0x02,0x01,0x00,0x08,0xE0,0x58}, --Diagaonal
|
|
{0x00,0x80,0xFE,0x00,0x01,0x00,0xFF,0xFF,0x01,0x00,0x01,0x01,0x00,0x02,0x01,0x00,0x09,0xE1,0x58}, --Grayscale
|
|
{0x00,0x80,0xFE,0x00,0x01,0x00,0xFF,0xFF,0x01,0x00,0x01,0x01,0x00,0x02,0x01,0x00,0x0A,0xE2,0x58} --Aging-All
|
|
},
|
|
DisplayNormal = { 0x00,0x00,0xFE,0x00,0x00,0x00,0x00,0x00,0x01,0x00,0x50,0x00,0x20,0x02,0x01,0x00,0x00,0xC7,0x56 },
|
|
DisplayNormalAlt = { 0x00,0x38,0xFE,0x00,0x00,0x00,0x00,0x00,0x01,0x00,0x04,0x00,0x00,0x13,0x01,0x00,0x03,0xA7,0x56 },
|
|
Inputs = {
|
|
VX4S = {
|
|
{0x00,0x00,0xFE,0x00,0x00,0x00,0x00,0x00,0x01,0x00,0x2D,0x00,0x20,0x02,0x01,0x00,0x10,0xB4,0x56}, --DVI
|
|
{0x00,0x00,0xFE,0x00,0x00,0x00,0x00,0x00,0x01,0x00,0x2D,0x00,0x20,0x02,0x01,0x00,0xA0,0x44,0x57}, --HDMI
|
|
{0x00,0x00,0xFE,0x00,0x00,0x00,0x00,0x00,0x01,0x00,0x2D,0x00,0x20,0x02,0x01,0x00,0x01,0xA5,0x56}, --VGA1
|
|
{0x00,0x00,0xFE,0x00,0x00,0x00,0x00,0x00,0x01,0x00,0x2D,0x00,0x20,0x02,0x01,0x00,0x02,0xA6,0x56}, --VGA2
|
|
{0x00,0x00,0xFE,0x00,0x00,0x00,0x00,0x00,0x01,0x00,0x2D,0x00,0x20,0x02,0x01,0x00,0x71,0x15,0x57}, --CVBS1
|
|
{0x00,0x00,0xFE,0x00,0x00,0x00,0x00,0x00,0x01,0x00,0x2D,0x00,0x20,0x02,0x01,0x00,0x72,0x16,0x57}, --CVBS2
|
|
{0x00,0x00,0xFE,0x00,0x00,0x00,0x00,0x00,0x01,0x00,0x2D,0x00,0x20,0x02,0x01,0x00,0x40,0xE4,0x56}, --SDI
|
|
{0x00,0x00,0xFE,0x00,0x00,0x00,0x00,0x00,0x01,0x00,0x2D,0x00,0x20,0x02,0x01,0x00,0x90,0x34,0x57}, --DP
|
|
{},
|
|
{},
|
|
},
|
|
VX4S_N = {
|
|
{0x00,0x00,0xFE,0x00,0x00,0x00,0x00,0x00,0x01,0x00,0x2D,0x00,0x20,0x02,0x01,0x00,0xA0,0x44,0x57}, --HDMI
|
|
{0x00,0x00,0xFE,0x00,0x00,0x00,0x00,0x00,0x01,0x00,0x2D,0x00,0x20,0x02,0x01,0x00,0x10,0xB4,0x56}, --DVI
|
|
{0x00,0x00,0xFE,0x00,0x00,0x00,0x00,0x00,0x01,0x00,0x2D,0x00,0x20,0x02,0x01,0x00,0x01,0xA5,0x56}, --VGA
|
|
{},
|
|
{},
|
|
{0x00,0x00,0xFE,0x00,0x00,0x00,0x00,0x00,0x01,0x00,0x2D,0x00,0x20,0x02,0x01,0x00,0x71,0x15,0x57}, --CVBS
|
|
{0x00,0x00,0xFE,0x00,0x00,0x00,0x00,0x00,0x01,0x00,0x2D,0x00,0x20,0x02,0x01,0x00,0x90,0x34,0x57}, --DP
|
|
{0x00,0x00,0xFE,0x00,0x00,0x00,0x00,0x00,0x01,0x00,0x2D,0x00,0x20,0x02,0x01,0x00,0x40,0xE4,0x56}, --SDI
|
|
{},
|
|
{},
|
|
},
|
|
VX6S = {
|
|
{0x00,0x88,0xFE,0x00,0x00,0x00,0x00,0x00,0x01,0x00,0x12,0x00,0x02,0x13,0x03,0x00,0x00,0x00,0x11,0x17,0x57}, --HDMI1
|
|
{0x00,0xA8,0xFE,0x00,0x00,0x00,0x00,0x00,0x01,0x00,0x12,0x00,0x02,0x13,0x03,0x00,0x01,0x00,0x12,0x39,0x57}, --HDMI2
|
|
{0x00,0xC4,0xFE,0x00,0x00,0x00,0x00,0x00,0x01,0x00,0x12,0x00,0x02,0x13,0x03,0x00,0x02,0x00,0x31,0x75,0x57}, --SDI1
|
|
{0x00,0xD4,0xFE,0x00,0x00,0x00,0x00,0x00,0x01,0x00,0x12,0x00,0x02,0x13,0x03,0x00,0x03,0x00,0x32,0x87,0x57}, --SDI2
|
|
{0x00,0xD6,0xFE,0x00,0x00,0x00,0x00,0x00,0x01,0x00,0x12,0x00,0x02,0x13,0x03,0x00,0x04,0x00,0x01,0x59,0x57}, --DVI1
|
|
{0x00,0xD7,0xFE,0x00,0x00,0x00,0x00,0x00,0x01,0x00,0x12,0x00,0x02,0x13,0x03,0x00,0x06,0x00,0x02,0x5D,0x57}, --DVI2
|
|
{0x00,0xD9,0xFE,0x00,0x00,0x00,0x00,0x00,0x01,0x00,0x12,0x00,0x02,0x13,0x03,0x00,0x07,0x00,0xA0,0xFE,0x57}, --USB
|
|
{},
|
|
{},
|
|
{},
|
|
},
|
|
PROHD = {
|
|
{0x00,0x2B,0xFE,0x00,0x00,0x00,0x00,0x00,0x01,0x00,0x22,0x00,0x20,0x02,0x01,0x00,0x1A,0xDE,0x56}, --SDI
|
|
{0x00,0x34,0xFE,0x00,0x00,0x00,0x00,0x00,0x01,0x00,0x22,0x00,0x20,0x02,0x01,0x00,0x1C,0xE9,0x56}, --DVI
|
|
{0x00,0x3F,0xFE,0x00,0x00,0x00,0x00,0x00,0x01,0x00,0x22,0x00,0x20,0x02,0x01,0x00,0x1B,0xF3,0x56}, --HDMI
|
|
{0x00,0x51,0xFE,0x00,0x00,0x00,0x00,0x00,0x01,0x00,0x22,0x00,0x20,0x02,0x01,0x00,0x1E,0x08,0x57}, --DP
|
|
{0x00,0x48,0xFE,0x00,0x00,0x00,0x00,0x00,0x01,0x00,0x22,0x00,0x20,0x02,0x01,0x00,0x17,0xF8,0x56}, --VGA
|
|
{0x00,0x5A,0xFE,0x00,0x00,0x00,0x00,0x00,0x01,0x00,0x22,0x00,0x20,0x02,0x01,0x00,0x02,0xF5,0x56}, --CVBS
|
|
{},
|
|
{},
|
|
{},
|
|
{},
|
|
},
|
|
PROUHDJR = {
|
|
{0x00,0x2B,0xFE,0x00,0x00,0x00,0x00,0x00,0x01,0x00,0x22,0x00,0x20,0x02,0x01,0x00,0x1A,0xDE,0x56}, --SDI
|
|
{0x00,0x34,0xFE,0x00,0x00,0x00,0x00,0x00,0x01,0x00,0x22,0x00,0x20,0x02,0x01,0x00,0x1C,0xE9,0x56}, --DVI
|
|
{0x00,0x3F,0xFE,0x00,0x00,0x00,0x00,0x00,0x01,0x00,0x22,0x00,0x20,0x02,0x01,0x00,0x1B,0xF3,0x56}, --HDMI
|
|
{0x00,0x51,0xFE,0x00,0x00,0x00,0x00,0x00,0x01,0x00,0x22,0x00,0x20,0x02,0x01,0x00,0x1E,0x08,0x57}, --DP
|
|
{},
|
|
{},
|
|
{},
|
|
{},
|
|
{},
|
|
{},
|
|
},
|
|
MCTRL4K = {
|
|
{0x00,0x3E,0xFE,0xFF,0x00,0x00,0x00,0x00,0x01,0x00,0x23,0x00,0x00,0x02,0x01,0x00,0x61,0x18,0x58}, --DVI
|
|
{0x00,0x8A,0xFE,0xFF,0x00,0x00,0x00,0x00,0x01,0x00,0x23,0x00,0x00,0x02,0x01,0x00,0x05,0x08,0x58}, --HDMI
|
|
{0x00,0x9D,0xFE,0xFF,0x00,0x00,0x00,0x00,0x01,0x00,0x23,0x00,0x00,0x02,0x01,0x00,0x5F,0x75,0x58}, --DP
|
|
{},
|
|
{},
|
|
{},
|
|
{},
|
|
{},
|
|
{},
|
|
{},
|
|
}
|
|
|
|
}
|
|
},
|
|
Response = {
|
|
Connected = {0xAA,0x55,0x00,0x00,0x00,0xFE,0x00,0x00,0x00,0x00,0x00,0x00,0x02,0x00,0x00,0x00,0x02,0x00,0x06,0x61,0xBE,0x56},
|
|
ConnectedAlt = {0xAA,0x55,0x00,0x00,0x00,0xFE,0x00,0x00,0x00,0x00,0x00,0x00,0x02,0x00,0x00,0x00,0x02,0x00,0x2a,0x61,0xe2,0x56}
|
|
},
|
|
|
|
}
|
|
-- NovaStar.socket.ReadTimeout = 0.5
|
|
|
|
function computeChecksum(bytes)
|
|
local sum = 0
|
|
for k,v in pairs(bytes) do
|
|
sum = sum + v
|
|
end
|
|
sum = sum + 0x5555
|
|
local sum_l = sum >> 8
|
|
local sum_h = sum & 0xFF
|
|
|
|
local checksum = {}
|
|
table.insert(checksum, sum_h)
|
|
table.insert(checksum, sum_l)
|
|
return checksum
|
|
end
|
|
|
|
function getCmdString(bytes)
|
|
local cmd = ""
|
|
for k,v in pairs(bytes) do
|
|
cmd = cmd .. string.pack("B", v)
|
|
end
|
|
return cmd
|
|
end
|
|
|
|
function sendCommand(cmd)
|
|
if NovaStar.socket.IsConnected then
|
|
print("Sending packet to connected NovaStar")
|
|
else
|
|
print("Following would have been sent if NovaStar was connected")
|
|
end;
|
|
print(hex_dump(getCmdString(cmd)))
|
|
if NovaStar.socket.IsConnected then
|
|
NovaStar.socket:Write(getCmdString(NovaStar.Commands.Preamble) .. getCmdString(cmd))
|
|
end
|
|
end
|
|
|
|
function sendBrightness(value)
|
|
local cmd = NovaStar.Commands.Brightness
|
|
cmd[17] = value
|
|
if NovaStar.socket.IsConnected then
|
|
NovaStar.socket:Write(getCmdString(NovaStar.Commands.Preamble) .. getCmdString(cmd) .. getCmdString(computeChecksum(cmd)))
|
|
end
|
|
end
|
|
|
|
function hex_dump (str)
|
|
local len = string.len( str )
|
|
local dump = ""
|
|
local hex = ""
|
|
local asc = ""
|
|
|
|
for i = 1, len do
|
|
if 1 == i % 8 then
|
|
dump = dump .. hex .. asc .. "\n"
|
|
hex = string.format( "%04x: ", i - 1 )
|
|
asc = ""
|
|
end
|
|
|
|
local ord = string.byte( str, i )
|
|
hex = hex .. string.format( "%02x ", ord )
|
|
if ord >= 32 and ord <= 126 then
|
|
asc = asc .. string.char( ord )
|
|
else
|
|
asc = asc .. "."
|
|
end
|
|
end
|
|
return dump .. hex .. string.rep( " ", 8 - len % 8 ) .. asc
|
|
end
|
|
|
|
NovaStar.socket.Connected = function()
|
|
print("TCP Connection Established to NovaStar @ " .. Properties['IP Address'].Value)
|
|
sendCommand(NovaStar.Commands.Connect)
|
|
end
|
|
|
|
NovaStar.socket.Reconnect = function()
|
|
NovaStar.setStatus(5,"Attempting to reconnect")
|
|
end
|
|
|
|
NovaStar.socket.Data = function ()
|
|
print("Reading " .. NovaStar.socket.BufferLength .. " Bytes")
|
|
local data = NovaStar.socket:Read(NovaStar.socket.BufferLength);
|
|
print(hex_dump(data))
|
|
|
|
if data == getCmdString(NovaStar.Response.Connected) then
|
|
print("Successful Connection Response Received")
|
|
NovaStar.setStatus(0,"Connected - " .. Properties['IP Address'].Value)
|
|
elseif data == getCmdString(NovaStar.Response.ConnectedAlt) then
|
|
print("Successful Connection Response Received")
|
|
NovaStar.setStatus(0,"Connected - " .. Properties['IP Address'].Value)
|
|
end
|
|
end
|
|
|
|
NovaStar.socket.Closed = function()
|
|
NovaStar.setStatus(2,"Connection closed by NovaStar")
|
|
end
|
|
|
|
NovaStar.socket.Error = function(sock, err)
|
|
print("TCP Socket Error: ", err)
|
|
NovaStar.setStatus(2,"Communication error with NovaStar")
|
|
end
|
|
|
|
NovaStar.socket.Timeout = function(sock, err)
|
|
NovaStar.setStatus(2,"Timeout in connection to NovaStar")
|
|
end
|
|
|
|
if Properties['Model'].Value ~= '' then
|
|
for k,v in pairs(NovaStar.Commands.Inputs[Properties['Model'].Value]) do
|
|
if (v ~= nil and #v > 1) then
|
|
print("value is not nill and length greater than 1")
|
|
Controls['IN'..k].EventHandler = function()
|
|
if(Properties['Model'].Value ~= 'VX6S') then
|
|
sendCommand(NovaStar.Commands.DisplayNormal)
|
|
else
|
|
sendCommand(NovaStar.Commands.DisplayNormalAlt)
|
|
end;
|
|
sendCommand(v)
|
|
end
|
|
else
|
|
if(k == 10) then
|
|
Controls['IN0'].IsDisabled = true;
|
|
Controls['IN0'].IsInvisible = true;
|
|
else
|
|
Controls['IN'..k].IsDisabled = true;
|
|
Controls['IN'..k].IsInvisible = true;
|
|
end;
|
|
end;
|
|
end
|
|
|
|
for k,v in pairs(NovaStar.Commands.TestPatterns) do
|
|
Controls['TEST'..k].EventHandler = function()
|
|
sendCommand(v)
|
|
end
|
|
end
|
|
end
|
|
|
|
|
|
Controls['Brightness'].EventHandler = function()
|
|
sendBrightness(Controls['Brightness'].Value)
|
|
end
|
|
|
|
if(Properties['IP Address'].Value ~= '') then
|
|
NovaStar.setStatus(5, 'Connecting to NovaStar');
|
|
NovaStar.socket:Connect(Properties['IP Address'].Value, 5200);
|
|
else
|
|
NovaStar.setStatus(3, '\nPlease set IP address.');
|
|
Controls['IN1'].IsDisabled = true;
|
|
Controls['IN2'].IsDisabled = true;
|
|
Controls['IN3'].IsDisabled = true;
|
|
Controls['IN4'].IsDisabled = true;
|
|
Controls['IN5'].IsDisabled = true;
|
|
Controls['IN6'].IsDisabled = true;
|
|
Controls['IN7'].IsDisabled = true;
|
|
Controls['IN8'].IsDisabled = true;
|
|
Controls['IN9'].IsDisabled = true;
|
|
Controls['IN0'].IsDisabled = true;
|
|
Controls['Brightness'].IsDisabled = true;
|
|
end;
|
|
|
|
end |