Skip to content

newPlayerCheck powers players off at every server start, with no code path to power them back on #44

Description

@nzilberberg

Plugin version: 5.4.5
Server: Lyrion Music Server 9.0.3 (Windows)
Players: Squeezebox Boom / Classic hardware, pref_Enabled: 1, zones 0 and 1

Symptom

Every time the server starts, players enabled in the plugin come up powered off. LMS itself restores them correctly; the plugin then turns them off at runtime. The players stay off until powered on by hand. Nothing in the LMS settings affects this, because it is not an LMS setting.

Cause

newPlayerCheck is subscribed at Plugin.pm:291 to [['client'],['new','reconnect']]. Every server start causes each player to reconnect, so the callback runs, and this block at Plugin.pm:475 powers the player off:

if ($client->power()) {    # turn the player off if currently on, to avoid confusion
    $log->debug("Turning " . $client->name() . " off to sync with plugin\n");
    $iPowerState{$client,$zone} = 0;
    my $request = $client->execute([('power', 0)]);
    $request->addResult('denonavpcontrolInitiated', 1);
}

This is intentional and documented — the V4.6 changelog entry (2022/06/01) says: "When a new player registers with the plugin and is already powered 'on', power it off first in order to avoid later confusion as to its status."

Why this leaves the player stranded

There is no code path in the plugin that transitions an LMS player from off to on. Across the whole of Plugin.pm:

  • Three power-off sites: lines 478, 2698, 3577
  • One power-on site: line 2210

and that single power-on sits in the elsif branch of if (!$client->power()), so it only executes when the player is already on (its inline comment is # power AVR on — it exists to wake the AVR, not the player).

So the startup power-off is one-way.

pref_PowerSynch does not mitigate it

Two reasons:

  1. Line 475 fires regardless of pref_PowerSynch.
  2. In syncPowerState, the $avrPower == 1 branch only sets $iPowerOnInProgress and schedules handleVolumeRequest — it never issues power 1. Only the else branch (AVR off) issues execute([('power', 0)]).

Note that syncPowerState logs this at line 2689:

$log->debug("Turning player " . $player . ($avrPower ? " ON" : " OFF") . " to sync with AVR\n");

When $avrPower == 1 this logs "Turning player X ON to sync with AVR" while the code never performs that action. That message is misleading when debugging.

Why the original rationale may no longer hold

The V4.6 justification was sound at the time: the plugin had no way to know the AVR's actual power state, so it forced a known-consistent one. But polling-based power synchronisation arrived in V5.2 (2024/8/10), over two years later. When power polling is enabled the plugin can determine AVR state, so unconditionally forcing the player off at registration looks like an oversight that predates polling rather than a deliberate current design.

Possible fixes

Any of these would resolve it; the maintainer is better placed to choose:

  1. Skip the block when power polling is enabled, and let the first poll establish the true state.
  2. Query AVR power at registration and sync the player to it rather than forcing off.
  3. Make the behaviour a user preference, defaulting to current behaviour for compatibility.

Separately, the syncPowerState debug string could be corrected so it does not claim an action the code does not take.

Workaround

Commenting out the block at Plugin.pm:475-481 resolves it. With that block disabled, the enabled players come back powered on after a cold server restart — verified by querying the LMS CLI on a freshly started server and getting power 1 for each of them. $iPowerState is already initialised to 0 just above that block, so the plugin still assumes the AVR is off and the first Play re-syncs it through commandCallback.

I appreciate the work on this plugin — happy to test any change or provide further logs.

Metadata

Metadata

Assignees

Labels

No labels
No labels

Projects

No projects

Milestone

No milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions