2
0
Эх сурвалжийг харах

Allow firmware installation from LMS' player settings page

Michael Herger 3 жил өмнө
parent
commit
1a4a8ba559

+ 40 - 15
plugin/SqueezeESP32/FirmwareHelper.pm

@@ -38,26 +38,33 @@ sub init {
 }
 
 sub initFirmwareDownload {
-	my ($client) = @_;
+	my ($client, $cb) = @_;
 
 	Slim::Utils::Timers::killTimers($client, \&initFirmwareDownload);
 
+	return unless preferences('server')->get('checkVersion') || $cb;
+
 	Slim::Networking::SimpleAsyncHTTP->new(
 		sub {
 			my $http = shift;
 			my $content = eval { from_json( $http->content ) };
 
 			if ($content && ref $content) {
-				my $releaseInfo = _getFirmwareTag($content->{version});
+				my $releaseInfo = getFirmwareTag($content->{version});
 
 				if ($releaseInfo && ref $releaseInfo) {
-					prefetchFirmware($releaseInfo);
+					prefetchFirmware($releaseInfo, $cb);
+				}
+				else {
+					$cb->() if $cb;
 				}
 			}
 		},
 		sub {
 			my ($http, $error) = @_;
 			$log->error("Failed to get releases from Github: $error");
+
+			$cb->() if $cb;
 		},
 		{
 			timeout => 10
@@ -68,7 +75,7 @@ sub initFirmwareDownload {
 }
 
 sub prefetchFirmware {
-	my ($releaseInfo) = @_;
+	my ($releaseInfo, $cb) = @_;
 
 	return unless $releaseInfo;
 
@@ -93,15 +100,21 @@ sub prefetchFirmware {
 				}
 			}
 
-			downloadFirmwareFile(sub {
-				main::INFOLOG && $log->is_info && $log->info("Pre-cached firmware file: " . $_[0]);
-			}, sub {
-				my ($http, $error, $url, $code) = @_;
-				$error ||= ($http && $http->error) || 'unknown error';
-				$url   ||= ($http && $http->url) || 'no URL';
+			my $customFwUrl = sprintf('%s/plugins/SqueezeESP32/firmware/custom.bin', Slim::Utils::Network::serverURL()) if $cb && -f _customFirmwareFile();
+
+			if ( ($url && $url =~ /^https?/) || $customFwUrl ) {
+				downloadFirmwareFile(sub {
+					main::INFOLOG && $log->is_info && $log->info("Pre-cached firmware file: " . $_[0]);
+				}, sub {
+					my ($http, $error, $url, $code) = @_;
+					$error ||= ($http && $http->error) || 'unknown error';
+					$url   ||= ($http && $http->url) || 'no URL';
+
+					$log->error(sprintf("Failed to get firmware image from Github: %s (%s)", $error || $http->error, $url));
+				}, $url) if $url;
 
-				$log->error(sprintf("Failed to get firmware image from Github: %s (%s)", $error || $http->error, $url));
-			}, $url) if $url && $url =~ /^https?/;
+				$cb->($releaseInfo, _gh2lmsUrl($url), $customFwUrl) if $cb;
+			}
 		},
 		sub {
 			my ($http, $error) = @_;
@@ -115,6 +128,18 @@ sub prefetchFirmware {
 	)->get(GITHUB_RELEASES_URI);
 }
 
+sub _gh2lmsUrl {
+	my ($url) = @_;
+	my $ghPrefix = GITHUB_DOWNLOAD_URI;
+	my $baseUrl = Slim::Utils::Network::serverURL();
+	$url =~ s/$ghPrefix/$baseUrl\/plugins\/SqueezeESP32\/firmware\//;
+	return $url;
+}
+
+sub _customFirmwareFile {
+	return catfile(scalar Slim::Utils::OSDetect::dirsFor('updates'), 'squeezelite-esp32-custom.bin');
+}
+
 sub handleFirmwareDownload {
 	my ($httpClient, $response) = @_;
 
@@ -139,7 +164,7 @@ sub handleFirmwareDownload {
 	}
 
 	if ($path =~ $FW_CUSTOM_REGEX) {
-		my $firmwareFile = catfile(scalar Slim::Utils::OSDetect::dirsFor('updates'), 'squeezelite-esp32-custom.bin');
+		my $firmwareFile = _customFirmwareFile();
 
 		if (! -f $firmwareFile) {
 			main::INFOLOG && $log->is_info && $log->info("Failed to find custom firmware build: $firmwareFile");
@@ -167,7 +192,7 @@ sub downloadFirmwareFile {
 	my ($cb, $ecb, $url, $name) = @_;
 
 	# keep track of the last firmware we requested, to prefetch it in the future
-	my $releaseInfo = _getFirmwareTag($url);
+	my $releaseInfo = getFirmwareTag($url);
 
 	$name ||= basename($url);
 
@@ -207,7 +232,7 @@ sub downloadFirmwareFile {
 	return;
 }
 
-sub _getFirmwareTag {
+sub getFirmwareTag {
 	my ($info) = @_;
 
 	if (my ($model, $resolution, $version, $branch) = $info =~ $FW_TAG_REGEX) {

+ 12 - 0
plugin/SqueezeESP32/HTML/EN/plugins/SqueezeESP32/settings/player.html

@@ -2,6 +2,18 @@
 
 	[% WRAPPER setting title="PLUGIN_SQUEEZEESP32_FIRMWARE" desc="" %]
 		<div><a href="http://[% player_ip %]" target="_blank">[% "PLUGIN_SQUEEZEESP32_PLAYERSETTINGS" | string %] ([% player_ip %])</a></div>
+		[% IF fwUpdateAvailable %]
+			<div>
+				<input type="submit" name="installUpdate" class="stdclick" value="[% "CONTROLPANEL_INSTALL_UPDATE" | string %]"/>
+				[% fwUpdateAvailable %]
+			</div>
+		[% END %]
+		[% IF fwCustomUpdateAvailable %]
+			<div>
+				<input type="submit" name="installCustomUpdate" class="stdclick" value="[% "CONTROLPANEL_INSTALL_UPDATE" | string %]"/>
+				[% fwCustomUpdateAvailable | string %]
+			</div>
+		[% END %]
 	[% END %]
 
 	[% IF prefs.pref_width %]

+ 43 - 6
plugin/SqueezeESP32/PlayerSettings.pm

@@ -2,6 +2,7 @@ package Plugins::SqueezeESP32::PlayerSettings;
 
 use strict;
 use base qw(Slim::Web::Settings);
+use JSON::XS::VersionOneAndTwo;
 use List::Util qw(first);
 
 use Slim::Utils::Log;
@@ -36,7 +37,7 @@ sub prefs {
 }
 
 sub handler {
-	my ($class, $client, $paramRef) = @_;
+	my ($class, $client, $paramRef, $callback, @args) = @_;
 
 	my ($cprefs, @prefs) = $class->prefs($client);
 
@@ -62,7 +63,7 @@ sub handler {
 				x => $paramRef->{'pref_artwork_x'} || 0,
 				y => $paramRef->{'pref_artwork_y'} || 0,
 			};
-			
+
 			$cprefs->set('artwork', $artwork);
 			$client->display->modes($client->display->build_modes);
 			# the display update will be done below, after all is completed
@@ -76,14 +77,14 @@ sub handler {
 
 		}
 
-		if ($client->depth == 16) {
+		if ($client->can('depth') && $client->depth == 16) {
 			my $equalizer = $cprefs->get('equalizer');
 			for my $i (0 .. $#{$equalizer}) {
 				$equalizer->[$i] = $paramRef->{"pref_equalizer.$i"} || 0;
 			}
 			$cprefs->set('equalizer', $equalizer);
 			$client->update_tones($equalizer);
-		}		
+		}
 	}
 
 	if ($client->displayWidth) {
@@ -93,10 +94,46 @@ sub handler {
 		$paramRef->{'pref_artwork'} = $cprefs->get('artwork');
 	}
 
-	$paramRef->{'pref_equalizer'} = $cprefs->get('equalizer') if $client->depth == 16;
+	$paramRef->{'pref_equalizer'} = $cprefs->get('equalizer') if $client->can('depth') &&  $client->depth == 16;
 	$paramRef->{'player_ip'} = $client->ip;
 
-	return $class->SUPER::handler($client, $paramRef);
+	Plugins::SqueezeESP32::FirmwareHelper::initFirmwareDownload($client, sub {
+		my ($currentFWInfo, $newFWUrl, $customFwUrl) = @_;
+
+		$currentFWInfo ||= {};
+		my $newFWInfo = Plugins::SqueezeESP32::FirmwareHelper::getFirmwareTag($newFWUrl) || {};
+
+		if ($paramRef->{installUpdate} || $paramRef->{installCustomUpdate}) {
+			my $http = Slim::Networking::SimpleAsyncHTTP->new(sub {
+				main::INFOLOG && $log->is_info && $log->info("Firmware update triggered");
+			}, sub {
+				main::INFOLOG && $log->is_info && $log->info("Failed to trigger firmware update");
+				main::DEBUGLOG && $log->is_debug && $log->debug(Data::Dump::dump(@_));
+			})->post(sprintf('http://%s/config.json', $client->ip), to_json({
+				timestamp => int(Time::HiRes::time() * 1000) * 1,
+				config => {
+					fwurl => {
+						value => $paramRef->{installCustomUpdate} ? $customFwUrl : $newFWUrl,
+						type => 33
+					}
+				}
+			}));
+		}
+		else {
+			if ($currentFWInfo->{version} && $newFWInfo->{version} && $currentFWInfo->{version} > $newFWInfo->{version}) {
+				main::INFOLOG && $log->is_info && $log->info("There's an update for your SqueezeESP32 player: $newFWUrl");
+				$paramRef->{fwUpdateAvailable} = sprintf($client->string('PLUGIN_SQUEEZEESP32_FIRMWARE_AVAILABLE'), $newFWInfo->{version}, $currentFWInfo->{version});
+			}
+			if ($customFwUrl) {
+				main::INFOLOG && $log->is_info && $log->info("There's a custom firmware for your SqueezeESP32 player: $customFwUrl");
+				$paramRef->{fwCustomUpdateAvailable} = 'PLUGIN_SQUEEZEESP32_CUSTOM_FIRMWARE_AVAILABLE';
+			}
+		}
+
+		$callback->( $client, $paramRef, $class->SUPER::handler($client, $paramRef), @args );
+	});
+
+	return;
 }
 
 1;

+ 8 - 0
plugin/SqueezeESP32/strings.txt

@@ -24,6 +24,14 @@ PLUGIN_SQUEEZEESP32_PLAYERSETTINGS
 PLUGIN_SQUEEZEESP32_FIRMWARE
 	EN	Firmware
 
+PLUGIN_SQUEEZEESP32_FIRMWARE_AVAILABLE
+	DE	Es steht eine neue Firmware Version v%s zur Verfügung (aktuell installiert: v%s).
+	EN	A new firmware version v%s is available (currently installed: v%s).
+
+PLUGIN_SQUEEZEESP32_CUSTOM_FIRMWARE_AVAILABLE
+	DE	Es steht eine benutzerdefinierte Firmware Version zur Verfügung.
+	EN	A custom firmware image is available for installation.
+
 PLUGIN_SQUEEZEESP32_WIDTH
 	DE	Displaybreite
 	EN	Screen width