--[[
-- Plugin for Pioneer VSX-2020, VSX-2021, VSX-1120 Amplifier and many VSX model
-- Pioneer VSX-822, VSX-42,use port 8102 instead of 23
-- Version 1.0.2 (11-13-2013)
-- Author: Jean-christophe Vermandé
--]]
local _deviceIp = fibaro:get(fibaro:getSelfId(), "IPAddress");
local _devicePort = fibaro:get(fibaro:getSelfId(), "TCPPort");
local _maxRetryProcess = 5;
-- Polling time (value in milliseconds)
local _polling = 5*60*1000;
local _trace = true;
local _volumeTable = {
"-80.0", "-79.5", "-79.0", "-78.5", "-78.0", "-77.5", "-77.0", "-76.5", "-76.0", "-75.5",
"-75.0", "-74.5", "-74.0", "-73.5", "-73.0", "-72.5", "-72.0", "-71.5", "-71.0", "-70.5",
"-70.0", "-69.5", "-69.0", "-68.5", "-68.0", "-67.5", "-67.0", "-66.5", "-66.0", "-65.5",
"-65.0", "-64.5", "-64.0", "-63.5", "-63.0", "-62.5", "-62.0", "-61.5", "-61.0", "-60.5",
"-60.0", "-59.5", "-59.0", "-58.5", "-58.0", "-57.5", "-57.0", "-56.5", "-56.0", "-55.5",
"-55.0", "-54.5", "-54.0", "-53.5", "-53.0", "-52.5", "-52.0", "-51.5", "-51.0", "-50.5",
"-50.0", "-49.5", "-49.0", "-48.5", "-48.0", "-47.5", "-47.0", "-46.5", "-46.0", "-45.5",
"-45.0", "-44.5", "-44.0", "-43.5", "-43.0", "-42.5", "-42.0", "-41.5", "-41.0", "-40.5",
"-40.0", "-39.5", "-39.0", "-38.5", "-38.0", "-37.5", "-37.0", "-36.5", "-36.0", "-35.5",
"-35.0", "-34.5", "-34.0", "-33.5", "-33.0", "-32.5", "-32.0", "-31.5", "-31.0", "-30.5",
"-30.0", "-29.5", "-29.0", "-28.5", "-28.0", "-27.5", "-27.0", "-26.5", "-26.0", "-25.5",
"-25.0", "-24.5", "-24.0", "-23.5", "-23.0", "-22.5", "-22.0", "-21.5", "-21.0", "-20.5",
"-20.0", "-19.5", "-19.0", "-18.5", "-18.0", "-17.5", "-17.0", "-16.5", "-16.0", "-15.5",
"-15.0", "-14.5", "-14.0", "-13.5", "-13.0", "-12.5", "-12.0", "-11.5", "-11.0", "-10.5",
"-10.0", "-9.5", "-9.0", "-8.5", "-8.0", "-7.5", "-7.0", "-6.5", "-6.0", "-5.5", "-5.0",
"-4.5", "-4.0", "-3.5", "-3.0", "-2.5", "-2.0", "-1.5", "-1.0", "-0.5", "+0.0", "+0.5",
"+1.0", "+1.5", "+2.0", "+2.5", "+3.0", "+3.5", "+4.0", "+4.5", "+5.0", "+5.5", "+6.0",
"+6.5", "+7.0", "+7.5", "+8.0", "+8.5", "+9.0", "+9.5", "+10.0", "+10.5", "+11.0",
"+11.5", "+12.0"};
device = device or {
id = fibaro:getSelfId(),
name = "Pioneer VSX-2021K",
online = false,
zones = {
{
power = false,
volume = 0,
mode = 0,
modeInfos = "unknown",
input = 0,
inputInfos = {number = "", default = "", name = ""}
},
{
power = false,
volume = 0,
mode = 0,
modeInfos = "unknown",
input = 0,
inputInfos = {number = "", default = "", name = ""}
}
}
};
function interceptErrorCode(msg)
if (msg:match("B00")) then
fibaro:debug("Now AV Receiver is Busy. Please wait few seconds.");
fibaro:sleep(2000);
return true;
elseif (msg:match("E04")) then
fibaro:debug("Detect inappropriate Command line.");
return true;
elseif (msg:match("E06")) then
fibaro:debug("Detect inappropriate Parameter.");
return true;
else
return false;
end
end
function trim(s)
return (string.gsub(s, "^%s*(.-)%s*$", "%1"))
end
function trace(value)
if (_trace) then
return fibaro:debug(tostring(value));
end
end
function getPower(zone, retry)
zone = zone or 1;
retry = retry or 0;
--write socket
fibaro:sleep(150);
bytes, errorCode = _tcpSocket:write("\r");
fibaro:sleep(150);
bytes, errorCode = _tcpSocket:write("\r?P\r");
fibaro:sleep(150);
if errorCode == 0 then
trace("?P cmd successufully transmited.");
local result = string.upper(_tcpSocket:read() or string.char());
-- look for Error message
interceptErrorCode(result);
-- parse response
local response = result:match("PWR(%d)");
if (response ~= nil) then
return tonumber(response);
else
return 0;
end
else
if retry < _maxRetryProcess then
trace("Retry process, please wait...");
fibaro:sleep(2000);
return getPower(zone, retry + 1);
end
return nil;
end
end
function getVolume(zone, retry)
zone = zone or 1;
retry = retry or 0;
--write socket
fibaro:sleep(300);
bytes, errorCode = _tcpSocket:write("\r");
fibaro:sleep(150);
bytes, errorCode = _tcpSocket:write("\r?V\r");
fibaro:sleep(150);
if errorCode == 0 then
trace("?V cmd successufully transmited.");
-- Should return VOL160<CR+LF> egg. if success
local result = string.upper(_tcpSocket:read() or string.char());
-- Look for Error message
interceptErrorCode(result);
-- Parse response...
local response = result:match("VOL(%d+)");
if (response ~= nil) then
return tonumber(response);
else
return 0;
end
else
if retry < _maxRetryProcess then
trace("Retry process, please wait...");
fibaro:sleep(2000);
return getVolume(zone, retry + 1);
end
return nil;
end
end
--Request Input Name information (?RGB**)
function getInputName(number, retry)
number = number or 1;
retry = retry or 0;
local response = {number = "", default = "", name = ""};
--write socket
fibaro:sleep(300);
bytes, errorCode = _tcpSocket:write("\r");
fibaro:sleep(150);
local command = string.format("?RGB%02d", number);
bytes, errorCode = _tcpSocket:write("\r"..command.."\r");
fibaro:sleep(150);
if errorCode == 0 then
trace(command.." command successufully transmited.");
-- Should return RGB**0<CR+LF> egg. if success
local result = string.upper(_tcpSocket:read() or string.char());
-- Look for Error message
local err = interceptErrorCode(result);
-- Parse response
if (err == false) then
response.number = result:match("RGB(%d%d)%d");
response.default = result:match("RGB%d%d(%d)");
response.name = result:match("RGB%d%d%d([%w_%s\/\\-]*)");
end
return response;
else
if retry < _maxRetryProcess then
trace("Retry process, please wait...");
fibaro:sleep(2000);
return getInputName(number, retry + 1);
end
return nil;
end
end
function getInput(zone, retry)
zone = zone or 1;
retry = retry or 0;
--write socket
fibaro:sleep(300);
bytes, errorCode = _tcpSocket:write("\r");
fibaro:sleep(150);
bytes, errorCode = _tcpSocket:write("\r?F\r");
fibaro:sleep(150);
if errorCode == 0 then
trace("?F cmd successufully transmited.");
-- Should return FN10<CR+LF> egg. if success
local result = string.upper(_tcpSocket:read() or string.char());
-- Look for Error message
interceptErrorCode(result);
-- Parse response...
local response = result:match("FN(%d+)") or -1;
if (tonumber(response) >= 0) then
return tonumber(response);
else
trace("Unable to decode response!");
return nil;
end
else
if retry < _maxRetryProcess then
trace("Retry process, please wait...");
fibaro:sleep(2000);
return getInput(zone, retry + 1);
end
return nil;
end
end
function refreshInterface()
if (device.zones[1].power == true) then
fibaro:call(device.id, "setProperty", "ui.lblPowerStatus.value", "ON");
-- update ui volume
if (device.zones[1].volume ~= nil) then
local label = string.format("%s dB", _volumeTable[device.zones[1].volume] or "");
local sliderValue = tonumber(math.floor(device.zones[1].volume/1.85));
fibaro:call(device.id, "setProperty", "ui.lblVolume.value", label);
fibaro:call(device.id, "setProperty", "ui.VolumeSlider.value", sliderValue);
end
-- update ui input
if (device.zones[1].input ~= nil) then
fibaro:call(device.id, "setProperty", "ui.lblInput.value", device.zones[1].inputInfos.number .. " - " .. device.zones[1].inputInfos.name);
end
else
fibaro:call(device.id, "setProperty", "ui.lblPowerStatus.value", "OFF");
fibaro:call(device.id, "setProperty", "ui.lblVolume.value", "---.- dB");
fibaro:call(device.id, "setProperty", "ui.VolumeSlider.value", "0");
fibaro:call(device.id, "setProperty", "ui.lblInput.value", "unknown");
end
if (device.online) then
fibaro:call(device.id, "setProperty", "ui.OnlineStatusLabel.value", "Online");
if (device.online) then
fibaro:setGlobal("Pioneernetwork", "Online");
else
fibaro:call(device.id, "setProperty", "ui.OnlineStatusLabel.value", "Offline");
fibaro:setGlobal("Pioneernetwork", "Offline");
end
end
return true;
end
function main()
-- prepare a global counter
if (_count == nil) then
trace("HC2 start script at " .. os.date());
_count = 0;
end
--notify begin of process
trace("Start process #".._count..", please wait...");
--open the socket
if (_tcpSocket == nil) then
_tcpSocket = Net.FTcpSocket(_deviceIp, _devicePort);
--set the read timeout
_tcpSocket:setReadTimeout(500);
end
-- Query power status
local power = getPower(1);
if (power ~= nil) then
-- flag as online
device.online = true;
if (power == 0) then
device.zones[1].power = true;
trace("Z1 Power is ON");
-- Query volume
device.zones[1].volume = getVolume(1);
trace("Z1 Volume is "..device.zones[1].volume);
-- Query input
device.zones[1].input = getInput(1);
trace("Z1 Input selected is "..device.zones[1].input);
-- Query input informations
device.zones[1].inputInfos = getInputName(device.zones[1].input);
trace("Z1 Input selected infor are "..device.zones[1].inputInfos.number .. " - " .. device.zones[1].inputInfos.name);
elseif (power == 1) then
device.zones[1].power = false;
trace("Z1 Power is OFF");
end
else
device.online = false;
end
-- call refresh interface to repaint UI
refreshInterface();
-- dispose socket
if (_tcpSocket ~= nil) then
-- close socket
_tcpSocket:disconnect();
-- destroy object
_tcpSocket = nil;
end
--notify end of process
trace("Process #".._count.." is finish!");
-- increment global counter
_count = _count + 1;
end
-- Start main loop process
main();
-- Sleep
fibaro:sleep(_polling);
-- EOF Main loop
Das sieh mir sehr mächtig aus… kann mir wer sagen welchen Codbereiche ich benötige um z.b. nur den Netwerkstatus im Main loop auszulesen.