package Plugins::SqueezeESP32::RgbLed; =head1 NAME Plugins::SqueezeESP32::RgbLed =head1 DESCRIPTION L =cut use strict; use Slim::Utils::Strings qw(string cstring); use Slim::Utils::Log; use Slim::Utils::Prefs; use Plugins::SqueezeESP32::Player my $log = logger('player.RgbLed'); my $prefs = preferences('plugin.squeezeesp32'); my $log = logger('plugin.squeezeesp32'); sub init { Slim::Control::Request::subscribe( sub { onNotification(@_) }, [ ['playlist'], ['open', 'pause', 'resume', 'stop', 'clear'] ]); # register led visualizer comands to allow independant update and command line controls. Slim::Control::Request::addDispatch([ 'dmx', '_data', '_xoff'], [1, 0, 0, \&sendDMX]); Slim::Control::Request::addDispatch([ 'led_visual', '_mode', '_bright'], [1, 0, 0, \&setLEDVisu]); } my $VISUALIZER_NONE = 0; my $VISUALIZER_VUMETER = 1; my $VISUALIZER_SPECTRUM_ANALYZER = 2; my $VISUALIZER_WAVEFORM = 3; my @ledvisualizers = ( { desc => ['BLANK'], params => [$VISUALIZER_NONE], }, { desc => ['VISUALIZER_ANALOG_VUMETER'], params => [$VISUALIZER_VUMETER, 0], }, { desc => ['VISUALIZER_DIGITAL_VUMETER'], params => [$VISUALIZER_VUMETER, 1], }, { desc => ['VISUALIZER_SPECTRUM_ANALYZER'], params => [$VISUALIZER_SPECTRUM_ANALYZER, 0], }, { desc => ['VISUALIZER_SPECTRUM_ANALYZER','2'], params => [$VISUALIZER_SPECTRUM_ANALYZER, 1], }, { desc => ['PLUGIN_SQUEEZEESP32_WAVEFORM'], params => [$VISUALIZER_WAVEFORM, 0], }, { desc => ['PLUGIN_SQUEEZEESP32_WAVEFORM','2'], params => [$VISUALIZER_WAVEFORM, 1], }, ); my $nledvisualizers = $#ledvisualizers; sub ledVisualizerModes { return \@ledvisualizers; } sub ledVisualizerNModes { return $nledvisualizers; } sub updateLED { my $client = shift; my $on = shift || 1; my $cprefs = $prefs->client($client); my $visu = $cprefs->get('led_visualizer') || 0; my $bright = $cprefs->get('led_brightness') || 20; $visu = 0 if ($visu < 0 || $visu > ledVisualizerNModes || !(Slim::Player::Source::playmode($client) eq 'play') || !$on); my $modes = ledVisualizerModes; my $params = $modes->[$visu]{'params'}; my $data = pack('CCC', $params->[0], $params->[1], $bright); main::INFOLOG && $log->is_debug && $log->info("Sending visu mode $visu ", $client->name); $client->sendFrame( ledv => \$data ); } sub ledVisualParams { my $client = shift; my $visu = $prefs->client($client)->get('led_visualizer') || 0; return $ledvisualizers[$visu]{params}; } sub ledVisualModeOptions { my $client = shift; my $display = { '-1' => ' ' }; my $modes = ledVisualizerModes; my $nmodes = ledVisualizerNModes; for (my $i = 0; $i <= $nmodes; $i++) { my $desc = $modes->[$i]{'desc'}; for (my $j = 0; $j < scalar @$desc; $j++) { $display->{$i} .= ' ' if ($j > 0); $display->{$i} .= string(@{$desc}[$j]) || @{$desc}[$j]; } } return $display; } sub sendDMX { my $request = shift; # check this is the correct command. if ($request->isNotCommand([['dmx']])) { $request->setStatusBadDispatch(); return; } # get our parameters my $client = $request->client(); my $count = 0; my $outData; my @values = split(',', $request->getParam('_data') || ''); foreach my $val (@values) { $outData .= pack ( 'C', $val); $count++; } $count /= 3; my $data = pack('nn', $request->getParam('_xoff') || 0, $count ) . $outData; # changed from dmxt to ledd (matches 'ledc' for tricolor led in receiver player) $client->sendFrame( ledd => \$data ); } sub setLEDVisu { my $request = shift; # check this is the correct command. if ($request->isNotCommand([['led_visual']])) { $request->setStatusBadDispatch(); return; } my $client = $request->client(); return if (!$client->hasLED); my $cprefs = $prefs->client($client); my $visu = $cprefs->get('led_visualizer') || 0; my $mode = $request->getParam('_mode') || -1; if ($mode == -1) { $visu+=1; } else { $visu = $mode; } $visu = 0 if ($visu < 0 || $visu > ledVisualizerNModes); $cprefs->set('led_visualizer', $visu); my $bright = $request->getParam('_bright') || -1; if ($bright >= 0 && $bright < 256) { $cprefs->set('led_brightness', $bright); } updateLED($client); # display name my $modes = ledVisualizerModes; my $desc = $modes->[$visu]{'desc'}; my $name = ''; for (my $j = 0; $j < scalar @$desc; $j++) { $name .= ' ' if ($j > 0); $name .= $client->string(@{$desc}[$j]) || @{$desc}[$j]; } $client->showBriefly( { 'line1' => $client->string('PLUGIN_SQUEEZEESP32_LED_VISUALIZER'), 'line2' => $name, }); } sub onNotification { my $request = shift; my $client = $request->client || return; foreach my $player ($client->syncGroupActiveMembers) { next unless $player->isa('Plugins::SqueezeESP32::Player'); updateLED($player) if $player->hasLED; } } sub setMainMode { my $client = shift; my $method = shift; if ($method eq 'pop') { Slim::Buttons::Common::popMode($client); $client->update(); return; } Slim::Buttons::Common::pushModeLeft($client, 'INPUT.Choice', { 'listRef' => [ { name => string('PLUGIN_SQUEEZEESP32_LED_VISUALIZER'), onPlay => sub { Slim::Control::Request::executeRequest($client, ['led_visual']); }, }, { name => string('PLUGIN_SQUEEZEESP32_LED_BRIGHTNESS'), onPlay => sub { Slim::Buttons::Common::pushModeLeft($client, 'squeezeesp32_ledvu_bright'); }, }, ], 'header' => string('PLUGIN_SQUEEZEESP32'), 'headerAddCount' => 1, 'overlayRef' => sub { return (undef, shift->symbols('rightarrow')) }, }); } sub setLedvuBrightMode { my $client = shift; my $method = shift; if ($method eq 'pop') { Slim::Buttons::Common::popMode($client); $client->update(); return; } my $bright = $prefs->client($client)->get('led_brightness'); Slim::Control::Request::executeRequest($client, ['led_visual',1,$bright]); Slim::Buttons::Common::pushMode($client, 'INPUT.Bar', { 'header' => 'PLUGIN_SQUEEZEESP32_LED_BRIGHTNESS', 'stringHeader' => 1, 'headerValue' => 'unscaled', 'min' => 1, 'max' => 255, 'increment' => 1, 'onChange' => sub { my ($client, $value) = @_; $bright = $bright + $value; if ($bright > 0 && $bright <= 255) { $prefs->client($client)->set('led_brightness', $bright); updateLED($client); } }, 'valueRef' => $bright, }); } 1;