首先,我有一个可行的解决方案,但它很容易失败。
我想从Logitech Squeeze Center打开我的放大器。
我已经能够从播放器向放大器发送CEC命令以将其打开。
我进一步开发了(来自网络代码片段的帮助)解决方案,以便SqueezeCenter中的界面,当按下电源按钮时,将TCP数据包发送到播放器运行bash脚本的播放器中turn向AMP发送一个CEC命令 - 为其供电。
按下相关播放器电源按钮时发送数据包的Perl插件注意我将其设置为只发送数据包给特定的餐厅播放器 - 但我希望将来能够找到按下电源按钮的播放器的IP,然后发送一个数据包。
package Plugins::PowerMonitor::Plugin;
use strict;
use IO::Socket;
use Slim::Utils::Log;
use Slim::Control::Request;
my $log = Slim::Utils::Log->addLogCategory(
{ category => 'plugin.powerMonitor',
defaultLevel => 'ERROR',
description => getDisplayName(),
}
);
sub getFunctions {
return '';
}
sub getDisplayName {
return 'PLUGIN_POWER_MONITOR';
}
sub initPlugin {
$log->debug("initPlugin");
# Subscribe to power events
Slim::Control::Request::subscribe( \&powerCallback, [ ['power'] ] );
}
sub shutdownPlugin {
$log->debug("shutdownPlugin");
Slim::Control::Request::unsubscribe( \&powerCallback );
}
sub powerCallback {
$log->debug("powerCallback");
my $request = shift;
my $client = $request->client() || return;
my $sock = IO::Socket::INET->new(
Proto => 'tcp',
PeerPort => 6500,
PeerAddr => '192.168.0.31',
);
if ( !$sock ) {
$log->error("Could not create socket: $!");
return;
}
my $msg = $client->id() . ':' . $client->name() . ':' . $client->power() . $/;
$log->debug($msg);
my $rc = $sock->send($msg);
if ( !$rc ) {
$log->error("Send error: $!");
}
}
播放器上的Bash脚本 - 它作为守护程序在侦听端口6500上的数据包上播放:
#!/bin/bash
netcat -lk 6500 | while read line
do
if echo $line | grep -q 'Dining_Room:1'
then
powerStatus=$(echo "pow 5" | cec-client -s -d 1 |grep "power status" |cut -d ' ' -f 3)
if [ "$powerStatus" = "standby" ]; then
echo "Powering On Amp....."
echo "on 5" | cec-client -s -d 1
fi
elif echo $line | grep -q 'Dining_Room:0'
then
powerStatus=$(echo "pow 5" | cec-client -s -d 1 |grep "power status" |cut -d ' ' -f 3)
if [ "$powerStatus" = "on" ]; then
echo "Powering Off Amp....."
echo "standby 5" | cec-client -s -d 1
fi
fi
done
非常精心设置,但这是我在Squeezebox的Perl插件方面必须使用的。
我想知道是否有一种更稳定的方法可以做到这一点,那会是什么 - 我可以调整当前设置以使其更稳定 - 我是否可以更改Perl脚本以在播放器上写入文件发送数据包和使用netcat(这个接缝是它破坏的地方)
我不了解Perl,但我非常精通Linux和bash脚本
更新29/08/2014: 关于它发送到播放器的IP的话题,看起来它实例化了一个$ client并且有一个名字的方法 - 我想知道还有什么可用 - 我希望我知道Perl。
答案 0 :(得分:0)
我决定改变我的方法,以便服务器SSH进入播放器并运行相关的脚本。
初步测试显示这比netcat更可靠。我无法使密钥auth工作,因此必须在脚本中输入密码。
Perl脚本:
package Plugins::PowerMonitor::Plugin;
use strict;
use warnings;
use IO::Socket;
use Slim::Utils::Log;
use Slim::Control::Request;
use Net::SSH::Any;
my $log = Slim::Utils::Log->addLogCategory( {
category => 'plugin.powerMonitor',
defaultLevel => 'ERROR',
description => getDisplayName(),
});
sub getFunctions {
return '';
}
sub getDisplayName {
return 'PLUGIN_POWER_MONITOR';
}
sub initPlugin {
$log->debug("initPlugin");
# Subscribe to power events
Slim::Control::Request::subscribe(
\&powerCallback,
[['power']]
);
}
sub shutdownPlugin {
$log->debug("shutdownPlugin");
Slim::Control::Request::unsubscribe( \&powerCallback );
}
sub powerCallback {
$log->debug("powerCallback");
my $request = shift;
my $client = $request->client() || return;
my $host = "192.168.0.31";
my $user = "pi";
my $pass = "myPassword";
my $ssh = Net::SSH::Any->new($host, user => $user, password => $pass);
if ($ssh->error) {
$log->error("whee...something wrong here: " . $ssh->error);
}
else {
my @out = $ssh->capture('nohup /home/pi/ampOn > foo.out 2> foo.err < /dev/null &');
$log->debug("@out");
}
}
改变了bash脚本:
#!/bin/bash
if [ ! -f /tmp/ampIsOn ]
then
powerStatus=$(echo "pow 5" | cec-client -s -d 1 |grep "power status" |cut -d ' ' -f 3)
if [ "$powerStatus" = "standby" ]; then
echo "Powering On Amp....."
echo "on 5" | cec-client -s -d 1
touch /tmp/ampIsOn
fi
else
powerStatus=$(echo "pow 5" | cec-client -s -d 1 |grep "power status" |cut -d ' ' -f 3)
if [ "$powerStatus" = "on" ]; then
echo "Powering Off Amp....."
echo "standby 5" | cec-client -s -d 1
rm /tmp/ampIsOn
fi
fi
如果某人有更好的解决方案或提示,我不会标记为正确。