Включите AMP с CEC из полученных пакетов TCP

Во-первых, у меня есть рабочее решение, но оно подвержено сбоям.

Я хотел бы включить свой усилитель из Logitech Squeeze Center.

  • Сервер работает на 192.168.0.30
  • Игрок в столовой работает на 192.168.0.31
  • Плеер подключен через HDMI к усилителю

Мне удалось отправить команды CEC от плеера на усилитель, чтобы включить его.

Я далее разработал (с помощью фрагментов кода из Интернета) решение, чтобы интерфейс в SqueezeCenter при нажатии кнопки питания отправлял TCP-пакет игроку, в котором проигрыватель запускает сценарий bash, и, в свою очередь, отправляет Команда CEC для AMP - включение.

Кнопка питания для плеера

Плагин 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

Очень сложная настройка, но это то, с чем я должен работать в плане плагинов Perl для Squeezebox.

Я хотел бы знать, есть ли более стабильный способ сделать это и что бы это было - могу ли я настроить текущую настройку, чтобы сделать ее более стабильной - могу ли я изменить скрипт Perl, чтобы записать файл на проигрыватель вместо отправки пакет и использование netcat (это швы, чтобы быть местом, где он ломается)

Я не знаю Perl, но довольно разбираюсь в Linux и bash-скриптах

ОБНОВЛЕНИЕ 29/08/2014: на тему отправки по IP-адресу проигрывателя похоже, что он создает экземпляр $ client и у него есть метод имени - интересно, что там еще есть - человек, я бы хотел знать Perl,

1 ответ

Решение

Я решил изменить свой подход, чтобы сервер передавал SSH в проигрыватель и запускал соответствующий скрипт.

Начальные тесты показывают, что это намного надежнее, чем netcat. Я не смог заставить работать ключ auth, поэтому пришлось ввести пароль в скрипт.

Perl Script:

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

Я не буду отмечать как правильный, но в случае, если у кого-то есть лучшие решения или подсказки.

Другие вопросы по тегам