Thanks
I found an alternative in the mean time
Hereby the full script for anyone looking for a PJ Talk solution
add trigger scripts to call the functions in the user lib
I found an alternative in the mean time
Hereby the full script for anyone looking for a PJ Talk solution
Code:
--------------------------------------
-- Author: Nicky Wessels
-- Last Modified: 30/11/2017
--
-- Change Log:
-- 24/04/2016 Intial Version
-- 30/11/2017 Update Based on SDCP-Com - By Vokkim on JSDelivr
-- 30/11/2017 Javascript code https://github.com/vokkim/sony-sdcp-com
-- 30/11/2017 Protocol https://www.digis.ru/upload/iblock/f5a/VPL-VW320,%20VW520_ProtocolManual.pdf
--------------------------------------
-------------------------
-- CONFIG
-------------------------
-- IP of the projector
BASEMENT_PROJECTOR_IP = '192.168.0.21'
BASEMENT_PROJECTOR_PORT = '53484'
-------------------------
-- CONSTANTS
-------------------------
-- CONSTANTS
VERSION = '02'
CATEGORY = '0A'
-- Default to 'SONY'
COMMUNITY = '534F4E59'
actions = {
GET= '01',
SET= '00'
}
commands = {
SET_POWER= '0130',
CALIBRATION_PRESET= '0002',
ASPECT_RATIO= '0020',
INPUT= '0001',
GET_STATUS_ERROR= '0101',
GET_STATUS_POWER= '0102',
GET_STATUS_LAMP_TIMER= '0113'
}
input = {
HDMI1 = '0002',
HDMI2 = '0003',
}
aspectRatio = {
NORMAL= '0001',
V_STRETCH= '000B',
ZOOM_1_85= '000C',
ZOOM_2_35= '000D',
STRETCH= '000E',
SQUEEZE= '000F'
}
powerStatus = {
STANDBY= '0000',
START_UP= '0001',
START_UP_LAMP= '0002',
POWER_ON= '0003',
COOLING= '0004',
COOLING2= '0005'
}
-- set projector input
function setInput(input, ip, port, debug)
if (debug) then
log (string.format("setInput:%s projector:%s:%s", input, ip, port))
end
frame = createMessageAsHex(actions.SET, commands.INPUT, input, debug)
result = sony_sdcp_send_frame(frame, ip, port, debug)
return result
end
-- get projector input status
function getInputStatus(ip, port, debug)
if (debug) then
log (string.format("getInputStatus projector:%s:%s", ip, port))
end
frame = createMessageAsHex(actions.GET, commands.INPUT, nil, debug)
result = sony_sdcp_send_frame(frame, ip, port, debug)
inputStatus = nil
if (result and result.reply and result.reply.data) then
inputStatus = result.reply.data
end
return inputStatus
end
-- power projector on
function setPower(powerOn, ip, port, debug)
if (debug) then
log (string.format("powerOn:%s projector:%s:%s", tostring(powerOn), ip, port))
end
if (powerOn) then
frame = createMessageAsHex(actions.SET, commands.SET_POWER, powerStatus.START_UP, debug)
else
frame = createMessageAsHex(actions.SET, commands.SET_POWER, powerStatus.STANDBY, debug)
end
result = sony_sdcp_send_frame(frame, ip, port, debug)
return result
end
-- get projector power status
function getPowerStatus(ip, port, debug)
if (debug) then
log (string.format("getPowerStatus projector:%s:%s", ip, port))
end
frame = createMessageAsHex(actions.GET, commands.GET_STATUS_POWER, nil, debug)
result = sony_sdcp_send_frame(frame, ip, port, debug)
powerstatus = false
if (result and result.reply and result.reply.data) then
powerstatus = result.reply.data
end
return powerstatus
end
-- get projector power status as a boolean
function getPowerStatusAsBool(ip, port, debug)
if (debug) then
log (string.format("getPowerStatusAsBool projector:%s:%s", ip, port))
end
result = false
powerstatus = getPowerStatus(ip, port, debug)
if (powerstatus) then
result = powerstatus == powerStatus.POWER_ON or powerstatus == powerStatus.START_UP or powerstatus == powerStatus.START_UP_LAMP
end
return result
end
-- convert hex char array to string
function string.fromhex(str)
result =''
for c in str:gmatch"." do
result = result .. string.format("%02x", string.byte(c))
end
return string.upper(result)
end
-- convert string to hex char array
function string.tohex(str)
result =''
for cc in str:gmatch".." do
result = result .. string.char(tonumber(cc, 16))
end
return string.upper(result)
end
-- create a sdcp message
function createMessageAsHex(action, command, data, debug)
if (command and type(command) ~= "string") then
alert(string.format("Accepts command only as String (HEX) for now, was %s", type(command)))
end
if (string.len(command) ~= 4) then
alert(string.format("Command must be 4 bytes long"))
end
if (data and type(data) ~= "string") then
alert(string.format("Accepts data only as String (HEX) for now, was %s", type(data)))
end
if (not data) then
data = ""
end
dataLength = string.format('%02x', string.len(data)/2)
if (debug) then
-- log ("dataLength:" .. dataLength)
end
frame = VERSION .. CATEGORY.. COMMUNITY.. action.. command.. dataLength.. data
if (debug) then
-- log ("frame:" .. frame)
end
return string.tohex(frame)
end
-- parse a sdcp message
function parseResponse(value, debug)
if (not value) then
alert(string.format("Empty value passed"))
assert(not value, string.format("Empty value passed"))
end
frame = string.fromhex(value)
if (string.len(frame) < 20) then
alert(string.format("Unknown response %s, length %d",frame,string.len(frame)))
assert(string.len(frame) < 20, string.format("Unknown response %s",frame))
end
version = string.sub(frame, 1, 2)
category = string.sub(frame, 3, 4)
community = string.sub(frame, 5, 12)
success = string.sub(frame, 13, 14)
command = string.sub(frame, 15, 18)
dataLength = string.sub(frame, 19, 20)
if (tonumber(dataLength, 16) > 0) then
data = string.sub(frame,21, 21 + tonumber(dataLength, 16) * 2)
end
result = {
version=version,
category=category,
community=community,
command=command,
dataLength=dataLength,
data=data,
success=success ~= '00',
raw = frame
}
return result
end
-- funtion to send basic commands to the projector
function sony_sdcp_send_frame(frame, ip, port, debug)
require 'socket.http'
response_tbl = { }
-- fill up optional parameters
if (ip == nil) then
ip = BASEMENT_PROJECTOR_IP
end
if (port == nil) then
port = BASEMENT_PROJECTOR_PORT
end
response_tbl['ip']=ip
response_tbl['port']=port
response_tbl['frame']=frame
if (debug) then
log("ip:" .. ip)
log("port:" .. port)
log("transmit frame char:" .. string.fromhex(frame))
log("transmit frame hex:" .. frame)
log("transmit frame length:" .. string.len(frame))
end
-- Send command to projector
sock = socket.tcp()
sock:settimeout(3)
result, err = sock:connect(ip, port)
response_tbl['result']=result
response_tbl['error']=err
if result then
result, err = sock:send(frame .. "\r")
response_tbl['result']=result
response_tbl['error']=error
-- Check response from projector
if result then
if (debug) then
log ('transmit succesfully send')
end
-- read the response
resframe = ''
while true do
resp, err, part = sock:receive(1)
if resp ~= nil then
resframe = resframe .. resp
else
break
end
end
resstring = string.fromhex(resframe)
resdecoded = parseResponse(resframe)
response_tbl['reply']=resdecoded
if (debug and resframe) then
log("response frame char:" .. resstring)
log("response frame hex:" .. resframe)
log("response frame length:" .. string.len(resframe))
log("response frame decoded", resdecoded)
end
else
alert('send failed: ' .. tostring(err), response_tbl)
end
else
alert('connect failed: ' .. tostring(err), response_tbl)
end
sock:close()
return response_tbl
end
add trigger scripts to call the functions in the user lib
Code:
-- activate projector
setPower(bStatus, BASEMENT_PROJECTOR_IP, BASEMENT_PROJECTOR_PORT)
-- check if it is active or starting up
-- warning takes a few seconds before projector boots up
bPowerStatus = getPowerStatusAsBool(BASEMENT_PROJECTOR_IP, BASEMENT_PROJECTOR_PORT)
-- set the input
setInput(input.HDMI1, BASEMENT_PROJECTOR_IP, BASEMENT_PROJECTOR_PORT, true)
-- check the input state
sInputStatus = getInputStatus(BASEMENT_PROJECTOR_IP, BASEMENT_PROJECTOR_PORT)