import dataCall
import constants
import versions
-
+#import VAD
#dev_type = "G10"
dev_type = "7PIN_BK"#小瑞
#dev_type = "7PIN"#柒牌
#dev_type = 'momo'#食梦貘
#dev_type = 'sjgq'#四季甘泉
#dev_type = 'szbst'#深圳百事通
-#dev_type = 'rabbit'
class AI_led(Abstract):
def __init__(self):
if dev_type == "G10":
class AI_dev(Abstract):
# AI
def __init__(self):
- self.is_wdt = 1 #是否开启看门狗
+ self.is_wdt = 0 #是否开启看门狗
self.VBATT_tab = {"charge_full":4300,"100" :4250 , "90":4179 , "80":4070, "60": 3883, "40":3770, "20":3699, "10":3652,"5":3600,}
self.KeyAI_status = 0
EventMesh.subscribe("audio_montage_play",self.audio_montage_play)
EventMesh.subscribe("paly_iccid_imei",self.paly_iccid_imei)
EventMesh.subscribe("paly_device_res_error",self.paly_device_res_error)
+ EventMesh.subscribe("Power_off",self.pwk_key_Long_Press)
+
print("AI_dev:2")
self.pk = PowerKey()
self.pk.powerKeyEventRegister(self.powerKey_callback)
self.aud.stopAll()
Power.powerDown()
#print("AI_key_release")
- EventMesh.publish("pwk_key_long_press")
+ #EventMesh.publish("pwk_key_long_press")
#EventMesh.publish("publish_AI_btnInfo",{"func":self.pwk_key_Long_Press})
if self.pwk_key_status == 1:#松开
#print("pwk_key_timer_cb:{}".format(self.pwk_key_timer_count))
print("AI_key_release")
EventMesh.publish("AI_key_release")
- def pwk_key_Long_Press(self):
+ def pwk_key_Long_Press(self,event=None,msg=None):
self.check_rest_timer_count = 0
print("pwk_key_long_press!!!!!!!")
print("pwk_key_long_press!!!!!!!")
self.aud.stopAll()
Power.powerDown()
#print("AI_key_release")
- EventMesh.publish("pwk_key_long_press")
+ #EventMesh.publish("pwk_key_long_press")
def pwk_key_release(self):
self.check_rest_timer_count = 0
self.is_long_record = 0 #是否开启长录音模式(语音打断模式)
self.ai_OTA = OTA()
self.is_auth = 0 #是否开启dmp鉴权
- #self.VC_mode = 0 #0:短按连续问答模式 1:长按录音模式
+ #self.VC_mode = 1 #0:短按连续问答模式 1:长按录音模式
self.VC_mode = EventMesh.publish("get_storage_config","VC_mode")#
if self.VC_mode == None :
self.VC_mode = 0
self.is_up_error= 0 #是否上传错误id
+ self.Close_flag =0 #=1时,连续对话播放完音频就退出
+ self.is_llm_commands = 1#=1用大模型判断命令,=0用服务器本地插件判断命令
self.error_data = []
self.asr_taskid = ""
self.VC_taskid = ""
self.VC_server = 86 #0柒牌正式服务器,1:测试服务器1,2:测试服务器2
-
+
self.server_ip = EventMesh.publish("get_storage_config","server_ip")#
if self.server_ip == None:
if self.VC_server == 1:#
self.server_ip="amp-wss.raisound.com"
elif self.VC_server == 6:#
self.server_ip="118.145.158.207:22080"
+ elif self.VC_server == 7:#
+ self.server_ip="118.145.158.207:22080"
+ elif self.VC_server == 8:#
+ self.server_ip="115.190.94.208:22080"
elif self.VC_server == 86:#
- self.server_ip="118.145.158.207:22086"
+ self.server_ip="118.145.158.207:22086"
else:
#self.server_ip="sevenpin.qipai.com.cn"
self.server_ip="118.145.158.207:22082"
elif dev_type == "sjgq":
self.server_ip="118.145.158.207:22084"
- elif dev_type == "szbst" or dev_type == 'rabbit':
- self.server_ip="118.145.158.207:22086"
- #self.server_ip="115.190.94.208:22080"
+
#开机提示音
self.power_on_tone = EventMesh.publish("get_storage_config","power_on_tone")#
if dev_type != "7PIN":
self.power_on_tone = "已开机,您好!我是北科瑞讯智能 AI bot_name"
elif dev_type == "7PIN_BK":
self.power_on_tone = "小瑞来了!我们一起来愉快地聊天吧!"
- elif dev_type == 'rabbit':
- self.power_on_tone = "兔兔来了!我们一起来愉快地聊天吧!"
- elif dev_type == "szbst":
- self.power_on_tone = "深圳百事通来了!请问您有什么需要我帮忙的吗?"
-
elif dev_type == "momo":
self.power_on_tone = "DuloDulo,我是上古神兽食梦貘,主人可以叫我momo,我来自《山海经》,是一只以梦为食的神秘灵兽,每当颜色朦胧、人们入睡时,我就会悄悄飞到人们的床头,用我长长的鼻子把噩梦统统吞噬掉,只留下甜甜的美梦。从今往后,就由我守护在主人身边,一起度过每一个星河璀璨的夜晚。"
elif dev_type == "sjgq":
self.power_on_tone = "您好!我是巴马四季甘泉的智能助手。我可以为你解答各种各样的问题,像是有关巴马四季甘泉知识库、中基长寿科学产品、卫斯曼院士国际先进医疗中心的问题,还有日常生活与工作、旅游信息、健康咨询、教育与学习、情感交流、全球资讯、世界文化等方面的问题哦。你有没有这方面的问题想要问我呀?"
+ elif dev_type == "szbst":
+ self.power_on_tone = "深圳百事通来了!请问您有什么需要我帮忙的吗?"
else:
self.power_on_tone = "您好!我是世界首创柒牌男装AI生活好帮手-bot_name, 很高兴为您服务,我可以帮您解答柒牌公司知识库、日常生活与工作、旅游信息、健康与运动咨询、教育与学习、情感交流、全球资讯、世界文化等问题!请问您有什么需要我帮忙的吗?"
self.VC_play_TYPE = VC_play_TYPE_PCM #0:PCM 1:mp3
self.VC_record_samplerate = 16000
self.VC_play_samplerate = 16000
-
+ # ARG_sample_rate, // 采样率
+ # ARG_channel, // 通道数
+ # ARG_frame_size, // 每帧字节数
+ # ARG_energy_threshold, // 能量阈值
+ # ARG_voice_time, // 语音持续时间阈值(ms)
+ # ARG_silence_time, // 静音持续时间阈值(ms)
+ # ARG_silence_start_threshold, // 静音开始阈值(ms)
+ #self.vad = VAD.VAD(self.VC_record_samplerate ,1,6400,300,50,300,100)
+ self.speech_rate = EventMesh.publish("get_storage_config","speech_rate")#语速配置
+ if self.speech_rate == None:
+ self.speech_rate = 0
self.VC_TTS_voice_type = EventMesh.publish("get_storage_config","VC_TTS_voice_type")#音色配置
if self.VC_TTS_voice_type == None or ("男" in self.VC_TTS_voice_type) == False:
- if dev_type == "G10" or dev_type == "7PIN_BK"or dev_type == "szbst"or dev_type == 'rabbit':
+ if dev_type == "G10" or dev_type == "7PIN_BK"or dev_type == "szbst":
self.VC_TTS_voice_type = {
"女":{
"bot_name":"小瑞",
- "voice":"huoshan::zh_female_wanwanxiaohe_moon_bigtts" ,
+ "voice":"zh_female_wanwanxiaohe_moon_bigtts" ,
"lang":"zh-cn"
},
"男":{
"bot_name":"小瑞",
- "voice":"huoshan::zh_male_wennuanahu_moon_bigtts" ,
+ "voice":"zh_male_wennuanahu_moon_bigtts" ,
"lang":"zh-cn"
},
"童":{
"bot_name":"小瑞",
- "voice":"huoshan::ICL_zh_female_huoponvhai_tob" ,
+ "voice":"ICL_zh_female_huoponvhai_tob" ,
"lang":"zh-cn"
},
"粤":{
"bot_name":"小瑞",
- "voice":"huoshan::zh_female_wanqudashu_moon_bigtts" ,
+ "voice":"zh_female_wanqudashu_moon_bigtts" ,
"lang":"zh-hk"
},
"四川":{
"bot_name":"小瑞",
- "voice":"huoshan::zh_female_daimengchuanmei_moon_bigtts",
+ "voice":"zh_female_daimengchuanmei_moon_bigtts",
"lang":"&lang=zh-cn-sc"
},
"个性":{
"bot_name":"小瑞",
- "voice":"huoshan::zh_male_sunwukong_mars_bigtts" ,
+ "voice":"zh_male_sunwukong_mars_bigtts" ,
"lang":"zh-cn"
}
self.VC_TTS_voice_type = {
"女":{
"bot_name":"食梦貘",
- "voice":"huoshan::zh_female_shaoergushi_mars_bigtts" ,
+ "voice":"zh_female_shaoergushi_mars_bigtts" ,
"lang":"zh-cn"
},
"男":{
"bot_name":"食梦貘",
- "voice":"huoshan::zh_male_yangguangqingnian_mars_bigtts" ,
+ "voice":"zh_male_yangguangqingnian_mars_bigtts" ,
"lang":"zh-cn"
},
"童":{
"bot_name":"食梦貘",
- "voice":"huoshan::ICL_zh_female_huoponvhai_tob" ,
+ "voice":"ICL_zh_female_huoponvhai_tob" ,
"lang":"zh-cn"
},
}
self.VC_TTS_voice_type = {
"女":{
"bot_name":"小巴",
- "voice":"huoshan::zh_female_wanwanxiaohe_moon_bigtts" ,
+ "voice":"zh_female_wanwanxiaohe_moon_bigtts" ,
"lang":"zh-cn"
},
"男":{
"bot_name":"小巴",
- "voice":"huoshan::zh_male_wennuanahu_moon_bigtts" ,
+ "voice":"zh_male_wennuanahu_moon_bigtts" ,
"lang":"zh-cn"
},
"童":{
"bot_name":"小巴",
- "voice":"huoshan::ICL_zh_female_huoponvhai_tob" ,
+ "voice":"ICL_zh_female_huoponvhai_tob" ,
"lang":"zh-cn"
},
}
#EventMesh.publish("set_storage_config",["VC_TTS_voice_type",self.VC_TTS_voice_type])
-
try:
self.VC_TTS_voice_key = EventMesh.publish("get_storage_config","VC_TTS_voice_key")#音色配置
if self.VC_TTS_voice_key == None :
- if dev_type == "7PIN_BK" or dev_type == 'rabbit':
+ if dev_type == "7PIN_BK":
self.VC_TTS_voice_key = "童"
+ #self.VC_TTS_voice_key = "男"
elif dev_type == "momo":
self.VC_TTS_voice_key = "男"
else:
self.VC_TTS_volume = EventMesh.publish("get_storage_config","VC_TTS_volume")#音量配置
except Exception as e:
usys.print_exception(e)
-
+ #配置词
+ self.commands = [
+ {
+ "command": "切换音色",#命令
+ "patterns": [ #多种问法,说法
+ "声音改成", "声音改为", "改成", "改为", "换成", "切换成", "变成", "声音"
+ "使用", "设置声音为", "把声音改成", "声音切换到", "用","声音切换的"
+ ],
+ "exact_matches": ["声音改成", "声音改为", "改成", "改为"],#精确匹配的完整短语
+ "has_param": True,# 是否包含参数
+ "param_regexp": r"(?P<cmd_parameter>(男|难|女|童|同|粤|广东话|粤语|四川话|川普|四川口音))",#参数提取正则表达式
+ "require_full_match": False,#是否要求完全匹配
+ "negative_patterns": [],#否定模式(避免误触发)
+ "keyword_threshold": 0.6#关键词匹配阈值
+ },
+ {
+ "command": "音量加大",
+ "patterns": [
+ "音量加大","音量大", "声音大" ,"声音加大","听不清楚","声音太小","太小声了"
+ ],
+ "exact_matches": [],
+ "has_param": False,
+ "param_regexp": "",
+ "require_full_match": False,
+ "negative_patterns": ["声音太大"],
+ "keyword_threshold": 1
+ },
+ {
+ "command": "音量减小",
+ "patterns": [
+ "音量减小","音量小", "声音小","你太吵了","声音太大","太大声了"
+ ],
+ "exact_matches": [],
+ "has_param": False,
+ "param_regexp": "",
+ "require_full_match": False,
+ "negative_patterns": ["声音太小"],
+ "keyword_threshold": 0.8
+ },
+ {
+ "command": "关机",
+ "patterns": [
+ "关机", "关闭电源"
+ ],
+ "exact_matches": ["关机", "关闭电源"],
+ "has_param": False,
+ "param_regexp": "",
+ "require_full_match": True,
+ "negative_patterns": [],
+ "keyword_threshold": 0.8
+ },
+ {
+ "command": "进入工厂模式",
+ "patterns": [
+ "进入工厂模式"
+ ],
+ "exact_matches": ["进入工厂模式"],
+ "has_param": False,
+ "param_regexp": "",
+ "require_full_match": True,
+ "negative_patterns": [],
+ "keyword_threshold": 0.8
+ },
+ {
+
+ "command": "再见",
+ "patterns": [
+ "再见","拜拜","我要走了"
+ ],
+ "exact_matches": [],
+ "has_param": False,
+ "param_regexp": "",
+ "require_full_match": False,
+ "negative_patterns": [],
+ "keyword_threshold": 0.8
+ },
+ {
+
+ "command": "查询信号",
+ "patterns": [
+ "查询信号","信号怎样","信号是多少","信号怎么样"
+ ],
+ "exact_matches": [],
+ "has_param": False,
+ "param_regexp": "",
+ "require_full_match": False,
+ "negative_patterns": ["查询"],
+ "keyword_threshold": 0.8
+ },
+ {
+
+ "command": "查询卡号",
+ "patterns": [
+ "查询卡号","卡号","iccid号","ICCID号"
+ ],
+ "exact_matches": [],
+ "has_param": False,
+ "param_regexp": "",
+ "require_full_match": False,
+ "negative_patterns": ["查询"],
+ "keyword_threshold": 0.8
+ },
+ {
+
+ "command": "查询设备号",
+ "patterns": [
+ "设备号","查询设备号","查询IMEI号"
+ ],
+ "exact_matches": [],
+ "has_param": False,
+ "param_regexp": "",
+ "require_full_match": False,
+ "negative_patterns": ["查询"],
+ "keyword_threshold": 0.8
+ },
+ {
+ "command": "OTA升级",
+ "patterns": [
+ "OTA升级"
+ ],
+ "exact_matches": ["OTA升级"],
+ "has_param": False,
+ "param_regexp": "",
+ "require_full_match": True,
+ "negative_patterns": [],
+ "keyword_threshold": 1
+ },
+ {
+ "command": "查询服务器地址",
+ "patterns": [
+ "查询服务器地址"
+ ],
+ "exact_matches": [],
+ "has_param": False,
+ "param_regexp": "",
+ "require_full_match": False,
+ "negative_patterns": ["查询"],
+ "keyword_threshold": 0.9
+ }
+ ,
+ {
+ "command": "切换对话模式",
+ "patterns": [
+ "切换对话模式","切换兑换模式"
+ ],
+ "exact_matches": [],
+ "has_param": False,
+ "param_regexp": "",
+ "require_full_match": False,
+ "negative_patterns": [],
+ "keyword_threshold": 0.8
+ },
+ {
+ "command": "查询版本",
+ "patterns": [
+ "查询版本号","软件版本"
+ ],
+ "exact_matches": [],
+ "has_param": False,
+ "param_regexp": "",
+ "require_full_match": False,
+ "negative_patterns": ["查询"],
+ "keyword_threshold": 0.6
+ },
+ ]
if self.VC_TTS_volume == None:
self.VC_TTS_volume = 100
self.AI_audio_queue_thread_id = 0
self.audio_play_state = 1 #音频播放完状态
self.close_timerout = 0
self.LocalRespondingEnded_timerout = 0
-
+
+ self.VC_Play_flag = 0
self.play_flag = 0
self.VC_record_state_flag = 0
self.AI_key_long_press_flag = 0
EventMesh.publish("set_storage_config",["powerRestart",0])
else:
-
+ pass
self.AI_TTS_str = self.power_on_tone.replace("bot_name", self.bot_name)
print("开机提示:{}".format(self.AI_TTS_str))
EventMesh.publish("publish_AI_btnInfo",{"func":self.AI_VC_start})
print("AI_key_press")
self.get_config_timer_count = 0
self.key_state = 1
+ self.Close()
+
#self.aud.aud_tone_play(10,200)#播放按键音
self.AI_TTS_str = ""#"你好,有什么吩咐"
self.AI_ASR_str = ""
self.VC_Speech_Start()
self.AI_VC_start()
+ self.chenggong_tone()
# self.Close()
# self.AI_VC_start()
self.AI_key_long_press_flag = 0
+
def AI_key_release(self, event, msg):#按键弹起
print("AI_key_release123")
self.key_state = 0
if self.AI_key_long_press_flag == 1 :#有长按
#self.AI_client_VC_end_speech()
- EventMesh.publish("publish_AI_btnInfo",{"func":utime.sleep_ms,'data':(1000)})
- EventMesh.publish("publish_AI_btnInfo",{"func":self.AI_client_asr_StopTranscription_requset})
+ #EventMesh.publish("publish_AI_btnInfo",{"func":utime.sleep_ms,'data':(1000)})
+ #EventMesh.publish("publish_AI_btnInfo",{"func":self.AI_client_asr_StopTranscription_requset})
#self.AI_client_asr_StopTranscription_requset()#请求停止
if self.VC_mode == 1 :#长按单次问答模式
- if self.AI_ASR_str_tmp != "":
- print("AI_key_release:asr_str:{}".format(self.AI_ASR_str))
- EventMesh.publish("publish_AI_btnInfo",{"func":self.AI_VC_start})
+ # if self.AI_ASR_str_tmp != "":
+ print("AI_key_release:asr_str:{}".format(self.AI_ASR_str))
+ # EventMesh.publish("publish_AI_btnInfo",{"func":self.AI_VC_start})
+ self.AI_client_VC_end_speech()
+ pass
else :
if self.VC_mode == 1 :#长按单次问答模式
- # try:
- # EventMesh.publish("publish_AI_btnInfo",{"func":self.Close})
- # except Exception as e:
- # usys.print_exception(e)
- # EventMesh.publish("publish_AI_btnInfo",{"func":self.key_prompt}) #提示请您按住中间的按钮开始讲话,讲完松开即可
- self.AI_TTS_str = "请您按住中间的按钮开始讲话,讲完松开即可 "
- EventMesh.publish("publish_AI_btnInfo",{"func":self.AI_VC_start})
-
+ try:
+ EventMesh.publish("publish_AI_btnInfo",{"func":self.Close})
+ except Exception as e:
+ usys.print_exception(e)
+ EventMesh.publish("publish_AI_btnInfo",{"func":self.key_prompt}) #提示请您按住中间的按钮开始讲话,讲完松开即可
+ #self.AI_TTS_str = "请您按住中间的按钮开始讲话,讲完松开即可 "
+ #EventMesh.publish("publish_AI_btnInfo",{"func":self.AI_VC_start})
+ pass
#self.VC_Speech_End()
def AI_key_long_press(self, event, msg):#按键长按
def VC_error(self, event, msg):#错误播报
self.websocket_error()
#EventMesh.publish("publish_AI_btnInfo",{"func":self.websocket_error})
-#****************************************ASR连接**********************************************************************
- def websocket_connect_asr(self):
- print("websocket_connect_asr:{} e:{}!!!!!!!!!!!!!!!!!!!!!".format(self.AI_client_asr_isconnect,self.AI_client_asr_debug))
- self.AI_ASR_text_repet_count = 0
- self.AI_ASR_check_timeout = 0
- self.AI_ASR_error_timeout = 0
- self.AI_ASR_text_tmp = ""
- if self.AI_client_asr_isconnect == 1:
- return
- # 创建ASR客户端
- try:
- signal = net.csqQueryPoll()
- if signal == -1 or sim.getStatus() != 1:#网络正常
- self.websocket_error()
- return
-
- # self.AI_client_asr = uwebsocket.Client.connect('wss://nls-gateway-cn-beijing.aliyuncs.com/ws/v1',headers=Headers, debug=False)
- req_str = ""
- platform = "platform=huoshan"
- #platform= "platform=xfyun-ita"
- platform= "platform=xfyun-bigmodel-ita"
- lang = "lang=zh-cn"#普通话测试环境
- try:
- if "loang" in self.VC_TTS_voice_type[self.VC_TTS_voice_key]:
- lang = self.VC_TTS_voice_type[self.VC_TTS_voice_key]["lang"]
- else:
- print("not lang!!!!!!!!!!!!!!!!!!!!!!")
- except Exception as e:
- usys.print_exception(e)
- req_str = "asr/ws?is_auth={}&{}&{}".format(self.is_auth,platform,lang)
- print("req_str:{}".format(req_str))
- token = EventMesh.publish("get_dev_token")
- print("token:{}".format(token))
- url = 'ws://{}/{}&dt={}'.format(self.server_ip,req_str,token)
- print("websocket_connect_asr URL:{}".format(url))
- self.AI_client_asr = uwebsocket.Client.connect(url, debug=True)#
- #self.AI_WS_connect_Queue.put(self.AI_client_asr)
-
- except Exception as e: #网络连接异常
- usys.print_exception(e)
-
- print("websocket_connect_asr error!!!\r\n")
- #self.connect_timerout_popup(2)
- str_error = str(e)
- if str_error.find("[Errno 22] EINVAL")!= -1:
- self.websocket_error()
- print("[Errno 22] EINVAL!!!\r\n")
- print("[Errno 22] EINVAL!!!\r\n")
- print("[Errno 22] EINVAL!!!\r\n")
- print("[Errno 22] EINVAL!!!\r\n")
- EventMesh.publish("set_storage_config",["powerRestart",1])#调试临时关闭
- utime.sleep_ms(1000)
- self.aud.stopPlayStream()
- self.aud.stopAll()
- Power.powerRestart()
-
- self.websocket_error()
-
- return
- if self.AI_client_asr == None:
- EventMesh.publish_async("update_dev_token",thread_size = 8192)#获取token
- return
- self.AI_client_asr_debug+=1
- utime.sleep_ms(10)
- self.AI_client_asr.settimeout(5)
- #开启发送线程
- if self.AI_ASR_send_data_queue_thread_id == 0:
- _thread.stack_size(self.Audio_buf_size+8*1024)
- self.AI_ASR_send_data_queue_thread_id = _thread.start_new_thread(self.AI_ASR_send_data_queue_thread, ())
- _thread.stack_size(8*1024)
- print("AI_VC_start :AI_ASR_send_data_queue_thread_id :{} ".format(self.AI_ASR_send_data_queue_thread_id))
- print("websocket_connect_asr 222!!!\r\n")
- self.AI_client_asr_recv_thread_close()#关闭读线程
- # 创建线程接收数据
- _thread.stack_size(self.Audio_buf_size+8*1024)
- self.AI_client_asr_recv_id = _thread.start_new_thread(self.AI_client_asr_recv, (self.AI_client_asr,))
- _thread.stack_size(8*1024)
- self.AI_client_asr_isconnect = 1
- self.AI_ASR_timer.start(1000, 1, self.AI_ASR_timer_cb)
- self.AI_client_asr_start_requset()#开始请求
- print("websocket_connect_asr:OK!!!!!!!!!!!!!!!!!!!!!")
-
- def websocket_deconnect_asr(self):
- print("websocket_deconnect_asr {}!!!!!!!".format(self.AI_client_asr_isconnect))
- print("websocket_deconnect_asr!!!!!!!")
- self.AI_ASR_text_repet_count = 0
- self.AI_ASR_text_tmp = ""
- self.AI_ASR_timer.stop()
- #self.AI_ASR_send_data_queue_thread_close()#关闭发送线程
- self.AI_client_asr_recv_thread_close()#关闭读线程
- if self.AI_client_asr_isconnect == 1 or self.AI_client_asr!= None:
- try:
- self.AI_client_asr_isconnect = 0
- count = 500
- while True:#等待发完数据
- count-=1
- if count <=0 or self.AI_ASR_send_data_queue_thread_lock == 0:
- break
- print("等待发送完成:{}".format(count))
- if self.AI_ASR_send_data_queue.empty()!=True:
- self.AI_ASR_send_data_queue.clear()
- utime.sleep_ms(1)
-
- try:
- self.AI_client_asr_StopTranscription_requset()#发送停止ASR
- self.AI_client_asr.close()
- except Exception as e:
- usys.print_exception(e)
- utime.sleep_ms(200)#再尝试关闭一次
- try:
- self.AI_client_asr.close()
-
- except Exception as e:
- usys.print_exception(e)
- self.AI_client_asr_debug-=1
- try:
- self.AI_client_asr._close()
- except Exception as e:
- usys.print_exception(e)
- self.AI_client_asr = None
- except Exception as e:
- usys.print_exception(e)
- print("websocket_deconnect_asr {}!!!!!!!".format(self.AI_client_asr_isconnect))
-
- #websocket发送数据
- def AI_client_asr_send(self,data_str):
- # if isinstance(data_str, str):#是字符串
- # print("ASR ASR AI_client_asr_send:{}".format(data_str))
- # pass
- # else:
- # pass
- # #print("ASR ASR AI_client_asr_send:len:{}".format(len(data_str)))
- self.AI_ASR_send_data_queue.put([AI_client_asr_num,data_str])
-
- def AI_client_asr_ping(self):
- pass
- if self.AI_client_asr_isconnect == 1:
- #self.AI_client_asr.write_frame(0x09,b'ping ping')
- self.AI_client_asr_send("ping")
- def set_AI_ASR_flag(self,data):
- self.AI_ASR_flag = data
- def AI_ASR_timer_cb(self, *args): #
- EventMesh.publish("publish_AI_btnInfo",{"func":self.AI_ASR_timer_cb_})
-
- def AI_ASR_timer_cb_(self):
- if self.AI_ASR_check_timeout > 0:
- print("AI_ASR_check_timeout:{}".format(self.AI_ASR_check_timeout))
- self.AI_ASR_check_timeout-=1
- if self.AI_ASR_check_timeout <=0:
- self.AI_ASR_check_timeout = 0
- self.AI_ASR_error_timeout = 3#发送停止后3秒后没正式结果就提示
- #EventMesh.publish("publish_AI_btnInfo",{"func":self.AI_client_asr_StopTranscription_requset})
-
- if self.AI_ASR_error_timeout>0:
- self.AI_ASR_error_timeout-=1
- print("AI_ASR_error_timeout:{}".format(self.AI_ASR_error_timeout))
- if self.AI_ASR_error_timeout <= 0:
- self.AI_ASR_error_timeout = 0
- #if self.AI_ASR_str == "":
- if self.AI_ASR_str_tmp == "" and self.AI_ASR_str == "" and self.AI_ASR_text_tmp == "":
- self.AI_TTS_str = "没有识别到您说话,请重试"
- else :
- self.AI_ASR_str = self.AI_ASR_str_tmp + self.AI_ASR_str+self.AI_ASR_text_tmp
- self.AI_ASR_str_tmp = self.AI_ASR_str
- print("AI_ASR_error_timeout2:重连:{}!!!!!!!!!!\r\n".format(self.AI_ASR_str) )
- print("AI_ASR_error_timeout2:重连:{}!!!!!!!!!!\r\n".format(self.AI_ASR_str) )
- print("AI_ASR_error_timeout2:重连:{}!!!!!!!!!!\r\n".format(self.AI_ASR_str) )
- EventMesh.publish("publish_AI_btnInfo",{"func":self.websocket_deconnect_asr})
- EventMesh.publish("publish_AI_btnInfo",{"func":self.websocket_connect_asr}) #重连ASR
- #EventMesh.publish("publish_AI_btnInfo",{"func":self.VC_Speech_End}) #重连ASR
- EventMesh.publish("publish_AI_btnInfo",{"func":self.AI_VC_start})
- EventMesh.publish("publish_AI_btnInfo",{"func":self.set_AI_ASR_flag,"data":1})#设置以打断过一次
- if self.VC_record_state_flag > 1:
- self.VC_record_state_flag =1
- pass
- #关闭ASR数据发送线程
- def AI_ASR_send_data_queue_thread_close(self):
- if self.AI_ASR_send_data_queue_thread_id != 0:
- count =500
- while True:
- count -= 1
- if self.AI_ASR_send_data_queue_thread_lock == 0 or count <=0:
- break
- else:
- self.AI_ASR_send_data_queue_thread_lock = 2
- print("AI_ASR_send_data_queue_thread going:{}...".format(count))
- utime.sleep_ms(1)
- self.AI_ASR_send_data_queue_thread_lock = 0
- print("AI_ASR_send_data_queue_thread_close")
- try:
- _thread.stop_thread(self.AI_ASR_send_data_queue_thread_id)
- except Exception as e:
- usys.print_exception(e)
- self.AI_ASR_send_data_queue_thread_id = 0
- #发送数据队列
- def AI_ASR_send_data_queue_thread(self):
- print("AI_ASR_send_data_queue_thread:start")
- count_t = 0
- while True:
- if self.AI_ASR_send_data_queue_thread_lock == 2:
- print("AI_ASR_send_data_queue_thread:该退出了")
- break
- if self.AI_ASR_send_data_queue.empty() :#不能去掉,去掉会卡死
- self.AI_ASR_send_data_queue_thread_lock = 0
- count_t+=1
- utime.sleep_ms(1)
- else:
- #data[0]是websocket连接对象编号,data[1]是数据
- #print("AI_ASR_send_data_queue_thread:get")
-
- self.AI_ASR_send_data_queue_thread_lock = 1
- data = self.AI_ASR_send_data_queue.get()
- #print("AI_ASR_send_data_queue_thread:num{} len{}".format(data[0],len(data[1])))
- if data != None:
- try:
- # 发送数据
- if data[0] == AI_client_asr_num:
- self.AI_ASR_send_buf_len -= len(data[1])
- self.asr_pingping_timerout = 0
- if self.AI_client_asr != None and self.AI_client_asr_isconnect == 1:
- self.AI_client_asr.send(data[1])
- if isinstance(data[1], str):#是字符串
- print("ASR ASR: send_data:{}".format(data[1]))
- # else:
- # print("ASR ASR: send_data!:{}".format(len(data[1])))
- else:
- if isinstance(data[1], str):#是字符串
- print("ASR ASR: send_data error!!!:{}".format(data[1]))
- else:
- print("ASR ASR: send_data error!!!:{}".format(len(data[1])))
-
- except Exception as e:
- usys.print_exception(e)
- if data[0] == AI_client_asr_num:
- if self.AI_client_asr_isconnect != 0:
- print("ASR发送数据错误,退出")
- EventMesh.publish("publish_AI_btnInfo",{"func":self.websocket_error,"data":"ASR发送出错了,请重试"})
- self.ud_error(["asr",self.asr_taskid])
- #EventMesh.publish("publish_AI_btnInfo",{"func":self.websocket_connect_asr}) #重连
- utime.sleep_ms(1)
- self.AI_ASR_send_data_queue_thread_lock = 0
-
- #ASR关闭读线程
- def AI_client_asr_recv_thread_close(self):
- if self.AI_client_asr_recv_id != 0:
- count =500
- while True:
- count -= 1
- if self.AI_client_asr_recv_lock == 1:
- self.AI_client_asr_recv_lock = 2
- if self.AI_client_asr_recv_lock == 0 or count <=0:
- break
- else:
- print("AI_client_asr_recv_thread going:{}...".format(count))
- utime.sleep_ms(1)
- self.AI_client_asr_recv_lock = 0
- print("AI_client_asr_recv_thread_close")
- try:
- _thread.stop_thread(self.AI_client_asr_recv_id)
- except Exception as e:
- usys.print_exception(e)
- self.AI_client_asr_recv_id = 0
-
- #Ai ASR websocket返回数据
- def AI_client_asr_recv(self,cli):
- while True:
- try:
- # 死循环接收数据
- self.AI_client_asr_recv_lock = 0
- utime.sleep_ms(1)
- recv_data = cli.recv()
- if self.AI_client_asr_recv_lock == 2:#要关闭线程了
- print("AI_client_asr_recv 该退出了")
- break
- self.AI_client_asr_recv_lock = 1
- self.close_timerout = 0#服务器有返回清零退出时间
- if recv_data == "websocket close":
- # 服务器关闭连接
- print("ASR 服务器主动关闭连接!!!!!!!!!!!!!!!!!!!!!!!!!!!")
-
- EventMesh.publish("publish_AI_btnInfo",{"func":self.websocket_error,"data":"ASR连接断开了,请重试"})
- self.ud_error(["asr",self.asr_taskid])
- break
- elif recv_data == "":#客户端关闭连接
- print("ASR ASR :客户端关闭连接")
- EventMesh.publish("publish_AI_btnInfo",{"func":self.websocket_error,"data":"ASR连接断开了,请重试"})
- self.ud_error(["asr",self.asr_taskid])
- break
- try:
- if isinstance(recv_data, str):
- jsload_data = ujson.loads(recv_data)
- print("ASR ASR recv_data: {}".format(jsload_data))
- if jsload_data["status"] != 20000000:#返回错误
- print("ASR返回非20000000状态码,退出")
- EventMesh.publish("publish_AI_btnInfo",{"func":self.websocket_error,"data":"ASR出错了,请重试"})
- self.ud_error(["asr",self.asr_taskid])
- break
-
- if jsload_data["task_id"] != None:
- self.asr_taskid = jsload_data["task_id"]
- if jsload_data["event"] != None:
- if jsload_data["event"] == "TranscriptionStarted": #开始录音
- self.VC_record_state_flag = 2
- self.VC_state = VC_State_SpeechStart
- EventMesh.publish("open_led_blue")
- self.AI_ASR_error_timeout = 0
-
- pass
-
- elif jsload_data["event"] == "Changed" or jsload_data["event"] == "SentenceEnd" : #开始录音Changed
- # if self.VC_record_state_flag == 2:
- #
-
- self.AI_ASR_timer_count = 0
- if jsload_data["result"]["result"]:
- #self.AI_listen_text = str(jsload_data["result"]["result"])
- text= str(jsload_data["result"]["result"])
- print("ASR recv self.VC_state :{}".format(self.VC_state))
- if self.is_long_record == 0:
- if self.VC_state >= VC_State_TTSStart:#开始播音后不响应asr结果
- print("asr continue")
- continue
- EventMesh.publish("open_led_blue")
-
- if jsload_data["result"]["is_end"] == True: #asr结束
- self.AI_ASR_check_timeout = 0
- self.AI_ASR_error_timeout = 0
- self.AI_ASR_text_repet_count = 0
- self.AI_ASR_text_tmp = ""
- self.VC_record_state_flag = 4
- ret= self.check_text(text)
- if ret == 0:#配置指令
-
- if self.AI_VC_send_data_queue.empty()!=True:
- self.AI_VC_send_data_queue.clear()
- if self.AI_ASR_send_data_queue.empty()!=True:
- self.AI_ASR_send_data_queue.clear()
- self.AI_ASR_send_buf_len = 0
- EventMesh.publish("open_led_all")
- try:
-
- EventMesh.publish("publish_AI_btnInfo",{"func":self.VC_Speech_End})
- #print("AI_client_asr_recv VC_Speech_End")
- EventMesh.publish("publish_AI_btnInfo",{"func":self.websocket_deconnect_VC})
- #EventMesh.publish("publish_AI_btnInfo",{"func":self.websocket_deconnect_asr})
- EventMesh.publish("publish_AI_btnInfo",{"func":self.AI_VC_start})
- except Exception as e:
- usys.print_exception(e)
- continue
- elif ret == 1:#不处理
- pass
- else:#正常asr
- if self.VC_mode == 0 :#连续问答模式
- self.AI_ASR_str = text#
- if self.AI_ASR_flag == 0:#d第一次识别,没有打断
- self.AI_ASR_str_tmp = self.AI_ASR_str
- else:#第二次识别,打断了
- self.AI_ASR_str = self.AI_ASR_str_tmp+text
- print("ASR ASR 打断 续集 AI_ASR_str {}".format(self.AI_ASR_str))
- self.AI_ASR_str_tmp = self.AI_ASR_str
- if self.is_long_record != 0:
- #if self.VC_state >= VC_State_TTSStart:#如果已经播放了,关闭VC连接,重新打开,处理音频数据太多问题
- EventMesh.publish("publish_AI_btnInfo",{"func":self.websocket_deconnect_VC})#关闭vc连接
- self.AI_ASR_flag = 1
- print("asr recv :asr_str:{}".format(self.AI_ASR_str))
- #EventMesh.publish("publish_AI_btnInfo",{"func":utime.sleep_ms,"data":(500)}) #等一秒
- EventMesh.publish("publish_AI_btnInfo",{"func":self.AI_VC_start})
- elif self.VC_mode == 1:#单对话模式
- self.AI_ASR_str += text#
- self.AI_ASR_str_tmp = self.AI_ASR_str
- if self.key_state == 0:#按键已经弹起
- self.AI_ASR_str_tmp =""
- print("asr recv :asr_str:{}".format(self.AI_ASR_str))
- #EventMesh.publish("publish_AI_btnInfo",{"func":utime.sleep_ms,"data":(500)}) #等一秒
- EventMesh.publish("publish_AI_btnInfo",{"func":self.AI_VC_start})
- self.VC_state = VC_State_SpeechEnd
- elif jsload_data["result"]["is_end"] == False:
-
- self.VC_state = VC_State_SpeechIng
- if self.AI_ASR_text_tmp != "" and self.AI_ASR_text_tmp == text:
- pass
- # self.AI_ASR_text_repet_count+=1
- # if self.AI_ASR_text_repet_count>=40:#重复30次下发一样结果,就报错
- # print("asr 错误,无正式结果:{}".format(text))
- # #EventMesh.publish("publish_AI_btnInfo",{"func":self.websocket_error})#
- # EventMesh.publish("publish_AI_btnInfo",{"func":self.websocket_error,"data":"ASR出错了,请重试"})
- else:
- self.AI_ASR_check_timeout = 5 #5秒没更新结果,强制stop
- self.AI_ASR_error_timeout = 0
- self.AI_ASR_text_repet_count = 0
- if self.VC_mode == 0 :#连续问答模式
- self.AI_ASR_text_tmp = text
- self.VC_record_state_flag = 3
- if self.AI_ASR_flag ==1 :#如果已经识别过一次asr
- self.AI_ASR_flag = 2
- print("asr 打断,关闭VC连接")
- self.AI_ASR_str = ""
- if self.is_long_record != 0:
- self.VC_Play_End()
- EventMesh.publish("publish_AI_btnInfo",{"func":self.websocket_deconnect_VC})#关闭vc连接
- # EventMesh.publish("publish_AI_btnInfo",{"func":self.websocket_connect_VC})#连接服务器
- # EventMesh.publish("publish_AI_btnInfo",{"func":self.AI_client_VC_start_requset})#请求
- EventMesh.publish("publish_AI_btnInfo",{"func":self.AI_VC_start})
- EventMesh.publish("publish_AI_btnInfo",{"func":EventMesh.publish,"data":"open_led_blue"})#
- elif self.VC_mode ==1:#单对话模式
- self.AI_ASR_str_tmp =""
-
- except Exception as e:
- usys.print_exception(e)
-
- except Exception as e:
- error_str = str(e)
- print("ASR ASR:e:{}".format(error_str))
- #usys.print_exception(e)
- if error_str.find("[Errno 110]")!= -1:
- #print("ASR ASR:recv TIMEDOUT 正常")
- pass
- else:
- usys.print_exception(e)
- print("{}".format(cli))
- #self.websocket_error()
- print("ASR读数据报错,退出")
- EventMesh.publish("publish_AI_btnInfo",{"func":self.websocket_error,"data":"ASR出错了,请重试"})#
- self.ud_error(["asr",self.asr_taskid])
- break
- self.AI_client_asr_isconnect = 0
- self.AI_client_asr_recv_id = 0
- self.AI_client_asr_recv_lock = 0
- print("AI_client_asr_recv END!!!!!!!!!!!!!!!!!!!!!!!!!!!")
- #ASR开始会话
- def AI_client_asr_start_requset(self):
- self.session_id = self.get_session_id()
- json_data = \
- {
- "header":{
- "event":"StartTranscription",
- "trace_id":self.get_trace_id()
- },
- "payload":{
- "format":"pcm",
- "sample_rate":self.VC_record_samplerate,
- "session_id": self.session_id ,
- }
-
- }
- if self.VC_record_TYPE == VC_record_TYPE_AMR :
- json_data["payload"]["format"]='amr'
- pass
- self.AI_ASR_error_timeout = 5
- self.AI_client_asr_send(ujson.dumps(json_data))
- #ASR终止
- def AI_client_asr_StopTranscription_requset(self):
- print("AI_client_asr_StopTranscription_requset!!!!!")
- json_data = \
- {
- "header":{
- "event":"StopTranscription",
- "trace_id":self.get_trace_id()
- }
- }
-
- #self.AI_client_asr_send(ujson.dumps(json_data))
- if self.AI_client_asr != None and self.AI_client_asr_isconnect == 1:
- self.AI_client_asr.send(ujson.dumps(json_data))
-
#开始录音
def VC_Speech_Start(self):
try:
return
if self.VC_record_state_flag == 0:
- if dev_type != "7PIN" :
- EventMesh.publish("publish_AI_btnInfo",{"func":self.chenggong_tone})
- self.websocket_connect_asr()
+
self.VC_record_thread_close()#关闭录音线程
_thread.stack_size(self.Audio_buf_size+8*1024)
self.VC_record_thread_id = _thread.start_new_thread(self.VC_record_thread,())
# print("self.record_pcm.stream_read_start:ret:{}".format(ret))
except Exception as e:
usys.print_exception(e)
-
- self.VC_record_state_flag = 1
+ if self.VC_mode == 1 :
+ self.VC_record_state_flag = 1
+ else:
+ self.VC_record_state_flag = 2
except Exception as e:
self.websocket_error()
self.VC_record_state_flag = 1
self.VC_Speech_End()#关闭录音
- usys.print_exception(e)
-
+ usys.print_exception(e)
#停止录音
def VC_Speech_End(self):
try:
self.VC_record_thread_close()#关闭录音线程
if self.AI_record_tmp_queue.empty() != True:
self.AI_record_tmp_queue.clear()
- try:
- self.websocket_deconnect_asr()
- except Exception as e:
- usys.print_exception(e)
+
self.VC_record_state_flag = 0
print("VC_Speech_End VC_record_state_flag:{}!!!!!!!!".format(self.VC_record_state_flag))
#关闭录音线程
Record_len = 0
if self.VC_record_TYPE == VC_record_TYPE_PCM:#pcm
Record_len = self.record.stream_read(Record_read_buf, self.Audio_buf_size)
- utime.sleep_ms(20)
+ #utime.sleep_ms(60)
else :
#print("VC_record_thread:{}".format(Record_len))
if Record_len > 0:
read_buf = bytes(Record_read_buf[:Record_len])
+ # ret = self.vad.custom_vad_process(Record_read_buf,Record_len)
+ # print("VAD检测:datalen:{},结果:{}".format(Record_len,ret))
if self.record_data_save_flag == 1:
if self.record_fd == None:
try:
# if count >150*1024:
# self.record_fd.close()
#self.record_fd = None
- # if self.VC_record_state_flag >= 2:
- # self.AI_client_asr_send(read_buf)
+
if self.VC_record_state_flag <=1 :#没发送前先存起来
self.AI_record_tmp_queue.put(read_buf)
if self.AI_record_tmp_queue.empty() == True:
break
else:
- self.AI_client_asr_send(self.AI_record_tmp_queue.get()) #发送之前存的数据
- self.AI_client_asr_send(read_buf)
+ pass
+ self.AI_client_VC_send(self.AI_record_tmp_queue.get()) #发送之前存的数据
+ self.AI_client_VC_send(read_buf)
#print("VC_record_thread:{}".format(len(read_buf)))
#count+=len(read_buf)
platform = "platform=huoshan&is_boot=1"
#platform = "platform=raisound"
#platform = "platform=aliyun"
- elif dev_type == "7PIN_BK" :
+ elif dev_type == "7PIN_BK":
platform = "platform=huoshan"
#platform = "platform=raisound&bot_type=dify"
- #platform = "platform=raisound&bot_type=fourseason_water"
- #platform = "platform=raisound&bot_type=szbst"
-
+ platform = "platform=raisound&bot_type=fourseason_water"
pass
- elif dev_type == "szbst":
- platform = "platform=raisound&bot_type=szbst"
- elif dev_type == 'rabbit':
- platform = "platform=raisound&bot_type=rabbit"
elif dev_type == 'momo':#
#22080/voice-chat/v2.1/ws?platform=raisound&bot_type=deepseek
platform = "platform=raisound&bot_type=shimeng_mo"
print("token:{}".format(token))
if dev_type == 'momo' :#
req_str = "voice-chat/v2.1/ws?is_auth={}&{}&{}".format(self.is_auth,platform,lang)
- elif dev_type == '7PIN_BK'or dev_type == "szbst" or dev_type == 'rabbit':
- req_str = "voice-chat/v2.1/ws?is_auth={}&{}&{}".format(self.is_auth,platform,lang)
- #req_str = "voice-chat/ws?is_auth={}&{}&{}".format(self.is_auth,platform,lang)
+ elif dev_type == '7PIN_BK':
+ #req_str = "voice-chat/v2.1/ws?is_auth={}&{}&{}".format(self.is_auth,platform,lang)
+ req_str = "voice-chat/ws?is_auth={}&{}&{}".format(self.is_auth,platform,lang)
elif dev_type == "sjgq":
req_str = "22085/voice-chat/ws?is_auth={}&{}&{}".format(self.is_auth,platform,lang)
+ elif dev_type == "G10":
+ req_str = "vc/chat?is_auth={}".format(self.is_auth)
else:
req_str = "voice-chat/ws?is_auth={}&{}&{}".format(self.is_auth,platform,lang)
+ req_str = "vc/chat?is_auth={}".format(self.is_auth)
url = 'ws://{}/{}&dt={}'.format(self.server_ip,req_str,token)
+ #url = 'ws://115.190.94.208:22080/vc/coze?dt={}'.format(token)
+
print("VC VC:url{}".format(url))
self.AI_client_VC = uwebsocket.Client.connect(url, debug=True)
#self.AI_WS_connect_Queue.put(self.AI_client_VC)
if self.AI_client_VC_isconnect == 1:
#self.AI_client_VC.write_frame(0x09,b'ping ping')
self.AI_client_VC_send("ping")
- #print("websocket ping ping")
+ print("VC: ping ping")
#websocket发送数据
def AI_client_VC_send(self,data_str):
#print("AI_VC_send_data_queue_thread:len:{}".format(len(data[1])))
#print("AI_VC_send_data_queue_thread on line asr recv :{} vc recv:{}".format(_thread.threadIsRunning(self.AI_client_asr_recv_id),_thread.threadIsRunning(self.AI_client_VC_recv_id)))
if data[0] == AI_client_VC_num:
- self.VC_pingping_timerout = 0
+
if isinstance(data[1], str):#是字符串
+ self.VC_pingping_timerout = 0
print("VC VC: send_data:{}".format(data[1]))
- #print("VC: send_data len:{}".format(len(data[1])))
+ else:
+ print("VC: send_data len:{}".format(len(data[1])))
if self.AI_client_VC != None and self.AI_client_VC_isconnect == 1:
self.AI_client_VC.send(data[1])
else:
- print("VC VC: send_data:ERROR:{}".format(data[1]))
+ print("VC VC: send_data:ERROR:{}".format(len(data[1])))
#print("VC: send_data end")
#print("VC: send_data end")
#Ai VC websocket返回数据
def AI_client_VC_recv(self,cli):
count = 0
-
+ asr_led_flag = 0
+ tts_led_flag = 0
while True:
try:
# 死循环接收数据
self.AI_client_VC_recv_lock = 0
- if self.is_VC_ACK == 1:
- self.AI_client_VC_Read()
- #EventMesh.publish("publish_AI_btnInfo",{"func":self.AI_client_VC_Read})
+
count+=1
if self.VC_state >= VC_State_TTSStart and (self.tts_in_data_len - self.tts_out_data_len > 64*1024 or count>5):
count = 0
print("VC VC:recv_data:{}".format(recv_data))
jsload_data = ujson.loads(recv_data)
#print("AI_client_VC_recv jsload_data = {}".format(jsload_data))
- if jsload_data["status"] != 20000000:#返回错误
- print("VC VC :服务器返回非20000000状态码,退出")
- EventMesh.publish("publish_AI_btnInfo",{"func":self.websocket_error,"data":"VC出错了,请重试"})
- self.ud_error(["VC",self.VC_taskid])
- break
- if jsload_data["task_id"] != None:
- self.VC_taskid = jsload_data["task_id"]
- if jsload_data["event"] == "Started" :#会话开始
- payload = jsload_data["payload"]
- self.VC_dialog_id = payload["dialog_id"]
- self.VC_task_id = jsload_data["task_id"]
+ #self.LocalRespondingEnded_timerout = 0
+ if jsload_data["event"] == "started" :#会话开始
+ #payload = jsload_data["payload"]
+ # self.VC_dialog_id = payload["dialog_id"]
+ # self.VC_task_id = jsload_data["task_id"]
+ EventMesh.publish("open_led_blue")
print("VC:Started!!!!!!!!\r\n")
- elif jsload_data["event"] == "SpeechContent" :#asr转译
- print("VC:SpeechContent!!!!!!!!\r\n")
- payload = jsload_data["payload"]
-
-
- if(payload['finished'] == True):#asr结束
- self.VC_state = VC_State_SpeechEnd
- #self.VC_Speech_End()#停止录音
- text = payload["text"]
- if self.check_text(text) == 0:
- if self.AI_VC_send_data_queue.empty()!=True:
- self.AI_VC_send_data_queue.clear()
- if self.AI_ASR_send_data_queue.empty()!=True:
- self.AI_ASR_send_data_queue.clear()
- self.AI_ASR_send_buf_len = 0
- EventMesh.publish("open_led_all")
- try:
- EventMesh.publish("publish_AI_btnInfo",{"func":self.websocket_deconnect_VC})
- EventMesh.publish("publish_AI_btnInfo",{"func":self.VC_Speech_End})
-
- # EventMesh.publish("publish_AI_btnInfo",{"func":self.websocket_deconnect_asr})
- EventMesh.publish("publish_AI_btnInfo",{"func":self.AI_VC_start})
- except Exception as e:
- usys.print_exception(e)
+ if self.AI_TTS_str == "":
+ #self.AI_client_VC_send_speech()#开始上传语音
+ EventMesh.publish("publish_AI_btnInfo",{"func":self.AI_client_VC_send_speech})
+ else:
+ EventMesh.publish("publish_AI_btnInfo",{"func":self.AI_client_VC_synthesis})
- pass
- else:
- pass
-
- elif jsload_data["event"] == "SpeechEnded" :#服务器下发ASR说话结束
- self.VC_state = VC_State_SpeechEnd
- elif jsload_data["event"] == "RespondingContent" :#chat回答
+ elif jsload_data["event"] == "asr.started" :#asr开始
+ self.VC_state = VC_State_SpeechStart
+ if self.VC_mode == 1 :
+ self.VC_record_state_flag = 2
+ EventMesh.publish("open_led_blue")
+ elif jsload_data["event"] == "asr.result" :#asr结果
+ self.AI_ASR_str = jsload_data["payload"]["content"]
+ if asr_led_flag == 0:
+ asr_led_flag = 1
+ EventMesh.publish("close_led")
+ else :
+ asr_led_flag = 0
+ EventMesh.publish("open_led_blue")
+ elif jsload_data["event"] == "asr.completed" :#asr 终止的标识
+ #self.VC_Speech_End()
+ #EventMesh.publish("publish_AI_btnInfo",{"func":self.VC_Speech_End})
+ if self.record_data_save_flag == 1:
+ if self.record_fd :
+ self.record_fd.close()
+ self.record_fd = None
+ # if dev_type != "7PIN" :
+ #EventMesh.publish("publish_AI_btnInfo",{"func":self.send_tone})
+ elif jsload_data["event"] == "vad.silence" :#VAD 终止的标识
+ pass
+ #EventMesh.publish("publish_AI_btnInfo",{"func":self.VC_Speech_End})
+ elif jsload_data["event"] == "llm.created" :#会话开始
+ EventMesh.publish("open_led_red_green")#
+ self.VC_state = VC_State_Thinking
+ # EventMesh.publish("publish_AI_btnInfo",{"func":self.VC_Play_Start})
pass
+ elif jsload_data["event"] == "tts.started" :#tts开始
- elif jsload_data["event"] == "RespondingStarted" :#音频开始下发
- self.play_flag = 0
- self.VC_state = VC_State_TTSStart
- if self.is_long_record == 0:
- EventMesh.publish("publish_AI_btnInfo",{"func":self.VC_Speech_End})#
- else:
- self.AI_ASR_str_tmp = ""
- self.AI_ASR_str = ""
+ EventMesh.publish("publish_AI_btnInfo",{"func":self.VC_Speech_End})
EventMesh.publish("publish_AI_btnInfo",{"func":self.VC_Play_Start})
- self.VC_Thinking_timerout = 0#关闭超时重试
- # self.VC_Play_Start()
- EventMesh.publish("open_led_green")#绿色
- #self.tts_fd = open('/usr/tts_tesr.pcm','w')
- if self.play_data_save_flag == 1:
- try:
- uos.remove('/usr/play_data.pcm')
- except Exception as e:
- usys.print_exception(e)
- self.play_fd = open('/usr/play_data.pcm','w')
+ #self.VC_Play_Start()
+ EventMesh.publish("open_led_green")#绿色
+ elif jsload_data["event"] == "tts.completed" :#tts结束
+ EventMesh.publish("open_led_green")#绿色
+ EventMesh.publish("publish_AI_btnInfo",{"func":self.VC_Play_Start})
+ self.LocalRespondingEnded_timerout = 8
+ self.VC_state = VC_State_TTSEnd
pass
- elif jsload_data["event"] == "RespondingEnded" :#音频下发结束
- #if self.VC_state == VC_State_TTSStart:
+ # self.AI_client_VC_send_speech()#开始上传语音
+ # self.VC_record_state_flag = 2
+ elif jsload_data["event"] == "completed" :#会话结束
+ #EventMesh.publish("open_led_green")#绿色
- print("RespondingEnded!!!!!!" )
- self.VC_state = VC_State_TTSEnd
- self.LocalRespondingEnded_timerout = 10 #最长倒数10秒发送音频结束或者终止对话
- if self.VC_mode == 0 :#连续问答模式
- #EventMesh.publish("publish_AI_btnInfo",{"func":self.VC_Speech_End})#调试临时打开
- if dev_type != "7PIN_BK":
- EventMesh.publish("publish_AI_btnInfo",{"func":self.VC_Speech_Start})#开始录音
- pass
- if self.play_data_save_flag == 1:
- if self.play_fd !=None:
- self.play_fd.close()
- #self.tts_fd.close()
- #pass
- elif jsload_data["event"] == "DialogStateChanged" :#状态切换事件
- payload = jsload_data["payload"]
- if payload["state"] == "Listening":#可以说了
- self.VC_state = VC_State_Listening
- if self.AI_TTS_str != "" or self.AI_ASR_str != "":#有tts数据,则请求TTS数据,没有就请求开始上传语音
- self.AI_client_VC_RequestToRespond()
- else:
- pass
- #self.VC_Speech_Start()#开启线程获取录音数据
- if self.is_long_record == 0:
- EventMesh.publish("publish_AI_btnInfo",{"func":self.VC_Speech_Start})#
- #self.AI_client_VC_send_speech()#开始上传语音
-
- #EventMesh.publish("open_led_red")
- if payload["state"] == "Thinking":#思考
- self.VC_state = VC_State_Thinking
- if self.VC_Thinking_timerout == 0:
- self.VC_Thinking_timerout = 15#倒计时15秒,如果没有音频数据返回就重试
- EventMesh.publish("open_led_red_green")#黄色
- if payload["state"] == "Responding":#开始音频播放
- #self.VC_state = VC_State_Responding#
- pass
- elif jsload_data["event"] == "RequestAccepted" :#请求上传语音被允许
- #self.VC_state = VC_State_Responding
- #self.AI_client_VC_send_speech()#开始上传语音
+ self.LocalRespondingEnded_timerout = 8
+ self.VC_state = VC_State_End
pass
+ # self.AI_client_VC_send_speech()#开始上传语音
+ # self.VC_record_state_flag = 2
+ elif jsload_data["event"] == "command" :#命令匹配
+ ret = -1
+ try:
+ if self.is_llm_commands ==1:
+ if len(jsload_data["payload"]["functions"])>0:
+
+ cmd = jsload_data["payload"]["functions"][0]["function"]["arguments"]
+ print("llm:cmd:{}".format(cmd))
+ cmd = ujson.loads(cmd)
+ ret = self.check_text_llm(cmd)
+ else:
+
+ cmd = jsload_data["payload"]
+ print("server:cmd:{}".format(cmd))
+ ret = self.check_text(cmd)
+ except Exception as e:
+ usys.print_exception(e)
+ if ret == -1:
+ if self.AI_TTS_str =="":
+ self.AI_TTS_str = "抱歉,没找到对应操作,可以换个说法试试"
+ #EventMesh.publish("publish_AI_btnInfo",{"func":utime.sleep_ms,'data':(10)})
+ EventMesh.publish("publish_AI_btnInfo",{"func":self.VC_Speech_End})
+ EventMesh.publish("publish_AI_btnInfo",{"func":self.websocket_deconnect_VC})
+ EventMesh.publish("publish_AI_btnInfo",{"func":self.AI_VC_start})
else:#下发音频数据
#self.AI_ASR_str = ""#下发音频后清掉asr结果
+ if tts_led_flag == 0:
+ tts_led_flag = 1
+ EventMesh.publish("open_led_green")#绿色
+ else:
+ tts_led_flag = 0
+ EventMesh.publish("close_led")#
print("下发音频数据1:{}".format(len(recv_data)))
if self.play_data_save_flag == 1:
if self.play_fd !=None:
self.play_fd.write(recv_data)
# print("下发音频数据2:{}".format(len(recv_data)))
- if self.VC_state >= VC_State_TTSStart:
+ #if self.VC_state >= VC_State_TTSStart:
#self.put_record_data([recv_data,""])
- EventMesh.publish("publish_AI_btnInfo",{"func":self.put_record_data,"data":[recv_data,""]})
+ EventMesh.publish("publish_AI_btnInfo",{"func":self.put_record_data,"data":[recv_data,""]})
utime.sleep_ms(1)
except Exception as e:
usys.print_exception(e)
except Exception as e:
-
error_str = str(e)
#print("VC VC:e:{}".format(error_str))
if error_str.find("[Errno 110] ETIMEDOUT")!= -1:
ret=self.AI_audio_queue.put(data)
self.tts_in_data_len += len(data[0])
#print("下发音频数据2:{},{}".format(len(data[0]),self.tts_in_data_len))
- def check_text(self,text):
- if len(text)>60:
- return -1
+ def check_text(self,cmd):
+ # if len(text)>60:
+ # return -1
try:
- if isinstance(text, str):
- if text.find("声é\9f³") != -1 and text.find("æ\94¹") != -1:
+ text = cmd["command"]
+ if text.find("å\88\87æ\8d¢é\9f³è\89²") != -1 :
try:
+ text = cmd["params"]["cmd_parameter"]
for key in self.VC_TTS_voice_type:
if text.find(key) != -1 :
self.VC_TTS_voice_key = key
self.AI_TTS_str = "当前已是最新版本"
return 0
- if len(text)<12 and (text.find("再见") != -1 or text.find("拜拜") != -1):
+ if len(text)<20 and (text.find("再见") != -1 or text.find("拜拜") != -1 or text.find("关闭对话") != -1):
+ #EventMesh.publish("publish_AI_btnInfo",{"func":self.Close})
+ self.AI_TTS_str = "好嘞,再见,我们下次再聊"
+ self.Close_flag = 1
+ return 0
+ if len(text)<12 and (text.find("关机") != -1 ):
EventMesh.publish("publish_AI_btnInfo",{"func":self.Close})
+ EventMesh.publish("Power_off")
return 1
except Exception as e:
usys.print_exception(e)
return -1
+ def check_text_llm(self,cmd):
+ try:
+ text = cmd["command"]["chinese_description"]
+ if text.find("切换音色") != -1:
+ text = cmd["command"]["params_json"]
+ try:
+ for key in self.VC_TTS_voice_type:
+ if text.find(key) != -1 :
+ self.VC_TTS_voice_key = key
+ EventMesh.publish("set_storage_config",["VC_TTS_voice_key",self.VC_TTS_voice_key])
+ self.AI_TTS_str = "了解,声音已切换"
+ return 0
+ except Exception as e:
+ usys.print_exception(e)
+ if text.find("男") != -1 :
+ if "男" in self.VC_TTS_voice_type:
+ self.VC_TTS_voice_key = "男"
+ EventMesh.publish("set_storage_config",["VC_TTS_voice_key",self.VC_TTS_voice_key])
+
+ self.AI_TTS_str = "了解,声音已切换"
+ return 0
+ if text.find("女") != -1 :
+ if "女" in self.VC_TTS_voice_type:
+ self.VC_TTS_voice_key = "女"
+ EventMesh.publish("set_storage_config",["VC_TTS_voice_key",self.VC_TTS_voice_key])
+
+ self.AI_TTS_str = "了解,声音已切换"
+ return 0
+ if text.find("同声") != -1 or text.find("童") != -1 :
+ if "童" in self.VC_TTS_voice_type:
+ self.VC_TTS_voice_key = "童"
+ EventMesh.publish("set_storage_config",["VC_TTS_voice_key",self.VC_TTS_voice_key])
+
+ self.AI_TTS_str = "了解,声音已切换"
+ return 0
+ if text.find("粤") != -1 or text.find("越野") != -1 or text.find("广东话") != -1:
+ if "粤" in self.VC_TTS_voice_type:
+ self.VC_TTS_voice_key = "粤"
+ EventMesh.publish("set_storage_config",["VC_TTS_voice_key",self.VC_TTS_voice_key])
+
+ self.AI_TTS_str = "了解,声音已切换"
+ return 0
+ if text.find("四川") != -1 :
+ if "四川" in self.VC_TTS_voice_type:
+ self.VC_TTS_voice_key = "四川"
+ EventMesh.publish("set_storage_config",["VC_TTS_voice_key",self.VC_TTS_voice_key])
+
+ self.AI_TTS_str = "了解,声音已切换"
+ return 0
+ if text.find("个性") != -1 :
+ if "个性" in self.VC_TTS_voice_type:
+ self.VC_TTS_voice_key = "个性"
+ EventMesh.publish("set_storage_config",["VC_TTS_voice_key",self.VC_TTS_voice_key])
+
+ self.AI_TTS_str = "了解,声音已切换"
+ return 0
+ if text.find("英语") != -1 :
+ if "英语" in self.VC_TTS_voice_type:
+ self.VC_TTS_voice_key = "英语"
+ EventMesh.publish("set_storage_config",["VC_TTS_voice_key",self.VC_TTS_voice_key])
+
+ self.AI_TTS_str = "了解,声音已切换"
+ return 0
+ self.AI_TTS_str = "很抱歉,没找到对应声音"
+ return 0
+ if text.find("切换对话模式") != -1:
+ if self.VC_mode == 0:
+ self.VC_mode = 1
+ self.AI_TTS_str = "了解,已切换到单对话模式"
+ else:
+ self.VC_mode = 0
+ self.AI_TTS_str = "了解,已切换到长对话模式"
+ EventMesh.publish("set_storage_config",["VC_mode",self.VC_mode])
+
+
+ return 0
+ if text.find("音量调整") != -1:
+ text = cmd["command"]["params_json"]
+ text = ujson.loads(text)
+ volume = text["n"]
+ if volume >100 or volume<0:
+ self.AI_TTS_str = "音量调整超出范围了,只能0-100哦"
+ else:
+ self.VC_TTS_volume = volume
+ self.aud.setVolume(self.VC_TTS_volume //10)
+ EventMesh.publish("set_storage_config",["VC_TTS_volume",self.VC_TTS_volume])
+ self.AI_TTS_str = "了解,音量已经调整,当前音量是{}".format(self.VC_TTS_volume)
+ return 0
+ if text.find("音量增大") != -1:
+ self.VC_TTS_volume += 10
+ if self.VC_TTS_volume > 100:
+
+ self.AI_TTS_str = "音量已经是最大啦"
+ self.VC_TTS_volume = 100
+ else:
+ self.aud.setVolume(self.VC_TTS_volume //10)
+ EventMesh.publish("set_storage_config",["VC_TTS_volume",self.VC_TTS_volume])
+
+ self.AI_TTS_str = "了解,音量已经调大了,当前音量是{}".format(self.VC_TTS_volume)
+
+ return 0
+ if text.find("音量减小") != -1:
+ self.VC_TTS_volume -= 10
+ if self.VC_TTS_volume < 0:
+ self.VC_TTS_volume = 0
+ #EventMesh.publish("audio_montage_play",["yinliangyizuixiao.mp3"])
+ #self.aud.play(1,0,'U:/static/yinliangyizuixiao.mp3')#音量已最小
+ self.AI_TTS_str = "音量已经是最小啦"
+ else:
+ self.aud.setVolume(self.VC_TTS_volume //10)
+ EventMesh.publish("set_storage_config",["VC_TTS_volume",self.VC_TTS_volume])
+ self.AI_TTS_str = "好嘞,音量已经调小了,当前音量是{}".format(self.VC_TTS_volume)
+ return 0
+
+ if text.find("语速增大") != -1:
+ self.speech_rate += 10
+ if self.speech_rate > 50:
+
+ self.AI_TTS_str = "语速已经是最快啦"
+ self.speech_rate = 50
+ else:
+
+ EventMesh.publish("set_storage_config",["speech_rate",self.speech_rate])
+
+ self.AI_TTS_str = "明白,语速已经调快了,当前语速是{}".format(self.speech_rate)
+
+ return 0
+ if text.find("语速减小") != -1:
+ self.speech_rate -= 10
+ if self.speech_rate < -50:
+ self.speech_rate = -50
+ #EventMesh.publish("audio_montage_play",["yinliangyizuixiao.mp3"])
+ #self.aud.play(1,0,'U:/static/yinliangyizuixiao.mp3')#音量已最小
+ self.AI_TTS_str = "语速已经是最慢啦"
+ else:
+ EventMesh.publish("set_storage_config",["speech_rate",self.speech_rate])
+
+ self.AI_TTS_str = "明白,语速已经调慢了,当前语速是{}".format(self.speech_rate)
+ return 0
+
+ if text.find("进入工厂模式") != -1 :
+ self.factory_mode()
+ return 1
+ if text.find("查询") != -1:
+ if text.find("信号") != -1 :
+ signal = net.csqQueryPoll()
+
+ self.AI_TTS_str = "当前信号{}".format(signal)
+ return 0
+ if text.find("电量") != -1 :
+ battery = EventMesh.publish("get_battery")
+ print("电量查询:{}".format(battery))
+ #EventMesh.publish("audio_montage_play",["dianliangshengyu{}.mp3".format(battery)])
+ #self.aud.play(1,0,'U:/static/dianliangshengyu{}.mp3'.format(battery))#电量剩余
+ self.AI_TTS_str = "电量剩余百分之{}".format(battery)
+ return 0
+ if text.find("电压") != -1 :
+ Vbatt = Power.getVbatt()
+ #EventMesh.publish("audio_montage_play",["dianliangshengyu{}.mp3".format(battery)])
+ #self.aud.play(1,0,'U:/static/dianliangshengyu{}.mp3'.format(battery))#电量剩余
+ self.AI_TTS_str = "当前电池电压{}".format(Vbatt)
+ return 0
+
+ if text.find("卡号") != -1 :
+ iccid = sim.getIccid()
+ if iccid != -1 and len(iccid) > 5:
+ print("iccid{}".format(iccid))
+ self.AI_TTS_str = "当前卡号为:{}".format(iccid)
+ else:
+ self.AI_TTS_str = "卡号查询失败"
+ return 0
+ if text.find("设备号") != -1 :
+ imei = modem.getDevImei()
+ if imei != -1 and len(imei) > 5:
+ print("IMEI:{}".format(imei))
+ self.AI_TTS_str = "当前设备号为:{}".format(imei)
+ else:
+ self.AI_TTS_str = "设备号查询失败"
+ return 0
+ if text.find("版本") != -1 :
+ sourceVersion = versions.Build_Time
+ self.AI_TTS_str ="Mr-Seven-"+sourceVersion
+ return 0
+ if text.find("服务器地址") != -1 :
+ self.AI_TTS_str ="服务器地址"+self.server_ip
+ return 0
+ if text.find("升级") != -1 and (text.find("OTA") != -1 or text.find("ota") != -1):
+ if self.ai_OTA.min_sys_ota()==1:
+ self.AI_TTS_str = "有新版本,准备开始升级,升级过程会多次重启设备,请保证流量充足及电量充足"
+ else:
+ self.AI_TTS_str = "当前已是最新版本"
+ return 0
+
+ if len(text)<20 and (text.find("再见") != -1 or text.find("拜拜") != -1 or text.find("关闭对话") != -1):
+ #EventMesh.publish("publish_AI_btnInfo",{"func":self.Close})
+ self.AI_TTS_str = "好嘞,再见,我们下次再聊"
+ self.Close_flag = 1
+ return 0
+ if len(text)<12 and (text.find("关机") != -1 ):
+ EventMesh.publish("publish_AI_btnInfo",{"func":self.Close})
+ EventMesh.publish("Power_off")
+ return 1
+ except Exception as e:
+ usys.print_exception(e)
+ self.AI_TTS_str = cmd["command"]["fail_prompt"]
+ return -1
#获取trace_id
def get_trace_id(self):
t = utime.mktime(utime.localtime())
def VC_Play_Start(self):
self.tts_in_data_len = 0
self.tts_out_data_len = 0
- try:
- if self.VC_play_TYPE == VC_play_TYPE_PCM:
- if self.VC_play_samplerate == 8000:
- pass
- elif self.VC_play_samplerate == 16000:
+ if self.VC_Play_flag == 0:
+ try:
+ if self.VC_play_TYPE == VC_play_TYPE_PCM:
if self.play_pcm == None:
- self.play_pcm = audio.Audio.PCM(0,1,16000,1,1,2)
+ self.play_pcm = audio.Audio.PCM(0,1,self.VC_play_samplerate,1,1,2)
#self.play_pcm.setVolume(11)
ret = self.play_pcm.stream_write_start()
print("self.record_pcm.stream_write_start:ret:{}".format(ret))
- elif self.VC_play_TYPE == VC_play_TYPE_MP3:
- pass
- except Exception as e:
-
- usys.print_exception(e)
- EventMesh.publish("publish_AI_btnInfo",{"func":self.websocket_error,"data":"接口出错了。请重试"})
+ elif self.VC_play_TYPE == VC_play_TYPE_MP3:
+ pass
+ self.VC_Play_flag = 1
+ except Exception as e:
+ self.VC_Play_End()
+ usys.print_exception(e)
+
+
#停止播放声音
def VC_Play_End(self):
+ self.VC_Play_flag = 0
if self.VC_play_TYPE == VC_play_TYPE_PCM:
if self.VC_play_samplerate == 8000:
self.aud.stopPlayStream()
if self.VC_mode == 1 :#长按单次问答模式
EventMesh.publish("publish_AI_btnInfo",{"func":self.Close})
else:
- EventMesh.publish("publish_AI_btnInfo",{"func":self.VC_Speech_Start})#开始录音
+ EventMesh.publish("open_led_blue")
+ if self.Close_flag == 1:
+ self.Close_flag = 0
+ EventMesh.publish("publish_AI_btnInfo",{"func":self.Close})
+ else:
+ #utime.sleep_ms(1000)
+ EventMesh.publish("publish_AI_btnInfo",{"func":self.VC_Play_End})
+ #EventMesh.publish("publish_AI_btnInfo",{"func":self.chenggong_tone})
+ EventMesh.publish("publish_AI_btnInfo",{"func":self.AI_client_VC_send_speech})#开始录音
#通知服务器播放结束
- self.AI_client_VC_LocalRespondingEnded()
+ #self.AI_client_VC_LocalRespondingEnded()
+
self.VC_pingping_timerout+=1
if self.VC_pingping_timerout>3:
self.VC_pingping_timerout=0
self.AI_client_VC_ping()
- self.asr_pingping_timerout += 1
- if self.asr_pingping_timerout>3:
- self.asr_pingping_timerout=0
- self.AI_client_asr_ping()
+ # self.asr_pingping_timerout += 1
+ # if self.asr_pingping_timerout>3:
+ # self.asr_pingping_timerout=0
+ # self.AI_client_asr_ping()
if self.VC_Thinking_timerout > 0 and self.VC_Thinking_timerout < 100:#VC Thinking超时后重新开始
print("VC_Thinking_timerout:{}!!!!!!!!!!!!!!!!!!!!!".format(self.VC_Thinking_timerout))
self.VC_Thinking_timerout -=1
#
if self.AI_client_VC_isconnect == 0:#没连接的时候请求开始
self.websocket_connect_VC()#连接服务器
- self.AI_client_VC_start_requset()
+
#utime.sleep_ms(50)
else:
print("self.VC_state :{}".format(self.VC_state ))
- if self.VC_state > VC_State_SpeechStart:
- #客户端打断对话
- print("打断对话")
- # self.websocket_deconnect_VC()
- # self.websocket_connect_VC()#连接服务器
- # self.AI_client_VC_start_requset()
- self.AI_client_VC_RequestToSpeak()
- elif self.VC_state == VC_State_Listening:
- #直接chat
- print("直接chat")
- self.AI_client_VC_RequestToRespond()
- return
- else:
- print("异常状态")
+ # if self.VC_state > VC_State_SpeechStart:
+ # #客户端打断对话
+ # print("打断对话")
+ # # self.websocket_deconnect_VC()
+ # # self.websocket_connect_VC()#连接服务器
+ # # self.AI_client_VC_start_requset()
+ # #self.AI_client_VC_RequestToSpeak()
+ # elif self.VC_state == VC_State_Listening:
+ # #直接chat
+ # print("直接chat")
+ # # self.AI_client_VC_RequestToRespond()
+ # return
+ # else:
+ # print("异常状态")
#self.AI_client_VC_RequestToSpeak()
- self.websocket_deconnect_VC()
- self.websocket_connect_VC()#连接服务器
- self.AI_client_VC_start_requset()
+ # self.websocket_deconnect_VC()
+ # self.websocket_connect_VC()#连接服务器
+ # self.AI_client_VC_start_requset()
if self.AI_client_VC_isconnect == 0:
return
+ self.AI_client_VC_start_requset()
print("AI_VC_start3")
self.VC_state = VC_State_None
if self.AI_TTS_str == "":#没有tts要播放的时候才开始录音
#开始asr录音
- self.VC_Speech_Start()
+ if self.VC_mode == 1:#单对话模式
+ self.VC_Speech_Start()#开启线程获取录音数据
+ else :
+ self.VC_Speech_Start()#开启线程获取录音数据
+ self.VC_record_state_flag = 2
# pass
print("AI_VC_start4")
-
+ #self.VC_Play_Start()
+ #EventMesh.publish("publish_AI_btnInfo",{"func":self.VC_Play_Start})
#开始线程
# if self.AI_VC_send_data_queue_thread_id == 0:
voice = self.VC_TTS_voice_type[self.VC_TTS_voice_key]["voice"]
except Exception as e:
usys.print_exception(e)
+ #voice="huoshan::zh_female_dongmanxiaoyang_moon_bigtts"
+
json_data = \
{
- "header":{
- "trace_id":self.get_trace_id(),
- "event":"Start"
+ "header": {
+ "event": "Start",
+ "trace_id": self.get_trace_id(),
+ },
+ "payload": {
+ "device_id": modem.getDevImei(),
+ "user_agent": "AudioClient/1.0",
+ "dialog_attributes": {
+ #"provider": "doubao",
+ "provider": "coze",
+
+ "cfg": {
+ "disable_empty_prompt" : True,#拦截空字符请求大模型
+ "custom_variables": {
+ "name": self.bot_name,
+ },
+ # "greeting":{
+ # "enabled":True,
+ # "content":"小瑞来陪你聊天了!"
+ # }
+ "bot_option": {
+ "use_workflow": True,
+ "bot_id":"7481164663863459850",#鸭子
+ "workflow_id":"7480485093845991443",
+ # "bot_id":"7462617881076351002",#语言助手
+ # "workflow_id":"7462621757327196187",
+ # "bot_id":"7469964258592931852",#深圳百事通
+ # "workflow_id":"7469968083063603241",
+ }
+ }
},
- "payload":{
- "dialog_id":self.VC_dialog_id,
- "device_id":modem.getDevImei(),
- "user_agent":"python",
- "in_format":"pcm",
- "out_format":"mp3",
- "in_sample_rate":self.VC_record_samplerate,
- "sample_rate":self.VC_play_samplerate,
- "space_time": 10,
- "volume": str(self.VC_TTS_volume),
- "voice":voice,#self.VC_TTS_voice_type[str(self.VC_TTS_voice_key)],
- "voice_detection":"enabled",
- "simple_response":True,
- "session_id": self.session_id ,
- "custom_variables":{
- "bot_name":"{}".format(self.bot_name)
+ "outbound_attributes": {
+ "provider": "volcengine",
+ "cfg": {
+ "format": "pcm",
+ "sample_rate": self.VC_play_samplerate,
+ "bit_rate": 16,
+ "channel": 1,
+ "volume": self.VC_TTS_volume,
+ #"voice": "7426720361732980745",
+ "voice": voice,
+ "speech_rate": self.speech_rate,#语速
+ }
+ },
+ "inbound_attributes": {
+ #"provider": "xun-fei",#
+ "provider": "volcengine",
+ "disable_vad":True,
+ "vad_silence":300,
+ "interrupt_options":{
+ "concatenate_results":True,
+ "thinking_time_only": True,
},
+ "cfg": {
+ "format": "pcm",
+ "sample_rate": self.VC_record_samplerate,
+ "bit_rate": 16,
+ "channel": 1
+ }
},
-
+ "commands":self.commands,
+ }
}
- if self.VC_play_TYPE == VC_play_TYPE_PCM:
- json_data["payload"]["out_format"]='pcm'
- if self.VC_record_TYPE == VC_record_TYPE_AMR :
- json_data["payload"]["in_format"]='amr'
- pass
- if self.VC_mode == 1:
- json_data["payload"]["voice_detection"]='disable'
+ if self.is_llm_commands ==1:
+ json_data["payload"]["commands"] = []
+ if self.VC_mode == 0:#长对话模式打开vad
+ json_data["payload"]["inbound_attributes"]["disable_vad"] = False
self.VC_state = VC_State_None
self.AI_client_VC_send(ujson.dumps(json_data))
def AI_client_VC_send_speech(self):
json_data = \
{
- "header":{
- "trace_id":self.get_trace_id(),
- "event":"SendSpeech"
- },
- "payload":
- {
- "dialog_id":self.VC_dialog_id,
- "session_id": self.session_id ,
- }
+ "header": {
+ "event": "audio.create",
+
+ },
}
- self.AI_client_VC_send(ujson.dumps(json_data))
- self.VC_Speech_Start()#开启线程获取录音数据
+
+ if self.VC_mode == 1:#单对话模式
+ self.AI_client_VC_send(ujson.dumps(json_data))
+ EventMesh.publish("publish_AI_btnInfo",{"func":self.VC_Speech_Start})
+ #self.VC_Speech_Start()#开启线程获取录音数据
+ else :
+ #EventMesh.publish("publish_AI_btnInfo",{"func":self.VC_Play_End})
+ EventMesh.publish("publish_AI_btnInfo",{"func":self.VC_Speech_Start})
+
+ # self.VC_Play_End()
+ # self.VC_Speech_Start()#开启线程获取录音数据
+
+
+
self.VC_state = VC_State_SpeechStart
#结束上传语音
def AI_client_VC_end_speech(self):
json_data = \
{
- "header":{
- "trace_id":self.get_trace_id(),
- "event":"StopSpeech"
- },
- "payload":{
- "dialog_id":self.VC_dialog_id,
- "session_id": self.session_id ,
- }
+ "header": {
+ "event": "audio.completed",
+
+ },
}
self.AI_client_VC_send(ujson.dumps(json_data))
EventMesh.publish("publish_AI_btnInfo",{"func":self.VC_Speech_End})
-
- #通知服务器开始播放
- def AI_client_VC_LocalRespondingStarted(self):
- json_data = \
- {
- "header":{
- "trace_id":self.get_trace_id(),
- "event":"LocalRespondingStarted"
- },
- "payload":{
- "dialog_id":self.VC_dialog_id,
- "session_id": self.session_id ,
- }
- }
- self.AI_client_VC_send(ujson.dumps(json_data))
- #通知服务器播放结束
- def AI_client_VC_LocalRespondingEnded(self):
- json_data = \
- {
- "header":{
- "trace_id":self.get_trace_id(),
- "event":"LocalRespondingEnded"
- },
- "payload":{
- "dialog_id":self.VC_dialog_id,
- "session_id": self.session_id ,
- }
- }
- EventMesh.publish("publish_AI_btnInfo",{"func":self.VC_init})
- EventMesh.publish("publish_AI_btnInfo",{"func":self.AI_client_VC_send,"data":ujson.dumps(json_data)})
- # json_data = \
- # {
- # "header":{
- # "trace_id":self.get_trace_id(),
- # "event":"AAAAAAAAAAAAAA1"
- # },
- # "payload":{
- # "dialog_id":self.VC_dialog_id,
- # "session_id": self.session_id ,
- # }
- # }
- # EventMesh.publish("publish_AI_btnInfo",{"func":self.AI_client_VC_send,"data":ujson.dumps(json_data)})
- # utime.sleep_ms(1)
- # self.AI_client_VC_send(ujson.dumps(json_data))
- self.VC_state = VC_State_End
+
#客户端打断对话
def AI_client_VC_RequestToSpeak(self):
json_data = \
EventMesh.publish("publish_AI_btnInfo",{"func":self.VC_init})
EventMesh.publish("publish_AI_btnInfo",{"func":self.AI_client_VC_send,"data":ujson.dumps(json_data)})
# utime.sleep_ms(1)
- #请求TTS或者chat事件
- def AI_client_VC_RequestToRespond(self):
- self.session_id = self.get_session_id()#调试临时打开
+ #TTS播放
+ def AI_client_VC_synthesis(self):
json_data = \
{
- "header":{
- "trace_id":self.get_trace_id(),
- "event":"RequestToRespond"
- },
- "payload":{
- "dialog_id":self.VC_dialog_id,
- "session_id": self.session_id ,
- "type":"transcript",#prompt是跳过asr,transcript是跳过asr和大模型
- "text":""
- }
+ "event": "synthesis",
+ "payload": {
+ "text": self.AI_TTS_str
+ }
}
-
- print("AI_client_VC_RequestToRespond!!!!!!!!!!!!!!!!!!!!!!!!!!!!!")
+ self.AI_TTS_str = ""
+ print("AI_client_VC_synthesis!!!!!!!!!!!!!!!!!!!!!!!!!!!!!")
# if self.VC_state == VC_State_RequestToRespond:
# print("AI_client_VC_RequestToRespond 重复 tts_str:{}\nasr_str:{}".format(self.AI_TTS_str,self.AI_ASR_str))
- self.VC_state = VC_State_RequestToRespond
- if self.AI_TTS_str != "":
- json_data["payload"]["text"] = self.AI_TTS_str
- json_data["payload"]["type"] = "transcript"
- EventMesh.publish("publish_AI_btnInfo",{"func":self.VC_init})
- EventMesh.publish("publish_AI_btnInfo",{"func":self.AI_client_VC_send,"data":ujson.dumps(json_data)})
- self.AI_TTS_str = ""
- elif self.AI_ASR_str != "":
- json_data["payload"]["text"] = self.AI_ASR_str
- json_data["payload"]["type"] = "prompt"
- EventMesh.publish("publish_AI_btnInfo",{"func":self.VC_init})
- EventMesh.publish("publish_AI_btnInfo",{"func":self.AI_client_VC_send,"data":ujson.dumps(json_data)})
- if dev_type != "7PIN" :
- EventMesh.publish("publish_AI_btnInfo",{"func":self.send_tone})
- #
- #self.AI_ASR_str = ""
- # utime.sleep_ms(1)
+ self.AI_client_VC_send(ujson.dumps(json_data))
+
def chenggong_tone(self):
EventMesh.publish("audio_montage_play",["chenggong.mp3"])
def send_tone(self):
EventMesh.publish("audio_montage_play",["send_tone.mp3"])
#给服务器回应ack
- def AI_client_VC_Read(self):
- json_data = \
- {
- "header":{
- "trace_id":self.get_trace_id(),
- "event":"Read"
- },
- "payload":{
- "dialog_id":self.VC_dialog_id
- }
- }
- print("AI_client_VC_Read!!!!!!!!!!!!!!!!!!!!!!!!!!!!!")
-
- #for i in range(6):
- #EventMesh.publish("publish_AI_btnInfo",{"func":self.AI_client_VC_send,"data":ujson.dumps(json_data)})
- # utime.sleep_ms(1)
- if self.AI_client_VC != None and self.AI_client_VC_isconnect == 1:
- self.AI_client_VC.send(ujson.dumps(json_data))
+
############################################
#关闭音频播放线程
def AI_audio_queue_thread(self):
print("AI_audio_queue_thread start")
count = 0
+ if self.AI_audio_queue.empty()!=True:
+ self.AI_audio_queue.clear()
+ print("音频数据还有剩余!!!!!!!!!!!!")
while True:
try:
if self.AI_audio_queue_thread_lock == 2:
self.close_timerout = 0
if self.play_flag == 0:
self.play_flag =1
- print("AI_client_VC_LocalRespondingStarted!!!")
- self.AI_client_VC_LocalRespondingStarted()#通知服务器开始播放
#self.AI_client_tts_data_len=len(data)
#print("audio_queue:len:{}".format(len(data[0])))
+
if len(data[0]) > 10:
+ for i in range(5):
+ if self.VC_Play_flag == 0:
+ self.VC_Play_Start()
+ utime.sleep_ms(2)
+ else:
+ break
try:
if self.VC_play_TYPE == VC_play_TYPE_PCM:
- if self.VC_play_samplerate == 8000:
- tmp= self.aud.playStream(1,data[0] )
- elif self.VC_play_samplerate == 16000:
-
-
-
+ # if self.VC_play_samplerate == 8000:
+ # tmp= self.aud.playStream(1,data[0] )
+ # else:
write_buf = bytearray(data[0])
- #print("play_pcm.stream_write1!!")
+ print("play_pcm.stream_write1 len:{}".format(len(write_buf)))
if self.play_pcm != None:
#print("play_pcm.stream_write !!!")
ret = self.play_pcm.stream_write(write_buf,len(write_buf))
self.tts_in_data_len = 0
self.tts_out_data_len = 0
#必须先销毁线程,不然线程会容易报错
- try:
- self.AI_ASR_send_data_queue_thread_close()#销毁ASR发送线程
- except Exception as e:
- usys.print_exception(e)
+
try:
self.AI_audio_queue_thread_close()#销毁音频线程
except Exception as e:
usys.print_exception(e)
self.VC_Speech_End()
+
print("ai_VC Close1.1!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!")
self.VC_init()
-
print("ai_VC Close1.2!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!")
- try:
- self.websocket_deconnect_asr()
- except Exception as e:
- usys.print_exception(e)
try:
self.websocket_deconnect_VC()
except Exception as e:
usys.print_exception(e)
+
+
+
+
+
print("ai_VC Close1.3!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!")
print("ai_VC Close2!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!")
if self.AI_VC_send_data_queue.empty()!=True:
self.AI_VC_send_data_queue.clear()
- if self.AI_ASR_send_data_queue.empty()!=True:
- self.AI_ASR_send_data_queue.clear()
+
self.AI_ASR_send_buf_len = 0
#self.AI_WS_connect_Queue.put(self.AI_client_VC)
self._1S_timer.stop()
if self.AI_VC_send_data_queue.empty()!=True:
self.AI_VC_send_data_queue.clear()
- if self.AI_ASR_send_data_queue.empty()!=True:
- self.AI_ASR_send_data_queue.clear()
+
self.AI_ASR_send_buf_len = 0
if self.AI_audio_queue.empty()!=True:
self.AI_audio_queue.clear()