Home of the Squeezebox™ & Transporter® network music players.
Page 1 of 5 123 ... LastLast
Results 1 to 10 of 44
  1. #1
    Senior Member Aesculus's Avatar
    Join Date
    Jan 2008
    Posts
    414

    Adding a player parameter

    Can a plugin add a parameter to a player that can be seen by other plugins without knowing the origin? ie the parameter could be queried by any program or plugin in the system by the player itself versus as a parameter of a given plugin.

    We would like to be able to create a parameter that can be exchanged, or at least viewed by various components that is plugin independent.

    For example a parameter that announces to interested programs that at least one plugin has verified that it will be able to respond to volume changes in the player even when the user has the volume set to 100% fixed.
    Chris

  2. #2
    Quote Originally Posted by Aesculus View Post
    Can a plugin add a parameter to a player that can be seen by other plugins without knowing the origin? ie the parameter could be queried by any program or plugin in the system by the player itself versus as a parameter of a given plugin.

    We would like to be able to create a parameter that can be exchanged, or at least viewed by various components that is plugin independent.

    For example a parameter that announces to interested programs that at least one plugin has verified that it will be able to respond to volume changes in the player even when the user has the volume set to 100% fixed.
    #1: nested CLI commands

    One option would be to devise a new CLI query command. Any plugin could implement it via addDispatch. And if a plugin saw that some other plugin had registered that command and did not control the volume for the player in question, it should gracefully call the other registered implementation -- for instance, somebody might have both Denon-specific and Yamaha-specific RS232 plugins loaded, and use each for different Squeezeboxes. Maybe the command would look like
    Code:
    00:04:20:11:22:33 hasexternalvolumecontrol ?
    with the response of "0" for "no", "1" for yes, and maybe "+/-" for a player using something like IR Blaster that can take "up"/"down" changes but cannot accept exact volumes. Or maybe there should be a separate query to differentiate between the precise control Denon allows and the up/down control of IR Blaster, e.g.
    Code:
    00:04:20:11:22:33 preciseexternalvolume ?
    and plugins like DenonAVP Control and DenonSerial would indicate "1" for both (and iPeng would give those players normal UI treatment). A player for which preciseexternalvolume was 0 might have simple Up/Down controls in software like iPeng but not have nicer features like relative volume change with sync group partners. If an app like iPeng got CLI errors (as with SBS systems that didn't have external volume control plugins installed), it would treat those as equivalent to "0". Apps like iPeng should only need to query once per player per invocation of the control app -- if a user enabled or disabled Denon AVP Control, it's reasonable to expect he should restart iPeng.

    #2: agreed-upon client prefs

    Alternately, you could simply set a preference in the "server" space, e.g.
    Code:
    preferences('server')->client($client)->set('x-external-volume','1');
    preferences('server')->client($client)->set('x-external-precise-volume','1');
    but the trick would be that you should probably unset that from a shutdownPlugin() method in case the user restarted SBS with your plugin disabled --but only for players for which you control external volume!

    Or we could agree on a new preference namespace and do something like
    Code:
    preferences('volumecontrol')->client($client)->set('external','1');
    preferences('volumecontrol')->client($client)->set('precise','1');
    #3: notifications

    A third option would be a twist on the first. Is it easy for iPeng to subscribe to notifications from SBS? If so, we could agree on a CLI command to request external volume info, e.g. iPeng could send a single CLI command like
    Code:
    getexternalvolumeinfo
    and each plugin like ours would use the notifyFromArray() API to give information about any players for which it controlled external amp volume, e.g.
    Code:
    Slim::Control::Request::notifyFromArray($client, ['externalvolume', 1, 1]);
    might signify that $client had external volume control despite the 100% locking (the first "1") and that its volume could be controlled precisely (the second "1", e.g. mixer volume 50 vs. mixer volume +10). iPeng would subscribe to 'externalvolume' notifications and process any it got after sending the 'getexternalvolume' command. This 3rd option might be the easiest for plugin developers, and least likely to have problems if a user had a mix of different external volume control plugins, as all plugins could share pretty much the same code for implementing 'getexternalvolume'.
    owner of the stuff at https://tuxreborn.netlify.app/
    (which used to reside at www.tux.org/~peterw/)
    Note: The best way to reach me is email or PM, as I don't spend much time on the forums.
    Free plugins: AllQuiet Auto Dim/AutoDisplay BlankSaver ContextMenu DenonSerial
    FuzzyTime KidsPlay KitchenTimer PlayLog PowerCenter/BottleRocket SaverSwitcher
    SettingsManager SleepFade StatusFirst SyncOptions VolumeLock

  3. #3
    Senior Member Aesculus's Avatar
    Join Date
    Jan 2008
    Posts
    414
    And the last even easier for us to implement but not necessarily for Pippin is that he add a setting for a player through his settings page that states it should still process volume controls even though the volume is locked at 100%. That only solves the problem for iPeng though and it puts all the pressure on Pippin and the user to manage it.

    I am worried that without some way to back out settings (as you have described above) then one plugin could add a setting and not have a way to remove it (it would have to be done during the clearCallback? routine) without effecting someone elses rights to the same feature (for example someone replaced my plugin with yours and I took the parameter away when I was disabled).
    Chris

  4. #4
    Senior Member pippin's Avatar
    Join Date
    Oct 2007
    Location
    Berlin
    Posts
    14,781
    Well, I kind of like #3 but would especially prefer it if IRBlaster could buy into this, too.

    The most simple solution is of course #2, but as Aesculus pointed out, that does have some issues with reverting the setting. Even today I did have several occasions (not just you ) where people had left-over IRBlaster settings in their prefs after uninstalling IRBlaster so iPeng erroneously uses that control.

    I believe the UNDERLYING issue here is a broken state model.
    The player reports a state to the client (iPeng; state = "you can't control my volume") while in between a plugin gets in the way and tries to do exactly that (control the volume).
    In a proper state model, the server would report an effective state, independent of which kind of flag is set on the player side so that you can hook into that logic.
    After all: what is the sense of this player state (digitalVolumeControl = 0) if all clients just ignore it? After all, this occupies quite a bit of bandwidth since it's sent every 10s to each Squeezeplay based client plus every 30s to the WebUI. Pretty much for something supposed to be ignored.

    So I still believe the _real_ solution would be a way to get into the state model and modify that very state before it gets sent to the client (controller).
    ---
    learn more about iPeng, the iPhone and iPad remote for the Squeezebox and
    Logitech UE Smart Radio as well as iPeng Party, the free Party-App,
    at penguinlovesmusic.com
    New: iPeng 9, the Universal App for iPhone, iPad and Apple Watch

  5. #5
    Senior Member Aesculus's Avatar
    Join Date
    Jan 2008
    Posts
    414
    Quote Originally Posted by pippin View Post
    Well, I kind of like #3 but would especially prefer it if IRBlaster could buy into this, too.
    I am ready to do #3 and its sounds like Peter is too. 2 out of 3 ain't bad :-)

    Perhaps you can influence IRBLASTER
    Felix Mueller <felix(dot)mueller(at)gwendesign(dot)com>
    to join in too.
    Chris

  6. #6

    sample implementation

    two changes:
    1) the notification must use an existing CLI command name, so the notification here uses the same name as the CLI command that's used to request info
    2) I added another argument to the notifications -- a string naming the plugin that provides the external volume control

    Obviously usingDenonSerial() is a method I wrote (already had it) to report true if a given player used my plugin for external amp/volume control, and you'll need to replace this with your own logic.

    If this works OK, I'd be happy to take a stab at a patch for IR Blaster -- hopefully Felix will be amenable to including that in a new release. If this doesn't work well, no need to bother him. :-)

    Code:
    # --------------------------------------- external volume indication code -------------------------------
    # at the top of Plugin.pm, define a scalar to hold a pointer to the getexternalcolumeinfo CLI command
    #       my $getexternalvolumeinfoCoderef;
    # set $getexternalvolumeinfoCoderef in the initPlugin() method with a line like the following:
    #       $getexternalvolumeinfoCoderef = Slim::Control::Request::addDispatch(['getexternalvolumeinfo'],[0, 0, 0, \&getexternalvolumeinfoCLI]);
    
    sub getexternalvolumeinfoCLI {
            my @args = @_;
            &reportOnOurPlayers();
            if ( defined($getexternalvolumeinfoCoderef) ) {
                    # chain to the next implementation
                    return &$getexternalvolumeinfoCoderef(@args);
            }
            # else we're authoritative
            my $request = $args[0];
            $request->setStatusDone();
    }
    
    sub reportOnOurPlayers() {
            # loop through all currently attached players
            foreach my $client (Slim::Player::Client::clients()) {
                    if (&usingDenonSerial($client) ) {
                            # using our volume control, report on our capabilities
                            $log->debug("Note that ".$client->name()." uses us for external volume control");
                            Slim::Control::Request::notifyFromArray($client, ['getexternalvolumeinfo', 1,   1,   string(&getDisplayName())]);
                            #                                                                          ^ uses software-controlled external volume
                            #                                                                            despite SB output being fixed at 100%
                            #                                                                               ^ can set precise volumes (vs relative changes)
                            #                                                                                     ^ string identifying who provides this control
                    }
            }
    }
    
            
    # --------------------------------------- external volume indication code -------------------------------
    Last edited by peterw; 2010-01-26 at 22:47. Reason: fix code problems
    owner of the stuff at https://tuxreborn.netlify.app/
    (which used to reside at www.tux.org/~peterw/)
    Note: The best way to reach me is email or PM, as I don't spend much time on the forums.
    Free plugins: AllQuiet Auto Dim/AutoDisplay BlankSaver ContextMenu DenonSerial
    FuzzyTime KidsPlay KitchenTimer PlayLog PowerCenter/BottleRocket SaverSwitcher
    SettingsManager SleepFade StatusFirst SyncOptions VolumeLock

  7. #7
    Oh, and I just published DenonSerial version 0.1.29 to my test repository, http://www.tux.org/~peterw/slim/slim7/repodata-test.xml, with this code in place. I haven't tested it with an Ethernet-equipped Denon, but it should work with your gear if you set Amplifier Connection Type to "Network address" and put your Denon's IP in the Amplifier Address field. Watch the poll interval numbers; it looks like those might not be defaulting to sane values. The defaults should be 2 for active, and 5 for idle. Good news is that the code (in one spot intentionally, and in another accidentally) seems to treat poll frequency 0 as "do not poll".

    Actually, I'd love to hear if it works OK with your real gear. I've tested my lesser amp using a netbook running serial port software, but don't have access to a nicer, Ethernet-equipped Denon amp. :-)
    owner of the stuff at https://tuxreborn.netlify.app/
    (which used to reside at www.tux.org/~peterw/)
    Note: The best way to reach me is email or PM, as I don't spend much time on the forums.
    Free plugins: AllQuiet Auto Dim/AutoDisplay BlankSaver ContextMenu DenonSerial
    FuzzyTime KidsPlay KitchenTimer PlayLog PowerCenter/BottleRocket SaverSwitcher
    SettingsManager SleepFade StatusFirst SyncOptions VolumeLock

  8. #8
    Senior Member Aesculus's Avatar
    Join Date
    Jan 2008
    Posts
    414
    OK. If Pippin sends us a beta iPeng we can give it a try.

    Do you think we need to have an option for people to ask us to support this? ie in my last attempt I had a setting to indicate they wanted to support volume passthrough.
    Last edited by Aesculus; 2010-01-25 at 21:27.
    Chris

  9. #9
    Senior Member Aesculus's Avatar
    Join Date
    Jan 2008
    Posts
    414
    Quote Originally Posted by peterw View Post
    Oh, and I just published DenonSerial version 0.1.29 to my test repository, http://www.tux.org/~peterw/slim/slim7/repodata-test.xml, with this code in place. I haven't tested it with an Ethernet-equipped Denon, but it should work with your gear if you set Amplifier Connection Type to "Network address" and put your Denon's IP in the Amplifier Address field. Watch the poll interval numbers; it looks like those might not be defaulting to sane values. The defaults should be 2 for active, and 5 for idle. Good news is that the code (in one spot intentionally, and in another accidentally) seems to treat poll frequency 0 as "do not poll".

    Actually, I'd love to hear if it works OK with your real gear. I've tested my lesser amp using a netbook running serial port software, but don't have access to a nicer, Ethernet-equipped Denon amp. :-)
    ON - worked
    Code:
    0027: [10-01-25 20:52:40.5687] Plugins::DenonSerial::Plugin::closeTCPSocket (628) closing TCP connection for IP:192.168.1.102
    0026: [10-01-25 20:52:38.5769] Plugins::DenonSerial::Plugin::processResponses (733) for 00:04:20:16:5f:a0, command "MV?", process response "MVMAX 705"
    0025: [10-01-25 20:52:38.5689] Plugins::DenonSerial::Plugin::processResponses (733) for 00:04:20:16:5f:a0, command "MV?", process response "MV45"
    0024: [10-01-25 20:52:38.2886] Plugins::DenonSerial::Plugin::getResponse (513) for 00:04:20:16:5f:a0, command "MV?", got response "MVMAX 705" from remote host
    0023: [10-01-25 20:52:38.2794] Plugins::DenonSerial::Plugin::getResponse (513) for 00:04:20:16:5f:a0, command "MV?", got response "MV45" from remote host
    0022: [10-01-25 20:52:38.2702] Plugins::DenonSerial::Plugin::getResponse (480) for 00:04:20:16:5f:a0, indicate we're done with the current command since we're reading responses, queue length now 1
    0021: [10-01-25 20:52:38.2619] Plugins::DenonSerial::Plugin::processCommandFromQueue (409) look for response for 00:04:20:16:5f:a0 command MV?
    0020: [10-01-25 20:52:37.9917] Plugins::DenonSerial::Plugin::processCommandFromQueue (447) not done with queue
    0019: [10-01-25 20:52:37.9835] Plugins::DenonSerial::Plugin::sendCommand (886) for 00:04:20:16:5f:a0, indicate we're working on a command, queue length now 1
    0018: [10-01-25 20:52:37.9727] Plugins::DenonSerial::Plugin::sendCommand (815) send command: (connection IP, address 192.168.1.102, command MV?)
    0017: [10-01-25 20:52:37.9644] Plugins::DenonSerial::Plugin::processCommandFromQueue (436) for 00:04:20:16:5f:a0 , send command MV?, queue length 1
    0016: [10-01-25 20:52:37.8311] Plugins::DenonSerial::Plugin::processCommandFromQueue (447) not done with queue
    0015: [10-01-25 20:52:37.8227] Plugins::DenonSerial::Plugin::processResponses (733) for 00:04:20:16:5f:a0, command "PWON", process response "ZMON"
    0014: [10-01-25 20:52:37.8143] Plugins::DenonSerial::Plugin::processResponses (733) for 00:04:20:16:5f:a0, command "PWON", process response "PWON"
    0013: [10-01-25 20:52:37.7148] Plugins::DenonSerial::Plugin::getResponse (513) for 00:04:20:16:5f:a0, command "PWON", got response "ZMON" from remote host
    0012: [10-01-25 20:52:37.4667] Plugins::DenonSerial::Plugin::getResponse (513) for 00:04:20:16:5f:a0, command "PWON", got response "PWON" from remote host
    0011: [10-01-25 20:52:37.4556] Plugins::DenonSerial::Plugin::getResponse (480) for 00:04:20:16:5f:a0, indicate we're done with the current command since we're reading responses, queue length now 2
    0010: [10-01-25 20:52:37.4472] Plugins::DenonSerial::Plugin::processCommandFromQueue (409) look for response for 00:04:20:16:5f:a0 command PWON
    0009: [10-01-25 20:52:37.0667] Plugins::DenonSerial::Plugin::processCommandFromQueue (447) not done with queue
    0008: [10-01-25 20:52:37.0588] Plugins::DenonSerial::Plugin::sendCommand (886) for 00:04:20:16:5f:a0, indicate we're working on a command, queue length now 2
    0007: [10-01-25 20:52:37.0448] Plugins::DenonSerial::Plugin::sendCommand (842) opening control socket to 192.168.1.102:23
    0006: [10-01-25 20:52:37.0342] Plugins::DenonSerial::Plugin::sendCommand (818) send command: (connection IP, address 192.168.1.102, command PWON)
    0005: [10-01-25 20:52:37.0259] Plugins::DenonSerial::Plugin::processCommandFromQueue (436) for 00:04:20:16:5f:a0 , send command PWON, queue length 2
    0004: [10-01-25 20:52:35.7411] Plugins::DenonSerial::Plugin::enqueue (380) run MV? for 00:04:20:16:5f:a0 at next convenience
    0003: [10-01-25 20:52:35.7303] Plugins::DenonSerial::Plugin::enqueue (384) indicate that processCommandFromQueue() should run
    0002: [10-01-25 20:52:35.7211] Plugins::DenonSerial::Plugin::enqueue (380) run PWON for 00:04:20:16:5f:a0 at next convenience
    0001: [10-01-25 20:52:35.7114] Plugins::DenonSerial::Plugin::turnAmpOn (1133) turning amp on for Family Room
    Chris

  10. #10
    Senior Member Aesculus's Avatar
    Join Date
    Jan 2008
    Posts
    414
    OFF - did not work
    Code:
    0042: [10-01-25 20:55:32.5889] Plugins::DenonSerial::Plugin::closeTCPSocket (628) closing TCP connection for IP:192.168.1.102
    0041: [10-01-25 20:55:30.5821] Plugins::DenonSerial::Plugin::processResponses (733) for 00:04:20:16:5f:a0, command "PW?", process response "PWON"
    0040: [10-01-25 20:55:30.3014] Plugins::DenonSerial::Plugin::getResponse (513) for 00:04:20:16:5f:a0, command "PW?", got response "PWON" from remote host
    0039: [10-01-25 20:55:30.2912] Plugins::DenonSerial::Plugin::getResponse (480) for 00:04:20:16:5f:a0, indicate we're done with the current command since we're reading responses, queue length now 1
    0038: [10-01-25 20:55:30.2828] Plugins::DenonSerial::Plugin::processCommandFromQueue (409) look for response for 00:04:20:16:5f:a0 command PW?
    0037: [10-01-25 20:55:29.8858] Plugins::DenonSerial::Plugin::processCommandFromQueue (447) not done with queue
    0036: [10-01-25 20:55:29.8776] Plugins::DenonSerial::Plugin::sendCommand (886) for 00:04:20:16:5f:a0, indicate we're working on a command, queue length now 1
    0035: [10-01-25 20:55:29.8669] Plugins::DenonSerial::Plugin::sendCommand (815) send command: (connection IP, address 192.168.1.102, command PW?)
    0034: [10-01-25 20:55:29.8585] Plugins::DenonSerial::Plugin::processCommandFromQueue (436) for 00:04:20:16:5f:a0 , send command PW?, queue length 1
    0033: [10-01-25 20:55:29.7369] Plugins::DenonSerial::Plugin::processCommandFromQueue (447) not done with queue
    0032: [10-01-25 20:55:29.7272] Plugins::DenonSerial::Plugin::processResponses (733) for 00:04:20:16:5f:a0, command "SI?", process response "SVSOURCE"
    0031: [10-01-25 20:55:29.7160] Plugins::DenonSerial::Plugin::processResponses (733) for 00:04:20:16:5f:a0, command "SI?", process response "SICD"
    0030: [10-01-25 20:55:29.7077] Plugins::DenonSerial::Plugin::processResponses (733) for 00:04:20:16:5f:a0, command "SI?", process response "MVMAX 705"
    0029: [10-01-25 20:55:29.6863] Plugins::DenonSerial::Plugin::updateSBVolume (332) for Family Room amp volume 45 =~ SB volume 65
    0028: [10-01-25 20:55:29.6770] Plugins::DenonSerial::Plugin::processResponses (733) for 00:04:20:16:5f:a0, command "SI?", process response "MV45"
    0027: [10-01-25 20:55:29.3063] Plugins::DenonSerial::Plugin::getResponse (513) for 00:04:20:16:5f:a0, command "SI?", got response "SVSOURCE" from remote host
    0026: [10-01-25 20:55:29.2969] Plugins::DenonSerial::Plugin::getResponse (513) for 00:04:20:16:5f:a0, command "SI?", got response "SICD" from remote host
    0025: [10-01-25 20:55:29.2882] Plugins::DenonSerial::Plugin::getResponse (513) for 00:04:20:16:5f:a0, command "SI?", got response "MVMAX 705" from remote host
    0024: [10-01-25 20:55:29.2790] Plugins::DenonSerial::Plugin::getResponse (513) for 00:04:20:16:5f:a0, command "SI?", got response "MV45" from remote host
    0023: [10-01-25 20:55:29.2701] Plugins::DenonSerial::Plugin::getResponse (480) for 00:04:20:16:5f:a0, indicate we're done with the current command since we're reading responses, queue length now 2
    0022: [10-01-25 20:55:29.2618] Plugins::DenonSerial::Plugin::processCommandFromQueue (409) look for response for 00:04:20:16:5f:a0 command SI?
    0021: [10-01-25 20:55:28.9701] Plugins::DenonSerial::Plugin::processCommandFromQueue (447) not done with queue
    0020: [10-01-25 20:55:28.9619] Plugins::DenonSerial::Plugin::sendCommand (886) for 00:04:20:16:5f:a0, indicate we're working on a command, queue length now 2
    0019: [10-01-25 20:55:28.9511] Plugins::DenonSerial::Plugin::sendCommand (815) send command: (connection IP, address 192.168.1.102, command SI?)
    0018: [10-01-25 20:55:28.9427] Plugins::DenonSerial::Plugin::processCommandFromQueue (436) for 00:04:20:16:5f:a0 , send command SI?, queue length 2
    0017: [10-01-25 20:55:28.8378] Plugins::DenonSerial::Plugin::processCommandFromQueue (447) not done with queue
    0016: [10-01-25 20:55:28.5578] Plugins::DenonSerial::Plugin::getResponse (480) for 00:04:20:16:5f:a0, indicate we're done with the current command since we're reading responses, queue length now 3
    0015: [10-01-25 20:55:28.5494] Plugins::DenonSerial::Plugin::processCommandFromQueue (409) look for response for 00:04:20:16:5f:a0 command MV?
    0014: [10-01-25 20:55:28.4264] Plugins::DenonSerial::Plugin::processCommandFromQueue (447) not done with queue
    0013: [10-01-25 20:55:28.4184] Plugins::DenonSerial::Plugin::sendCommand (886) for 00:04:20:16:5f:a0, indicate we're working on a command, queue length now 3
    0012: [10-01-25 20:55:28.4048] Plugins::DenonSerial::Plugin::sendCommand (842) opening control socket to 192.168.1.102:23
    0011: [10-01-25 20:55:28.3938] Plugins::DenonSerial::Plugin::sendCommand (815) send command: (connection IP, address 192.168.1.102, command MV?)
    0010: [10-01-25 20:55:28.3854] Plugins::DenonSerial::Plugin::processCommandFromQueue (436) for 00:04:20:16:5f:a0 , send command MV?, queue length 3
    0009: [10-01-25 20:55:28.3752] Plugins::DenonSerial::Plugin::enqueue (380) run PW? for 00:04:20:16:5f:a0 at next convenience
    0008: [10-01-25 20:55:28.3642] Plugins::DenonSerial::Plugin::enqueue (380) run SI? for 00:04:20:16:5f:a0 at next convenience
    0007: [10-01-25 20:55:28.3535] Plugins::DenonSerial::Plugin::enqueue (384) indicate that processCommandFromQueue() should run
    0006: [10-01-25 20:55:28.3446] Plugins::DenonSerial::Plugin::enqueue (380) run MV? for 00:04:20:16:5f:a0 at next convenience
    0005: [10-01-25 20:55:28.3348] Plugins::DenonSerial::Plugin::pollAmpStatus (1198) checking amp status for Family Room
    0004: [10-01-25 20:55:28.3243] Plugins::DenonSerial::Plugin::rescheduleAmpStatusPoll (1023) rescheduling amp status poll
    0003: [10-01-25 20:55:28.3155] Plugins::DenonSerial::Plugin::rescheduleAmpStatusPoll (1019) scheduling an amp status poll in 5 minutes
    0002: [10-01-25 20:55:14.4892] Plugins::DenonSerial::Plugin::turnAmpOff (1115) leaving amp IP:192.168.1.102 on for player 00:04:20:16:5f:a0
    0001: [10-01-25 20:55:14.4758] Plugins::DenonSerial::Plugin::turnAmpOff (1103) turning amp off for Family Room
    Chris

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •