1
1
import sys
2
2
from PyQt5 .QtCore import pyqtSignal
3
- from PyQt5 .QtWidgets import QApplication , QWidget , QLabel , QLineEdit , QPushButton , QHBoxLayout , QVBoxLayout ,QRadioButton ,QDesktopWidget ,QTextEdit ,QFrame ,QMessageBox
3
+ from PyQt5 .QtWidgets import QApplication , QWidget , QLabel , QLineEdit , QPushButton , QHBoxLayout , QVBoxLayout ,QRadioButton ,QDesktopWidget ,QTextEdit ,QFrame ,QMessageBox , QButtonGroup
4
4
from PyQt5 .QtGui import QPixmap
5
5
from PyQt5 .QtGui import QIcon
6
6
from pathlib import Path
7
7
import os
8
8
import json
9
9
from miaccount import MiAccount
10
10
from minaservice import MiNAService
11
+ from miioservice import MiIOService
12
+ from miiocommand import miio_command
11
13
from aiohttp import ClientSession
12
14
from pathlib import Path
13
15
import os
@@ -33,22 +35,35 @@ def __init__(self):
33
35
super ().__init__ ()
34
36
35
37
# 设置窗口标题和大小
36
- self .setWindowTitle ('小米音箱服务' )
37
- self .resize (600 , 200 )
38
-
38
+ self .setWindowTitle ('小米音箱服务 github库名字MiChatGUI' )
39
+
40
+ connectmode_select_box = QHBoxLayout ()
41
+ connectmode_selectbg = QButtonGroup ()
42
+ self .connectrb1 = QRadioButton ('接入方式1' )
43
+ self .connectrb1 .setChecked (True )
44
+ connectmode_select_box .addWidget (self .connectrb1 )
45
+ self .connectrb2 = QRadioButton ('接入方式2' )
46
+ connectmode_select_box .addWidget (self .connectrb2 )
47
+ connectmode_select_box .addStretch ()
48
+ self .connectrb1 .clicked .connect (self .connect_mode_select )
49
+ self .connectrb2 .clicked .connect (self .connect_mode_select )
50
+ connectmode_selectbg .addButton (self .connectrb1 )
51
+ connectmode_selectbg .addButton (self .connectrb2 )
39
52
# 创建用于输入用户名、密码和设备型号的文本输入框
40
53
self .username_input = QLineEdit ()
41
54
self .password_input = QLineEdit ()
42
55
self .device_input = QLineEdit ()
43
-
56
+ self .did_input = QLineEdit ()
57
+ self .tts_input = QLineEdit ()
44
58
# 将密码输入框设置为密码模式
45
59
self .password_input .setEchoMode (QLineEdit .Password )
46
60
47
61
# 创建用于显示标签的标签
48
62
username_label = QLabel ('你的ID:' )
49
63
password_label = QLabel ('你的密码:' )
50
64
device_label = QLabel ('你的设备型号:' )
51
-
65
+ self .did_label = QLabel ('DID(设备ID):' )
66
+ self .tts_input_label = QLabel ('语音命令:' )
52
67
# 创建登录按钮
53
68
self .login_button = QPushButton ('开始' )
54
69
@@ -67,8 +82,16 @@ def __init__(self):
67
82
input_layout .addWidget (self .device_input )
68
83
input_layout .addWidget (speaker_label )
69
84
input_layout .addWidget (self .speaker_input )
85
+ input_layout .addWidget ( self .did_label )
86
+ input_layout .addWidget (self .did_input )
87
+ input_layout .addWidget ( self .tts_input_label )
88
+ input_layout .addWidget (self .tts_input )
89
+ self .did_label .hide ()
90
+ self .did_input .hide ()
91
+ self .tts_input_label .hide ()
92
+ self .tts_input .hide ()
70
93
input_layout .addWidget (self .login_button )
71
-
94
+
72
95
# 创建用于显示图片的标签
73
96
imagesize = 200
74
97
img_label = QLabel (self )
@@ -80,17 +103,19 @@ def __init__(self):
80
103
81
104
82
105
service_select_box = QHBoxLayout ()
83
- rb1 = QRadioButton ('OpenAI' , self )
106
+ rb1 = QRadioButton ('OpenAI' )
84
107
rb1 .setChecked (True )
85
108
service_select_box .addWidget (rb1 )
86
- rb2 = QRadioButton ('你的自定义服务' , self )
109
+ rb2 = QRadioButton ('你的自定义服务' )
87
110
service_select_box .addWidget (rb2 )
88
111
#rb3 = QRadioButton('作者的免费测试(仅限最多50个问题)', self)
89
112
#service_select_box.addWidget(rb3)
90
113
service_select_box .addStretch ()
91
114
rb1 .clicked .connect (self .radioClicked )
92
115
rb2 .clicked .connect (self .radioClicked )
93
- #rb3.clicked.connect(self.radioClicked)
116
+ self .service_selectbg = QButtonGroup ()
117
+ self .service_selectbg .addButton (rb1 )
118
+ self .service_selectbg .addButton (rb2 )
94
119
#服务的设置
95
120
service_config_box = QHBoxLayout ()
96
121
self .openai_config = self .createOpenAIConfigPanel ()
@@ -126,6 +151,7 @@ def __init__(self):
126
151
testServiceLayout .addLayout (askLayout )
127
152
128
153
layout = QVBoxLayout ()
154
+ layout .addLayout (connectmode_select_box )
129
155
layout .addLayout (input_layout )
130
156
layout .addLayout (service_select_box )
131
157
layout .addLayout (service_config_box )
@@ -135,16 +161,19 @@ def __init__(self):
135
161
136
162
# 设置该窗口的布局器为垂直布局器
137
163
self .setLayout (layout )
138
-
139
- self . readUserInfo ()
164
+ self . ApiMode = 1 #1 openapi 2 自定义服务 3 作者的测试服务器
165
+
140
166
self .loopflag = True
141
167
self .started = False
142
168
self .center_window ()
143
- self .ApiMode = 1 #1 openapi 2 自定义服务 3 作者的测试服务器
169
+
170
+ self .ConnectMode = 1 #1 连接方式 2 连接方式2
171
+ self .readUserInfo ()
144
172
self .chatgpt_bot = ChatGPTBot (self .openaikey_input .text ())
145
173
self .alert .connect (self .deviceInvalid ) #
146
174
self .logevent .connect (self .logPrint ) #
147
175
self .testaskthread = None
176
+
148
177
149
178
150
179
def logPrint (self ,msg ):
@@ -235,7 +264,7 @@ def center_window(self):
235
264
y = (screen_size .height () - window_size .height ()) // 2
236
265
# 设置窗口的位置
237
266
self .move (x , y )
238
- self .setGeometry (x , y , 900 , 400 )
267
+ self .setGeometry (x , y , 1000 , 700 )
239
268
240
269
def ask (self ,query ):
241
270
if self .ApiMode == 1 :
@@ -251,7 +280,24 @@ def clear(self):
251
280
elif self .ApiMode == 3 :
252
281
pass
253
282
254
-
283
+
284
+ def connect_mode_select (self ):
285
+ '''接入方式1'''
286
+ radioButton = self .sender ()
287
+ if radioButton .isChecked ():
288
+ if radioButton .text ()== "接入方式1" :
289
+ self .ConnectMode = 1
290
+ self .did_label .hide ()
291
+ self .did_input .hide ()
292
+ self .tts_input_label .hide ()
293
+ self .tts_input .hide ()
294
+ elif radioButton .text ()== "接入方式2" :
295
+ self .ConnectMode = 2
296
+ self .did_label .show ()
297
+ self .did_input .show ()
298
+ self .tts_input_label .show ()
299
+ self .tts_input .show ()
300
+
255
301
def radioClicked (self ):
256
302
radioButton = self .sender ()
257
303
if radioButton .isChecked ():
@@ -261,7 +307,7 @@ def radioClicked(self):
261
307
self .usercustom_config .hide ()
262
308
self .auther_config .hide ()
263
309
self .ApiMode = 1
264
- self .resize (900 , 500 )
310
+ self .resize (1000 , 700 )
265
311
elif radioButton .text ()== "你的自定义服务" :
266
312
print ("你将使用你的自定义服务" )
267
313
self .openai_config .hide ()
@@ -275,7 +321,7 @@ def radioClicked(self):
275
321
self .usercustom_config .hide ()
276
322
self .auther_config .show ()
277
323
self .ApiMode = 3
278
- self .resize (900 , 400 )
324
+ self .resize (1000 , 700 )
279
325
280
326
print ("选中了:" + radioButton .text ())
281
327
@@ -290,12 +336,23 @@ def readUserInfo(self):
290
336
self .speaker_input .setText (user_data ["speakername" ])
291
337
self .openaikey_input .setText (user_data ["chatgptkey" ])
292
338
self .customcode_input .setText (user_data ["usercode" ])
339
+
340
+ if "did" in user_data :
341
+ self .did_input .setText (user_data ["did" ])
342
+ if "tts" in user_data :
343
+ self .tts_input .setText (user_data ["tts" ])
344
+ if "connectmode" in user_data and user_data ["connectmode" ]!= "" :
345
+ self .ConnectMode = user_data ["connectmode" ]
346
+ if self .ConnectMode == 2 :
347
+ self .connectrb2 .setChecked (True )
348
+ self .did_label .show ()
349
+ self .did_input .show ()
350
+ self .tts_input_label .show ()
351
+ self .tts_input .show ()
293
352
except Exception as e :
294
353
print (e )
295
-
296
- def on_login_button_clicked (self ):
297
- # 在点击登录按钮时触发这个事件处理函数
298
- # 获取文本输入框中用户输入的内容
354
+
355
+ def saveconfig (self ):
299
356
try :
300
357
username = self .username_input .text ()
301
358
password = self .password_input .text ()
@@ -304,10 +361,15 @@ def on_login_button_clicked(self):
304
361
usercode = self .customcode_input .toPlainText ()
305
362
chatgptkey = self .openaikey_input .text ()
306
363
with open (os .path .join (str (Path .home ()), ".michatgpt.token" ),'w' ) as f :
307
- info = {"userid" :username ,"password" :password ,"model" :device ,"speakername" :speakername ,"chatgptkey" :chatgptkey ,"usercode" :usercode }
364
+ info = {"userid" :username ,"password" :password ,"model" :device ,"speakername" :speakername ,"chatgptkey" :chatgptkey ,"usercode" :usercode ,"did" :self .did_input .text (),
365
+ "tts" :self .tts_input .text (),"connectmode" :self .ConnectMode }
308
366
f .write (json .dumps (info ))
309
367
except Exception as e :
310
368
print (e )
369
+ def on_login_button_clicked (self ):
370
+ # 在点击登录按钮时触发这个事件处理函数
371
+ # 获取文本输入框中用户输入的内容
372
+ self .saveconfig ()
311
373
# 在这里处理登录逻辑
312
374
# ...
313
375
if self .started == True :
@@ -346,18 +408,65 @@ def deviceInvalid(self):
346
408
self .started = False
347
409
self .login_button .setText ("开始" )
348
410
QMessageBox .warning (self ,"警告" ,"没有找到你的音箱" )
349
-
411
+ def findttsCommand (self ,s ):
412
+ ttscommand = ""
413
+ try :
414
+ index = s .index ("Device_Information" )
415
+ if index < 0 :
416
+ index = 0
417
+ if index >= 0 :
418
+ s = s [index :]
419
+ d = {}
420
+
421
+ for line in s .strip ().split ('\n ' ):
422
+ if "Intelligent_Speaker" in line or "_Play_Text" in line :
423
+ if '=' in line and 'Intelligent_Speaker' in line :
424
+ key , value = line .split ('=' )
425
+ d [key .strip ()] = value .strip ()
426
+ if '=' in line and "_Play_Text" in line :
427
+ index = line .index ('#' )
428
+ if index >= 0 :
429
+ line = line [0 :index ]
430
+ key , value = line .split ('=' )
431
+ d [key .strip ()] = value .strip ()
432
+
433
+
434
+ # 找到 Intelligent_Speaker 的值和 _Play_Text 的值
435
+ intelligent_speaker_value = d ['Intelligent_Speaker' ]
436
+ play_text_value = d ['_Play_Text' ]
437
+ ttscommand = intelligent_speaker_value + "-" + play_text_value
438
+ except Exception as e :
439
+ print (e )
440
+ return ttscommand
350
441
async def xiaomimain (self ):
351
442
try :
352
443
#-------------------------用户配置
353
444
hardware ,user_id ,password = self .device_input .text (), self .username_input .text (),self .password_input .text ()
354
445
wifispeaker_name = self .speaker_input .text ()
446
+ MI_DID = ""
355
447
#---------------------------
356
448
LATEST_ASK_API = "https://userprofile.mina.mi.com/device_profile/v2/conversation?source=dialogu&hardware={hardware}×tamp={timestamp}&limit=2"
357
449
COOKIE_TEMPLATE = "deviceId={device_id}; serviceToken={service_token}; userId={user_id}"
358
450
lastTimeStamp = int (time .time ()* 1000 )
359
451
async with ClientSession () as session :
360
452
account = MiAccount (session ,user_id ,password ,os .path .join (str (Path .home ()),".mi.token" ),)
453
+ if self .ConnectMode == 2 :
454
+ ioservice = MiIOService (account )
455
+ deviceresult = await miio_command (ioservice , MI_DID , "list" , '' )
456
+ print (deviceresult )
457
+ for item in deviceresult :
458
+ if item ["name" ]== wifispeaker_name :
459
+ MI_DID = item ["did" ]
460
+ if self .did_input .text ()== "" :
461
+ self .did_input .setText (MI_DID )
462
+ MODEl = item ["model" ]
463
+ if MODEl and self .tts_input .text ()== "" :
464
+ modelresult = await miio_command (ioservice , MI_DID , f"spec { MODEl } " , '' )
465
+ ttscommand = self .findttsCommand (modelresult )
466
+ self .tts_input .setText (ttscommand )
467
+ break
468
+ self .saveconfig ()
469
+
361
470
await account .login ("micoapi" )
362
471
service = MiNAService (account )#通过这个发送消息
363
472
deviceresult = await service .device_list ()
@@ -405,26 +514,49 @@ async def get_if_xiaoai_is_playing(): #测试音乐播放
405
514
if await get_if_xiaoai_is_playing ():
406
515
await service .player_pause (deviceid )
407
516
await asyncio .sleep (0.5 )
408
- await service .text_to_speech (deviceid , '' )
517
+ if self .ConnectMode == 1 :
518
+ await service .text_to_speech (deviceid , '' )
519
+ else :
520
+ await miio_command (ioservice , MI_DID , self .tts_input .text ()+ " " + "" )
409
521
message = ""
410
522
if "清除消息" in last_record :
411
523
message = "GPT清除历史消息"
412
524
self .logevent .emit ("GPT清除历史消息" )
413
- await service .text_to_speech (deviceid , message )
525
+ if self .ConnectMode == 1 :
526
+ await service .text_to_speech (deviceid , message )
527
+ else :
528
+ await miio_command (ioservice , MI_DID , self .tts_input .text ()+ " " + message )
529
+
414
530
self .clear ()
415
531
elif "停止" in last_record or "休息一下" in last_record :
416
532
self .logevent .emit ("好的" )
417
- await service .text_to_speech (deviceid , "好的" )
533
+ if self .ConnectMode == 1 :
534
+ await service .text_to_speech (deviceid , "好的" )
535
+ else :
536
+ await miio_command (ioservice , MI_DID , self .tts_input .text ()+ " " + "好的" )
537
+
418
538
else :
419
- await service .text_to_speech (deviceid , "正在问大哥GPT请等待" )
539
+ if self .ConnectMode == 1 :
540
+ await service .text_to_speech (deviceid , "正在问大哥GPT请等待" )
541
+ else :
542
+ await miio_command (ioservice , MI_DID , self .tts_input .text ()+ " " + "正在问大哥GPT请等待" )
543
+
420
544
gpt_result = self .ask (last_record )
421
545
if gpt_result == "-1" :
422
546
self .logevent .emit ("出错了无法获取GPT消息" )
423
- await service .text_to_speech (deviceid , "出错了无法获取GPT消息" )
547
+ if self .ConnectMode == 1 :
548
+ await service .text_to_speech (deviceid , "出错了无法获取GPT消息" )
549
+ else :
550
+ await miio_command (ioservice , MI_DID , self .tts_input .text ()+ " " + "出错了无法获取GPT消息" )
551
+
424
552
else :
425
553
message += gpt_result
426
554
self .logevent .emit (message )
427
- await service .text_to_speech (deviceid , message )
555
+ if self .ConnectMode == 1 :
556
+ await service .text_to_speech (deviceid , message )
557
+ else :
558
+ await miio_command (ioservice , MI_DID , self .tts_input .text ()+ " " + message )
559
+
428
560
429
561
while True :
430
562
if not await get_if_xiaoai_is_playing ():
0 commit comments