Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

CLI Documentation Questions #52

Open
Daksol opened this issue Apr 15, 2024 · 19 comments
Open

CLI Documentation Questions #52

Daksol opened this issue Apr 15, 2024 · 19 comments
Assignees

Comments

@Daksol
Copy link
Contributor

Daksol commented Apr 15, 2024

Command line interface - CLI commands documentation

Some (not high priority) issues which came up when doing some further testing of the CLI - done mostly with the intention of generating some more examples, particularly JSONRPC ones, which are (IMHO) heaps easier to read.

PURPOSE OF ID PARAMETER WITH JSONRPC ?

See JSONRPC section of Using the CLI
Question about the "id" parameter for JSONRPC. In the JSONRPC notes for use by CURL etc, one of the parameters passed is "id" (along with "params" and "method"). I realise that when running the commmands via JSON I have not included "id" and it still seems to work.

What is its function? - maybe to allow the response to multiple JSONRPC calls to be easily distinnguished?


PLAYER COMMAND INCONSISTENCIES

I was doing some followup checking on behaviour of certain CLI commands for Players.

The command players provides full info about all connected players; this works fine, documentation is inline with behaviour.

There is also group of eight commands like "player name" which return a specific piece of info about a particular player.
The subcommands are: name, uuid, displaytype, id, ip, model, isplayer, canpoweroff

These commands have more than one format to achieve the same result - based on the documentation and examples given. The variants are wrt the parameter used (playerid or playerindex) and where the parameter is placed (as a pre-pended player identifier or after the 'player ' bit).

Syntax Options with Player identifier after the player <subcommand> string

  • SYNTAX-1 player name <playerindex> ?
  • SYNTAX-2 player name <playerid> ?

where <playerid> is (usually) the player's MAC address, and <playerindex> is a sequence number assigned to players currently recognised by the server, with values like 0, 1, 2 etc

Syntax options where Player identifier precedesthe player <subcommand> string

Some places in the documentation it is shown that these two forms are also permissable.

  • SYNTAX-3 <playerindex> player name ?
  • SYNTAX-4 <playerid> player name ?

See for instance syntax and examples for player name

Testing results

All of these formats (SYNTAX-1 thru -4) "work" in that they return a result; but I noticed some discrepancies.

So we need to test all four formats for eight subcommands for four players (as one does).

  • used all four SYNTAX options as above
  • used all eight subcommands (name, uuid, displaytype, id, ip, model, isplayer, canpoweroff)
  • while having four players connected (one squeezelite, two Sb Radios one SB Classic v3)

And compared the results with what comes back from the players command

Result of this testing is that SYNTAX-3, and SYNTAX-4 while they work (in that a result is returned) do not provide an accurate response. They seem to always return information about the player currently with Index 0.

Suggested actions:

  • Remove any use of Syntax-3 or Syntax-4 from the documentation, including the Examples
  • Include a cautionary note

@mherger - Your call as whether this should be raised as a bug?

Number of players: 4
Info on all players from the players command
0 {'playerindex': '0', 'playerid': '98:2c:bc:18:e1:06', 'uuid': None, 'ip': '192.168.5.22:60888', 'name': 'Squeezelite-X', 'seq_no': 0, 'model': 'squeezelite', 'modelname': 'Squeezelite-X', 'power': 1, 'isplaying': 0, 'displaytype': 'none', 'isplayer': 1, 'canpoweroff': 1, 'connected': 1, 'firmware': 'v1.9.9-1419'}
1 {'playerindex': 1, 'playerid': '00:04:20:28:c7:f1', 'uuid': 'ca1c8fbf2d48cbb1c859b5ea7ce4ecf9', 'ip': '192.168.5.102:56551', 'name': 'Stalking Horse', 'seq_no': '12', 'model': 'baby', 'modelname': 'Squeezebox Radio', 'power': 1, 'isplaying': 0, 'displaytype': 'none', 'isplayer': 1, 'canpoweroff': 1, 'connected': 1, 'firmware': '8.0.1-r16924'}
2 {'playerindex': 2, 'playerid': '00:04:20:12:ae:f5', 'uuid': None, 'ip': '192.168.5.103:47742', 'name': 'Dittography', 'seq_no': 0, 'model': 'squeezebox3', 'modelname': 'Squeezebox Classic', 'power': 1, 'isplaying': 0, 'displaytype': 'graphic-320x32', 'isplayer': 1, 'canpoweroff': 1, 'connected': 1, 'firmware': 137}
3 {'playerindex': 3, 'playerid': '00:04:20:2a:e0:74', 'uuid': '7147ee259b66f5c9c39c0eb14cfefb5c', 'ip': '192.168.5.101:53614', 'name': 'Runcible Red', 'seq_no': '220', 'model': 'baby', 'modelname': 'Squeezebox Radio', 'power': 1, 'isplaying': 0, 'displaytype': 'none', 'isplayer': 1, 'canpoweroff': 1, 'connected': 1, 'firmware': '8.0.1-r16924'}
****************************************

Now testing the 'player <subcommand>' set of commands giving info on individual players
Subcommands to test are: ['canpoweroff', 'displaytype', 'id', 'ip', 'isplayer', 'model', 'name', 'uuid']

Subcommand      Syntax 1              Syntax 2              Syntax 3              Syntax 4             
--------------- --------------------- --------------------- --------------------- ---------------------
PLAYER Index:0 ID:98:2c:bc:18:e1:06  Name:Squeezelite-X

canpoweroff     1                     1                     1                     1                    
displaytype     none                  none                  none                  none                 
id              98:2c:bc:18:e1:06     98:2c:bc:18:e1:06     98:2c:bc:18:e1:06     98:2c:bc:18:e1:06    
ip              192.168.5.22:60888    192.168.5.22:60888    192.168.5.22:60888    192.168.5.22:60888   
isplayer        1                     1                     1                     1                    
model           squeezelite           squeezelite           squeezelite           squeezelite          
name            Squeezelite-X         Squeezelite-X         Squeezelite-X         Squeezelite-X        
uuid            None                  None                  None                  None                 
*******************************************************************************************************
PLAYER Index:1 ID:00:04:20:28:c7:f1  Name:Stalking Horse

canpoweroff     1                     1                     1                     1                    
displaytype     none                  none                  none                  none                 
id              00:04:20:28:c7:f1     00:04:20:28:c7:f1     98:2c:bc:18:e1:06     98:2c:bc:18:e1:06    
ip              192.168.5.102:56551   192.168.5.102:56551   192.168.5.22:60888    192.168.5.22:60888   
isplayer        1                     1                     1                     1                    
model           baby                  baby                  squeezelite           squeezelite          
name            Stalking Horse        Stalking Horse        Squeezelite-X         Squeezelite-X        
uuid            ca1c8fbf2d48cbb1c...  ca1c8fbf2d48cbb1c...  None                  None                 
*******************************************************************************************************
PLAYER Index:2 ID:00:04:20:12:ae:f5  Name:Dittography

canpoweroff     1                     1                     1                     1                    
displaytype     graphic-320x32        graphic-320x32        none                  none                 
id              00:04:20:12:ae:f5     00:04:20:12:ae:f5     98:2c:bc:18:e1:06     98:2c:bc:18:e1:06    
ip              192.168.5.103:47742   192.168.5.103:47742   192.168.5.22:60888    192.168.5.22:60888   
isplayer        1                     1                     1                     1                    
model           squeezebox2           squeezebox2           squeezelite           squeezelite          
name            Dittography           Dittography           Squeezelite-X         Squeezelite-X        
uuid            None                  None                  None                  None                 
*******************************************************************************************************
PLAYER Index:3 ID:00:04:20:2a:e0:74  Name:Runcible Red

canpoweroff     1                     1                     1                     1                    
displaytype     none                  none                  none                  none                 
id              00:04:20:2a:e0:74     00:04:20:2a:e0:74     98:2c:bc:18:e1:06     98:2c:bc:18:e1:06    
ip              192.168.5.101:53614   192.168.5.101:53614   192.168.5.22:60888    192.168.5.22:60888   
isplayer        1                     1                     1                     1                    
model           baby                  baby                  squeezelite           squeezelite          
name            Runcible Red          Runcible Red          Squeezelite-X         Squeezelite-X        
uuid            7147ee259b66f5c9c...  7147ee259b66f5c9c...  None                  None                 
*******************************************************************************************************

UUID values truncated to 17 chars to keep the table pretty.
UUID values of None (the Python key word indicating a nullvalue) shown as the string 'None'
@Daksol Daksol self-assigned this Apr 15, 2024
@Daksol Daksol converted this from a draft issue Apr 15, 2024
@Daksol Daksol moved this to In progress in Documentation cleanup Apr 15, 2024
@michaelherger
Copy link
Member

Thanks for looking into all this, @Daksol! Alas, it can be overwhelming... It would be easier to follow up if you had one question per issue, or if you posted one question per thread in the forums. Here you have at least two totally independent questions, with a lot of information...

So in short: the id I don't know, really. Might be something from CometD. But in my JSON/RPC requests I always put 1 and don't care. I believe in theory it would allow to link the response to a request, as they can be out of sync in CometD. But with JSON/RPC that's not the case, therefore probably irrelevant for that use case.

As for the playerindex: I never used that. I mean... how would you know which player you're dealing with? I'm pretty sure that's a legacy thing nobody bothers to use that way. We should probably remove it from the documentation and consistently use the playerid instead (MAC address).

player <id> something also sounds like legacy. We should always suggest the <id> player something syntax.

@Daksol
Copy link
Contributor Author

Daksol commented Apr 16, 2024

OK thanks, will ensure one question per comment.

Let me restate the issue with the player <subcommand> ? only using playerid as identifier.

  • Using Syntax-2: player <subcommand> <playerid> ?

    • Responses are accurate
  • Using Syntax-4: <playerid> player <subcommand> ?

    • You get a response but it is not accurate. Info returned when querying any of the players is same - equal to that for the particular player with playerindex = 0. In the output query above the query response for Syntax-3 and Syntax-4 is always the same as that for the Squeezelite-X player which has playerindex = 0

@Daksol
Copy link
Contributor Author

Daksol commented Apr 16, 2024

I have a Python script which runs the whole thing, can share that if useful.

Meantime here is the CURL version, should work once you have correct IP and port
STEP 1 - Ensure you have at least two players connected. Three or more makes it more obvious.

STEP 2 - Run this command to get the current players and their mac addresses

curl -g -X POST -d '{"id":1, "method":"slim.request","params":["-",["players", "0"]]}' http://192.168.5.75:9005/jsonrpc.js

STEP 3 - Take the mac addresses of first three players and put them into the code below. There are two commands (as per my syntax-2, syntax-4 from above) for each player,

If for the second and subsequent players you see different responses from the two syntax commands - then problem demonstrated.

STEP 3-0: playerindex=0, 98:2c:bc:18:e1:06

curl -g -X POST -d '{"id":1, "method":"slim.request","params":["-",["player", "name", "98:2c:bc:18:e1:06", "?"]]}' http://192.168.5.75:9005/jsonrpc.js

curl -g -X POST -d '{"id":1, "method":"slim.request","params":["98:2c:bc:18:e1:06",["player", "name", "?"]]}' http://192.168.5.75:9005/jsonrpc.js

STEP 3-1: Playerindex=1, 00:04:20:28:c7:f1

curl -g -X POST -d '{"id":1, "method":"slim.request","params":["-",["player", "name", "00:04:20:28:c7:f1", "?"]]}' http://192.168.5.75:9005/jsonrpc.js

curl -g -X POST -d '{"id":1, "method":"slim.request","params":["00:04:20:28:c7:f1",["player", "name", "?"]]}' http://192.168.5.75:9005/jsonrpc.js


STEP 3-2: Playerindex=2, 00:04:20:12:ae:f5

curl -g -X POST -d '{"id":1, "method":"slim.request","params":["-",["player", "name", "00:04:20:12:ae:f5", "?"]]}' http://192.168.5.75:9005/jsonrpc.js

curl -g -X POST -d '{"id":1, "method":"slim.request","params":["00:04:20:12:ae:f5",["player", "name", "?"]]}' http://192.168.5.75:9005/jsonrpc.js

@Daksol
Copy link
Contributor Author

Daksol commented Apr 16, 2024

Markup of the curl queries indicating where the two different syntaxes of the player name get a different response except for player with playerindex=0

curl

@michaelherger
Copy link
Member

You should look at the code where those functions are registered. The decision to have player with and without the requirement for a client certainly is a legacy. But it's clearly defined in the registration call whether the client is required as the first parameter or not. See eg. https://github.com/LMS-Community/slimserver/blob/public/9.0/Slim/Control/Request.pm#L466-L472 - there's the "requires Client" column (parameter).

@michaelherger
Copy link
Member

@Daksol I just learned that the favorites commands/queries were not documented here. Should they be part of one of the existing sections?

@edgar-vincent
Copy link
Contributor

I'd be happy to help add the favorites commands after I have familiarised myself with the way the website is structured and built.

@Daksol
Copy link
Contributor Author

Daksol commented Jul 4, 2024

@michaelherger
Thanks for your note, sorry not responding more quickly,

I have looked again at the original HTML source, and can see the error I made.
The original steer was that the "Plugins" section should not be migrated.

I clearly not careful enough when looking at the section starting with "Plugins" - because there are other sections (Favorites, RandomPlay, MusicIP ??) which may not really have been part of "Plugins".

The unmigrated sections are as follows, in the order in which they appear...

  • Plugins commands and queries - presume NOT migrating
  • Podcasts, RadioTime, RSS - Not sure
  • Favorites - Still to be Migrated
  • RandomPlay - Still to be Migrated
  • MusicIP - Still to be Migrated
  • Deprecated commands and queries - presume NOT migrating

Could I ask @michaelherger to review this list and confirm which sections still need to be migrated?

With that clear, happy to work with @edgar-vincent to see work to completion.

Thanks.

@michaelherger
Copy link
Member

  • Plugins commands and queries - presume NOT migrating
  • Podcasts, RadioTime, RSS - Not sure
  • Favorites - Still to be Migrated
  • RandomPlay - Still to be Migrated
  • MusicIP - Still to be Migrated
  • Deprecated commands and queries - presume NOT migrating

I'd say only migrate those labeled Still to be Migrated. All of the rest can be considered obsolete. Thanks!

@Daksol
Copy link
Contributor Author

Daksol commented Jul 4, 2024

@michaelherger
Hi, followup questions - will need some help for "musicip", see below

I have done some quick tests to confirm that I can make these other commands work properly - via a Python script which submits the commands into the JSONRPC processor.

Observations/Questions arising from that testing (may need some help with musicip, see below)

Favorites

Randomplay

MusicIP

  • observations
    • Not getting a response via JSON commands to any of the musicip options
    • getting value of 0 FALSE from the can commmand "can musicip ?"
    • and that remained true even after enabling the "MusicIP" plugin
  • please confirm
  • please assist
    • what else do I need to do to make this appear on menus or respond to CLI ?

@michaelherger
Copy link
Member

The Favorites plugin is "enforced": you can't disable it, as it's too deeply integrated in to the core of LMS. "can" seems to be buggy, but I wouldn't care too much either. Just don't tell anyone 😂.

Random Mix requires the plugin.

MusicIP not only requires the plugin itself, but also a working MusicIP application setup. If the plugin can't find the application, it wouldn't initialise.

@Daksol
Copy link
Contributor Author

Daksol commented Jul 5, 2024

MusicIP not only requires the plugin itself, but also a working MusicIP application setup. If the plugin can't find the application, it wouldn't initialise.

OK. So this the application described on the "Spicefly" website?
https://www.spicefly.com/section.php?section=lms
Website is quite useful, it explains how MusicIP came out of an earlier product MusicMatch

For this documentation task, can I suggest that MusicIP second priority behind Favorites and RandomPlay

Suggest that the way forwards would be for MusicIP and friends to get their own documentation page which would cover:-

  • MusicIP related plugins
    • MusicIP
    • Spicefly Sugarcube
    • Dynamic Mix
  • MusicIP related Command Line Interface

Related suggestion:
Would it be approprriate to include MusicIP in the Playlist related section of the Lyrion.org plugins page?
https://lyrion.org/plugins/directory/#playlists

@Daksol
Copy link
Contributor Author

Daksol commented Jul 5, 2024

@edgar-vincent
Do you want to go ahead and add the Favorites and RandomPlay related commands to the CLI documentation page.

I have another couple of tasks I had committed to but not done, so pleased if someone else picks up this work.

I had been intending to revisit the CLI docn page with a view to adding in some examples of JSON output which (imho) makes things much more readable - particularly when the output contains loops. Running the commands like this has also meant that I have been able to verify that things works, and the docn is indeed accurate,

To that end, I have some Python code which I have used to run JSON commands. Can share that with you if that might be useful to you,

@edgar-vincent
Copy link
Contributor

@Daksol Absolutely. I've got mkdocs running locally and have started adding the favorites section. It will take me some time to make sure my newly-converted pages are consistent with what is already there. Also, I'm going on holiday for a week, so I won't have time to do much this week, but I will add Favorites and RandomPlay as soon as I can.

I had been intending to revisit the CLI docn page with a view to adding in some examples of JSON output which (imho) makes things much more readable - particularly when the output contains loops. Running the commands like this has also meant that I have been able to verify that things works, and the docn is indeed accurate

Excellent idea.

To that end, I have some Python code which I have used to run JSON commands. Can share that with you if that might be useful to you,

Please do! Thanks a lot.

@michaelherger
Copy link
Member

Suggest that the way forwards would be for MusicIP and friends to get their own documentation page which would cover:-

  • MusicIP related plugins

    • MusicIP
    • Spicefly Sugarcube
    • Dynamic Mix
  • MusicIP related Command Line Interface

Related suggestion: Would it be approprriate to include MusicIP in the Playlist related section of the Lyrion.org plugins page? lyrion.org/plugins/directory/#playlists

MIP is not a third party plugin, but part of LMS. Therefore it's not in that list. And as spicefly does a great job describing things already, I'd leave the documentation there. Let's concentrate on migrating the CLI documentation only here. But yes, the MIP CLI isn't that important, can probably be left alone. I guess that most people using MIP nowadays do so using spicefly's plugin rather than the built-in version.

@Daksol
Copy link
Contributor Author

Daksol commented Jul 8, 2024

MIP is not a third party plugin, but part of LMS. Therefore it's not in that list. And as spicefly does a great job describing things already, I'd leave the documentation there. Let's concentrate on migrating the CLI documentation only here. But yes, the MIP CLI isn't that important, can probably be left alone. I guess that most people using MIP nowadays do so using spicefly's plugin rather than the built-in version.

Michael.
Thanks for this steer. It is so useful to get the perspective you provide on how the various bits fit together!

Will follow your guidance. Appreciated.

@Daksol
Copy link
Contributor Author

Daksol commented Jul 16, 2024

@edgar-vincent
fyi. Python code to make for easier testing etc of CLI. (Links below Updated)

I have submitted a pull request which includes a link to a Python module in a repository, and a documentation page of python examples.
Not sure how long it will be before that will get put live.

So in meantime I have attached the link to the module
and a version of the documentation page to this comment.
Hope it makes sense.

(Docn page which will be published now updated to hold info about multiple languages, not just Python)

Links to Files

@Daksol
Copy link
Contributor Author

Daksol commented Jul 17, 2024

@mherger Michael

Thanks for your response to the pull request including a Python module. Couple of questions below.

My original thinking was - does the LMS-Community need yet another repository to support? So I tried to make something as light as it possibly could be to get people up to speed quickly. Hence .py module with hardly 20 lines of code with only one dependency (requests module, commonly used with anything involving http/https). And with the thought that it need not be developed or extended further - KISS approach.

But I take your point - code should live in repositories designed to manage code.

I will set up a repo on Github ("daksol/lms-cli-minimal" ?) with the stated purpose of providing minimal code to get people productive with the LMS CLI. I will set it up to support multiple languages, starting with Python. I will find something similar for Javascript.

Questions:-

  • What other languages would you suggest be incorporated ? (beyond Python, Javascript)
  • Once organised is this the kind of thing which should become an "lms-community" repo ?

Background on LMS CLI Python repos

fyi my thinking here influenced by my original attempts to find some Python code - which revealed a fair number of stale projects. And no desire to create another one....

When I first looked for some Python to work with LMS I took some quick looks at Github, and mostly found Archived or Obsolete repos. I asked a question in the LMS Developer forums and @daverz kindly shared some code which formed the basis of what I am still working with.

I just took at deeper dive, searching with more terms (squeeze, slim, logitech, lms etc), looking particularly at Pypi (pypi.org) which is the most widely used Python module library - once you have set a default library in a local Python setup, "pip install xx-mypackage-xx" gets it for you.

This produced around 18, of which 7 have been updated in last three years. So many have become stale, but I would guess that is not unusual.

Repo status:-

  • All but one on Pypi,
  • Code repositories: Github (9), Gitlab (1), Bitbucket (1), no linked repo (7).

@edgar-vincent
Copy link
Contributor

@Daksol PR for favorites and randomplay here: #67

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
Status: In progress
Development

No branches or pull requests

3 participants