-
Notifications
You must be signed in to change notification settings - Fork 1
/
lmsmanager.py
368 lines (280 loc) · 12.3 KB
/
lmsmanager.py
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
"""
2020-01-25: we want to use Python3 "requests" for LMS
There was something existing but in python2 not using requests
The goal was to use Python3 and Request to have something more "modern"
Some code has a hobby and maybe an help to decypher the LMS API.
"""
import sys
import requests
import argparse
from json import dumps
class LmsServer:
"""
This class to grab informations from the LMS SERVER
2023-01-02: V1.2.2: adding sys.stderr.write when request fails
2022-07-26: V1.2.1: returns [] when no player found
2021-03-24: V1.2.0: adding 2 methods
- cls_player_playlist_clear
- cls_player_playlist_add
2021-03-20: v1.1.2: mode docstring
2021-03-18: v1.1.1: cleaning code (todo: doc)
- dead method
- better naming
add methods
- player on / off
- player sleep in x seconds
- player skip track (positive or neg to scroll the playlist)
- server is scanning
- server scanning status
2021-03-10: v1.0.1: cleaning code
2021-03-09: v1.0.0: "Official" v1 version!
2021-01-25: v0.0.1: starting
"""
def __init__(self, serveur_ip:str):
"""
Init the class
serveur_ip: str, the ip address of the LMS server
"""
self.__version__ = "1.2.2"
self.URL = "http://" + serveur_ip + "/jsonrpc.js"
def _cls_execute_request(self, payload)-> dict:
"""
Execute request
"""
headers = {'Content-Type': 'application/json'}
try:
response = requests.request("POST", url=self.URL, headers=headers, data=payload)
except Exception as err:
sys.stderr.write("LmsServer v" + self.__version__ + " cannot get response from: " + self.URL)
print("LmsServer v" + self.__version__ + " cannot get response from: " + self.URL)
print(str(err))
return err
return response.json()
def cls_players_list(self)-> list:
"""
Returns a list of players
detected connected to the server
input
: None
returns
: players, list of dict
"""
players = []
payload='{"id": 0, "params": ["-",["players","0"]],"method":"slim.request"}'
try:
players = self._cls_execute_request(payload)["result"]["players_loop"]
except Exception as err:
print(str(err))
return []
# for player in players:
# print(player["playerid"] + " =" + player["modelname"] + " - " + player["name"] + " : " + str(player["isplaying"]))
return players
def cls_player_on_off(self, mac_player:str, on_off:int)->None:
"""
player on or off
input
: mac_player: str, the player mac address, ie: 5a:65:a2:33:80:79
: on_off: int, value between 0-1, 0=OFF, 1=ON
returns
: None
"""
if on_off == 0 or on_off == 1:
payload = '{"id": 0, "params": ["' + mac_player + '",["power","' + str(on_off) + '"]],"method": "slim.request"}'
self._cls_execute_request(payload)
print("Power on/off: " + str(on_off))
else:
print("Power on off value should be 0 or 1, received:" + str(on_off))
def cls_player_sleep(self, mac_player:str, seconds_before_sleep:int)->None:
"""
player on or off
input
: mac_player: str, the player mac address, ie: 5a:65:a2:33:80:79
: seconds_before_sleep: number of seconds before sleep
returns
: None
"""
payload = '{"id": 0, "params": ["' + mac_player + '",["sleep","' + str(seconds_before_sleep) + '"]],"method": "slim.request"}'
self._cls_execute_request(payload)
print("Player goind to sleep in: " + str(seconds_before_sleep) + " seconds")
def cls_player_define_volume(self, mac_player:str, volume:int)->None:
"""
Define the volume for specified player
input
: mac_player: str, the player mac address, ie: 5a:65:a2:33:80:79
: volume: int, between 0-100
returns
: None
"""
if volume > 100:
volume = 100
elif volume < 0:
volume = 0
payload = '{"id": 0, "params": ["' + mac_player + '",["mixer","volume","' + str(volume) + '"]],"method": "slim.request"}'
self._cls_execute_request(payload)
print("volume set to:" + str(volume))
def cls_player_play(self, mac_player:str)->None:
"""
player play!
input
: mac_player: str, the player mac address, ie: 5a:65:a2:33:80:79
"""
payload = '{"id": 0, "params": ["' + mac_player + '",["button","play"]],"method": "slim.request"}'
self._cls_execute_request(payload)
print("Player play:" + mac_player)
def cls_player_stop(self, mac_player:str)->None:
"""
player stop!
input
: mac_player: str, the player mac address, ie: 5a:65:a2:33:80:79
"""
payload = '{"id": 0, "params": ["' + mac_player + '",["button","stop"]],"method": "slim.request"}'
self._cls_execute_request(payload)
print("Player stop:" + mac_player)
def cls_player_next_previous(self, mac_player:str, skip:int)->None:
"""
player on or off
input
: mac_player: str, the player mac address, ie: 5a:65:a2:33:80:79
: skip: number of track(s) to skip, ie 1, -1, 4, -2...
"""
payload = '{"id": 0, "params": ["' + mac_player + '",["playlist","index","' + str(skip) + '"]],"method": "slim.request"}'
self._cls_execute_request(payload)
print("Player is skipping : " + str(skip) + " track(s)")
def cls_player_status(self, mac_player:str)->dict:
"""
player status
input
: mac_player: str, the player mac address, ie: 5a:65:a2:33:80:79
returns
: dict: list of information about the player
"""
payload = '{"id": 0, "params": ["' + mac_player + '",["status"]],"method": "slim.request"}'
player_status = self._cls_execute_request(payload)
# for status in player_status["result"]:
# print(status + ":" + str(player_status["result"][status]))
return player_status["result"]
def cls_player_current_title_status(self, mac_player:str)->dict:
"""
player status
input
: mac_player: str, the player mac address, ie: 5a:65:a2:33:80:79
returns
: dict: list of information about the player
"""
payload = '{"id": 0, "params": ["' + mac_player + '",["status","current_title"]],"method": "slim.request"}'
player_status = self._cls_execute_request(payload)
try:
return player_status["result"]
except:
return None
def cls_player_playlist_clear(self, mac_player:str)->None:
"""
Clear the playlist for the player
input
: player_id: str as a MAC address, ie : "00:11:22:33:44:55:66"
returns
: None
"""
payload = '{"id": 0, "params": ["' + mac_player + '",["playlist","clear"]],"method": "slim.request"}'
self._cls_execute_request(payload)
print("clear playlist")
def cls_player_playlist_add(self, mac_player:str, playlist_name:str)->None:
"""
Clear the playlist for the player
input
: mac_player: str as a MAC address, ie : "00:11:22:33:44:55:66"
: playlist_name: str, the mu3 file without extension, ie "pitsf_preset1"
returns
: None
"""
payload = '{"id": 0, "params": ["' + mac_player + '",["playlist","add","' + playlist_name + '"]],"method": "slim.request"}'
self._cls_execute_request(payload)
print("add playlist" + playlist_name)
def cls_song_info(self, song_id, mac_player:str)->dict:
"""
Grab info about song
input
: song_id; int
: mac_player: str as a MAC address, ie : "00:11:22:33:44:55:66"
returns
: dict containing info
"""
payload = '{"id": 0,"params": ["' + mac_player + '",["songinfo",0,100,"track_id:' + str(song_id) + '"]],"method": "slim.request"}'
song_info = self._cls_execute_request(payload)
return song_info["result"]
def cls_server_status(self)->dict:
"""
grab the server status
"""
payload = '{"id": 0,"params": ["-",["serverstatus",0,100]],"method": "slim.request"}'
server_status = self._cls_execute_request(payload)
return server_status # ["result"]
def cls_server_is_scanning(self)->bool:
"""
returns:
: True if scanning
: False otherwise
"""
payload = '{"id": 0, "params": ["00:00:00:00:00",["rescanprogress"]],"method": "slim.request"}'
rescan = self._cls_execute_request(payload)
# print("Server is scanning? " + str(rescan["result"]))
if rescan["result"]["rescan"]== 1:
# print(True)
return True
else:
# print(False)
return False
def cls_server_scanning_status(self)->dict:
"""
check the server to know the scan status
and returns the scan status
returns
: rescan["result"] dict if scanning, ie
{'discovering_directory': -1,
'fullname': 'Discovering files/di...o/Musiques',
'info': '/mnt/syno/Musiques/J...and I.flac',
'rescan': 1,
'steps': 'discovering_directory',
'totaltime': '00:00:30'}
if not scanning: {'rescan': 0}
"""
payload = '{"id": 0, "params": ["00:00:00:00:00",["rescanprogress"]],"method": "slim.request"}'
rescan = self._cls_execute_request(payload)
# print("Server scanning status " + str(rescan["result"]))
return rescan["result"]
if __name__ == "__main__":
print("--- LMS API Requester ---")
print("please use -s option to define your IP:PORT address")
print("ie: python lmsmanager.py -s 192.168.1.112:9000")
print("note: at least one player shoud be playing for demoing!")
description = "LMS API Requester"
server_help = "ip and port for the server. something like 192.168.1.192:9000"
parser = argparse.ArgumentParser(description = description)
parser.add_argument("-s","--server", type=str, default="192.168.1.192:9000", help = server_help)
args = parser.parse_args()
myServer = LmsServer(args.server)
myServer.cls_server_is_scanning()
myServer.cls_server_scanning_status()
players = myServer.cls_players_list()
for player in players:
if player["isplaying"] == 1:
print("Waoo ->" + player['name'])
# define volume
myServer.cls_player_define_volume(player['playerid'], 40)
# next previous track
myServer.cls_player_next_previous(player['playerid'], 1)
myServer.cls_player_next_previous(player['playerid'],-1)
# stop and play
myServer.cls_player_stop(player['playerid'])
myServer.cls_player_play(player['playerid'])
# Off / On
myServer.cls_player_on_off(player['playerid'], 0)
myServer.cls_player_on_off(player['playerid'], 1)
# clear playlist
myServer.cls_player_playlist_clear(player['playerid'])
# Sleep in 1000 seconds
# myServer.cls_player_sleep(player['playerid'], 1000)
myServer.cls_player_status(player['playerid'])
song = myServer.cls_player_current_title_status(player['playerid'])
print(str(song))
break