Skip to content

Commit

Permalink
fix many question for LX04
Browse files Browse the repository at this point in the history
  • Loading branch information
pete-li committed Jul 20, 2023
1 parent 156e691 commit 5da4f07
Show file tree
Hide file tree
Showing 6 changed files with 105 additions and 85 deletions.
3 changes: 3 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -135,3 +135,6 @@ config/
*.mp3
.pdm-python
.pdm-build/

# 有key的不上传
one_click.bat
6 changes: 3 additions & 3 deletions one_click.bat
Original file line number Diff line number Diff line change
Expand Up @@ -3,8 +3,8 @@ cd C:\Users\50517\Desktop\xiaogpt
set MI_USER=18024490465
set MI_PASS=peter!971213
set MI_DID=568651665
set OPENAI_API_KEY=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
set OPENAI_API_KEY=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

python xiaogpt.py --hardware LX04 --use_chatgpt_api --use_command --mute_xiaoai
start /B /HIGH python xiaogpt.py --hardware LX04 --use_chatgpt_api --use_command --mute_xiaoai

cmd /k
cmd /k
1 change: 1 addition & 0 deletions xiaogpt/bot/chatgptapi_bot.py
Original file line number Diff line number Diff line change
Expand Up @@ -60,6 +60,7 @@ async def ask(self, query, **options):
# only keep 5 history
first_history = self.history.pop(0)
self.history = [first_history] + self.history[-5:]
message += " 主人,我已经回答完啦!您如果还有什么想法或者疑问,可以继续用关键词向我提问喔! \n"
print(message)
return message

Expand Down
15 changes: 9 additions & 6 deletions xiaogpt/config.py
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,6 @@

LATEST_ASK_API = "https://userprofile.mina.mi.com/device_profile/v2/conversation?source=dialogu&hardware={hardware}&timestamp={timestamp}&limit=2"
COOKIE_TEMPLATE = "deviceId={device_id}; serviceToken={service_token}; userId={user_id}"
WAKEUP_KEYWORD = "小爱同学"

HARDWARE_COMMAND_DICT = {
# hardware: (tts_command, wakeup_command)
Expand All @@ -19,7 +18,7 @@
"S12A": ("5-1", "5-5"),
"LX01": ("5-1", "5-5"),
"L06A": ("5-1", "5-5"),
"LX04": ("5-1", "5-4"),
"LX04": ("5-1", "5-2", "5-4"), # 5-1是播报文本内容 5-2 #1是唤醒 5-4 #1是执行播放内容
"L05C": ("5-3", "5-4"),
"L17A": ("7-3", "7-4"),
"X08E": ("7-3", "7-4"),
Expand All @@ -41,9 +40,9 @@
# add more here
}

DEFAULT_COMMAND = ("5-1", "5-5")
DEFAULT_COMMAND = ("5-1", "5-2", "5-4") # 5-1是播报文本内容 5-2 #1是唤醒 5-4 #1是执行播放内容

KEY_WORD = ("帮我推荐", "请问", "请回答")
KEY_WORD = ("请问", "帮我挑", "帮我推荐", "推荐")
CHANGE_PROMPT_KEY_WORD = ("更改提示词",)
PROMPT = """
回答的注意事项:“你回答服务的对象教育文化程度不高,小学文化水平,请用通俗易懂的表达,在回答中不要出现英语与链接,
Expand Down Expand Up @@ -76,8 +75,8 @@ class Config:
deployment_id: str | None = None
use_command: bool = False
verbose: bool = False
start_conversation: str = "开始持续对话"
end_conversation: str = "结束持续对话"
# start_conversation: str = "开始持续对话"
# end_conversation: str = "结束持续对话"
stream: bool = False
enable_edge_tts: bool = False
localhost: bool = True
Expand Down Expand Up @@ -115,6 +114,10 @@ def tts_command(self) -> str:
def wakeup_command(self) -> str:
return HARDWARE_COMMAND_DICT.get(self.hardware, DEFAULT_COMMAND)[1]

@property
def execute_command(self) -> str:
return HARDWARE_COMMAND_DICT.get(self.hardware, DEFAULT_COMMAND)[2]

@classmethod
def from_options(cls, options: argparse.Namespace) -> Config:
config = {}
Expand Down
3 changes: 1 addition & 2 deletions xiaogpt/utils.py
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,7 @@ def parse_cookie_string(cookie_string):

def calculate_tts_elapse(text: str) -> float:
# for simplicity, we use a fixed speed
speed = 3.8 # 该值经过反复试验得出
speed = 3.6 # 该值经过反复试验得出
# Exclude quotes and brackets that do not affect the total elapsed time
return len(_no_elapse_chars.sub("", text)) / speed

Expand Down Expand Up @@ -58,7 +58,6 @@ def validate_proxy(proxy_str: str) -> bool:
raise ValueError("Proxy scheme must be http or https")
if not (parsed.hostname and parsed.port):
raise ValueError("Proxy hostname and port must be set")

return True


Expand Down
162 changes: 88 additions & 74 deletions xiaogpt/xiaogpt.py
Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,6 @@
EDGE_TTS_DICT,
LATEST_ASK_API,
MI_ASK_SIMULATE_DATA,
WAKEUP_KEYWORD,
Config,
)
from xiaogpt.utils import (
Expand Down Expand Up @@ -76,7 +75,7 @@ def __init__(self, config: Config):
self.parent_id = None
self.mina_service = None
self.miio_service = None
self.in_conversation = False
# self.in_conversation = False
self.polling_event = asyncio.Event()
self.new_record_event = asyncio.Event()
self.temp_dir = None
Expand Down Expand Up @@ -203,11 +202,8 @@ async def simulate_xiaoai_question(self):

def need_ask_gpt(self, record):
query = record.get("query", "")
return (
self.in_conversation
and not query.startswith(WAKEUP_KEYWORD)
or query.startswith(tuple(self.config.keyword))
)
return query.startswith(tuple(self.config.keyword))
# return self.in_conversation or query.startswith(tuple(self.config.keyword))

def need_change_prompt(self, record):
if self.config.bot == "gpt3":
Expand Down Expand Up @@ -258,7 +254,6 @@ async def do_tts(self, value, wait_for_finish=False):
try:
if not self.config.use_command:
await self.mina_service.text_to_speech(self.device_id, value)

else:
await miio_command(
self.miio_service,
Expand Down Expand Up @@ -427,7 +422,15 @@ async def wakeup_xiaoai(self):
return await miio_command(
self.miio_service,
self.config.mi_did,
f"{self.config.wakeup_command} {WAKEUP_KEYWORD} 0",
f"{self.config.wakeup_command} #1",
)

# 执行播放的文本
async def execute_text(self, text):
return await miio_command(
self.miio_service,
self.config.mi_did,
f"{self.config.execute_command} {text} #1",
)

async def run_forever(self):
Expand All @@ -436,67 +439,73 @@ async def run_forever(self):
task = asyncio.create_task(self.poll_latest_ask())
assert task is not None # to keep the reference to task, do not remove this
print(f"Running xiaogpt now, 用`{'/'.join(self.config.keyword)}`开头来提问 \n")
print(f"或用`{self.config.start_conversation}`开始持续对话 \n")
# print(f"或用`{self.config.start_conversation}`开始持续对话 \n")
while True:
self.polling_event.set()
await self.new_record_event.wait()
self.new_record_event.clear()
new_record = self.last_record
self.polling_event.clear() # stop polling when processing the question
query = new_record.get("query", "").strip()
if "帮我推荐" in query:
query = "帮我推荐" + query

if query == self.config.start_conversation:
if not self.in_conversation:
print("开始对话 \n")
self.in_conversation = True
await self.wakeup_xiaoai()
await self.stop_if_xiaoai_is_playing()
continue
elif query == self.config.end_conversation:
if self.in_conversation:
print("结束对话 \n")
self.in_conversation = False
await self.stop_if_xiaoai_is_playing()
continue

# we can change prompt
if self.need_change_prompt(new_record):
print(new_record)
self._change_prompt(new_record.get("query", ""))

if not self.need_ask_gpt(new_record):
self.log.debug("No new xiao ai record")
continue

query = re.sub(
rf"^({'|'.join(self.config.keyword)})", "", query
) # drop 帮我回答

print("-" * 40, "\n")
print("问题:" + query + "?\n")
if not self.chatbot.history:
query = f"{query}{self.config.prompt}"
if self.config.mute_xiaoai:
await self.stop_if_xiaoai_is_playing()
else:
await asyncio.sleep(8) # waiting for xiaoai speaker done

try:
print(
"以下是小爱的回答: \n\n",
new_record.get("answers", [])[0].get("tts", {}).get("text"),
"\n",
)
self.polling_event.set()
await self.new_record_event.wait()
self.new_record_event.clear()
new_record = self.last_record
self.polling_event.clear() # stop polling when processing the question
query = new_record.get("query", "").strip()
for k in self.config.keyword:
if k in query:
await self.execute_text("闭嘴")
query = k + query
break

# if query == self.config.start_conversation:
# if not self.in_conversation:
# print("开始对话 \n")
# self.in_conversation = True
# await self.wakeup_xiaoai()
# await self.stop_if_xiaoai_is_playing()
# continue
# elif query == self.config.end_conversation:
# if self.in_conversation:
# print("结束对话 \n")
# self.in_conversation = False
# await self.stop_if_xiaoai_is_playing()
# continue

# we can change prompt
if self.need_change_prompt(new_record):
print(new_record)
self._change_prompt(new_record.get("query", ""))

if not self.need_ask_gpt(new_record):
self.log.debug("No new xiao ai record")
continue

query = re.sub(
rf"^({'|'.join(self.config.keyword)})", "", query
) # drop 帮我回答

print("-" * 40, "\n")
print("问题:" + query + "?\n")
if not self.chatbot.history:
query = f"{query}{self.config.prompt}"
if self.config.mute_xiaoai:
await self.stop_if_xiaoai_is_playing()
else:
await asyncio.sleep(8) # waiting for xiaoai speaker done

if len(new_record.get("answers", [])) != 0:
print(
"以下是小爱的回答: \n\n",
new_record.get("answers", [])[0].get("tts", {}).get("text"),
"\n",
)
else:
print("小爱没有回答 \n")

# 播报开始,并创建任务
play_content = "您已触发智能问答模式,正在请教人工智能助手GPT,请耐心等待!如果您中途不想听了,可以叫我的名字打断我的说话,以下是GPT的回答:"
# play_content = "正在请教人工智能助手大哥GPT,请耐心等待!"
tts_task = asyncio.create_task(
self.do_tts(
"您已触发智能问答模式,正在请教人工智能助手chatGPT,请耐心等待!如果您中途不想听了,可以叫我的名字打断我说话,以下是GPT的回答:",
wait_for_finish=True,
)
self.do_tts(play_content, wait_for_finish=True)
)

print("以下是GPT的回答: \n")

gpt_responses = []
Expand All @@ -507,10 +516,11 @@ async def run_forever(self):
await tts_task

if not self.config.enable_edge_tts:
for message in gpt_responses:
await self.do_tts(
message, wait_for_finish=True
) # 逐条播放GPT生成的文本
if len(gpt_responses) > 0:
message = gpt_responses[0]
await self.do_tts(message, wait_for_finish=True)
else:
await self.do_tts("回答处理出错啦,请稍后再试叭!", wait_for_finish=True)
else:
tts_lang = (
find_key_by_partial_string(EDGE_TTS_DICT, query)
Expand All @@ -519,10 +529,14 @@ async def run_forever(self):
# tts with edge_tts
await self.edge_tts(self.ask_gpt(query), tts_lang)
print("回答完毕 \n")
except IndexError:
print("小爱没回 \n")
except Exception as e:
print(f"GPT处理报错: {e} \n")
if self.in_conversation:
print(f"继续对话, 或用`{self.config.end_conversation}`结束对话 \n")
# await asyncio.sleep(3)
await self.wakeup_xiaoai()
except Exception as e:
print(f"run_forever处理报错: {e} \n")
traceback.print_exc()
# if self.in_conversation:
# # print(f"继续对话, 或用`{self.config.end_conversation}`结束对话 \n")
# await self.wakeup_xiaoai()


import traceback

0 comments on commit 5da4f07

Please sign in to comment.