From: p15692025051 <846603105@qq.com> Date: Thu, 10 Jul 2025 09:35:09 +0000 (+0800) Subject: 备份 X-Git-Url: http://git.snicker.com.cn/?a=commitdiff_plain;h=b7a9aa6a3e2d7267f82541ed4fe3169f09192580;p=mirrors%2FASR1603_G5.git 备份 --- diff --git a/2.sdk/project/7PIN/sdk/services/microPython/ports/quectel/core/ai_VC.py b/2.sdk/project/7PIN/sdk/services/microPython/ports/quectel/core/ai_VC.py index cbfb134e..cc5261ed 100644 --- a/2.sdk/project/7PIN/sdk/services/microPython/ports/quectel/core/ai_VC.py +++ b/2.sdk/project/7PIN/sdk/services/microPython/ports/quectel/core/ai_VC.py @@ -30,11 +30,15 @@ import machine import dataCall import constants import versions -import VAD +try: + import VAD +except Exception as e: + usys.print_exception(e) #dev_type = "G10" #dev_type = "7PIN_BK"#小瑞 #dev_type = "7PIN_BK_coze"#k扣子小瑞 #dev_type = "7PIN_BK_EU"#英文小瑞 +#dev_type = "7PIN_coze"#柒牌扣子 dev_type = "7PIN"#柒牌 #dev_type = 'momo'#食梦貘 #dev_type = 'sjgq'#四季甘泉 @@ -194,7 +198,7 @@ def set_ipv4_datacall(): print('已经配置为IPv4') else: print('获取PDP Context失败。') -audio_buf = ['chenggong', 'didianguanji', 'IMEIhao', 'jianquancuowu', 'key_prompt', 'liuliangtishi', 'Low_power_warning', 'R_CHARGE_FULL', 'R_CHARGE_IN', 'R_CHARGE_OUT', 'R_READ_TIME_0', 'R_READ_TIME_1', 'R_READ_TIME_2', 'R_READ_TIME_3', 'R_READ_TIME_4', 'R_READ_TIME_5', 'R_READ_TIME_6', 'R_READ_TIME_7', 'R_READ_TIME_8', 'R_READ_TIME_9', 'R_READ_TIME_A', 'R_READ_TIME_B', 'R_READ_TIME_C', 'R_READ_TIME_D', 'R_READ_TIME_E', 'R_READ_TIME_F', 'R_READ_TIME_G', 'R_READ_TIME_H', 'R_READ_TIME_I', 'R_READ_TIME_J', 'R_READ_TIME_K', 'R_READ_TIME_L', 'R_READ_TIME_M', 'R_READ_TIME_N', 'R_READ_TIME_O', 'R_READ_TIME_P', 'R_READ_TIME_Q', 'R_READ_TIME_R', 'R_READ_TIME_S', 'R_READ_TIME_T', 'R_READ_TIME_U', 'R_READ_TIME_V', 'R_READ_TIME_W', 'R_READ_TIME_X', 'R_READ_TIME_Y', 'R_READ_TIME_Z', 'send_tone', 'shouhou', 'xinhaoruo1', 'zhengzaiguanji'] +audio_buf = ['chaobingfatis', 'chenggong', 'didianguanji', 'IMEIhao', 'jianquancuowu', 'key_prompt', 'liuliangtishi', 'Low_power_warning', 'R_CHARGE_FULL', 'R_CHARGE_IN', 'R_CHARGE_OUT', 'R_READ_TIME_0', 'R_READ_TIME_1', 'R_READ_TIME_2', 'R_READ_TIME_3', 'R_READ_TIME_4', 'R_READ_TIME_5', 'R_READ_TIME_6', 'R_READ_TIME_7', 'R_READ_TIME_8', 'R_READ_TIME_9', 'R_READ_TIME_A', 'R_READ_TIME_B', 'R_READ_TIME_C', 'R_READ_TIME_D', 'R_READ_TIME_E', 'R_READ_TIME_F', 'R_READ_TIME_G', 'R_READ_TIME_H', 'R_READ_TIME_I', 'R_READ_TIME_J', 'R_READ_TIME_K', 'R_READ_TIME_L', 'R_READ_TIME_M', 'R_READ_TIME_N', 'R_READ_TIME_O', 'R_READ_TIME_P', 'R_READ_TIME_Q', 'R_READ_TIME_R', 'R_READ_TIME_S', 'R_READ_TIME_T', 'R_READ_TIME_U', 'R_READ_TIME_V', 'R_READ_TIME_W', 'R_READ_TIME_X', 'R_READ_TIME_Y', 'R_READ_TIME_Z', 'send_tone', 'shouhou', 'xinhaoruo1', 'zhengzaiguanji'] class AI_dev(Abstract): # AI def __init__(self): @@ -427,7 +431,7 @@ class AI_dev(Abstract): self.KeyAI_timer.start(100, 1, self.KeyAI_timer_cb) self.KeyAI_timer_count = 0 #EventMesh.publish("AI_key_press") - if dev_type == "7PIN" : + if dev_type == "7PIN" or dev_type == "7PIN_coze" : self.aud.aud_tone_play(10,200)#播放按键音 EventMesh.publish("publish_AI_btnInfo",{"func":self.AI_key_press}) except Exception as e: @@ -682,9 +686,9 @@ class device_res_author(Abstract): #7pin self.key = b"uKLrChwrxA1LklgBc3VwawYjUkbT3BgX" self.pid = "cqxJZi5CNgzjS3mX21Zw" - if dev_type == 'jswm' or dev_type == 'jswm_BOX':#金三完美 - self.key = b"FuXG4ptpGbzvKbdB4vpUypisbENgy2nB" - self.pid = "DieBeXahZHLrjSnORbgN" + # if dev_type == 'jswm' or dev_type == 'jswm_BOX':#金三完美 + # self.key = b"FuXG4ptpGbzvKbdB4vpUypisbENgy2nB" + # self.pid = "DieBeXahZHLrjSnORbgN" self.dev_res_timer = osTimer() self.dev_res_timer.start(20000, 1, self.dev_timer_cb) self.dev_res_timerCount = 0 @@ -998,8 +1002,12 @@ class device_res_author(Abstract): data_tmp = data["data"] if "token" in data_tmp: #token self.dev_token = data_tmp["token"] + else:#报错清空密钥 + print("登录失败,清空密钥") + EventMesh.publish("set_storage_config",["dev_pass",""]) if data["code"] == 50003:#时间错误 self.ntptime_flag = 0 + print("token:{}\r\n".format(self.dev_token)) if response != None: response.close() @@ -1090,7 +1098,7 @@ class OTA(): url =None if dev_type == "7PIN_BK_EU":#英文小瑞 url = "http://dmp-global.raisound.com/bz-api/ota/task?deviceId={}&sourceVersion={}".format(modem.getDevImei(),sourceVersion) - if dev_type == "7PIN":#柒牌 + if dev_type == "7PIN" or dev_type == "7PIN_coze":#柒牌 url = "http://ota.qipai.com/bz-cmp-api/api/task?deviceId={}&sourceVersion={}".format(modem.getDevImei(),sourceVersion) else: url = "http://dmp.raisound.com/bz-api/ota/task?deviceId={}&sourceVersion={}".format(modem.getDevImei(),sourceVersion) @@ -1153,7 +1161,7 @@ class OTA(): url =None if dev_type == "7PIN_BK_EU":#英文小瑞 url = "http://dmp-global.raisound.com/bz-api/ota/result?deviceId={}¤tVersion={}".format(modem.getDevImei(),currentVersion) - if dev_type == "7PIN":#柒牌 + if dev_type == "7PIN" or dev_type == "7PIN_coze":#柒牌 url = "http://ota.qipai.com/bz-cmp-api/api/result?deviceId={}¤tVersion={}".format(modem.getDevImei(),currentVersion) else: url = "http://dmp.raisound.com/bz-api/ota/result?deviceId={}¤tVersion={}".format(modem.getDevImei(),currentVersion) @@ -1291,12 +1299,13 @@ class AI_VC(Abstract): if dev_type == 'jswm' or dev_type == 'jswm_BOX':# #self.server_ip="115.190.94.208:22080" self.server_ip="118.145.158.207:22086" - elif dev_type == "7PIN": + elif dev_type == "7PIN" : #self.server_ip="sevenpin.qipai.com.cn" # self.server_ip="220.160.104.34" # self.server_ip="118.145.158.207:22082" # self.server_ip="118.145.158.207:22080/22087" self.server_ip="ai.qipai.com" + #self.server_ip="sevenpin1.qipai.com.cn:22082" elif dev_type == "G10": self.server_ip="115.190.94.208:22080" elif dev_type == "sjgq": @@ -1304,13 +1313,15 @@ class AI_VC(Abstract): elif dev_type == "7PIN_BK" or dev_type == 'csh'or dev_type == "7PIN_BK_coze"or dev_type == 'momo': self.server_ip="amp.raisound.com" #self.server_ip="118.145.158.207:22086" + elif dev_type == "7PIN_coze": + self.server_ip="118.145.158.207:22086" elif dev_type == "7PIN_BK_EU": #self.server_ip="amp-global.raisound.com" self.server_ip="amp-cdn-test.raisound.com" #开机提示音 self.power_on_tone = EventMesh.publish("get_storage_config","power_on_tone")# - if dev_type != "7PIN" and dev_type != "jswm" and dev_type != 'jswm_BOX' and dev_type != "7PIN_BK": + if dev_type != "7PIN" and dev_type != "7PIN_coze"and dev_type != "jswm" and dev_type != 'jswm_BOX' and dev_type != "7PIN_BK": self.power_on_tone = None if self.power_on_tone == None: if dev_type == "G10": @@ -1355,7 +1366,7 @@ class AI_VC(Abstract): self.vad_silence = EventMesh.publish("get_storage_config","vad_silence")#语速配置 if self.vad_silence == None: - if dev_type == "7PIN": + if dev_type == "7PIN" or dev_type == "7PIN_coze": self.vad_silence = 200 else: self.vad_silence = 300 @@ -1560,6 +1571,40 @@ class AI_VC(Abstract): "lang":"zh-cn" }, } + elif dev_type == "7PIN_coze": + self.VC_TTS_voice_type = { + "女":{ + "bot_name":"柒妹妹", + "voice":"7468518753626488869" , + "lang":"zh-cn" + }, + "男":{ + "bot_name":"柒先生", + "voice":"7426720361732980745" , + "lang":"zh-cn" + }, + "ç«¥":{ + "bot_name":"柒乐乐", + "voice":"7468512265151676443" , + "lang":"zh-cn" + }, + "粤":{ + "bot_name":"柒先生", + "voice":"7481299960428888103" , + "lang":"zh-hk" + }, + "四川":{ + "bot_name":"柒妹妹", + "voice":"7426720361732931593", + "lang":"&lang=zh-cn-sc" + }, + "个性":{ + "bot_name":"柒先生", + "voice":"7468512265134850099" , + "lang":"zh-cn" + } + + } else: #女,男,童,粤,川,个性声 self.VC_TTS_voice_type = { @@ -1887,7 +1932,19 @@ class AI_VC(Abstract): EventMesh.subscribe("VC_error", self.VC_error) EventMesh.publish("close_led") - + self.dialog_attributes_provider = EventMesh.publish("get_storage_config","dialog_attributes_provider")#智能体类型配置 + if self.dialog_attributes_provider == None: + self.dialog_attributes_provider = "coze" + self.outbound_attributess_provider = EventMesh.publish("get_storage_config","outbound_attributess_provider")#tts服务选择 + if self.outbound_attributess_provider == None: + self.outbound_attributess_provider = "volcengine" + self.inbound_attributess_provider = EventMesh.publish("get_storage_config","inbound_attributess_provider")#tts服务选择 + if self.inbound_attributess_provider == None: + if dev_type == "7PIN" or dev_type == "7PIN_coze" : + self.inbound_attributess_provider = "xun-fei" + else: + self.inbound_attributess_provider = "volcengine" + self.bot_name = "柒先生" try: if "bot_name" in self.VC_TTS_voice_type[self.VC_TTS_voice_key]: @@ -1983,6 +2040,8 @@ class AI_VC(Abstract): url=None if dev_type == "7PIN_BK_EU":#英文小瑞 url = "http://dmp-global.raisound.com/bz-api/dev/config/{}".format(modem.getDevImei()) + elif dev_type == "7PIN" or dev_type == "7PIN_coze":#柒牌 + url = "http://ota.qipai.com/bz-cmp-api/api/config/{}".format(modem.getDevImei()) else: url = "http://dmp.raisound.com/bz-api/dev/config/{}".format(modem.getDevImei()) @@ -2014,7 +2073,15 @@ class AI_VC(Abstract): self.power_on_tone = data["data"]["power_on_tone"] EventMesh.publish("set_storage_config",["power_on_tone",self.power_on_tone]) print("配置power_on_tone成功") - + if "dialog_attributes_provider" in data["data"]: + self.dialog_attributes_provider = data["data"]["dialog_attributes_provider"] + EventMesh.publish("set_storage_config",["dialog_attributes_provider",self.dialog_attributes_provider]) + if "outbound_attributess_provider" in data["data"]: + self.outbound_attributess_provider = data["data"]["outbound_attributess_provider"] + EventMesh.publish("set_storage_config",["outbound_attributess_provider",self.outbound_attributess_provider]) + if "inbound_attributess_provider" in data["data"]: + self.inbound_attributess_provider = data["data"]["inbound_attributess_provider"] + EventMesh.publish("set_storage_config",["inbound_attributess_provider",self.inbound_attributess_provider]) except Exception as e: usys.print_exception(e) else: @@ -2426,7 +2493,7 @@ class AI_VC(Abstract): print("token:{}".format(token)) req_str = "vc/chat?is_auth={}".format(self.is_auth) - if dev_type == '7PIN_BK_coze': + if dev_type == '7PIN_BK_coze' or dev_type == '7PIN_coze': req_str = "vc/coze?is_auth={}".format(self.is_auth) elif dev_type == 'jswm' or dev_type == 'jswm_BOX': req_str = "vc/agent?is_auth={}".format(self.is_auth) @@ -2516,6 +2583,7 @@ class AI_VC(Abstract): print("websocket_error:tts:{}".format(TTS_str)) self.AI_TTS_str = TTS_str EventMesh.publish("publish_AI_btnInfo",{"func":self.AI_VC_start}) + self.Close_flag = 1 print("websocket_error2") @@ -2731,7 +2799,7 @@ class AI_VC(Abstract): print("VC:Started!!!!!!!!\r\n") if self.AI_TTS_str == "": #开始上传语音 - if dev_type != "7PIN": + if dev_type != "7PIN" and dev_type != "7PIN_coze": self.chenggong_tone() if self.VC_mode == 0 : self.VC_record_state_flag =2 @@ -2808,7 +2876,7 @@ class AI_VC(Abstract): 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.LocalRespondingEnded_timerout = 2 self.VC_state = VC_State_TTSEnd pass @@ -2818,7 +2886,7 @@ class AI_VC(Abstract): elif jsload_data["event"] == "completed" :#会话结束 #EventMesh.publish("open_led_green")#绿色 - self.LocalRespondingEnded_timerout = 8 + self.LocalRespondingEnded_timerout = 1 self.VC_state = VC_State_End pass elif jsload_data["event"] == "command" :#命令匹配 @@ -2826,7 +2894,6 @@ class AI_VC(Abstract): try: if self.commands_mode ==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) @@ -2845,6 +2912,15 @@ class AI_VC(Abstract): 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}) + elif jsload_data["event"] == "failed":#接口返回错误 + if jsload_data["payload"]["error"] == "concurrency_limit_exceeded":#超并发 + EventMesh.publish("publish_AI_btnInfo",{"func":self.concurrency_limit_exceeded_tone}) + + #utime.sleep_ms(4000) + + else: + EventMesh.publish("publish_AI_btnInfo",{"func":self.websocket_error,"data":jsload_data["payload"]["message"]}) + pass else:#下发音频数据 #self.AI_ASR_str = ""#下发音频后清掉asr结果 @@ -2874,7 +2950,7 @@ class AI_VC(Abstract): while buf_len < len(recv_data): utime.sleep_ms(1) count_tmp-=1 - if count_tmp<=0: + if count_tmp<=0 or self.play_pcm == None: break buf_len = self.play_pcm.stream_get_buf_len() #print("buf已满,等待释放:buf_len:{},count_tmp:{}".format(buf_len,count_tmp)) @@ -2902,6 +2978,7 @@ class AI_VC(Abstract): self.AI_client_VC_recv_id = 0 self.AI_client_VC_recv_lock = 0 print("AI_client_VC_recv END!!!!!!!!!!!!!!!!!!!!!!!!!!!") + def put_record_data(self,data): #print("下发音频数据1:{}".format(len(data[0]))) ret=self.AI_audio_queue.put(data) @@ -3540,7 +3617,7 @@ class AI_VC(Abstract): if len(text)<16 and (text.find("再见") != -1 or text.find("拜拜") != -1 or text.find("关闭对话") != -1): #EventMesh.publish("publish_AI_btnInfo",{"func":self.Close}) - if dev_type != "7PIN":#柒牌 + if dev_type != "7PIN" and dev_type != "7PIN_coze":#柒牌 self.AI_TTS_str = "好嘞,再见,我们下次再聊" self.Close_flag = 1 return 0 @@ -3548,7 +3625,7 @@ class AI_VC(Abstract): EventMesh.publish("publish_AI_btnInfo",{"func":self.Close}) return 1 if len(text)<12 and (text.find("关机") != -1 ): - if dev_type == "7PIN":#柒牌 + if dev_type == "7PIN" or dev_type == "7PIN_coze":#柒牌 EventMesh.publish("publish_AI_btnInfo",{"func":self.Close}) return 1 EventMesh.publish("publish_AI_btnInfo",{"func":self.Close}) @@ -3845,13 +3922,14 @@ class AI_VC(Abstract): # "workflow_id":"7469968083063603241", # "bot_id":"7411071327182438412",#柒牌 # "workflow_id":"7469049680291610636", + json_data["payload"]["outbound_attributes"]["provider"]=self.outbound_attributess_provider#TTS音色服务选择,火山 + json_data["payload"]["inbound_attributes"]["provider"]=self.inbound_attributess_provider#ASR服务选择,火山 if dev_type == "7PIN_BK"or dev_type == "7PIN_BK_coze"or dev_type == "G10":#小瑞 json_data["payload"]["dialog_attributes"]["cfg"]["bot_option"]["bot_id"]="7462617881076351002"#语言助手 json_data["payload"]["dialog_attributes"]["cfg"]["bot_option"]["workflow_id"]="7462621757327196187" # json_data["payload"]["dialog_attributes"]["cfg"]["bot_option"]["bot_id"]="7486697248416989193"#极简 # json_data["payload"]["dialog_attributes"]["cfg"]["bot_option"]["workflow_id"]="7486698347416649778" #json_data["payload"]["dialog_attributes"]["provider"]="doubao"#豆包 - json_data["payload"]["inbound_attributes"]["provider"]="volcengine"#火山 #json_data["payload"]["inbound_attributes"]["vad_silence"] = 200 #if self.VC_TTS_voice_type[self.VC_TTS_voice_key]["bot_id"] !="": if "bot_id" in self.VC_TTS_voice_type[self.VC_TTS_voice_key]: @@ -3871,22 +3949,23 @@ class AI_VC(Abstract): elif dev_type == "7PIN_BK_EU": json_data["payload"]["dialog_attributes"]["cfg"]["bot_option"]["bot_id"]="7493368740600446995"#英文 json_data["payload"]["dialog_attributes"]["cfg"]["bot_option"]["workflow_id"]="7493369551587213323" - json_data["payload"]["inbound_attributes"]["provider"]="volcengine"#火山 elif dev_type == "csh": json_data["payload"]["dialog_attributes"]["cfg"]["bot_option"]["bot_id"]="7490852493640384538"#慈善会 json_data["payload"]["dialog_attributes"]["cfg"]["bot_option"]["use_workflow"]=False json_data["payload"]["dialog_attributes"]["cfg"]["bot_option"]["workflow_id"]="" - json_data["payload"]["inbound_attributes"]["provider"]="volcengine"#火山 - elif dev_type == "7PIN":#柒牌 + elif dev_type == "7PIN" :#柒牌 json_data["payload"]["dialog_attributes"]["cfg"]["bot_option"]["bot_id"]=""# json_data["payload"]["dialog_attributes"]["cfg"]["bot_option"]["workflow_id"]="" #json_data["payload"]["inbound_attributes"]["vad_silence"] = 1000 + elif dev_type == "7PIN_coze": + json_data["payload"]["dialog_attributes"]["cfg"]["bot_option"]["bot_id"]=""# + json_data["payload"]["dialog_attributes"]["cfg"]["bot_option"]["workflow_id"]="" + json_data["payload"]["dialog_attributes"]["provider"]="qipai" # elif dev_type == 'momo':#食梦貘 json_data["payload"]["dialog_attributes"]["cfg"]["bot_option"]["bot_id"]="7491256313561825332" json_data["payload"]["dialog_attributes"]["cfg"]["bot_option"]["workflow_id"]="" json_data["payload"]["dialog_attributes"]["cfg"]["bot_option"]["use_workflow"]=False - json_data["payload"]["inbound_attributes"]["provider"]="volcengine"#火山 if "bot_id" in self.VC_TTS_voice_type[self.VC_TTS_voice_key]: json_data["payload"]["dialog_attributes"]["cfg"]["bot_option"]["bot_id"]=self.VC_TTS_voice_type[self.VC_TTS_voice_key]["bot_id"] if "workflow_id" in self.VC_TTS_voice_type[self.VC_TTS_voice_key]: @@ -3917,14 +3996,14 @@ class AI_VC(Abstract): json_data["payload"]["dialog_attributes"]["cfg"]["bot_option"]["workflow_id"]= "" else: json_data["payload"]["dialog_attributes"]["cfg"]["bot_option"]["workflow_id"]= self.VC_TTS_voice_type[self.VC_TTS_voice_key]["workflow_id"] - json_data["payload"]["inbound_attributes"]["provider"]="volcengine"#火山 if self.VC_TTS_voice_type[self.VC_TTS_voice_key]["openai_option"] : json_data["payload"]["dialog_attributes"]["cfg"]["openai_option"] =self.VC_TTS_voice_type[self.VC_TTS_voice_key]["openai_option"] keywords = []#热词 for key in self.VC_TTS_voice_type: keywords.append(key) json_data["payload"]["inbound_attributes"]["cfg"]["keywords"] = keywords - + if self.dialog_attributes_provider != None: + json_data["payload"]["dialog_attributes"]["provider"] = self.dialog_attributes_provider if self.commands_mode !=0 : json_data["payload"]["commands"] = [] if self.VC_mode == 0 :#and dev_type != "7PIN_BK_coze":#长对话模式打开vad @@ -3999,6 +4078,9 @@ class AI_VC(Abstract): EventMesh.publish("audio_montage_play",["chenggong.mp3"]) def send_tone(self): EventMesh.publish("audio_montage_play",["send_tone.mp3"]) + def concurrency_limit_exceeded_tone(self): + self.Close() + EventMesh.publish("audio_montage_play",["chaobingfatis.mp3"]) #播放超并发提醒 #给服务器回应ack @@ -4129,6 +4211,7 @@ class AI_VC(Abstract): self.AI_ASR_flag = 0 self.AI_ASR_check_timeout = 0 self.AI_ASR_error_timeout = 0 + self.LocalRespondingEnded_timerout = 0 print("ai_VC Close1!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!") EventMesh.publish("close_led") self.tts_in_data_len = 0 @@ -4236,18 +4319,3 @@ class AI_VC(Abstract): # self.aud.setVolume(num)#恢复原始音量 -{ - "version": "202505151440", - "VC_TTS_voice_type": { - "班度": { - "bot_name": "班度", - "voice": "huoshan::zh_male_yuanboxiaoshu_moon_bigtts", - "lang": "zh-cn", - "bot_id":"7490824341572075555",#AI语音APP女神经理 - "workflow_id":"", - }, - - }, - "power_on_tone": "阿弥陀佛,施主既来,便是有缘。心中若有烦忧,直说无妨。" - -} \ No newline at end of file diff --git a/2.sdk/project/7PIN/sdk/services/microPython/ports/quectel/core/ai_VC_7PIN.py b/2.sdk/project/7PIN/sdk/services/microPython/ports/quectel/core/ai_VC_7PIN.py deleted file mode 100644 index 75c09486..00000000 --- a/2.sdk/project/7PIN/sdk/services/microPython/ports/quectel/core/ai_VC_7PIN.py +++ /dev/null @@ -1,3662 +0,0 @@ -from common import Abstract, LogAdapter -import EventMesh -import uwebsocket -import usys -import gc -import urandom -import uhashlib -import ubinascii -import ujson -import osTimer -import _thread -from queue import Queue -import utime -import audio -import uos -from machine import Pin -from machine import ExtInt -from machine import WDT -import modem -import sim -import net -import base64 -import ucryptolib -import urandom as random -import request -import ql_fs -from misc import Power,USB,PowerKey -import ntptime -import machine -import dataCall -import constants -import versions - -dev_type = "G10" -#dev_type = "7PIN_BK"#小瑞 -#dev_type = "7PIN"#柒牌 -#dev_type = 'momo'#食梦貘 -#dev_type = 'sjgq'#四季甘泉 -class AI_led(Abstract): - def __init__(self): - if dev_type == "G10": - self.led_red = Pin(Pin.GPIO36, Pin.OUT, Pin.PULL_PD, 0) - self.led_green = Pin(Pin.GPIO44, Pin.OUT, Pin.PULL_PD, 1) - self.led_blue = Pin(Pin.GPIO21, Pin.OUT, Pin.PULL_PD, 1) - else: - self.led_red = Pin(Pin.GPIO36, Pin.OUT, Pin.PULL_PD, 0) - self.led_green = Pin(Pin.GPIO21, Pin.OUT, Pin.PULL_PD, 1) - self.led_blue = Pin(Pin.GPIO19, Pin.OUT, Pin.PULL_PD, 1) - - #=1 红灯闪,=2白灯闪,=3绿灯闪,=4全部灯闪 - self.led_flicker_flag = 0 - self.led_flicker_on_off_flag = 0 - self.led_flicker_timer = osTimer() - - EventMesh.subscribe("open_led_red",self.open_led_red) - EventMesh.subscribe("open_led_blue",self.open_led_blue) - EventMesh.subscribe("open_led_green",self.open_led_green) - EventMesh.subscribe("open_led_all",self.open_led_all) - EventMesh.subscribe("open_led_red_blue",self.open_led_red_blue) - EventMesh.subscribe("open_led_red_green",self.open_led_red_green) - EventMesh.subscribe("flicker_led_red",self.flicker_led_red) - EventMesh.subscribe("flicker_led_blue",self.flicker_led_blue) - EventMesh.subscribe("flicker_led_green",self.flicker_led_green) - EventMesh.subscribe("flicker_led_all",self.flicker_led_all) - EventMesh.subscribe("close_led",self.close_led) - EventMesh.publish("open_led_red") - - def flicker_led_red(self,event,msg): - self.led_flicker_flag = 1 - self.led_flicker_timer.start(1500, 1, self.led_flicker_timer_cb) - - def flicker_led_blue(self,event,msg): - self.led_flicker_flag = 2 - self.led_flicker_timer.start(1500, 1, self.led_flicker_timer_cb) - - def flicker_led_green(self,event,msg): - self.led_flicker_flag = 3 - self.led_flicker_timer.start(1500, 1, self.led_flicker_timer_cb) - - def flicker_led_all(self,event,msg): - self.led_flicker_flag = 4 - self.led_flicker_timer.start(1500, 1, self.led_flicker_timer_cb) - - def led_flicker_timer_cb(self, *args, **kwargs): - EventMesh.publish("publish_AI_btnInfo",{"func":self.led_flicker_timer_cb_}) - def led_flicker_timer_cb_(self): - if self.led_flicker_flag == 0: - self.led_flicker_timer.stop() - return - if self.led_flicker_on_off_flag == 0: - self.led_red.write(0) - self.led_blue.write(0) - self.led_green.write(0) - self.led_flicker_on_off_flag = 1 - else: - self.led_flicker_on_off_flag = 0 - if self.led_flicker_flag == 1: - self.led_blue.write(0) - self.led_green.write(0) - self.led_red.write(1) - elif self.led_flicker_flag == 2: - self.led_red.write(0) - self.led_green.write(0) - self.led_blue.write(1) - elif self.led_flicker_flag == 3: - self.led_red.write(0) - self.led_blue.write(0) - self.led_green.write(1) - elif self.led_flicker_flag == 4: - self.led_blue.write(1) - self.led_green.write(1) - self.led_red.write(1) - - def open_led_red(self,event,msg): - #print("open_led_red") - self.led_flicker_flag = 0 - #self.led_red.write(0) - self.led_blue.write(0) - self.led_green.write(0) - self.led_red.write(1) - - def open_led_blue(self,event,msg): - #print("open_led_blue") - self.led_flicker_flag = 0 - self.led_red.write(0) - #self.led_blue.write(0) - self.led_green.write(0) - self.led_blue.write(1) - - def open_led_green(self,event,msg): - #print("open_led_green") - self.led_flicker_flag = 0 - self.led_red.write(0) - self.led_blue.write(0) - #self.led_green.write(0) - self.led_green.write(1) - - def open_led_red_blue(self,event,msg): - #print("open_led_blue") - self.led_flicker_flag = 0 - self.led_red.write(1) - #self.led_blue.write(0) - self.led_green.write(0) - self.led_blue.write(1) - - def open_led_red_green(self,event,msg): - #print("open_led_blue") - self.led_flicker_flag = 0 - self.led_red.write(1) - #self.led_blue.write(0) - self.led_green.write(1) - self.led_blue.write(0) - - def open_led_all(self,event,msg): - #print("open_led_all") - self.led_flicker_flag = 0 - #self.led_red.write(0) - self.led_blue.write(1) - self.led_green.write(1) - self.led_red.write(1) - - def close_led(self,event,msg): - #print("close_led") - self.led_flicker_flag = 0 - self.led_red.write(0) - self.led_blue.write(0) - self.led_green.write(0) - -audio_buf = ['chenggong', 'didianguanji', 'IMEIhao', 'jianquancuowu', 'key_prompt', 'liuliangtishi', 'Low_power_warning', 'R_CHARGE_FULL', 'R_CHARGE_IN', 'R_CHARGE_OUT', 'R_READ_TIME_0', 'R_READ_TIME_1', 'R_READ_TIME_2', 'R_READ_TIME_3', 'R_READ_TIME_4', 'R_READ_TIME_5', 'R_READ_TIME_6', 'R_READ_TIME_7', 'R_READ_TIME_8', 'R_READ_TIME_9', 'R_READ_TIME_A', 'R_READ_TIME_B', 'R_READ_TIME_C', 'R_READ_TIME_D', 'R_READ_TIME_E', 'R_READ_TIME_F', 'R_READ_TIME_G', 'R_READ_TIME_H', 'R_READ_TIME_I', 'R_READ_TIME_J', 'R_READ_TIME_K', 'R_READ_TIME_L', 'R_READ_TIME_M', 'R_READ_TIME_N', 'R_READ_TIME_O', 'R_READ_TIME_P', 'R_READ_TIME_Q', 'R_READ_TIME_R', 'R_READ_TIME_S', 'R_READ_TIME_T', 'R_READ_TIME_U', 'R_READ_TIME_V', 'R_READ_TIME_W', 'R_READ_TIME_X', 'R_READ_TIME_Y', 'R_READ_TIME_Z', 'send_tone', 'shouhou', 'xinhaoruo1', 'zhengzaiguanji'] -class AI_dev(Abstract): - # AI - def __init__(self): - 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 - self.KeyAI_timer_count = 0 - self.KeyAI_long_press = 0 - self.KeyAI_press = 0 - if self.is_wdt == 1: - self.wdt = WDT(30) #开启看门狗 - # self.wdt_timer = osTimer() - # self.wdt_timer.start(5000, 1, self.wdt_timer_cb) - count = 0 - while True: - count += 1 - if count > 20 : - break - data = dataCall.getInfo(1, 0) - print("data call INFO {}".format(data)) - if data[2][0]: - self.network_state = 1 - break - print("等待网络 {}...".format(count)) - utime.sleep_ms(500) - self.KeyAI_timer = osTimer() - if dev_type == "G10": - self.extint_AI = ExtInt(ExtInt.GPIO19,ExtInt.IRQ_RISING_FALLING, ExtInt.PULL_PU, self.keyAI_extint_cb) - self.pwk_key = ExtInt(ExtInt.GPIO26, ExtInt.IRQ_RISING_FALLING, ExtInt.PULL_PU, self.pwk_extint_cb) - else: - self.pwk_key = ExtInt(ExtInt.GPIO41, ExtInt.IRQ_RISING_FALLING, ExtInt.PULL_PU, self.pwk_extint_cb) - #self.extint_AI = ExtInt(ExtInt.GPIO19,ExtInt.IRQ_RISING_FALLING, ExtInt.PULL_PU, self.keyAI_extint_cb) - self.extint_AI = ExtInt(ExtInt.GPIO22,ExtInt.IRQ_RISING_FALLING, ExtInt.PULL_PU, self.keyAI_extint_cb) - self.extint_AI.enable() - self.pwk_key_status = 0 - self.pwk_key_timer_count = 0 - self.pwk_key_long_press = 0 - self.pwk_key_press = 0 - self.pwk_key_timer = osTimer() - #self.pwk_key = ExtInt(ExtInt.GPIO26, ExtInt.IRQ_RISING_FALLING, ExtInt.PULL_DISABLE, self.pwk_extint_cb) - - self.pwk_key.enable() - print("AI_dev:1") - self.btnInfo_queue = Queue(100) - self.btnInfo_queue_count = 0 - _thread.stack_size(16*1024) - self.btnInfo_queue_thread_id = _thread.start_new_thread(self.btnInfo_queue_thread, ()) - _thread.stack_size(8*1024) - EventMesh.subscribe("publish_AI_btnInfo",self.publish_AI_btnInfo) - EventMesh.subscribe("get_battery",self.get_battery) - 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) - print("AI_dev:2") - self.pk = PowerKey() - self.pk.powerKeyEventRegister(self.powerKey_callback) - self.usb = USB() - self.usb.setCallback(self.usb_event_cb) - self.usb_status = self.usb.getStatus() - self.usb_charge_flag = 0 - self.Low_power_warning_timer = 0 - self.AI_dev_timer = osTimer() - self.AI_dev_timer.start(10000, 1, self.AI_dev_timer_cb) - print("AI_dev:AI_dev_timer") - self.aud = audio.Audio(0) - self.Low_power_warning_flag = 0 - self.VC_TTS_volume = EventMesh.publish("get_storage_config","VC_TTS_volume")#音量配置 - if self.VC_TTS_volume == None: - self.VC_TTS_volume = 100 - self.aud.setVolume(self.VC_TTS_volume //10) - #self.aud.play(1,0,'U:/static/xianyikaiji.mp3')#开机音频 - #EventMesh.publish("audio_montage_play",["xianyikaiji.mp3"]) - #EventMesh.publish("publish_AI_btnInfo",{"func":self.ntptime_cb}) - self.check_rest_timer_count = 0 - print("AI_dev:end") - def ntptime_cb(self): - #ntptime.settime(8) - print("timer:{}!!!!!!!!\r\n".format(utime.localtime())) - def usb_event_cb(self, state): - EventMesh.publish("publish_AI_btnInfo",{"func":self.usb_event,"data":state}) - - def usb_event(self, state): - status = state - self.usb_charge_flag = 0 - if status == 1:#插入USB - print("charge R_CHARGE_in") - self.usb_status = 1 - VC_satrt_flag = EventMesh.publish("get_VC_satrt_flag")#获取vc是否在运行 - if VC_satrt_flag == None: - VC_satrt_flag = 0 - if VC_satrt_flag == 0: - self.aud.stop() - #EventMesh.publish("flicker_led_red")#充电闪灯 - #self.aud.play(1,1,'U:/static/R_CHARGE_IN.mp3') - EventMesh.publish("open_led_red")#充电红灯常亮 - EventMesh.publish("audio_montage_play",["R_CHARGE_IN.mp3"]) - self.Low_power_warning_flag = 0 - pass - elif status == 0:#拨出usbs - self.usb_status = 0 - VC_satrt_flag = EventMesh.publish("get_VC_satrt_flag")#获取vc是否在运行 - if VC_satrt_flag == None: - VC_satrt_flag = 0 - if VC_satrt_flag == 0: - self.aud.stop() - EventMesh.publish("close_led") - EventMesh.publish("audio_montage_play",["R_CHARGE_OUT.mp3"]) - #self.aud.play(1,1,'U:/static/R_CHARGE_OUT.mp3') - def btnInfo_queue_thread(self): - while True: - data = self.btnInfo_queue.get() - self.btnInfo_queue_count-=1 - #EventMesh.debug_log("Info_queue:data = {}".format(data)) - if data != None: - try: - if "data" in data : - data["func"](data["data"]) - else : - data["func"]() - except Exception as e: - #EventMesh.debug_log("btnInfo_queue:ERROR:{}".format(e)) - usys.print_exception(e) - def publish_AI_btnInfo(self,event,msg): - #print("publish_AI_btnInfo 1") - self.btnInfo_queue.put(msg) - self.btnInfo_queue_count+=1 - if self.btnInfo_queue_count > 80: - self.btnInfo_queue_count =0 - print("事件处理线程队列出问题,重启!!!!!!!!!!!!!!") - print("线程:{} 队列:{}".format(_thread.threadIsRunning(self.btnInfo_queue_thread_id),self.btnInfo_queue.size())) - # if _thread.threadIsRunning(self.btnInfo_queue_thread_id): - # _thread.stop_thread(self.btnInfo_queue_thread_id) - # _thread.stack_size(10*1024) - # self.btnInfo_queue_thread_id = _thread.start_new_thread(self.btnInfo_queue_thread, ()) - # _thread.stack_size(8*1024) - # self.btnInfo_queue.clear() - # self.btnInfo_queue = Queue(100) - EventMesh.publish("VC_error") #播放报错 - utime.sleep_ms(1000) - self.aud.stopPlayStream() - self.aud.stopAll() - Power.powerRestart() - EventMesh.publish("set_storage_config",["powerRestart",1]) - #print("publish_AI_btnInfo 2") - def powerKey_callback(self, status): - print("powerKey_callback:{}".format(status)) - - def pwk_extint_cb(self,args):#pwk - try: - self.pwk_key_status = int(args[1]) - if self.pwk_key_status == 0: - self.pwk_key_status = 1 - else: - self.pwk_key_status = 0 - pass - if self.pwk_key_status == 0:#按下 - - if self.pwk_key_press == 0 : - self.pwk_key.disable() - self.pwk_key_press = 1 - self.pwk_key_long_press = 0 - self.pwk_key_timer.start(100, 1, self.pwk_key_timer_cb) - self.pwk_key_timer_count = 0 - #EventMesh.publish("AI_key_press") - except Exception as e: - usys.print_exception(e) - def pwk_key_timer_cb(self, *args, **kwargs): - # EventMesh.publish("publish_AI_btnInfo",{"func":self.pwk_key_timer_cb_}) - # def pwk_key_timer_cb_(self) : - try: - self.pwk_key_status = self.pwk_key.read_level() - self.pwk_key_timer_count +=1 - if self.pwk_key_timer_count >= 10*3: #长按3s - #print("pwk_key_long_press {}".format(self.pwk_key_long_press)) - if self.pwk_key_long_press == 0: - self.pwk_key_long_press = 1 - #EventMesh.publish("AI_key_long_press") - EventMesh.publish("audio_montage_play",["zhengzaiguanji.mp3"]) - #self.aud.play(1,0,'U:/static/zhengzaiguanji.mp3')#关机音频 - EventMesh.publish("open_led_red") - utime.sleep_ms(2000) - self.aud.stopPlayStream() - self.aud.stopAll() - Power.powerDown() - #print("AI_key_release") - 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)) - key_count = 5 - if dev_type == "7PIN_BK": - key_count = 3 - if self.pwk_key_timer_count >= key_count: #防抖200ms - #EventMesh.publish("AI_key_release") - EventMesh.publish("publish_AI_btnInfo",{"func":self.pwk_key_release}) - self.pwk_key.enable() - self.pwk_key_timer.stop() - self.pwk_key_timer_count = 0 - self.pwk_key_press = 0 - - except Exception as e: - usys.print_exception(e) - - def keyAI_extint_cb(self,args):#call 2 - try: - #print("AI_btn:keyAI_extint_cb{}".format(args[1])) - self.KeyAI_status = int(args[1]) - if self.KeyAI_status == 0: - self.KeyAI_status = 1 - else: - self.KeyAI_status = 0 - - if self.KeyAI_status == 0:#按下 - if self.KeyAI_press == 0 : - EventMesh.publish(constants.EVENT.SYSTEM_UP)#唤醒休眠 - self.extint_AI.disable() - self.KeyAI_press = 1 - self.KeyAI_long_press = 0 - self.KeyAI_timer.start(100, 1, self.KeyAI_timer_cb) - self.KeyAI_timer_count = 0 - #EventMesh.publish("AI_key_press") - if dev_type == "7PIN" : - self.aud.aud_tone_play(10,200)#播放按键音 - EventMesh.publish("publish_AI_btnInfo",{"func":self.AI_key_press}) - except Exception as e: - usys.print_exception(e) - def KeyAI_timer_cb(self, *args, **kwargs): - # EventMesh.publish("publish_AI_btnInfo",{"func":self.KeyAI_timer_cb_}) - # def KeyAI_timer_cb_(self): - try: - self.KeyAI_status = self.extint_AI.read_level() - self.KeyAI_timer_count +=1 - if self.KeyAI_timer_count >= 10*1: #长按3s - if self.KeyAI_long_press == 0: - self.KeyAI_long_press = 1 - #EventMesh.publish("AI_key_long_press") - EventMesh.publish("publish_AI_btnInfo",{"func":self.AI_key_long_press}) - if self.KeyAI_status == 1:#松开 - #print("KeyAI_timer_cb:{}".format(self.KeyAI_timer_count)) - key_count = 5 - if dev_type == "7PIN_BK": - key_count = 3 - if self.KeyAI_timer_count >= key_count: #防抖200ms - #EventMesh.publish("AI_key_release") - EventMesh.publish("publish_AI_btnInfo",{"func":self.AI_key_release}) - self.extint_AI.enable() - self.KeyAI_timer.stop() - self.KeyAI_timer_count = 0 - self.KeyAI_press = 0 - - except Exception as e: - usys.print_exception(e) - - def AI_key_press(self): - self.check_rest_timer_count = 0 - print("AI_key_press") - EventMesh.publish("AI_key_press") - - def AI_key_long_press(self): - self.check_rest_timer_count = 0 - print("AI_key_long_press") - EventMesh.publish("AI_key_long_press") - - def AI_key_release(self): - print("AI_key_release") - EventMesh.publish("AI_key_release") - - def pwk_key_Long_Press(self): - self.check_rest_timer_count = 0 - print("pwk_key_long_press!!!!!!!") - print("pwk_key_long_press!!!!!!!") - - # EventMesh.publish("paly_iccid_imei") - # return - EventMesh.publish("audio_montage_play",["zhengzaiguanji.mp3"]) - #self.aud.play(1,0,'U:/static/zhengzaiguanji.mp3')#关机音频 - EventMesh.publish("open_led_red") - utime.sleep_ms(3000) - self.aud.stopPlayStream() - self.aud.stopAll() - Power.powerDown() - #print("AI_key_release") - EventMesh.publish("pwk_key_long_press") - - def pwk_key_release(self): - self.check_rest_timer_count = 0 - #print("pwk_key_release") - EventMesh.publish("pwk_key_release") - - - def wdt_timer_cb(self, *args, **kwargs): - if self.is_wdt == 1: - self.wdt.feed() - - def AI_dev_timer_cb(self, *args, **kwargs): - #print("AI_dev_timer_cb") - EventMesh.publish("publish_AI_btnInfo",{"func":self.AI_dev_timer_event}) - def AI_dev_timer_event(self): - if self.is_wdt == 1: - self.wdt.feed() - VC_satrt_flag = EventMesh.publish("get_VC_satrt_flag")#获取vc是否在运行 - if VC_satrt_flag == None: - VC_satrt_flag = 0 - Vbatt = Power.getVbatt() - if self.usb_status == 1 and VC_satrt_flag == 0: - EventMesh.publish("open_led_red")#充电红灯常亮 - if self.usb_status == 1 and Vbatt>=self.VBATT_tab["charge_full"]and VC_satrt_flag == 0:#充电充满 - EventMesh.publish("open_led_green") - if self.usb_charge_flag == 0 : - EventMesh.publish("audio_montage_play",["R_CHARGE_FULL.mp3"]) - #self.aud.play(1,0,'U:/static/R_CHARGE_FULL.mp3')#充电已满 - self.usb_charge_flag = 1 - if self.usb_status == 0 and Vbatt= 2: - # self.Low_power_warning_timer = 0 - EventMesh.publish("audio_montage_play",["Low_power_warning.mp3"]) - - if self.usb_status == 0 and Vbatt= 8640:#24小时没按键,则关机 - self.pwk_key_Long_Press() - - def get_battery(self, event=None, msg=None): - Vbatt = Power.getVbatt() - if Vbatt>self.VBATT_tab["90"]: - return 100 - if Vbatt>self.VBATT_tab["80"]: - return 90 - if Vbatt>self.VBATT_tab["60"]: - return 80 - if Vbatt>self.VBATT_tab["40"]: - return 60 - if Vbatt>self.VBATT_tab["20"]: - return 40 - if Vbatt>self.VBATT_tab["10"]: - return 20 - if Vbatt<=self.VBATT_tab["10"]: - return 10 - def audio_montage_play(self,event,msg): - self.aud.stopPlayStream() - self.aud.stopAll() - str_data='mp3files=' - for i in msg: - try: - str_tmp = i.replace(".mp3","") - str_data+="{}.mp3+".format(audio_buf.index(str_tmp)) - except Exception as e: - usys.print_exception(e) - str_data = str_data[:-1] - print("audio_montage_play:{}".format(str_data)) - self.aud.montage_play('U:/static/audio.bin',1,1,str_data) - - def paly_iccid_imei(self,event,msg): - str_data = 'mp3files={}.mp3+'.format(audio_buf.index("liuliangtishi"))#流量提示 - imei = modem.getDevImei() - iccid = sim.getIccid() - print("paly_iccid_imei:ICCID:{}".format(iccid)) - if iccid != -1 and len(iccid) > 5: - iccid = iccid.upper() - if len(iccid) <20: - for i in range(20-len(iccid)): - iccid = "0"+iccid - str_data += '{}.mp3+{}.mp3+{}.mp3+{}.mp3+{}.mp3+{}.mp3+{}.mp3+{}.mp3+{}.mp3+{}.mp3+{}.mp3+{}.mp3+{}.mp3+{}.mp3+{}.mp3+{}.mp3+{}.mp3+{}.mp3+{}.mp3+{}.mp3+'.format(audio_buf.index("R_READ_TIME_{}".format(iccid[0]))\ - ,audio_buf.index("R_READ_TIME_{}".format(iccid[1])),audio_buf.index("R_READ_TIME_{}".format(iccid[2])),audio_buf.index("R_READ_TIME_{}".format(iccid[3])),\ - audio_buf.index("R_READ_TIME_{}".format(iccid[4])),audio_buf.index("R_READ_TIME_{}".format(iccid[5])),audio_buf.index("R_READ_TIME_{}".format(iccid[6])),audio_buf.index("R_READ_TIME_{}".format(iccid[7])),\ - audio_buf.index("R_READ_TIME_{}".format(iccid[8])),audio_buf.index("R_READ_TIME_{}".format(iccid[9])),audio_buf.index("R_READ_TIME_{}".format(iccid[10])),audio_buf.index("R_READ_TIME_{}".format(iccid[11])),\ - audio_buf.index("R_READ_TIME_{}".format(iccid[12])),audio_buf.index("R_READ_TIME_{}".format(iccid[13])),audio_buf.index("R_READ_TIME_{}".format(iccid[14])),audio_buf.index("R_READ_TIME_{}".format(iccid[15])),\ - audio_buf.index("R_READ_TIME_{}".format(iccid[16])),audio_buf.index("R_READ_TIME_{}".format(iccid[17])),audio_buf.index("R_READ_TIME_{}".format(iccid[18])),audio_buf.index("R_READ_TIME_{}".format(iccid[19]))) - str_data += '{}.mp3+'.format(audio_buf.index("shouhou"))#可联系售后解决,联系方式见售后客服电话是400-886-8777或到微信公众号柒牌SEVENBRAND自行充值: - self.aud.montage_play('U:/static/audio.bin',1,1,str_data) - #鉴权出错,播放imei号 - def paly_device_res_error(self,event,msg): - str_data = 'mp3files={}.mp3+'.format(audio_buf.index("jianquancuowu"))#AI功能异常,请联系客户查询,设备号为: - imei = modem.getDevImei() - imei = imei.upper() - str_data += '{}.mp3+{}.mp3+{}.mp3+{}.mp3+{}.mp3+{}.mp3+{}.mp3+{}.mp3+{}.mp3+{}.mp3+{}.mp3+{}.mp3+{}.mp3+{}.mp3+{}.mp3'.format(audio_buf.index("R_READ_TIME_{}".format(imei[0]))\ - ,audio_buf.index("R_READ_TIME_{}".format(imei[1])),audio_buf.index("R_READ_TIME_{}".format(imei[2])),audio_buf.index("R_READ_TIME_{}".format(imei[3])),\ - audio_buf.index("R_READ_TIME_{}".format(imei[4])),audio_buf.index("R_READ_TIME_{}".format(imei[5])),audio_buf.index("R_READ_TIME_{}".format(imei[6])),audio_buf.index("R_READ_TIME_{}".format(imei[7])),\ - audio_buf.index("R_READ_TIME_{}".format(imei[8])),audio_buf.index("R_READ_TIME_{}".format(imei[9])),audio_buf.index("R_READ_TIME_{}".format(imei[10])),audio_buf.index("R_READ_TIME_{}".format(imei[11])),\ - audio_buf.index("R_READ_TIME_{}".format(imei[12])),audio_buf.index("R_READ_TIME_{}".format(imei[13])),audio_buf.index("R_READ_TIME_{}".format(imei[14]))) - #print("str_data:{}".format(str_data)) - self.aud.montage_play('U:/static/audio.bin',1,1,str_data) - -#存储信息 -class getStorageDataManager(Abstract):#获取内存数据 - def __init__(self): - self.config_data = {} - check = ql_fs.path_exists("/usr/static/storage_file/config.json") - if check == True: - with open("/usr/static/storage_file/config.json","r") as fd: - self.config_data = ujson.load(fd) - else : - self.config_data = {'old_time': 0, 'flip_sw': 0} - pass - - def post_processor_after_instantiation(self): - EventMesh.subscribe("set_storage_data", self.set_storage_data) - EventMesh.subscribe("set_storage_config", self.set_storage_config) - EventMesh.subscribe("get_storage_data", self.get_storage_data) - EventMesh.subscribe("get_storage_config", self.get_storage_config) - - def set_storage_data(self, event, msg): - # EventMesh.debug_log("set_storage_data:{}".format(msg)) - if msg != None: - self.config_data = msg - with open("/usr/static/storage_file/config.json",'w+',encoding="utf-8") as fd: - ujson.dump(self.config_data,fd) - - - def set_storage_config(self,event,msg): - # EventMesh.debug_log("set_storage_key_data1:{}".format(msg)) - if len(msg) >= 2: - self.config_data[msg[0]]=msg[1] - # EventMesh.debug_log("set_storage_key_data2:{}".format(self.config_data[msg[0]])) - EventMesh.publish("publish_message_event_ui",{"func":self.set_storage_save,"data":0}) - def set_storage_save(self, data): - with open("/usr/static/storage_file/config.json",'w+',encoding="utf-8") as fd: - ujson.dump(self.config_data,fd) - def get_storage_data(self, event, msg): - # EventMesh.debug_log("get_storage_data:{}".format(self.config_data)) - return self.config_data - def get_storage_config(self,event,msg): - # EventMesh.debug_log("get_storage_key_data1:{}".format(msg)) - b = msg in self.config_data.keys() - if b == True: - # EventMesh.debug_log("get_storage_key_data2:{}".format(self.config_data[msg])) - return self.config_data[msg] - else : - return None - # try: - # return self.config_data[msg] - # except: - # EventMesh.debug_log("get_storage_key_data:none key:{}",msg) - # return None -#设备资源授权平台 -class device_res_author(Abstract): - - def __init__(self) : - print("device_res_author __init__ start !!!!!!!!!!!!!!!!!") - self.deviceId = modem.getDevImei()#"876226002022574" - self.SHA1_BLOCK_SIZE = 64 - self.PAD_BLOCK_SIZE = 16 - self.SHA256 = uhashlib.sha256 - self.pad = lambda s: s + chr(self.PAD_BLOCK_SIZE - len(s) % self.PAD_BLOCK_SIZE) * (self.PAD_BLOCK_SIZE - len(s) % self.PAD_BLOCK_SIZE) - # 除去补16字节的多余字符 - self.unpad = lambda s: s[:-s[-1]] - #K01 - # self.key = b"MWrMZjdtcPhj41jWuoqFAhTmqyFluqj1" - # self.pid = "qAtdDOGXgXYjT2HGFr3a" - #G15 - # self.key = b"3LWfBicxfRZ3ZAqmZCFuvMdGUXdAFWkb" - # self.pid = "qLx4Pu4mSUQxyfVKGLXG" - #7pin - self.key = b"uKLrChwrxA1LklgBc3VwawYjUkbT3BgX" - self.pid = "cqxJZi5CNgzjS3mX21Zw" - - self.dev_res_timer = osTimer() - self.dev_res_timer.start(20000, 1, self.dev_timer_cb) - self.dev_res_timerCount = 0 - self.ud_token_timer = osTimer() - self.ud_token_timer.start(10000, 1, self.ud_token_timer_cb) - self.ud_token_timer_Count = 0 - self.dev_token = None - self.res_error_count = 0 - self.ntptime_flag = 0 - EventMesh.subscribe("get_dev_token", self.get_dev_token) - EventMesh.subscribe("update_dev_token", self.update_dev_token) - EventMesh.subscribe("dev_active", self.dev_active) - EventMesh.subscribe("dev_sign_in", self.dev_sign_in) - EventMesh.subscribe("dev_NTP", self.dev_NTP) - #EventMesh.publish_async("dev_NTP",thread_size = 8192) - - # count = 0 - # while True: - # if self.ntptime_flag == 1: - # break - # utime.sleep_ms(1) - # count+=1 - # if count>600: - # break - # EventMesh.publish_async("dev_active",thread_size = 8192) - # EventMesh.publish_async("dev_sign_in",thread_size = 8192) - - self.dev_NTP()#获取时间 - self.dev_active() #设备激活 - self.dev_sign_in() #设备登入 - print("device_res_author __init__ end !!!!!!!!!!!!!!!!!") - - def get_dev_token(self, event, msg): - return self.dev_token - #网络校时 - def dev_NTP(self, event=None, msg=None): - response = None - try: - print("dev_NTP1") - url = "http://dmp.raisound.com/bz-api/dev/time" - response = request.get(url,timeout=5) - data = response.json() - print("dev_NTP:{}".format(data)) - if data: - try: - timeSecond = data["data"]["timestamp"]//1000 - - next_alarm_time = utime.localtime(timeSecond) - print("timeSecond {} next_alarm_time {}".format(timeSecond,next_alarm_time)) - machine.RTC().datetime((next_alarm_time[0],next_alarm_time[1],next_alarm_time[2],next_alarm_time[6],next_alarm_time[3],next_alarm_time[4],next_alarm_time[5],0)) - self.ntptime_flag = 1 - except Exception as e: - usys.print_exception(e) - except Exception as e: - usys.print_exception(e) - if response != None: - response.close() - print("dev_NTP end") - def dev_timer_cb(self, *args): #设备资源管理鉴权平台定时器 - EventMesh.publish("publish_AI_btnInfo",{"func":self.dev_timer_cb_}) - - def dev_timer_cb_(self): - #if EventMesh.DEV_RES_MANAGE_AUTHEN_PLATFORM == 1: - try: - if self.dev_token == None: - if self.ntptime_flag == 0: - self.ntptime_flag = 1 - EventMesh.publish_async("dev_NTP",thread_size = 8192) - #EventMesh.publish("publish_AI_btnInfo",{"func":self.dev_NTP}) - print("timer:{}!!!!!!!!\r\n".format(utime.localtime())) - EventMesh.publish_async("dev_active",thread_size = 8192) - EventMesh.publish_async("dev_sign_in",thread_size = 8192) - # self.dev_active() #设备激活 - # self.dev_sign_in() #设备登入 - self.dev_res_timerCount+=1 - if self.dev_res_timerCount > 3: #开机一分钟内没有获取到密码和token 等下一次更新令牌在走登入 激活流程 - self.dev_res_timerCount=0 - self.dev_res_timer.stop() - except Exception as e: - usys.print_exception(e) - def ud_token_timer_cb(self, *args): - EventMesh.publish("publish_AI_btnInfo",{"func":self.ud_token_timer_cb_}) - - def ud_token_timer_cb_(self): - try: - #print("ud_token_timer_!!!!") - self.ud_token_timer_Count+=1 - if self.ud_token_timer_Count >= 720: #定时10*3000s时更新token - self.ud_token_timer_Count = 0 - EventMesh.publish_async("dev_sign_in",thread_size = 8192) - except Exception as e: - usys.print_exception(e) - def get_sim_Status(self): - return sim.getStatus() - def HMAC(self,k, m): - - KEY_BLOCK = k + (b'\0' * (self.SHA1_BLOCK_SIZE - len(k))) - KEY_INNER = bytes((x ^ 0x36) for x in KEY_BLOCK) - KEY_OUTER = bytes((x ^ 0x5C) for x in KEY_BLOCK) - inner_message = KEY_INNER + m - outer_message = KEY_OUTER + self.SHA256(inner_message).digest() - return self.SHA256(outer_message) - def get_hmac_sha256(self,k, m): - data = self.HMAC(k, m).digest() - # print("HMAC(k, m).digest():", data) - # print("HMAC(k, m).digest():", ubinascii.hexlify(data)) - hex_data = ubinascii.hexlify(data) - hex_data = hex_data.decode('ascii') - return hex_data - # 加密函数 - def aes_CBC_Encrypt(self,data, key, iv): # CBC模式的加密函数,data为明文,key为16字节密钥,iv为16字节的偏移量 - key = key.encode('utf-8') - iv = iv.encode('utf-8') # CBC 模式下的偏移量 - data = self.pad(data) # 补位 - data = data.encode('utf-8') - aes = ucryptolib.aes(key,ucryptolib.MODE_CBC,iv) - result = base64.b64encode(aes.encrypt(data)) - return str(result, 'utf-8') # 以字符串的形式返回 - - # 解密函数 - def aes_CBC_Decrypt(self,data, key, iv): # CBC模式的解密函数,data为密文,key为16字节密钥 - key = key.encode('utf-8') - iv = iv.encode('utf-8') - - aes = ucryptolib.aes(key,ucryptolib.MODE_CBC,iv) #CBC模式 - - # decrypt AES解密 B64decode为base64 转码 - result = aes.decrypt(base64.b64decode(data)) - result = self.unpad(result) # 除去补16字节的多余字符 - return str(result, 'utf-8') # 以字符串的形式返回 - #激活接口 没有密码走激活 - def dev_active(self, event=None, msg=None): - signal = net.csqQueryPoll() - if signal == -1 or self.get_sim_Status() != 1:#网络不正常 - print("dev_active 无 SIM卡!!!!!!!!\r\n") - return - print("dev_active 1\r\n") - # 签名内容: = deviceId+pid+timeStamp - dev_pass = "" - dev_pass = EventMesh.publish("get_storage_config","dev_pass") - print("dev_pass:{}\r\n".format(dev_pass)) - if dev_pass == None: - dev_pass = "" - if dev_pass == "" or dev_pass == None: - try: - date_tmp = utime.localtime() #获取当前时间 - print("date_tmp:{}\r\n".format(date_tmp)) #转换时间戳s - timeStamp = (utime.mktime(date_tmp))*1000#获取时间戳ms - deviceId = self.deviceId #"876226002022574" #以imei号 - pid = self.pid - key = self.key - sign_data = "{}{}{}".format(deviceId,pid,timeStamp) #签名内容 - print("sign_data:{}\r\n".format(sign_data)) - sha256_hex = self.get_hmac_sha256(key,sign_data) - print("sha256_hex:{}\r\n".format(sha256_hex)) - - data = { - "deviceId":"{}".format(deviceId), #设备名 - "pid":pid, #产品PID - "sign":"{}".format(sha256_hex), #HMACSHA256签名后的数据 - "timeStamp":timeStamp, #要以ms的形式 - "signMethod":"HMACSHA256" #签名方式 HMACSHA256 - } - print(ujson.dumps(data)) - headers_T ={"Content-Type":"application/json"} - url = "http://dmp.raisound.com/bz-api/dev/auth/active" - data =ujson.dumps(data) - response = None - response_result = 0 - try: - response = request.put(url,data=data,headers = headers_T,timeout=5) - response_result = 1 - except Exception as e: - usys.print_exception(e) - print("put error!!!!!\r\n") - response_result = 0 - - IV = "" #偏移量 - PASSWORD= "" #服务器返回后的加密内容 密码 - if response_result == 1: #访问成功ip - if response.status_code == 200: - print("headers:{}".format(response.headers)) - content = response.content - c = next(content) - # "api.xcloudtech.com" - # d_server_port = 9000 - data = ujson.loads(c) - # data = response.json() - print("data-{}".format(data)) - if data != None: - if "success" in data: - if data['success'] == True: - if "data" in data: - data_tmp = data["data"] - if "nonce" in data_tmp: #偏移量 - IV = data_tmp["nonce"] - if "password" in data_tmp: - PASSWORD = data_tmp["password"] - # EventMesh.publish("set_storage_config",["dev_pass",PASS]) - if data["code"] == 20001:#鉴权成功 - pass - elif data["code"] > 50000:#时间错误 - self.res_error_count+=1 - if self.res_error_count>=3: - self.res_error_count = 0 - #EventMesh.publish("paly_device_res_error") - if data["code"] == 50003:#时间错误 - self.ntptime_flag = 0 - if PASSWORD != None and IV != None: - if len(PASSWORD) != 0 and len(IV) != 0: - password = PASSWORD - iv = IV - #解密 之后保存本地下一次登入做使用 - decrypt_data = self.aes_CBC_Decrypt(password, self.key, iv) #对服务器下发的密码进行解密 - print("decrypt_data {}".format(decrypt_data)) - EventMesh.publish("set_storage_config",["dev_pass",decrypt_data]) - print("IV:{}\r\n PASS:{}".format(IV,PASSWORD)) - if response != None: - response.close() - except Exception as e: - usys.print_exception(e) - print("dev_active end\r\n") - return [response_result,PASSWORD,IV] - #随机生成16个字节的字符串作为加密的IV 偏移量 - def generate_random_string(self,length=16): - random_str = "" - chars = 'abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789' - for i in range(length): - random_str+=chars[random.randint(0,length)] - return random_str - - #设备登入 没有Token 走登入获取token - def dev_sign_in(self, event=None, msg=None): - signal = net.csqQueryPoll() - if signal == -1 or self.get_sim_Status() != 1:#网络不正常 - print("dev_sign_in 无 SIM卡!!!!!!!!\r\n") - return - print("dev_sign_in 1") - token = "" - try: - token = self.dev_token - dev_pass = EventMesh.publish("get_storage_config","dev_pass") - #print("token:{}\r\n".format(token)) - if token == None: - token = "" - if dev_pass == None: - dev_pass = "" - if len(dev_pass) == 0:#没有密码 - return - #if token == None or token == "": - if 1: #返回结果成功 - #获取本地保存的密码 - decrypt_data=EventMesh.publish("get_storage_config","dev_pass") - # decrypt_data = self.aes_CBC_Decrypt(password, self.key, iv) #对服务器下发的密码进行解密 - print("decrypt_data {}".format(decrypt_data)) - #随机生成16个字符串 设备生成做加密使用 - random_string = self.generate_random_string(16) #随机的16个字符串 - enc_iv = random_string #加密的IV偏移量 - #设备端进行密码加密 - encrypt_data = self.aes_CBC_Encrypt(decrypt_data, self.key, enc_iv) - print("encrypt_data {}".format(encrypt_data)) - - #登入数据 - deviceId = self.deviceId - sign_in_data = { - "deviceId":"{}".format(deviceId), #设备ID - "password":"{}".format(encrypt_data), #加密的数据 - "nonce":"{}".format(random_string) #随机的16个字符串 - } - print(ujson.dumps(sign_in_data)) - sign_url = "http://dmp.raisound.com/bz-api/dev/auth/sign_in" #登入地址 - headers_T ={"Content-Type":"application/json"} - response_result = 0 - response = 0 - try: - response = request.post(sign_url,data=ujson.dumps(sign_in_data),headers = headers_T,timeout=5) - response_result = 1 - except Exception as e: - usys.print_exception(e) - print("post error!!!!!\r\n") - response_result = 0 - # {'msg': '', 'code': 20001, 'success': True, - # 'data': {'deviceId': '876226002022574', - # 'token': '95436a9e09fd0ff89feb8825257dca982f'} - # } - - #self.dev_token = "" - if response_result == 1: - if response.status_code == 200: - content = response.content - c = next(content) - data = ujson.loads(c) - print("data-{}".format(data)) - if data != None: - if "success" in data: - if data['success'] == True: #登入成功 - if "data" in data: - data_tmp = data["data"] - if "token" in data_tmp: #token - self.dev_token = data_tmp["token"] - if data["code"] == 50003:#时间错误 - self.ntptime_flag = 0 - print("token:{}\r\n".format(self.dev_token)) - if response != None: - response.close() - pass - except Exception as e: - print("post error!!!!!\r\n") - response_result = 0 - print("dev_sign_in end") - #获取新的令牌 更新token - def update_dev_token(self, event=None, msg=None): - print("update_dev_token") - try: - dev_pass = "" - dev_pass = EventMesh.publish("get_storage_config","dev_pass") - - if dev_pass == None: - dev_pass = "" - if len(dev_pass) == 0: #没有密码走激活 - print("no dev_pass:{}\r\n".format(dev_pass)) - EventMesh.publish("dev_active") - token = self.dev_token - if token == None: - token = "" - if len(token) == 0: #没有token走登入 - print("no dev_token:{}\r\n".format(token)) - #self.dev_sign_in() - EventMesh.publish("dev_sign_in") - dev_tokenip = "http://dmp.raisound.com/bz-api/dev/auth/token" #设备新令牌更新地址 - token = self.dev_token - if token == None: - token = "" - if len(token) != 0: - response_result=0 - response = None - headers_T = {"bz-dt":"{}".format(token)} - try: - response = request.get(dev_tokenip,headers = headers_T,timeout=5) - response_result = 1 - except Exception as e: - print("get error!!!!!\r\n") - response_result = 0 - if response_result == 1: - if response.status_code == 200: - try: - headers_data = response.headers - # print("headers_data!!!!! headers_data:{}\r\n".format(headers_data)) - if "bz-dt" in headers_data: #bz-dt字段是否在头部数据里面 如果有就需要更新 - bz_dt = headers_data["bz-dt"] - self.dev_token = bz_dt.replace(" ", "") #去掉所有的空格符 - print("update_dev_token:{}".format(self.dev_token)) - except Exception as e: - print("headers_data!!!!! error\r\n") - if response != None: - response.close() - except Exception as e: - usys.print_exception(e) - print("update_dev_token end") - -#OTA升级 -class OTA(): - def __init__(self): - #EventMesh.subscribe("min_sys_ota",self.min_sys_ota) - self.downloadFileVoURL1= "" - self.downloadFileVoURL2= "" - #小系统升级,返回0,没有升级;返回,1有升级,正在执行升级;返回2,电压不够 - def min_sys_ota(self,event=None,msg=None): - print("min_sys_ota") - signal = net.csqQueryPoll() - if signal == -1 or sim.getStatus() != 1:#网络不正常 - print("min_sys_ota 无 SIM卡!!!!!!!!\r\n") - return 0 - # return 0 - response = None - ret_str =0 - self.downloadFileVoURL1= "" - self.downloadFileVoURL2= "" - try: - sourceVersion = versions.Build_Time - sourceVersion = "7PIN-"+sourceVersion[:10]+"-"+sourceVersion[11:-3] - print("sourceVersion:{}".format(sourceVersion)) - sourceVersion = sourceVersion.replace(" ", "0") - print("sourceVersion2:{}".format(sourceVersion)) - #url = "http://iot.api.thisiot.com/ota/task?deviceId=860132060348836&sourceVersion=2024-12-20-15:35-1" - url = "http://dmp.raisound.com/bz-api/ota/task?deviceId={}&sourceVersion={}".format(modem.getDevImei(),sourceVersion) - print(url) - response = request.get(url,timeout=5) - if response.status_code == 200: - data = response.json() - print("min_sys_ota1:{}".format(data)) - - if data: - try: - if data["code"] == 20007:#有新版本 - if "fileList"in data["data"]: - if len(data["data"]["fileList"]) == 2: - for fileList in data["data"]["fileList"]: - if fileList["fileName"] == "dfota_2.bin": - self.downloadFileVoURL2 = fileList["url"] - elif fileList["fileName"] == "dfota_1.bin": - self.downloadFileVoURL1 = fileList["url"] - - if data["code"] == 20006:#已是最新版本 - ret_str = 0 - - except Exception as e: - usys.print_exception(e) - else: - print("min_sys_ota get error") - response.close() - except Exception as e: - usys.print_exception(e) - if response != None: - response.close() - - print("min_sys_ota:downloadFileVoURL1:{},\ndownloadFileVoURL2:{}".format(self.downloadFileVoURL1,self.downloadFileVoURL2)) - print("min_sys_ota end") - if self.downloadFileVoURL2!="" and self.downloadFileVoURL1!="": - battery = EventMesh.publish("get_battery") - if battery>=40: - self.ota_timer = osTimer() - self.ota_timer.start(15000, 0, self.ota_timer_cb) - ret_str = 1 - else: - ret_str = 2 - return ret_str - - def ota_timer_cb(self, *args, **kwargs): - import fota - fota_obj = fota() - fota_obj.httpDownload(url1=self.downloadFileVoURL1,url2=self.downloadFileVoURL2) - #ota升级结果返回,开机时调用一次即可 - def ota_result(self,event=None,msg=None): - response = None - try: - currentVersion = versions.Build_Time - currentVersion = "7PIN-"+currentVersion[:10]+"-"+currentVersion[11:-3] - print("currentVersion1:{}".format(currentVersion)) - currentVersion = currentVersion.replace(" ", "0") - print("currentVersion2:{}".format(currentVersion)) - url = "http://dmp.raisound.com/bz-api/ota/result?deviceId={}¤tVersion={}".format(modem.getDevImei(),currentVersion) - print(url) - response = request.post(url,timeout=5) - if response.status_code == 200: - data = response.json() - print("ota_result:{}".format(data)) - else: - print("ota_result error!!!!") - for i in response.text: - print(i) - response.close() - except Exception as e: - usys.print_exception(e) - if response != None: - response.close() - #ICCID上传 - def pots_ICCID(self,event=None,msg=None): - response = None - try: - iccid = sim.getIccid() - if iccid != -1 and len(iccid) > 5: - print("pots_ICCID:{}".format(iccid)) - #Headers = {'Transfer-Encodong':'chunked'} - #http://dmp.raisound.com/bz-api/dev/iccid?deviceId=866610001099679&iccid=89860002192307889057 - url = "http://dmp.raisound.com/bz-api/dev/iccid?deviceId={}&iccid={}".format(modem.getDevImei(),iccid) - print(url) - response = request.post(url,timeout=5) - if response.status_code == 200: - data = response.json() - print("pots_ICCID:{}".format(data)) - else: - print("pots_ICCID error!!!!") - for i in response.text: - print(i) - response.close() - except Exception as e: - usys.print_exception(e) - if response != None: - response.close() -#阿里VC状态枚举 -VC_State_None=0 -VC_State_Listening=1#听 -VC_State_SpeechStart=2#说开始 -VC_State_SpeechIng=3#正在说 -VC_State_SpeechEnd=4#说结束 -VC_State_RequestToRespond=5 #TTS请求或者chat请求 -VC_State_Thinking=6#想(chat) -VC_State_Responding=7#音频播放 -VC_State_TTSStart=8 -VC_State_TTSData=9 -VC_State_TTSFinish=10 -VC_State_TTSEnd=11 -VC_State_TTSError=12 -VC_State_DialogError=13 -VC_State_End=14 - -VC_record_TYPE_PCM = 0 -VC_record_TYPE_AMR = 1 -VC_play_TYPE_PCM = 0 -VC_play_TYPE_MP3 = 1 - -#websocket发送数据编号 -# AI_client_asr_num = 0 -# AI_client_chat_num = 1 -# AI_client_tts_num = 2 -AI_client_VC_num = 3 -AI_client_asr_num = 4 - - -class AI_VC(Abstract): - # AI - - def __init__(self): - try: - self.http_get_config()#获取/更新配置参数 - except Exception as e: - usys.print_exception(e) - self.VC_30S_timer = osTimer() - self.VC_30S_timer.start(30000, 1, self.VC_30S_timer_cb) - self.get_config_timer_count = 0 - self.record_data_save_flag = 0 #是否保存录音文件 - self.play_data_save_flag = 0 #是否保存tts数据到文件 - self.record_fd = None - self.play_fd = None - self.is_VC_ACK = 0 #是否开启ack应答模式 - self.is_long_record = 0 #是否开启长录音模式(语音打断模式) - self.ai_OTA = OTA() - self.is_auth = 0 #是否开启dmp鉴权 - #self.VC_mode = 0 #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.error_data = [] - self.asr_taskid = "" - self.VC_taskid = "" - self.VC_server = 2 #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="118.145.158.207:22083" - elif self.VC_server == 2:# - self.server_ip="118.145.158.207:22082" - elif self.VC_server == 4:# - self.server_ip="118.145.158.207:22084" - elif self.VC_server == 5:# - self.server_ip="amp-wss.raisound.com" - elif self.VC_server == 6:# - self.server_ip="118.145.158.207:22080" - else: - self.server_ip="sevenpin.qipai.com.cn" - - if dev_type == 'momo':# - self.server_ip="118.145.158.207:22080" - elif dev_type == "7PIN": - self.server_ip="sevenpin.qipai.com.cn" - elif dev_type == "sjgq": - self.server_ip="118.145.158.207:22084" - #开机提示音 - self.power_on_tone = EventMesh.publish("get_storage_config","power_on_tone")# - if dev_type != "7PIN": - self.power_on_tone = None - if self.power_on_tone == None: - if dev_type == "G10": - self.power_on_tone = "已开机,您好!我是北科瑞讯智能 AI bot_name" - elif dev_type == "7PIN_BK": - self.power_on_tone = "小瑞来了!我们一起来愉快地聊天吧!" - elif dev_type == "momo": - self.power_on_tone = "DuloDulo,我是上古神兽食梦貘,主人可以叫我momo,我来自《山海经》,是一只以梦为食的神秘灵兽,每当颜色朦胧、人们入睡时,我就会悄悄飞到人们的床头,用我长长的鼻子把噩梦统统吞噬掉,只留下甜甜的美梦。从今往后,就由我守护在主人身边,一起度过每一个星河璀璨的夜晚。" - elif dev_type == "sjgq": - self.power_on_tone = "您好!我是巴马四季甘泉的智能助手。我可以为你解答各种各样的问题,像是有关巴马四季甘泉知识库、中基长寿科学产品、卫斯曼院士国际先进医疗中心的问题,还有日常生活与工作、旅游信息、健康咨询、教育与学习、情感交流、全球资讯、世界文化等方面的问题哦。你有没有这方面的问题想要问我呀?" - else: - self.power_on_tone = "您好!我是世界首创柒牌男装AI生活好帮手-bot_name, 很高兴为您服务,我可以帮您解答柒牌公司知识库、日常生活与工作、旅游信息、健康与运动咨询、教育与学习、情感交流、全球资讯、世界文化等问题!请问您有什么需要我帮忙的吗?" - - - self.VC_record_TYPE = VC_record_TYPE_PCM #0:PCM 1:AMR - self.VC_play_TYPE = VC_play_TYPE_PCM #0:PCM 1:mp3 - self.VC_record_samplerate = 16000 - self.VC_play_samplerate = 16000 - - 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": - self.VC_TTS_voice_type = { - "女":{ - "bot_name":"小瑞", - "voice":"zh_female_wanwanxiaohe_moon_bigtts" , - "lang":"zh-cn" - }, - "男":{ - "bot_name":"小瑞", - "voice":"zh_male_wennuanahu_moon_bigtts" , - "lang":"zh-cn" - }, - "ç«¥":{ - "bot_name":"小瑞", - "voice":"ICL_zh_female_huoponvhai_tob" , - "lang":"zh-cn" - }, - "粤":{ - "bot_name":"小瑞", - "voice":"zh_female_wanqudashu_moon_bigtts" , - "lang":"zh-hk" - }, - "四川":{ - "bot_name":"小瑞", - "voice":"zh_female_daimengchuanmei_moon_bigtts", - "lang":"&lang=zh-cn-sc" - }, - "个性":{ - "bot_name":"小瑞", - "voice":"zh_male_sunwukong_mars_bigtts" , - "lang":"zh-cn" - } - - } - elif dev_type == 'momo': - self.VC_TTS_voice_type = { - "女":{ - "bot_name":"食梦貘", - "voice":"zh_female_shaoergushi_mars_bigtts" , - "lang":"zh-cn" - }, - "男":{ - "bot_name":"食梦貘", - "voice":"zh_male_yangguangqingnian_mars_bigtts" , - "lang":"zh-cn" - }, - "ç«¥":{ - "bot_name":"食梦貘", - "voice":"ICL_zh_female_huoponvhai_tob" , - "lang":"zh-cn" - }, - } - elif dev_type == 'sjgq': - self.VC_TTS_voice_type = { - "女":{ - "bot_name":"小巴", - "voice":"zh_female_wanwanxiaohe_moon_bigtts" , - "lang":"zh-cn" - }, - "男":{ - "bot_name":"小巴", - "voice":"zh_male_wennuanahu_moon_bigtts" , - "lang":"zh-cn" - }, - "ç«¥":{ - "bot_name":"小巴", - "voice":"ICL_zh_female_huoponvhai_tob" , - "lang":"zh-cn" - }, - } - else: - #女,男,童,粤,川,个性声 - self.VC_TTS_voice_type = { - "女":{ - "bot_name":"柒妹妹", - "voice":"huoshan::zh_female_wanwanxiaohe_moon_bigtts" , - "lang":"zh-cn" - }, - "男":{ - "bot_name":"柒先生", - "voice":"huoshan::zh_male_wennuanahu_moon_bigtts" , - "lang":"zh-cn" - }, - "ç«¥":{ - "bot_name":"柒乐乐", - "voice":"huoshan::ICL_zh_female_huoponvhai_tob" , - "lang":"zh-cn" - }, - "粤":{ - "bot_name":"柒先生", - "voice":"huoshan::zh_female_wanqudashu_moon_bigtts" , - "lang":"zh-hk" - }, - "四川":{ - "bot_name":"柒妹妹", - "voice":"huoshan::zh_female_daimengchuanmei_moon_bigtts", - "lang":"&lang=zh-cn-sc" - }, - "个性":{ - "bot_name":"柒先生", - "voice":"huoshan::zh_male_sunwukong_mars_bigtts" , - "lang":"zh-cn" - }, - "英语":{ - "bot_name":"柒先生", - "voice":"huoshan::en_male_smith_mars_bigtts" , - "lang":"zh-cn" - } - - - } - - # self.VC_TTS_voice_type = {0:"zh_female_xinlingjitang_moon_bigtts",1:"zh_male_wennuanahu_moon_bigtts",2:"ICL_zh_female_huoponvhai_tob", - # 3:"aliyun::longjiaxin",4:"zh_female_daimengchuanmei_moon_bigtts"} - #self.VC_TTS_voice_type = ["aliyun::longxiaoxia","aliyun::longnan","aliyun::longling"] - - #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": - self.VC_TTS_voice_key = "ç«¥" - elif dev_type == "momo": - self.VC_TTS_voice_key = "男" - else: - self.VC_TTS_voice_key = "男" - if self.VC_TTS_voice_key in self.VC_TTS_voice_type: - pass - else: - self.VC_TTS_voice_key = list(self.VC_TTS_voice_type.keys())[0] - print("音色配置:{}:{}\r\n\r\n".format(self.VC_TTS_voice_key,self.VC_TTS_voice_type[self.VC_TTS_voice_key])) - self.VC_TTS_volume = EventMesh.publish("get_storage_config","VC_TTS_volume")#音量配置 - except Exception as e: - usys.print_exception(e) - - if self.VC_TTS_volume == None: - self.VC_TTS_volume = 100 - self.AI_audio_queue_thread_id = 0 - self.AI_audio_queue_thread_lock = 0 - self.AI_VC_send_data_queue_thread_id = 0 - self.AI_VC_send_data_queue_thread_lock = 0 - self.AI_ASR_send_data_queue_thread_id = 0 - self.AI_ASR_send_data_queue_thread_lock = 0 - self.AI_record_tmp_queue = Queue(100) - self.AI_ASR_send_data_queue = Queue(200) - self.AI_VC_send_data_queue = Queue(100) - self.AI_audio_queue = Queue(100) - #self.AI_WS_connect_Queue = Queue(100) #释放用 - self.AI_TTS_str = "" - self.AI_ASR_str = "" - self.AI_ASR_flag = 0 - self.AI_ASR_str_tmp = "" - self.AI_ASR_send_buf_len = 0 - self.AI_ASR_text_tmp = "" - self.AI_ASR_text_repet_count = 0 - # #开始线程 - # if self.AI_audio_queue_thread_id ==0: - # self.AI_audio_queue_thread_id = _thread.start_new_thread(self.AI_audio_queue_thread, ()) - # else: - # print("AI_VC_start :AI_audio_queue_thread_id != 0 ") - # if self.AI_VC_send_data_queue_thread_id == 0: - # self.AI_VC_send_data_queue_thread_id = _thread.start_new_thread(self.AI_VC_send_data_queue_thread, ()) - - self.VC_state = VC_State_None #阿里ai VC状态 - self.VC_dialog_id = ""# - self.VC_message_id=None - self.VC_task_id =None - self.AI_client_VC = None - self.AI_client_VC_recv_id = 0 - self.AI_client_VC_recv_lock = 0 - self.AI_client_VC_isconnect =0 - self.AI_client_VC_debug =0 - - self.asr_state = VC_State_None #阿里VC_ASR VC状态 - self.key_state = 0 - - self.AI_client_asr = None - self.AI_client_asr_recv_id = 0 - self.AI_client_asr_recv_lock = 0 - self.AI_client_asr_isconnect =0 - self.AI_ASR_timer = osTimer() - self.AI_ASR_timer_count = 0 - self.AI_client_asr_debug =0 - self.AI_ASR_check_timeout = 0 - self.AI_ASR_error_timeout = 0 - self.VC_Thinking_timerout = 0 - self.VC_Speech_end_timerout = 0 - - self.record_pcm = None - self.play_pcm = None - self.VC_record_thread_id = 0 - self.VC_record_thread_lock = 0 - self.VC_pingping_timerout = 0 - self.asr_pingping_timerout = 0 - self.factory_timer = osTimer() - self._1S_timer = osTimer() - self.Audio_buf_size = 16*1024 - self.record = audio.Record() - #self.record.end_callback(self.record_callback) - self.record.gain_set(4,10) - #self.record.gain_set(4,12) - self.aud = audio.Audio(0) - self.aud.setCallback(self.audio_cb) - #self.aud.setVolume(self.VC_TTS_volume //10) - self.audio_play_state = 1 #音频播放完状态 - self.close_timerout = 0 - self.LocalRespondingEnded_timerout = 0 - - self.play_flag = 0 - self.VC_record_state_flag = 0 - self.AI_key_long_press_flag = 0 - self.websocket_error_count = 0 - - self.tts_in_data_len = 0 - self.tts_out_data_len = 0 - self.VC_satrt_flag = 0 - self.session_id = "" - EventMesh.subscribe("AI_key_press", self.AI_key_press) - EventMesh.subscribe("AI_key_release", self.AI_key_release) - EventMesh.subscribe("AI_key_long_press", self.AI_key_long_press) - EventMesh.subscribe("pwk_key_release", self.pwk_key_release) - EventMesh.subscribe("get_AI_audio_queue", self.get_AI_audio_queue) - EventMesh.subscribe("get_VC_satrt_flag", self.get_VC_satrt_flag) - EventMesh.subscribe("VC_error", self.VC_error) - - EventMesh.publish("close_led") - - self.bot_name = "柒先生" - try: - if "bot_name" in self.VC_TTS_voice_type[self.VC_TTS_voice_key]: - self.bot_name = self.VC_TTS_voice_type[self.VC_TTS_voice_key]["bot_name"] - else: - print("not bot_name!!!!!!!!!!!!!!!!!!!!!!") - except Exception as e: - usys.print_exception(e) - try: - if self.ai_OTA.min_sys_ota()==1: - #if 0: - self.AI_TTS_str = "检测到有新版本需要升级啦!升级时可千万别断电或乱按哦,升级完成后设备会自动重启,重启就代表升级成功" - EventMesh.publish("publish_AI_btnInfo",{"func":self.AI_VC_start}) - # if self.ai_OTA.min_sys_ota()==2: - # self.AI_TTS_str = "检测到有新版本需要升级啦!电量低于40%,无法保证升级正常执行,请充满电后重启设备再次升级!" - # EventMesh.publish("publish_AI_btnInfo",{"func":self.AI_VC_start}) - else: - try: - self.ai_OTA.ota_result() - self.ai_OTA.pots_ICCID() - except Exception as e: - usys.print_exception(e) - #开机提示语,如果联网失败,直接提示信号弱 - - #"voice":{"女":"柒妹妹-huoshan::zh_female_wanwanxiaohe_moon_bigtts","男":"柒先生-huoshan::zh_male_wennuanahu_moon_bigtts","ç«¥":"柒乐乐huoshan::ICL_zh_female_huoponvhai_tob","广东":"柒先生-huoshan::zh_female_wanqudashu_moon_bigtts","四川":"柒妹妹-huoshan::zh_female_daimengchuanmei_moon_bigtts","个性":"柒先生-zh_male_sunwukong_mars_bigtts"} - #EventMesh.publish("get_storage_config",["powerRestart",1]) - powerRestart = EventMesh.publish("get_storage_config","powerRestart")#=1非正常重启 - if powerRestart == None: - powerRestart = 0 - if powerRestart == 1: - EventMesh.publish("set_storage_config",["powerRestart",0]) - - else: - - 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}) - - - - except Exception as e: - usys.print_exception(e) - - - def post_processor_after_instantiation(self): - pass - def get_AI_audio_queue(self, event, msg): - return self.AI_audio_queue - def get_VC_satrt_flag(self, event, msg): - return self.VC_satrt_flag - - - def VC_30S_timer_cb(self, *args): # - EventMesh.publish("publish_AI_btnInfo",{"func":self.VC_30S_timer_cb_}) - - def VC_30S_timer_cb_(self): - self.get_config_timer_count += 1 - if self.get_config_timer_count >= 2*60*2:#2小时更新配置参数 - self.get_config_timer_count = 0 - try: - self.http_get_config()#获取/更新配置参数 - except Exception as e: - usys.print_exception(e) - #提交错误id - def ud_error(self,error_data): - response = None - if self.is_up_error == 1: - try: - # currentVersion = versions.Build_Time - # currentVersion = "7PIN-"+currentVersion[:10]+"-"+currentVersion[11:-3] - url = "http://{}/health?task_id={}".format(self.server_ip,error_data[0]+error_data[1]) - print(url) - response = request.get(url,timeout=5) - if response.status_code == 200: - - print("ud_error:ok") - else: - print("ud_error error!!!!") - for i in response.text: - print(i) - response.close() - except Exception as e: - usys.print_exception(e) - if response != None: - response.close() - #获取配置参数 - def http_get_config(self, event=None, msg=None): - print("http_get_config") - - response = None - #http://180.184.206.142/bz-api/dev/config?deviceId=xxx - try: - url = "http://dmp.raisound.com/bz-api/dev/config/{}".format(modem.getDevImei()) - print(url) - response = request.get(url,timeout=5) - if response.status_code == 200: - data = response.json() - print("http_get_config:{}".format(data)) - - if data: - try: - if data["code"] == 20000:#有配置 - if data["data"] : - if "version" in data["data"]: - config_version = EventMesh.publish("get_storage_config","config_version")#音量配置 - if config_version != data["data"]["version"]: - config_version = data["data"]["version"] - EventMesh.publish("set_storage_config",["config_version",config_version]) - if "VC_TTS_voice_type" in data["data"]: - self.VC_TTS_voice_type = data["data"]["VC_TTS_voice_type"] - EventMesh.publish("set_storage_config",["VC_TTS_voice_type",self.VC_TTS_voice_type]) - print("配置VC_TTS_voice_type成功") - if "server_ip" in data["data"]: - self.server_ip = data["data"]["server_ip"] - EventMesh.publish("set_storage_config",["server_ip",self.server_ip]) - print("配置server_ip成功") - if "power_on_tone" in data["data"]: - self.power_on_tone = data["data"]["power_on_tone"] - EventMesh.publish("set_storage_config",["power_on_tone",self.power_on_tone]) - print("配置power_on_tone成功") - - except Exception as e: - usys.print_exception(e) - else: - print("status_code:{}".format(response.status_code)) - print("http_get_config:error!!!!!!!!!!") - response.close() - except Exception as e: - usys.print_exception(e) - if response != None: - response.close() - - def audio_cb(self,event): - if event == 0: - self.audio_play_state =1 - #EventMesh.publish("set_audio_state", 1) - print('audio-play start.') - elif event == 7: - self.audio_play_state = 0 - #EventMesh.publish("set_audio_state", 0) - print('audio-play finish.!!!!!!') - - def AI_key_press(self, event, msg):#按键按下 - print("AI_key_press") - self.get_config_timer_count = 0 - self.key_state = 1 - #self.aud.aud_tone_play(10,200)#播放按键音 - self.AI_TTS_str = ""#"你好,有什么吩咐" - self.AI_ASR_str = "" - self.AI_ASR_str_tmp = "" - self.VC_state = VC_State_None - # if self.VC_state != VC_State_None: - # EventMesh.publish("publish_AI_btnInfo",{"func":self.Close}) - # EventMesh.publish("publish_AI_btnInfo",{"func":utime.sleep_ms,'data':(10)}) - #if self.VC_record_state_flag >1:#如果在录音,就先停止录音 - self.VC_Speech_End() - - self.VC_Speech_Start() - self.AI_VC_start() - # 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}) - #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}) - - 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}) - - - #self.VC_Speech_End() - def AI_key_long_press(self, event, msg):#按键长按 - print("AI_key_long_press") - self.AI_key_long_press_flag = 1 - - def pwk_key_release(self, event, msg):#电源键短按,关闭 - print("pwk_key_release") - EventMesh.publish("publish_AI_btnInfo",{"func":self.Close}) - - def key_prompt(self): - EventMesh.publish("audio_montage_play",["key_prompt.mp3"]) - #self.aud.play(1,1,'U:/static/key_prompt.mp3')#提示请您按住中间的按钮开始讲话,讲完松开即可 - 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: - - #self.VC_state = VC_State_SpeechStart - print("VC_Speech_Start VC_record_state_flag:{} self.AI_ASR_flag:{}!!!!!!!!".format(self.VC_record_state_flag,self.AI_ASR_flag)) - if self.AI_ASR_flag != 0: - 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,()) - _thread.stack_size(8*1024) - print("self.VC_record_thread_id:{}".format(self.VC_record_thread_id)) - try: - - if self.VC_record_TYPE == VC_record_TYPE_AMR : - try : - self.record.stream_start(audio.Record.AMRNB, self.VC_record_samplerate, 0) - except Exception as e: - usys.print_exception(e) - elif self.VC_record_TYPE == VC_record_TYPE_PCM: - print("record_pcm.stream_read_start()!!!!!!!!!!!!") - self.record.stream_start(audio.Record.WAV, self.VC_record_samplerate, 0) - # if self.record_pcm != None: - # try: - # self.record_pcm.stream_stop() - # self.record_pcm.close() - # self.record_pcm = None - # except Exception as e: - # usys.print_exception(e) - # if self.record_pcm == None: - # ret = self.record_pcm = audio.Audio.PCM(0,1,16000,0,1,2) - # print("audio.Audio.PCM:ret:{}".format(ret)) - # ret = self.record_pcm.stream_read_start() - # print("self.record_pcm.stream_read_start:ret:{}".format(ret)) - except Exception as e: - usys.print_exception(e) - - 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) - - #停止录音 - def VC_Speech_End(self): - try: - self.AI_ASR_flag = 0 - self.AI_ASR_str_tmp = "" - self.AI_ASR_str = "" - #EventMesh.publish("publish_AI_btnInfo",{"func":self.websocket_deconnect_asr}) - - if self.VC_record_state_flag == 0: - return - #self.AI_client_asr_StopTranscription_requset()#请求停止 - if self.VC_record_TYPE == VC_record_TYPE_AMR: - self.record.stream_stop() - self.record.stop()#关闭录音 - Record_read_buf = bytearray(self.Audio_buf_size) - for i in range(10): - Record_len = self.record.stream_read(Record_read_buf, self.Audio_buf_size) - print("Record_len:!!!!!!{}".format(Record_len)) - if Record_len <= 0: - break - elif self.VC_record_TYPE == VC_record_TYPE_PCM: - self.record.stream_stop() - self.record.stop()#关闭录音 - Record_read_buf = bytearray(self.Audio_buf_size) - for i in range(10): - Record_len = self.record.stream_read(Record_read_buf, self.Audio_buf_size) - print("Record_len:!!!!!!{}".format(Record_len)) - if Record_len <= 0: - break - # if self.record_pcm != None: - # try: - # self.record_pcm.stream_stop() - # self.record_pcm.close() - # self.record_pcm = None - # except Exception as e: - # usys.print_exception(e) - except Exception as e: - usys.print_exception(e) - 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)) - #关闭录音线程 - def VC_record_thread_close(self): - if self.VC_record_thread_id != 0: - count =50 - while True: - count -= 1 - if self.VC_record_thread_lock == 1: - self.VC_record_thread_lock = 2 - if self.VC_record_thread_lock == 0 or count <=0: - break - else: - print("VC_record_thread_thread going:{}...".format(count)) - utime.sleep_ms(1) - self.VC_record_thread_lock = 0 - print("VC_record_thread_thread_close") - try: - _thread.stop_thread(self.VC_record_thread_id) - except Exception as e: - usys.print_exception(e) - self.VC_record_thread_id = 0 - #获取录音数据 - def VC_record_thread(self): - ##return - print("VC_record_thread start!!!!!!!!!!!!!!!!!!!!\r\n") - count = 0 - # try: - # uos.remove('/usr/test.pcm') - # except Exception as e: - # usys.print_exception(e) - #record_data_queue = Queue(100) - #fd = open('/usr/test.pcm','w') - # if self.VC_record_TYPE == 1: - # h_data= [0x23,0x21 ,0x41 ,0x4D ,0x52 ,0x0A ] - # h_data_b = bytes(h_data) - # self.AI_client_VC_send(h_data_b) - AI_record_tmp_queue_len = 0 - while True: - try: - if self.VC_record_thread_lock == 2: - break - self.VC_record_thread_lock = 1 - # 死循环接收数据 - #if self.VC_state == VC_State_SpeechStart: - Record_read_buf = bytearray(self.Audio_buf_size) - - 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) - - else : - - Record_len = self.record.stream_read(Record_read_buf, self.Audio_buf_size) - utime.sleep_ms(600) - - #Record_len = 1024*2 - #print("VC_record_thread:{}".format(Record_len)) - if Record_len > 0: - read_buf = bytes(Record_read_buf[:Record_len]) - if self.record_data_save_flag == 1: - if self.record_fd == None: - try: - uos.remove('/usr/record_data.pcm') - except Exception as e: - usys.print_exception(e) - self.record_fd = open('/usr/record_data.pcm','w') - if self.record_fd != None: - self.record_fd.write(read_buf) - print("write record:{}".format(len(read_buf))) - # count+=Record_len - # 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) - AI_record_tmp_queue_len += len(read_buf) - else: - AI_record_tmp_queue_len = 0 - while True: - if self.AI_record_tmp_queue.empty() == True: - break - else: - self.AI_client_VC_input_audio_buffer_append(self.AI_record_tmp_queue.get()) - #self.AI_client_asr_send(self.AI_record_tmp_queue.get()) #发送之前存的数据 - #self.AI_client_asr_send(read_buf) - self.AI_client_VC_input_audio_buffer_append(read_buf) - #print("VC_record_thread:{}".format(len(read_buf))) - #count+=len(read_buf) - # if count>=500*1024:#结束 - # self.AI_client_VC_end_speech() - # break - # count+=1 - # if count %10 == 0: - # print("VC_record_thread on line {} asr recv :{} send:{}".format(self.VC_record_state_flag,_thread.threadIsRunning(self.AI_client_asr_recv_id),_thread.threadIsRunning(self.AI_VC_send_data_queue_thread_id))) - - # if self.VC_state >= VC_State_SpeechEnd: - # break - - except Exception as e: - usys.print_exception(e) - #break - self.VC_record_thread_lock = 0 - utime.sleep_ms(100) - #fd.close() - print("VC_record_thread:exit") - self.VC_record_thread_id = 0#线程退出 - self.VC_record_thread_lock = 0 -###################################################### VC ################################################################################### - def websocket_connect_VC(self): - print("websocket_connect_VC:{} e:{}!!!!!!!!!!!!!!!!!!!!!".format(self.AI_client_VC_isconnect,self.AI_client_VC_debug)) - if self.AI_client_VC_isconnect == 1: - return - # 创建VC客户端 - try: - signal = net.csqQueryPoll() - if signal == -1 or sim.getStatus() != 1:#网络正常 - self.websocket_error() - return - try: - if "bot_name" in self.VC_TTS_voice_type[self.VC_TTS_voice_key]: - self.bot_name = self.VC_TTS_voice_type[self.VC_TTS_voice_key]["bot_name"] - else: - print("not bot_name!!!!!!!!!!!!!!!!!!!!!!") - except Exception as e: - usys.print_exception(e) - - # Headers = {'X-NLS-Token':'0c8b8f05a46f423096be64a9c4c46310'} - # self.AI_client_VC = uwebsocket.Client.connect('wss://nls-gateway-cn-beijing.aliyuncs.com/ws/v1',headers=Headers, debug=False) - - url="ws://ws.coze.cn/v1/chat?bot_id=7462617881076351002" - url="ws://ws.coze.cn/v1/chat?bot_id=7486697248416989193" - - print("VC VC:url{}".format(url)) - Headers = {"Authorization":"Bearer pat_PtSpw6ODvy7nDm2NZQsnFzbArzOji5Hev09VfZSLFWBkMXuFrXmAriqlXw5h0I6i"} - self.AI_client_VC = uwebsocket.Client.connect(url, headers=Headers,debug=True) - #self.AI_WS_connect_Queue.put(self.AI_client_VC) - - - print("websocket_connect_VC:OK!!!!!!!!!!!!!!!!!!!!!") - except Exception as e: #网络连接异常 - usys.print_exception(e) - print("websocket_connect_VC error!!!\r\n") - str_error = str(e) - if str_error.find("[Errno 22] EINVAL")!= -1: - print("websocket_connect_VC:str_error:{}".format(str_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") - self.websocket_error() - EventMesh.publish("set_storage_config",["powerRestart",1])#调试临时关闭 - utime.sleep_ms(1000) - self.aud.stopPlayStream() - self.aud.stopAll() - Power.powerRestart() - - self.websocket_error() - return - #print("AI_client_VC:{}".format(self.AI_client_VC)) - if self.AI_client_VC == None: - EventMesh.publish("update_dev_token")#获取token - self.websocket_error() - return - self.AI_client_VC_debug+=1 - utime.sleep_ms(10) - #self.AI_client_VC.settimeout(5) - #self.AI_VC_send_data_queue_thread_close()#关闭发送线程 - if self.AI_VC_send_data_queue_thread_id == 0: - _thread.stack_size(self.Audio_buf_size+8*1024) - self.AI_VC_send_data_queue_thread_id = _thread.start_new_thread(self.AI_VC_send_data_queue_thread, ()) - _thread.stack_size(8*1024) - print("AI_VC_start :AI_VC_send_data_queue_thread_id :{} ".format(self.AI_VC_send_data_queue_thread_id)) - self.AI_client_VC_recv_thread_close()#关闭读线程 - # 线程接收数据 - _thread.stack_size(self.Audio_buf_size+8*1024) - self.AI_client_VC_recv_id = _thread.start_new_thread(self.AI_client_VC_recv, (self.AI_client_VC,)) - _thread.stack_size(8*1024) - self.AI_client_VC_isconnect = 1 - print("websocket_connect_VC end") - - def websocket_error(self,TTS_str=None): - print("websocket_error1!!!!") - self.Close() - print("websocket_error1.1!!!!") - print("websocket_error!!!!") - print("websocket_error!!!!") - self.VC_Thinking_timerout = 0 - self.VC_satrt_flag = 0 - self.AI_TTS_str = "" - self.AI_ASR_str = "" - self.AI_ASR_str_tmp = "" - self.AI_ASR_flag = 0 - self.VC_Speech_End() - EventMesh.publish("close_led") - if TTS_str == None: - self.websocket_error_count+=1 - # if self.websocket_error_count <=3: - # EventMesh.publish("audio_montage_play",["xinhaoruo1.mp3"]) - if self.websocket_error_count <10 : - EventMesh.publish("audio_montage_play",["xinhaoruo1.mp3"]) - elif self.websocket_error_count >=10: - EventMesh.publish("paly_iccid_imei") - # else: - # EventMesh.publish("audio_montage_play",["R_SIM_FAILE.mp3"]) - #self.aud.play(1,1,'U:/static/R_SIM_FAILE.mp3') - if self.websocket_error_count <3 : - utime.sleep_ms(3000) - EventMesh.publish("publish_AI_btnInfo",{"func":self.AI_VC_start}) - else: - print("websocket_error:tts:{}".format(TTS_str)) - self.AI_TTS_str = TTS_str - EventMesh.publish("publish_AI_btnInfo",{"func":self.AI_VC_start}) - print("websocket_error2") - - - print("websocket_error4") - - - def websocket_deconnect_VC(self): - #print("websocket_deconnect_VC {}!!!!!!!".format(self.AI_client_VC_isconnect)) - print("websocket_deconnect_VC!!!!!!!") - self.AI_client_VC_recv_thread_close()#关闭读线程 - self.AI_client_VC_recv_id = 0 - if self.AI_client_VC_isconnect == 1 or self.AI_client_VC!=None: - try: - self.AI_client_VC_isconnect = 0 - count = 500 - while True:#等待发完数据 - count-=1 - if count <=0 or self.AI_VC_send_data_queue_thread_lock == 0: - break - utime.sleep_ms(1) - - try: - self.AI_client_VC.close() - self.AI_client_VC_debug -=1 - #self.AI_client_VC=None - except Exception as e: - usys.print_exception(e) - try : - self.AI_client_VC.close() - self.AI_client_VC_debug -=1 - #self.AI_client_VC=None - except Exception as e: - usys.print_exception(e) - try : - self.AI_client_VC._close() - except Exception as e: - usys.print_exception(e) - self.AI_client_VC = None - except Exception as e: - usys.print_exception(e) - print("websocket_deconnect_VC {}!!!!!!!".format(self.AI_client_VC_isconnect)) - #websocket发送ping - def AI_client_VC_ping(self): - pass - 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") - - #websocket发送数据 - def AI_client_VC_send(self,data_str): - # if isinstance(data_str, str):#是字符串 - # print("AI_client_VC_send:{}".format(data_str)) - # pass - # else: - # print("AI_client_VC_send:len{}".format(len(data_str))) - self.AI_VC_send_data_queue.put([AI_client_VC_num,data_str]) - #关闭数据发送线程 - def AI_VC_send_data_queue_thread_close(self): - if self.AI_VC_send_data_queue_thread_id != 0: - count =500 - while True: - count -= 1 - if self.AI_VC_send_data_queue_thread_lock == 0 or count <=0: - break - else: - self.AI_VC_send_data_queue_thread_lock = 2 - print("AI_VC_send_data_queue_thread going:{}...".format(count)) - utime.sleep_ms(1) - if self.AI_VC_send_data_queue.empty()!=True: - self.AI_VC_send_data_queue.clear() - self.AI_VC_send_data_queue_thread_lock = 0 - print("AI_VC_send_data_queue_thread_close") - try: - _thread.stop_thread(self.AI_VC_send_data_queue_thread_id) - except Exception as e: - usys.print_exception(e) - self.AI_VC_send_data_queue_thread_id = 0 - #发送数据队列 - def AI_VC_send_data_queue_thread(self): - print("AI_VC_send_data_queue_thread:start") - count_t = 0 - while True: - if self.AI_VC_send_data_queue_thread_lock == 2: - print("AI_VC_send_data_queue_thread,该退出了") - break - if self.AI_VC_send_data_queue.empty() :#不能去掉,去掉会卡死 - self.AI_VC_send_data_queue_thread_lock = 0 - count_t+=1 - # if count_t%200 == 0: - # print("self.AI_VC_send_data_queue.empty") - utime.sleep_ms(1) - else: - #data[0]是websocket连接对象编号,data[1]是数据 - #print("AI_VC_send_data_queue_thread:get") - - self.AI_VC_send_data_queue_thread_lock = 1 - data = self.AI_VC_send_data_queue.get() - - - #print("AI_VC_send_data_queue_thread:num{} len{}".format(data[0],len(data[1]))) - if data != None: - try: - #data["func"](data["data"]) - # 发送数据 - #bytes_data = bytes(data[1]) - #data[0].send(data[1]) - #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):#是字符串 - if len(data[1])<900: - print("VC VC: send_data:{}".format(data[1])) - else: - print("VC VC: send_data:{}".format(len(data[1]))) - pass - #print("VC VC: send_data:{}...".format(data[1][:300])) - #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: send_data end") - - #print("VC: send_data end") - except Exception as e: - print("DeviceInfo_queue_thread:ERROR:{}".format(e)) - usys.print_exception(e) - if data[0] == AI_client_VC_num: - #self.websocket_error() - pass - - - try: - if self.AI_client_VC_isconnect != 0: - print("VC发送数据错误,退出") - EventMesh.publish("publish_AI_btnInfo",{"func":self.websocket_error,"data":"VC发送出错了,请重试"}) - self.ud_error(["VC",self.VC_taskid]) - except Exception as e: #网络连接异常 - usys.print_exception(e) - - utime.sleep_ms(1) - self.AI_VC_send_data_queue_thread_lock = 0 - #VC关闭读线程 - def AI_client_VC_recv_thread_close(self): - if self.AI_client_VC_recv_id != 0: - count =500 - while True: - count -= 1 - if self.AI_client_VC_recv_lock == 1: - self.AI_client_VC_recv_lock = 2 - if self.AI_client_VC_recv_lock == 0 or count <=0: - break - else: - print("AI_client_VC_recv_thread going:{}...".format(count)) - utime.sleep_ms(1) - self.AI_client_VC_recv_lock = 0 - print("AI_client_VC_recv_thread_close") - try: - _thread.stop_thread(self.AI_client_VC_recv_id) - except Exception as e: - usys.print_exception(e) - self.AI_client_VC_recv_id = 0 - #Ai VC websocket返回数据 - def AI_client_VC_recv(self,cli): - count = 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 - utime.sleep_ms(1) - if self.VC_state < VC_State_TTSStart: - utime.sleep_ms(1) - recv_data = cli.recv() - if self.AI_client_VC_recv_lock == 2: - print("AI_client_VC_recv 该退出了") - break - self.AI_client_VC_recv_lock = 1 - self.close_timerout = 0#服务器有返回清零退出时间 - if recv_data == "websocket close": - # 服务器关闭连接 - print("VC 服务器关闭连接!!!!!!!!!!!!!!!!!!!!!!!!!!!") - #self.AI_client_VC_isconnect = 0 - #self.websocket_deconnect_VC() - #EventMesh.publish("publish_AI_btnInfo",{"func":self.websocket_deconnect_asr}) - # #EventMesh.publish("publish_AI_btnInfo",{"func":utime.sleep_ms,'data':(1500)}) - #EventMesh.publish("publish_AI_btnInfo",{"func":self.websocket_connect_asr}) - EventMesh.publish("publish_AI_btnInfo",{"func":self.websocket_error,"data":"VC连接断开了,请重试"}) - self.ud_error(["VC",self.VC_taskid]) - break - elif recv_data == "":#客户端关闭连接 - print("VC VC :客户端关闭连接") - EventMesh.publish("publish_AI_btnInfo",{"func":self.websocket_error,"data":"VC连接断开了,请重试"}) - self.ud_error(["VC",self.VC_taskid]) - break - try: - self.websocket_error_count = 0 - if isinstance(recv_data, str):#返回的是字符串 - if len(recv_data)<800: - print("VC VC:recv_data:{}".format(recv_data)) - else: - print("VC VC:recv_data long :{}".format(recv_data[:300])) - jsload_data = ujson.loads(recv_data) - #print("AI_client_VC_recv jsload_data = {}".format(jsload_data)) - - if jsload_data["event_type"] == "chat.created" :#会话开始 - self.AI_client_VC_start_requset() - self.AI_client_VC_send_speech()#开始上传语音 - elif jsload_data["event_type"] == "chat.updated" :#会话开始 - print("VC:Started!!!!!!!!\r\n") - print("VC:Started!!!!!!!!\r\n") - print("VC:Started!!!!!!!!\r\n") - - #self.AI_client_VC_send_speech()#开始上传语音 - elif jsload_data["event_type"] == "conversation.audio_transcript.update" :#音频转译 - self.VC_Speech_end_timerout = 2 - # self.AI_ASR_str = jsload_data["data"]['content'] - # if self.AI_ASR_str.find("。") != -1 or self.AI_ASR_str.find("?") != -1 or self.AI_ASR_str.find("!") != -1: - # self.VC_Speech_end_timerout = 0 - # self.AI_client_VC_end_speech()#发送说话终止 - - elif jsload_data["event_type"] == "conversation.chat.created" :#开始对话 - self.open_play_flag = 0 - 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') - - elif jsload_data["event_type"] == "conversation.message.delta":#返回大模型回答数据 - if self.open_play_flag == 0: - EventMesh.publish("publish_AI_btnInfo",{"func":self.VC_Play_Start})#打开播放 - self.open_play_flag =1 - elif jsload_data["event_type"] == "conversation.audio.delta":#下发音频数据 - - audio_data = ubinascii.a2b_base64(jsload_data["data"]['content']) - print("下发音频数据1:{}".format(len(audio_data))) - EventMesh.publish("publish_AI_btnInfo",{"func":self.put_record_data,"data":[audio_data,""]}) - if self.play_data_save_flag == 1: - if self.play_fd !=None: - self.play_fd.write(audio_data) - elif jsload_data["event_type"] == "conversation.audio.completed":#结束播放 - if self.play_data_save_flag == 1: - if self.play_fd !=None: - print("输出音频文件关闭") - self.play_fd.close() - elif jsload_data["event_type"] == "conversation.chat.completed":#对话结束 - self.LocalRespondingEnded_timerout = 8 - - # 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) - - # pass - # else: - # pass - - # elif jsload_data["event"] == "SpeechEnded" :#服务器下发ASR说话结束 - # self.VC_state = VC_State_SpeechEnd - # elif jsload_data["event"] == "RespondingContent" :#chat回答 - # pass - - # 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_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') - - # pass - # elif jsload_data["event"] == "RespondingEnded" :#音频下发结束 - # #if self.VC_state == VC_State_TTSStart: - - # 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()#开始上传语音 - # pass - else:#下发音频数据 - #self.AI_ASR_str = ""#下发音频后清掉asr结果 - - 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: - #self.put_record_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: - #print("VC VC:recv TIMEDOUT 正常") - pass - else: - usys.print_exception(e) - #self.websocket_error() - print("VC VC :读数据报错,退出") - EventMesh.publish("publish_AI_btnInfo",{"func":self.websocket_error,"data":"VC出错了,请重试"}) - self.ud_error(["VC",self.VC_taskid]) - break - self.AI_client_VC_isconnect = 0 - self.AI_client_VC_recv_id = 0 - self.AI_client_VC_recv_lock = 0 - print("AI_client_VC_recv END!!!!!!!!!!!!!!!!!!!!!!!!!!!") - def put_record_data(self,data): - #print("下发音频数据1:{}".format(len(data[0]))) - 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 - try: - if isinstance(text, str): - if text.find("声音") != -1 and text.find("改") != -1: - 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]) - # EventMesh.publish("audio_montage_play",["peizhichenggong.mp3"]) - #self.aud.play(1,0,'U:/static/peizhichenggong.mp3')#切换成功 - 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]) - # EventMesh.publish("audio_montage_play",["peizhichenggong.mp3"]) - #self.aud.play(1,0,'U:/static/peizhichenggong.mp3')#切换成功 - 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]) - # EventMesh.publish("audio_montage_play",["peizhichenggong.mp3"]) - #self.aud.play(1,0,'U:/static/peizhichenggong.mp3')#切换成功 - 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]) - # EventMesh.publish("audio_montage_play",["peizhichenggong.mp3"]) - #self.aud.play(1,0,'U:/static/peizhichenggong.mp3')#切换成功 - 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]) - # EventMesh.publish("audio_montage_play",["peizhichenggong.mp3"]) - #self.aud.play(1,0,'U:/static/peizhichenggong.mp3')#切换成功 - 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]) - # EventMesh.publish("audio_montage_play",["peizhichenggong.mp3"]) - #self.aud.play(1,0,'U:/static/peizhichenggong.mp3')#切换成功 - 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]) - # EventMesh.publish("audio_montage_play",["peizhichenggong.mp3"]) - #self.aud.play(1,0,'U:/static/peizhichenggong.mp3')#切换成功 - 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]) - # EventMesh.publish("audio_montage_play",["peizhichenggong.mp3"]) - #self.aud.play(1,0,'U:/static/peizhichenggong.mp3')#切换成功 - - return 0 - if text.find("音量") != -1: - if text.find("加") != -1 : - self.VC_TTS_volume += 10 - if self.VC_TTS_volume > 100: - #EventMesh.publish("audio_montage_play",["yinliangyizuida.mp3"]) - #self.aud.play(1,0,'U:/static/yinliangyizuida.mp3')#音量已最大 - 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]) - #EventMesh.publish("audio_montage_play",["peizhichenggong.mp3"]) - #self.aud.play(1,0,'U:/static/peizhichenggong.mp3')#配置成功 - 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]) - #EventMesh.publish("audio_montage_play",["peizhichenggong.mp3"]) - #self.aud.play(1,0,'U:/static/peizhichenggong.mp3')#配置成功 - self.AI_TTS_str = "配置成功,当前音量 {}".format(self.VC_TTS_volume) - 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)<12 and (text.find("再见") != -1 or text.find("拜拜") != -1): - EventMesh.publish("publish_AI_btnInfo",{"func":self.Close}) - return 1 - except Exception as e: - usys.print_exception(e) - return -1 - #获取trace_id - def get_trace_id(self): - t = utime.mktime(utime.localtime()) - t = t*1000+urandom.randint(0, 1000) - md5_data = "{}".format(t)#md5签名 - sign_data = "" - hash_obj = uhashlib.md5(md5_data) - res = hash_obj.digest() - - # 转成十六进制表示 - sign_data = ubinascii.hexlify(res) - sign_data = sign_data.decode('ascii') - return sign_data - - def get_session_id(self,data = "session_id"): - t = utime.mktime(utime.localtime()) - t = t*1000+urandom.randint(0, 1000) - md5_data = "{}{}".format(data,t)#md5签名 - sign_data = "" - hash_obj = uhashlib.md5(md5_data) - res = hash_obj.digest() - - # 转成十六进制表示 - sign_data = ubinascii.hexlify(res) - sign_data = sign_data.decode('ascii') - return sign_data - - def get_new_message_id(self): - message_id = self.get_trace_id()+"aaa"+self.get_trace_id() - self.VC_message_id=message_id[:32] - return self.VC_message_id - def get_new_task_id(self): - task_id = self.get_trace_id()+"aaa"+self.get_trace_id() - self.VC_task_id=task_id[:32] - return self.VC_task_id - #开始播放声音 - def VC_Play_Start(self): - self.tts_in_data_len = 0 - self.tts_out_data_len = 0 - 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,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 - self.VC_Play_flag = 1 - except Exception as e: - self.VC_Play_End() - usys.print_exception(e) - #暂停/继续声音播放 Pause_flag = 1暂停 - def VC_Play_Pause(self,Pause_flag): - try: - if self.VC_play_TYPE == VC_play_TYPE_PCM: - if self.play_pcm != None: - self.play_pcm.stream_pause(Pause_flag) - 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() - self.aud.stopAll() - elif self.VC_play_samplerate == 16000: - if self.play_pcm != None: - print("Close:play_pcm.close()!!!!!!!!!!!!!!!!!!") - try: - self.play_pcm.stream_stop() - self.play_pcm.close() - except Exception as e: - usys.print_exception(e) - self.play_pcm=None - self.aud.stopPlayStream() - self.aud.stopAll() - elif self.VC_play_TYPE == VC_play_TYPE_MP3: - self.aud.stopPlayStream() - self.aud.stopAll() - if self.AI_audio_queue.empty()!=True: - self.AI_audio_queue.clear() - - def _1S_timer_cb(self,*argc): - EventMesh.publish("publish_AI_btnInfo",{"func":self._1S_timer_cb_}) - - def _1S_timer_cb_(self): - - EventMesh.publish("system_sleep_rest")#防止黑屏 - self.close_timerout += 1 - if self.close_timerout > 60:#20秒没数据就close - - if self.VC_state >= VC_State_SpeechIng: - print("接口无响应,超时退出") - EventMesh.publish("publish_AI_btnInfo",{"func":self.websocket_error,"data":"接口超时了。请重试"}) - self.ud_error(["VC",self.VC_taskid]) - else: - EventMesh.publish("publish_AI_btnInfo",{"func":self.Close}) - # print("get_audio_state !!!!!{} {} {}\r\n".format(self.play_end,EventMesh.publish("get_audio_state"),self.play_flag)) - if self.LocalRespondingEnded_timerout>0 :# - self.LocalRespondingEnded_timerout -= 1 - print("LocalRespondingEnded_timerout:{}".format(self.LocalRespondingEnded_timerout)) - if self.LocalRespondingEnded_timerout <= 0 or (self.play_pcm != None and self.play_pcm.stream_is_empty() == 1) :#超时或者音频播放完, - self.LocalRespondingEnded_timerout = 0 - if self.VC_mode == 1 :#长按单次问答模式 - EventMesh.publish("publish_AI_btnInfo",{"func":self.Close}) - else: - EventMesh.publish("publish_AI_btnInfo",{"func":self.VC_Speech_Start})#开始录音 - #通知服务器播放结束 - 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() - 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.VC_Thinking_timerout == 0: - self.VC_Thinking_timerout = 100 - print("Thinking重试,重试!!!!!!!!!!!!!!!!!!!!!") - self.VC_state = VC_State_None - EventMesh.publish("publish_AI_btnInfo",{"func":self.AI_VC_start}) - pass - if self.VC_Speech_end_timerout >0: - self.VC_Speech_end_timerout-=1 - if self.VC_Speech_end_timerout <=0: - self.VC_Speech_end_timerout = 0 - #self.AI_client_VC_end_speech()#发送说话终止 - #VC开始 - def AI_VC_start(self): - print("AI_VC_start1") - self.VC_satrt_flag = 1 - if self.VC_Thinking_timerout < 100: - self.VC_Thinking_timerout = 0 - EventMesh.publish("open_led_all") - self.VC_Play_End()#关闭音频播放 - print("AI_VC_start2") - #self.aud.aud_tone_play(16,200)#播放按键音 - self.LocalRespondingEnded_timerout = 0 - self.close_timerout = 0 - - - # - if self.AI_client_VC_isconnect == 0:#没连接的时候请求开始 - self.websocket_connect_VC()#连接服务器 - - #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("异常状态") - #self.AI_client_VC_RequestToSpeak() - self.websocket_deconnect_VC() - self.websocket_connect_VC()#连接服务器 - self.AI_client_VC_start_requset() - if self.AI_client_VC_isconnect == 0: - return - print("AI_VC_start3") - - self.VC_state = VC_State_None - if self.AI_TTS_str == "":#没有tts要播放的时候才开始录音 - #开始asr录音 - self.VC_Speech_Start() - # pass - print("AI_VC_start4") - - #开始线程 - - # if self.AI_VC_send_data_queue_thread_id == 0: - # _thread.stack_size(self.Audio_buf_size+8*1024) - # self.AI_VC_send_data_queue_thread_id = _thread.start_new_thread(self.AI_VC_send_data_queue_thread, ()) - # _thread.stack_size(8*1024) - # print("AI_VC_start :AI_VC_send_data_queue_thread_id :{} ".format(self.AI_VC_send_data_queue_thread_id)) - - if self.AI_audio_queue_thread_id ==0: - _thread.stack_size(24*1024) - self.AI_audio_queue_thread_id = _thread.start_new_thread(self.AI_audio_queue_thread, ()) - _thread.stack_size(8*1024) - print("AI_VC_start :AI_audio_queue_thread_id :{} ".format(self.AI_audio_queue_thread_id)) - else: - print("AI_VC_start :AI_audio_queue_thread_id != 0 ") - self._1S_timer.start(1000,1,self._1S_timer_cb) - # self.VC_pingping_timerout = 0 - # self.asr_pingping_timerout = 0 - print("AI_VC_start5") - #开始会话 - def AI_client_VC_start_requset(self): - voice="huoshan::zh_male_wennuanahu_moon_bigtts" - try: - voice = self.VC_TTS_voice_type[self.VC_TTS_voice_key]["voice"] - except Exception as e: - usys.print_exception(e) - json_data =\ - { - "id": "event_id", - "event_type": "chat.update", - "data": { - "chat_config": { - "auto_save_history": True, #保存历史记录。默认 true - #"conversation_id": "", #按需配置,conversation_id - "user_id": modem.getDevImei(), #标识当前与智能体的用户,由使用方自行定义、生成与维护。user_id 用于标识对话中的不同用户,不同的 user_id,其对话的上下文消息、数据库等对话记忆数据互相隔离。如果不需要用户数据隔离,可将此参数固定为一个任意字符串 - "meta_data": {}, #附加信息,通常用于封装一些业务相关的字段。查看对话消息详情时,系统会透传此附加信息。 - "custom_variables": {}, #智能体中定义的变量。在智能体prompt中设置变量{{key}}后,可以通过该参数传入变量值,同时支持Jinja2语法。详细说明可参考变量示例。变量名只支持英文字母和下划线。 - "extra_params": {}, #附加参数,通常用于特殊场景下指定一些必要参数供模型判断,例如指定经纬度,并询问智能体此位置的天气。自定义键值对格式,其中键(key)仅支持设置为:latitude:纬度,此时值(Value)为纬度值,例如39.9800718。longitude:经度,此时值(Value)为经度值,例如116.309314。 - "parameters": {"custom_var_1": "测试"} - }, - "input_audio": { #输入音频格式 - "format": "pcm", #输入音频格式,支持 pcm/wav/ogg。默认 wav - "codec": "pcm", #输入音频编码。 pcm/opus。默认 pcm - "sample_rate": 16000, #采样率 - "channel": 1, #通道数 - "bit_depth": 16 #位深 - }, - "output_audio": { #输出音频格式 - "codec": "pcm", - "pcm_config": { - "sample_rate": 16000, #默认 24000 - "frame_size_ms": 200, - "limit_config": { - "period": 1, - "max_frame_num": 6 - } - }, - "speech_rate": 0, #回复的语速,取值范围 [-50, 100],默认为 0,-50 表示 0.5 倍速,100 表示 2倍速 - "voice_id": "7426720361733046281" - }, - "turn_detection": { - "type": "server_vad" - }, - "event_subscriptions": [ - "error", - "input_audio_buffer.speech_started", - "input_audio_buffer.speech_stopped", - "conversation.audio.delta" - ] - } - } - # 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' - self.VC_state = VC_State_None - print("AI_client_VC_start_requset:{}".format(ujson.dumps(json_data))) - 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 , - } - } - #self.AI_client_VC_send(ujson.dumps(json_data)) - self.VC_Speech_Start()#开启线程获取录音数据 - self.VC_state = VC_State_SpeechStart - def AI_client_VC_input_audio_buffer_append(self,data): - json_data = \ - { - "id": "event_id", - "event_type": "input_audio_buffer.append", - "data": { - "delta": ubinascii.b2a_base64(data) - } - } - self.AI_client_VC_send(ujson.dumps(json_data)) - #结束上传语音 - def AI_client_VC_end_speech(self): - json_data = \ - { - "id": "event_id", - "event_type": "input_audio_buffer.complete", - "data": {} - } - self.AI_client_VC_send(ujson.dumps(json_data)) - EventMesh.publish("publish_AI_btnInfo",{"func":self.VC_Speech_End}) - #EventMesh.publish("publish_AI_btnInfo",{"func":self.send_tone}) - - #通知服务器开始播放 - 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 = \ - { - "header":{ - "trace_id":self.get_trace_id(), - "event":"RequestToSpeak" - }, - "payload":{ - "dialog_id":self.VC_dialog_id, - "session_id": self.session_id , - } - } - print("AI_client_VC_RequestToSpeak!!!!!!!!!!!!!!!!!!!!!!!!!!!!!") - 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()#调试临时打开 - 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":"" - } - } - - print("AI_client_VC_RequestToRespond!!!!!!!!!!!!!!!!!!!!!!!!!!!!!") - # 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) - 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_close(self): - print("AI_audio_queue_thread_close1!!!!!!!!!!!!!!!!!!!!!!") - if self.AI_audio_queue_thread_id != 0: - count =500 - while True: - count -= 1 - if self.AI_audio_queue_thread_lock == 0 or count <=0: - break - else: - self.AI_audio_queue_thread_lock = 2 - print("AI_audio_queue_thread going:{}...".format(count)) - utime.sleep_ms(1) - self.AI_audio_queue_thread_lock = 0 - print("AI_audio_queue_thread_close2!!!!!!!!!!!!!!!!!") - try: - _thread.stop_thread(self.AI_audio_queue_thread_id) - except Exception as e: - usys.print_exception(e) - self.AI_audio_queue_thread_id = 0 - # 音频队列 - 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: - print("AI_audio_queue_thread 该退出了") - break - # - count+=1 - if count%500 == 1: - print("AI_audio_queue_thread on") - utime.sleep_ms(1) - #print("AI_audio_queue_thread") - if self.AI_audio_queue.empty() : - self.AI_audio_queue_thread_lock = 0 - - - else: - self.AI_audio_queue_thread_lock = 1 - data = self.AI_audio_queue.get() - self.close_timerout = 0 - if self.play_flag == 0: - self.play_flag =1 - #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] ) - # else: - write_buf = bytearray(data[0]) - #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)) - #ret= self.aud.playStream(1, data[0])#播放音频流 - self.tts_out_data_len += ret - #print("play_pcm.stream_write2:{}".format(self.tts_out_data_len)) - elif self.VC_play_TYPE == VC_play_TYPE_MP3: - tmp= self.aud.playStream(3, data[0])#播放音频流 - - if tmp != 0: - print("2playStream:error tmp:{} data len:{}!!!!!!!!!!!!".format(tmp,len(data[0]))) - # # #播放失败的时候填充WAV头 - # data_len = len(data[0]) - # data_len_b = data_len.to_bytes(4,'little')#数据长度转16进制数组 - # h_data = [ 0x52 ,0x49 ,0x46 ,0x46 #,0x24 ,0x00 ,0x00 ,0x00 #文件标识、文件大小 - # ,0x57 ,0x41 ,0x56 ,0x45 ,0x66 ,0x6D ,0x74 ,0x20 #文件格式、格式块标识符 - # ,0x10 ,0x00 ,0x00 ,0x00 ,0x01 ,0x00 ,0x01 ,0x00 ,0x80 ,0x3E ,0x00 ,0x00 #格式块大小4、音频格式2、声道数2、采样率4 - # ,0x80 ,0x3E ,0x00 ,0x00 ,0x02 ,0x00 ,0x10 ,0x00 ,0x64 ,0x61 ,0x74 ,0x61]#每秒字节数4、数据块对齐2、位深度2、data4 - # h_data_b = bytes(h_data) - # file_len = data_len+len(h_data_b)+4+4 - # file_len_b = file_len.to_bytes(4,'little')#文件长度转16进制数组 - # h_data_b = h_data_b[:4]+file_len_b+h_data_b[4:]+data_len_b - # #self.aud.playStream(2, h_data_b)#播放音频流 - # tmp= self.aud.playStream(2, h_data_b+data[0])#播放音频流 - # print("3playStream:tmp:{} !!!!!!!!!!!!".format(tmp)) - - - mem = gc.mem_free() - #print('1剩余内存RAM:{} KB'.format(mem / 1024)) - except Exception as e: - print("AI_audio_queue_thread:ERROR:") - usys.print_exception(e) - - # if self.VC_state == VC_State_TTSEnd and self.AI_audio_queue.empty() :#self.AI_audio_queue为空且tts下发结束 - # #通知服务器播放结束 - # self.AI_client_VC_LocalRespondingEnded() - except Exception as e: - print("AI_audio_queue_thread:ERROR:") - usys.print_exception(e) - self.AI_audio_queue_thread_lock = 0 - #print("AI_audio_queue_thread:exit") - def factory_mode(self): - print("factory_mode") - EventMesh.publish("publish_AI_btnInfo",{"func":self.Close}) - EventMesh.publish("publish_AI_btnInfo",{"func":self.factory_start}) - def factory_start(self): - self.factory_timer.start(3000, 1, self.factory_timer_cb) - def factory_timer_cb(self, *args, **kwargs): - print("factory_timer_cb play......") - #self.aud.play(1,0,'U:/static/peizhichenggong.mp3')#切换成功 - EventMesh.publish("audio_montage_play",["xinhaoruo1.mp3"]) - - def Close(self): - self.VC_Thinking_timerout = 0 - self.VC_satrt_flag = 0 - self.AI_TTS_str = "" - self.AI_ASR_str = "" - self.AI_ASR_str_tmp = "" - self.AI_ASR_flag = 0 - self.AI_ASR_check_timeout = 0 - self.AI_ASR_error_timeout = 0 - print("ai_VC Close1!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!") - EventMesh.publish("close_led") - 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) - try: - self.AI_VC_send_data_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!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!") - - - self.AI_ASR_timer.stop() - self._1S_timer.stop() - self.factory_timer.stop() - - if self.record_data_save_flag == 1: - if self.record_fd : - self.record_fd.close() - self.record_fd = None - if self.play_data_save_flag == 1: - if self.play_fd !=None: - self.play_fd.close() - print("ai_VC Close3!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!\r\n") - - 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) - - # try: - # while True: - # if self.AI_WS_connect_Queue.empty()!=True: - # AI_WS_connect = self.AI_WS_connect_Queue.get() - # if AI_WS_connect : - # try: - # AI_WS_connect._close() - # AI_WS_connect = None - # except Exception as e: - # usys.print_exception(e) - # else: - # print("websocket链接已为空") - # else: - # break - # except Exception as e: - # usys.print_exception(e) - - def VC_init2(self): - self.VC_init() - - print("ai_VC VC_init2!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!") - try: - self.websocket_deconnect_VC() - except Exception as e: - usys.print_exception(e) - print("ai_VC Close3!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!\r\n") - 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() - def VC_init(self): - - print("VC_init:AI_VC_send_data_queue:size:{}".format(self.AI_VC_send_data_queue.size())) - - - print("VC_init2") - #self.VC_Speech_End() - print("VC_init3") - self.VC_Play_End() - print("VC_init4") - - if self.AI_audio_queue.empty()!=True: - self.AI_audio_queue.clear() - # num = EventMesh.publish("get_volum_size") - # if num == None: - # num = 8 - # self.aud.setVolume(num)#恢复原始音量 - \ No newline at end of file diff --git a/2.sdk/project/7PIN/sdk/services/microPython/ports/quectel/core/ai_VC_G15.py b/2.sdk/project/7PIN/sdk/services/microPython/ports/quectel/core/ai_VC_G15.py deleted file mode 100644 index 7b0ce78e..00000000 --- a/2.sdk/project/7PIN/sdk/services/microPython/ports/quectel/core/ai_VC_G15.py +++ /dev/null @@ -1,3633 +0,0 @@ -from common import Abstract, LogAdapter -import EventMesh -import uwebsocket -import usys -import gc -import urandom -import uhashlib -import ubinascii -import ujson -import osTimer -import _thread -from queue import Queue -import utime -import audio -import uos -from machine import Pin -from machine import ExtInt -from machine import WDT -import modem -import sim -import net -import base64 -import ucryptolib -import urandom as random -import request -import ql_fs -from misc import Power,USB,PowerKey -import ntptime -import machine -import dataCall -import constants -import versions - -dev_type = "G10" -#dev_type = "7PIN_BK"#小瑞 -#dev_type = "7PIN"#柒牌 -#dev_type = 'momo'#食梦貘 -#dev_type = 'sjgq'#四季甘泉 -class AI_led(Abstract): - def __init__(self): - if dev_type == "G10": - self.led_red = Pin(Pin.GPIO36, Pin.OUT, Pin.PULL_PD, 0) - self.led_green = Pin(Pin.GPIO44, Pin.OUT, Pin.PULL_PD, 1) - self.led_blue = Pin(Pin.GPIO21, Pin.OUT, Pin.PULL_PD, 1) - else: - self.led_red = Pin(Pin.GPIO36, Pin.OUT, Pin.PULL_PD, 0) - self.led_green = Pin(Pin.GPIO21, Pin.OUT, Pin.PULL_PD, 1) - self.led_blue = Pin(Pin.GPIO19, Pin.OUT, Pin.PULL_PD, 1) - - #=1 红灯闪,=2白灯闪,=3绿灯闪,=4全部灯闪 - self.led_flicker_flag = 0 - self.led_flicker_on_off_flag = 0 - self.led_flicker_timer = osTimer() - - EventMesh.subscribe("open_led_red",self.open_led_red) - EventMesh.subscribe("open_led_blue",self.open_led_blue) - EventMesh.subscribe("open_led_green",self.open_led_green) - EventMesh.subscribe("open_led_all",self.open_led_all) - EventMesh.subscribe("open_led_red_blue",self.open_led_red_blue) - EventMesh.subscribe("open_led_red_green",self.open_led_red_green) - EventMesh.subscribe("flicker_led_red",self.flicker_led_red) - EventMesh.subscribe("flicker_led_blue",self.flicker_led_blue) - EventMesh.subscribe("flicker_led_green",self.flicker_led_green) - EventMesh.subscribe("flicker_led_all",self.flicker_led_all) - EventMesh.subscribe("close_led",self.close_led) - EventMesh.publish("open_led_red") - - def flicker_led_red(self,event,msg): - self.led_flicker_flag = 1 - self.led_flicker_timer.start(1500, 1, self.led_flicker_timer_cb) - - def flicker_led_blue(self,event,msg): - self.led_flicker_flag = 2 - self.led_flicker_timer.start(1500, 1, self.led_flicker_timer_cb) - - def flicker_led_green(self,event,msg): - self.led_flicker_flag = 3 - self.led_flicker_timer.start(1500, 1, self.led_flicker_timer_cb) - - def flicker_led_all(self,event,msg): - self.led_flicker_flag = 4 - self.led_flicker_timer.start(1500, 1, self.led_flicker_timer_cb) - - def led_flicker_timer_cb(self, *args, **kwargs): - EventMesh.publish("publish_AI_btnInfo",{"func":self.led_flicker_timer_cb_}) - def led_flicker_timer_cb_(self): - if self.led_flicker_flag == 0: - self.led_flicker_timer.stop() - return - if self.led_flicker_on_off_flag == 0: - self.led_red.write(0) - self.led_blue.write(0) - self.led_green.write(0) - self.led_flicker_on_off_flag = 1 - else: - self.led_flicker_on_off_flag = 0 - if self.led_flicker_flag == 1: - self.led_blue.write(0) - self.led_green.write(0) - self.led_red.write(1) - elif self.led_flicker_flag == 2: - self.led_red.write(0) - self.led_green.write(0) - self.led_blue.write(1) - elif self.led_flicker_flag == 3: - self.led_red.write(0) - self.led_blue.write(0) - self.led_green.write(1) - elif self.led_flicker_flag == 4: - self.led_blue.write(1) - self.led_green.write(1) - self.led_red.write(1) - - def open_led_red(self,event,msg): - #print("open_led_red") - self.led_flicker_flag = 0 - #self.led_red.write(0) - self.led_blue.write(0) - self.led_green.write(0) - self.led_red.write(1) - - def open_led_blue(self,event,msg): - #print("open_led_blue") - self.led_flicker_flag = 0 - self.led_red.write(0) - #self.led_blue.write(0) - self.led_green.write(0) - self.led_blue.write(1) - - def open_led_green(self,event,msg): - #print("open_led_green") - self.led_flicker_flag = 0 - self.led_red.write(0) - self.led_blue.write(0) - #self.led_green.write(0) - self.led_green.write(1) - - def open_led_red_blue(self,event,msg): - #print("open_led_blue") - self.led_flicker_flag = 0 - self.led_red.write(1) - #self.led_blue.write(0) - self.led_green.write(0) - self.led_blue.write(1) - - def open_led_red_green(self,event,msg): - #print("open_led_blue") - self.led_flicker_flag = 0 - self.led_red.write(1) - #self.led_blue.write(0) - self.led_green.write(1) - self.led_blue.write(0) - - def open_led_all(self,event,msg): - #print("open_led_all") - self.led_flicker_flag = 0 - #self.led_red.write(0) - self.led_blue.write(1) - self.led_green.write(1) - self.led_red.write(1) - - def close_led(self,event,msg): - #print("close_led") - self.led_flicker_flag = 0 - self.led_red.write(0) - self.led_blue.write(0) - self.led_green.write(0) - -audio_buf = ['chenggong', 'didianguanji', 'IMEIhao', 'jianquancuowu', 'key_prompt', 'liuliangtishi', 'Low_power_warning', 'R_CHARGE_FULL', 'R_CHARGE_IN', 'R_CHARGE_OUT', 'R_READ_TIME_0', 'R_READ_TIME_1', 'R_READ_TIME_2', 'R_READ_TIME_3', 'R_READ_TIME_4', 'R_READ_TIME_5', 'R_READ_TIME_6', 'R_READ_TIME_7', 'R_READ_TIME_8', 'R_READ_TIME_9', 'R_READ_TIME_A', 'R_READ_TIME_B', 'R_READ_TIME_C', 'R_READ_TIME_D', 'R_READ_TIME_E', 'R_READ_TIME_F', 'R_READ_TIME_G', 'R_READ_TIME_H', 'R_READ_TIME_I', 'R_READ_TIME_J', 'R_READ_TIME_K', 'R_READ_TIME_L', 'R_READ_TIME_M', 'R_READ_TIME_N', 'R_READ_TIME_O', 'R_READ_TIME_P', 'R_READ_TIME_Q', 'R_READ_TIME_R', 'R_READ_TIME_S', 'R_READ_TIME_T', 'R_READ_TIME_U', 'R_READ_TIME_V', 'R_READ_TIME_W', 'R_READ_TIME_X', 'R_READ_TIME_Y', 'R_READ_TIME_Z', 'send_tone', 'shouhou', 'xinhaoruo1', 'zhengzaiguanji'] -class AI_dev(Abstract): - # AI - def __init__(self): - 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 - self.KeyAI_timer_count = 0 - self.KeyAI_long_press = 0 - self.KeyAI_press = 0 - if self.is_wdt == 1: - self.wdt = WDT(30) #开启看门狗 - # self.wdt_timer = osTimer() - # self.wdt_timer.start(5000, 1, self.wdt_timer_cb) - count = 0 - while True: - count += 1 - if count > 20 : - break - data = dataCall.getInfo(1, 0) - print("data call INFO {}".format(data)) - if data[2][0]: - self.network_state = 1 - break - print("等待网络 {}...".format(count)) - utime.sleep_ms(500) - self.KeyAI_timer = osTimer() - if dev_type == "G10": - self.extint_AI = ExtInt(ExtInt.GPIO19,ExtInt.IRQ_RISING_FALLING, ExtInt.PULL_PU, self.keyAI_extint_cb) - self.pwk_key = ExtInt(ExtInt.GPIO26, ExtInt.IRQ_RISING_FALLING, ExtInt.PULL_PU, self.pwk_extint_cb) - else: - self.pwk_key = ExtInt(ExtInt.GPIO41, ExtInt.IRQ_RISING_FALLING, ExtInt.PULL_PU, self.pwk_extint_cb) - #self.extint_AI = ExtInt(ExtInt.GPIO19,ExtInt.IRQ_RISING_FALLING, ExtInt.PULL_PU, self.keyAI_extint_cb) - self.extint_AI = ExtInt(ExtInt.GPIO22,ExtInt.IRQ_RISING_FALLING, ExtInt.PULL_PU, self.keyAI_extint_cb) - self.extint_AI.enable() - self.pwk_key_status = 0 - self.pwk_key_timer_count = 0 - self.pwk_key_long_press = 0 - self.pwk_key_press = 0 - self.pwk_key_timer = osTimer() - #self.pwk_key = ExtInt(ExtInt.GPIO26, ExtInt.IRQ_RISING_FALLING, ExtInt.PULL_DISABLE, self.pwk_extint_cb) - - self.pwk_key.enable() - print("AI_dev:1") - self.btnInfo_queue = Queue(100) - self.btnInfo_queue_count = 0 - _thread.stack_size(16*1024) - self.btnInfo_queue_thread_id = _thread.start_new_thread(self.btnInfo_queue_thread, ()) - _thread.stack_size(8*1024) - EventMesh.subscribe("publish_AI_btnInfo",self.publish_AI_btnInfo) - EventMesh.subscribe("get_battery",self.get_battery) - 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) - print("AI_dev:2") - self.pk = PowerKey() - self.pk.powerKeyEventRegister(self.powerKey_callback) - self.usb = USB() - self.usb.setCallback(self.usb_event_cb) - self.usb_status = self.usb.getStatus() - self.usb_charge_flag = 0 - self.Low_power_warning_timer = 0 - self.AI_dev_timer = osTimer() - self.AI_dev_timer.start(10000, 1, self.AI_dev_timer_cb) - print("AI_dev:AI_dev_timer") - self.aud = audio.Audio(0) - self.Low_power_warning_flag = 0 - self.VC_TTS_volume = EventMesh.publish("get_storage_config","VC_TTS_volume")#音量配置 - if self.VC_TTS_volume == None: - self.VC_TTS_volume = 100 - self.aud.setVolume(self.VC_TTS_volume //10) - #self.aud.play(1,0,'U:/static/xianyikaiji.mp3')#开机音频 - #EventMesh.publish("audio_montage_play",["xianyikaiji.mp3"]) - #EventMesh.publish("publish_AI_btnInfo",{"func":self.ntptime_cb}) - self.check_rest_timer_count = 0 - print("AI_dev:end") - def ntptime_cb(self): - #ntptime.settime(8) - print("timer:{}!!!!!!!!\r\n".format(utime.localtime())) - def usb_event_cb(self, state): - EventMesh.publish("publish_AI_btnInfo",{"func":self.usb_event,"data":state}) - - def usb_event(self, state): - status = state - self.usb_charge_flag = 0 - if status == 1:#插入USB - print("charge R_CHARGE_in") - self.usb_status = 1 - VC_satrt_flag = EventMesh.publish("get_VC_satrt_flag")#获取vc是否在运行 - if VC_satrt_flag == None: - VC_satrt_flag = 0 - if VC_satrt_flag == 0: - self.aud.stop() - #EventMesh.publish("flicker_led_red")#充电闪灯 - #self.aud.play(1,1,'U:/static/R_CHARGE_IN.mp3') - EventMesh.publish("open_led_red")#充电红灯常亮 - EventMesh.publish("audio_montage_play",["R_CHARGE_IN.mp3"]) - self.Low_power_warning_flag = 0 - pass - elif status == 0:#拨出usbs - self.usb_status = 0 - VC_satrt_flag = EventMesh.publish("get_VC_satrt_flag")#获取vc是否在运行 - if VC_satrt_flag == None: - VC_satrt_flag = 0 - if VC_satrt_flag == 0: - self.aud.stop() - EventMesh.publish("close_led") - EventMesh.publish("audio_montage_play",["R_CHARGE_OUT.mp3"]) - #self.aud.play(1,1,'U:/static/R_CHARGE_OUT.mp3') - def btnInfo_queue_thread(self): - while True: - data = self.btnInfo_queue.get() - self.btnInfo_queue_count-=1 - #EventMesh.debug_log("Info_queue:data = {}".format(data)) - if data != None: - try: - if "data" in data : - data["func"](data["data"]) - else : - data["func"]() - except Exception as e: - #EventMesh.debug_log("btnInfo_queue:ERROR:{}".format(e)) - usys.print_exception(e) - def publish_AI_btnInfo(self,event,msg): - #print("publish_AI_btnInfo 1") - self.btnInfo_queue.put(msg) - self.btnInfo_queue_count+=1 - if self.btnInfo_queue_count > 80: - self.btnInfo_queue_count =0 - print("事件处理线程队列出问题,重启!!!!!!!!!!!!!!") - print("线程:{} 队列:{}".format(_thread.threadIsRunning(self.btnInfo_queue_thread_id),self.btnInfo_queue.size())) - # if _thread.threadIsRunning(self.btnInfo_queue_thread_id): - # _thread.stop_thread(self.btnInfo_queue_thread_id) - # _thread.stack_size(10*1024) - # self.btnInfo_queue_thread_id = _thread.start_new_thread(self.btnInfo_queue_thread, ()) - # _thread.stack_size(8*1024) - # self.btnInfo_queue.clear() - # self.btnInfo_queue = Queue(100) - EventMesh.publish("VC_error") #播放报错 - utime.sleep_ms(1000) - self.aud.stopPlayStream() - self.aud.stopAll() - Power.powerRestart() - EventMesh.publish("set_storage_config",["powerRestart",1]) - #print("publish_AI_btnInfo 2") - def powerKey_callback(self, status): - print("powerKey_callback:{}".format(status)) - - def pwk_extint_cb(self,args):#pwk - try: - self.pwk_key_status = int(args[1]) - if self.pwk_key_status == 0: - self.pwk_key_status = 1 - else: - self.pwk_key_status = 0 - pass - if self.pwk_key_status == 0:#按下 - - if self.pwk_key_press == 0 : - self.pwk_key.disable() - self.pwk_key_press = 1 - self.pwk_key_long_press = 0 - self.pwk_key_timer.start(100, 1, self.pwk_key_timer_cb) - self.pwk_key_timer_count = 0 - #EventMesh.publish("AI_key_press") - except Exception as e: - usys.print_exception(e) - def pwk_key_timer_cb(self, *args, **kwargs): - # EventMesh.publish("publish_AI_btnInfo",{"func":self.pwk_key_timer_cb_}) - # def pwk_key_timer_cb_(self) : - try: - self.pwk_key_status = self.pwk_key.read_level() - self.pwk_key_timer_count +=1 - if self.pwk_key_timer_count >= 10*3: #长按3s - #print("pwk_key_long_press {}".format(self.pwk_key_long_press)) - if self.pwk_key_long_press == 0: - self.pwk_key_long_press = 1 - #EventMesh.publish("AI_key_long_press") - EventMesh.publish("audio_montage_play",["zhengzaiguanji.mp3"]) - #self.aud.play(1,0,'U:/static/zhengzaiguanji.mp3')#关机音频 - EventMesh.publish("open_led_red") - utime.sleep_ms(2000) - self.aud.stopPlayStream() - self.aud.stopAll() - Power.powerDown() - #print("AI_key_release") - 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)) - key_count = 5 - if dev_type == "7PIN_BK": - key_count = 3 - if self.pwk_key_timer_count >= key_count: #防抖200ms - #EventMesh.publish("AI_key_release") - EventMesh.publish("publish_AI_btnInfo",{"func":self.pwk_key_release}) - self.pwk_key.enable() - self.pwk_key_timer.stop() - self.pwk_key_timer_count = 0 - self.pwk_key_press = 0 - - except Exception as e: - usys.print_exception(e) - - def keyAI_extint_cb(self,args):#call 2 - try: - #print("AI_btn:keyAI_extint_cb{}".format(args[1])) - self.KeyAI_status = int(args[1]) - if self.KeyAI_status == 0: - self.KeyAI_status = 1 - else: - self.KeyAI_status = 0 - - if self.KeyAI_status == 0:#按下 - if self.KeyAI_press == 0 : - EventMesh.publish(constants.EVENT.SYSTEM_UP)#唤醒休眠 - self.extint_AI.disable() - self.KeyAI_press = 1 - self.KeyAI_long_press = 0 - self.KeyAI_timer.start(100, 1, self.KeyAI_timer_cb) - self.KeyAI_timer_count = 0 - #EventMesh.publish("AI_key_press") - if dev_type == "7PIN" : - self.aud.aud_tone_play(10,200)#播放按键音 - EventMesh.publish("publish_AI_btnInfo",{"func":self.AI_key_press}) - except Exception as e: - usys.print_exception(e) - def KeyAI_timer_cb(self, *args, **kwargs): - # EventMesh.publish("publish_AI_btnInfo",{"func":self.KeyAI_timer_cb_}) - # def KeyAI_timer_cb_(self): - try: - self.KeyAI_status = self.extint_AI.read_level() - self.KeyAI_timer_count +=1 - if self.KeyAI_timer_count >= 10*1: #长按3s - if self.KeyAI_long_press == 0: - self.KeyAI_long_press = 1 - #EventMesh.publish("AI_key_long_press") - EventMesh.publish("publish_AI_btnInfo",{"func":self.AI_key_long_press}) - if self.KeyAI_status == 1:#松开 - #print("KeyAI_timer_cb:{}".format(self.KeyAI_timer_count)) - key_count = 5 - if dev_type == "7PIN_BK": - key_count = 3 - if self.KeyAI_timer_count >= key_count: #防抖200ms - #EventMesh.publish("AI_key_release") - EventMesh.publish("publish_AI_btnInfo",{"func":self.AI_key_release}) - self.extint_AI.enable() - self.KeyAI_timer.stop() - self.KeyAI_timer_count = 0 - self.KeyAI_press = 0 - - except Exception as e: - usys.print_exception(e) - - def AI_key_press(self): - self.check_rest_timer_count = 0 - print("AI_key_press") - EventMesh.publish("AI_key_press") - - def AI_key_long_press(self): - self.check_rest_timer_count = 0 - print("AI_key_long_press") - EventMesh.publish("AI_key_long_press") - - def AI_key_release(self): - print("AI_key_release") - EventMesh.publish("AI_key_release") - - def pwk_key_Long_Press(self): - self.check_rest_timer_count = 0 - print("pwk_key_long_press!!!!!!!") - print("pwk_key_long_press!!!!!!!") - - # EventMesh.publish("paly_iccid_imei") - # return - EventMesh.publish("audio_montage_play",["zhengzaiguanji.mp3"]) - #self.aud.play(1,0,'U:/static/zhengzaiguanji.mp3')#关机音频 - EventMesh.publish("open_led_red") - utime.sleep_ms(3000) - self.aud.stopPlayStream() - self.aud.stopAll() - Power.powerDown() - #print("AI_key_release") - EventMesh.publish("pwk_key_long_press") - - def pwk_key_release(self): - self.check_rest_timer_count = 0 - #print("pwk_key_release") - EventMesh.publish("pwk_key_release") - - - def wdt_timer_cb(self, *args, **kwargs): - if self.is_wdt == 1: - self.wdt.feed() - - def AI_dev_timer_cb(self, *args, **kwargs): - #print("AI_dev_timer_cb") - EventMesh.publish("publish_AI_btnInfo",{"func":self.AI_dev_timer_event}) - def AI_dev_timer_event(self): - if self.is_wdt == 1: - self.wdt.feed() - VC_satrt_flag = EventMesh.publish("get_VC_satrt_flag")#获取vc是否在运行 - if VC_satrt_flag == None: - VC_satrt_flag = 0 - Vbatt = Power.getVbatt() - if self.usb_status == 1 and VC_satrt_flag == 0: - EventMesh.publish("open_led_red")#充电红灯常亮 - if self.usb_status == 1 and Vbatt>=self.VBATT_tab["charge_full"]and VC_satrt_flag == 0:#充电充满 - EventMesh.publish("open_led_green") - if self.usb_charge_flag == 0 : - EventMesh.publish("audio_montage_play",["R_CHARGE_FULL.mp3"]) - #self.aud.play(1,0,'U:/static/R_CHARGE_FULL.mp3')#充电已满 - self.usb_charge_flag = 1 - if self.usb_status == 0 and Vbatt= 2: - # self.Low_power_warning_timer = 0 - EventMesh.publish("audio_montage_play",["Low_power_warning.mp3"]) - - if self.usb_status == 0 and Vbatt= 8640:#24小时没按键,则关机 - self.pwk_key_Long_Press() - - def get_battery(self, event=None, msg=None): - Vbatt = Power.getVbatt() - if Vbatt>self.VBATT_tab["90"]: - return 100 - if Vbatt>self.VBATT_tab["80"]: - return 90 - if Vbatt>self.VBATT_tab["60"]: - return 80 - if Vbatt>self.VBATT_tab["40"]: - return 60 - if Vbatt>self.VBATT_tab["20"]: - return 40 - if Vbatt>self.VBATT_tab["10"]: - return 20 - if Vbatt<=self.VBATT_tab["10"]: - return 10 - def audio_montage_play(self,event,msg): - self.aud.stopPlayStream() - self.aud.stopAll() - str_data='mp3files=' - for i in msg: - try: - str_tmp = i.replace(".mp3","") - str_data+="{}.mp3+".format(audio_buf.index(str_tmp)) - except Exception as e: - usys.print_exception(e) - str_data = str_data[:-1] - print("audio_montage_play:{}".format(str_data)) - self.aud.montage_play('U:/static/audio.bin',1,1,str_data) - - def paly_iccid_imei(self,event,msg): - str_data = 'mp3files={}.mp3+'.format(audio_buf.index("liuliangtishi"))#流量提示 - imei = modem.getDevImei() - iccid = sim.getIccid() - print("paly_iccid_imei:ICCID:{}".format(iccid)) - if iccid != -1 and len(iccid) > 5: - iccid = iccid.upper() - if len(iccid) <20: - for i in range(20-len(iccid)): - iccid = "0"+iccid - str_data += '{}.mp3+{}.mp3+{}.mp3+{}.mp3+{}.mp3+{}.mp3+{}.mp3+{}.mp3+{}.mp3+{}.mp3+{}.mp3+{}.mp3+{}.mp3+{}.mp3+{}.mp3+{}.mp3+{}.mp3+{}.mp3+{}.mp3+{}.mp3+'.format(audio_buf.index("R_READ_TIME_{}".format(iccid[0]))\ - ,audio_buf.index("R_READ_TIME_{}".format(iccid[1])),audio_buf.index("R_READ_TIME_{}".format(iccid[2])),audio_buf.index("R_READ_TIME_{}".format(iccid[3])),\ - audio_buf.index("R_READ_TIME_{}".format(iccid[4])),audio_buf.index("R_READ_TIME_{}".format(iccid[5])),audio_buf.index("R_READ_TIME_{}".format(iccid[6])),audio_buf.index("R_READ_TIME_{}".format(iccid[7])),\ - audio_buf.index("R_READ_TIME_{}".format(iccid[8])),audio_buf.index("R_READ_TIME_{}".format(iccid[9])),audio_buf.index("R_READ_TIME_{}".format(iccid[10])),audio_buf.index("R_READ_TIME_{}".format(iccid[11])),\ - audio_buf.index("R_READ_TIME_{}".format(iccid[12])),audio_buf.index("R_READ_TIME_{}".format(iccid[13])),audio_buf.index("R_READ_TIME_{}".format(iccid[14])),audio_buf.index("R_READ_TIME_{}".format(iccid[15])),\ - audio_buf.index("R_READ_TIME_{}".format(iccid[16])),audio_buf.index("R_READ_TIME_{}".format(iccid[17])),audio_buf.index("R_READ_TIME_{}".format(iccid[18])),audio_buf.index("R_READ_TIME_{}".format(iccid[19]))) - str_data += '{}.mp3+'.format(audio_buf.index("shouhou"))#可联系售后解决,联系方式见售后客服电话是400-886-8777或到微信公众号柒牌SEVENBRAND自行充值: - self.aud.montage_play('U:/static/audio.bin',1,1,str_data) - #鉴权出错,播放imei号 - def paly_device_res_error(self,event,msg): - str_data = 'mp3files={}.mp3+'.format(audio_buf.index("jianquancuowu"))#AI功能异常,请联系客户查询,设备号为: - imei = modem.getDevImei() - imei = imei.upper() - str_data += '{}.mp3+{}.mp3+{}.mp3+{}.mp3+{}.mp3+{}.mp3+{}.mp3+{}.mp3+{}.mp3+{}.mp3+{}.mp3+{}.mp3+{}.mp3+{}.mp3+{}.mp3'.format(audio_buf.index("R_READ_TIME_{}".format(imei[0]))\ - ,audio_buf.index("R_READ_TIME_{}".format(imei[1])),audio_buf.index("R_READ_TIME_{}".format(imei[2])),audio_buf.index("R_READ_TIME_{}".format(imei[3])),\ - audio_buf.index("R_READ_TIME_{}".format(imei[4])),audio_buf.index("R_READ_TIME_{}".format(imei[5])),audio_buf.index("R_READ_TIME_{}".format(imei[6])),audio_buf.index("R_READ_TIME_{}".format(imei[7])),\ - audio_buf.index("R_READ_TIME_{}".format(imei[8])),audio_buf.index("R_READ_TIME_{}".format(imei[9])),audio_buf.index("R_READ_TIME_{}".format(imei[10])),audio_buf.index("R_READ_TIME_{}".format(imei[11])),\ - audio_buf.index("R_READ_TIME_{}".format(imei[12])),audio_buf.index("R_READ_TIME_{}".format(imei[13])),audio_buf.index("R_READ_TIME_{}".format(imei[14]))) - #print("str_data:{}".format(str_data)) - self.aud.montage_play('U:/static/audio.bin',1,1,str_data) - -#存储信息 -class getStorageDataManager(Abstract):#获取内存数据 - def __init__(self): - self.config_data = {} - check = ql_fs.path_exists("/usr/static/storage_file/config.json") - if check == True: - with open("/usr/static/storage_file/config.json","r") as fd: - self.config_data = ujson.load(fd) - else : - self.config_data = {'old_time': 0, 'flip_sw': 0} - pass - - def post_processor_after_instantiation(self): - EventMesh.subscribe("set_storage_data", self.set_storage_data) - EventMesh.subscribe("set_storage_config", self.set_storage_config) - EventMesh.subscribe("get_storage_data", self.get_storage_data) - EventMesh.subscribe("get_storage_config", self.get_storage_config) - - def set_storage_data(self, event, msg): - # EventMesh.debug_log("set_storage_data:{}".format(msg)) - if msg != None: - self.config_data = msg - with open("/usr/static/storage_file/config.json",'w+',encoding="utf-8") as fd: - ujson.dump(self.config_data,fd) - - - def set_storage_config(self,event,msg): - # EventMesh.debug_log("set_storage_key_data1:{}".format(msg)) - if len(msg) >= 2: - self.config_data[msg[0]]=msg[1] - # EventMesh.debug_log("set_storage_key_data2:{}".format(self.config_data[msg[0]])) - EventMesh.publish("publish_message_event_ui",{"func":self.set_storage_save,"data":0}) - def set_storage_save(self, data): - with open("/usr/static/storage_file/config.json",'w+',encoding="utf-8") as fd: - ujson.dump(self.config_data,fd) - def get_storage_data(self, event, msg): - # EventMesh.debug_log("get_storage_data:{}".format(self.config_data)) - return self.config_data - def get_storage_config(self,event,msg): - # EventMesh.debug_log("get_storage_key_data1:{}".format(msg)) - b = msg in self.config_data.keys() - if b == True: - # EventMesh.debug_log("get_storage_key_data2:{}".format(self.config_data[msg])) - return self.config_data[msg] - else : - return None - # try: - # return self.config_data[msg] - # except: - # EventMesh.debug_log("get_storage_key_data:none key:{}",msg) - # return None -#设备资源授权平台 -class device_res_author(Abstract): - - def __init__(self) : - print("device_res_author __init__ start !!!!!!!!!!!!!!!!!") - self.deviceId = modem.getDevImei()#"876226002022574" - self.SHA1_BLOCK_SIZE = 64 - self.PAD_BLOCK_SIZE = 16 - self.SHA256 = uhashlib.sha256 - self.pad = lambda s: s + chr(self.PAD_BLOCK_SIZE - len(s) % self.PAD_BLOCK_SIZE) * (self.PAD_BLOCK_SIZE - len(s) % self.PAD_BLOCK_SIZE) - # 除去补16字节的多余字符 - self.unpad = lambda s: s[:-s[-1]] - #K01 - # self.key = b"MWrMZjdtcPhj41jWuoqFAhTmqyFluqj1" - # self.pid = "qAtdDOGXgXYjT2HGFr3a" - #G15 - # self.key = b"3LWfBicxfRZ3ZAqmZCFuvMdGUXdAFWkb" - # self.pid = "qLx4Pu4mSUQxyfVKGLXG" - #7pin - self.key = b"uKLrChwrxA1LklgBc3VwawYjUkbT3BgX" - self.pid = "cqxJZi5CNgzjS3mX21Zw" - - self.dev_res_timer = osTimer() - self.dev_res_timer.start(20000, 1, self.dev_timer_cb) - self.dev_res_timerCount = 0 - self.ud_token_timer = osTimer() - self.ud_token_timer.start(10000, 1, self.ud_token_timer_cb) - self.ud_token_timer_Count = 0 - self.dev_token = None - self.res_error_count = 0 - self.ntptime_flag = 0 - EventMesh.subscribe("get_dev_token", self.get_dev_token) - EventMesh.subscribe("update_dev_token", self.update_dev_token) - EventMesh.subscribe("dev_active", self.dev_active) - EventMesh.subscribe("dev_sign_in", self.dev_sign_in) - EventMesh.subscribe("dev_NTP", self.dev_NTP) - #EventMesh.publish_async("dev_NTP",thread_size = 8192) - - # count = 0 - # while True: - # if self.ntptime_flag == 1: - # break - # utime.sleep_ms(1) - # count+=1 - # if count>600: - # break - # EventMesh.publish_async("dev_active",thread_size = 8192) - # EventMesh.publish_async("dev_sign_in",thread_size = 8192) - - self.dev_NTP()#获取时间 - self.dev_active() #设备激活 - self.dev_sign_in() #设备登入 - print("device_res_author __init__ end !!!!!!!!!!!!!!!!!") - - def get_dev_token(self, event, msg): - return self.dev_token - #网络校时 - def dev_NTP(self, event=None, msg=None): - response = None - try: - print("dev_NTP1") - url = "http://dmp.raisound.com/bz-api/dev/time" - response = request.get(url,timeout=5) - data = response.json() - print("dev_NTP:{}".format(data)) - if data: - try: - timeSecond = data["data"]["timestamp"]//1000 - - next_alarm_time = utime.localtime(timeSecond) - print("timeSecond {} next_alarm_time {}".format(timeSecond,next_alarm_time)) - machine.RTC().datetime((next_alarm_time[0],next_alarm_time[1],next_alarm_time[2],next_alarm_time[6],next_alarm_time[3],next_alarm_time[4],next_alarm_time[5],0)) - self.ntptime_flag = 1 - except Exception as e: - usys.print_exception(e) - except Exception as e: - usys.print_exception(e) - if response != None: - response.close() - print("dev_NTP end") - def dev_timer_cb(self, *args): #设备资源管理鉴权平台定时器 - EventMesh.publish("publish_AI_btnInfo",{"func":self.dev_timer_cb_}) - - def dev_timer_cb_(self): - #if EventMesh.DEV_RES_MANAGE_AUTHEN_PLATFORM == 1: - try: - if self.dev_token == None: - if self.ntptime_flag == 0: - self.ntptime_flag = 1 - EventMesh.publish_async("dev_NTP",thread_size = 8192) - #EventMesh.publish("publish_AI_btnInfo",{"func":self.dev_NTP}) - print("timer:{}!!!!!!!!\r\n".format(utime.localtime())) - EventMesh.publish_async("dev_active",thread_size = 8192) - EventMesh.publish_async("dev_sign_in",thread_size = 8192) - # self.dev_active() #设备激活 - # self.dev_sign_in() #设备登入 - self.dev_res_timerCount+=1 - if self.dev_res_timerCount > 3: #开机一分钟内没有获取到密码和token 等下一次更新令牌在走登入 激活流程 - self.dev_res_timerCount=0 - self.dev_res_timer.stop() - except Exception as e: - usys.print_exception(e) - def ud_token_timer_cb(self, *args): - EventMesh.publish("publish_AI_btnInfo",{"func":self.ud_token_timer_cb_}) - - def ud_token_timer_cb_(self): - try: - #print("ud_token_timer_!!!!") - self.ud_token_timer_Count+=1 - if self.ud_token_timer_Count >= 720: #定时10*3000s时更新token - self.ud_token_timer_Count = 0 - EventMesh.publish_async("dev_sign_in",thread_size = 8192) - except Exception as e: - usys.print_exception(e) - def get_sim_Status(self): - return sim.getStatus() - def HMAC(self,k, m): - - KEY_BLOCK = k + (b'\0' * (self.SHA1_BLOCK_SIZE - len(k))) - KEY_INNER = bytes((x ^ 0x36) for x in KEY_BLOCK) - KEY_OUTER = bytes((x ^ 0x5C) for x in KEY_BLOCK) - inner_message = KEY_INNER + m - outer_message = KEY_OUTER + self.SHA256(inner_message).digest() - return self.SHA256(outer_message) - def get_hmac_sha256(self,k, m): - data = self.HMAC(k, m).digest() - # print("HMAC(k, m).digest():", data) - # print("HMAC(k, m).digest():", ubinascii.hexlify(data)) - hex_data = ubinascii.hexlify(data) - hex_data = hex_data.decode('ascii') - return hex_data - # 加密函数 - def aes_CBC_Encrypt(self,data, key, iv): # CBC模式的加密函数,data为明文,key为16字节密钥,iv为16字节的偏移量 - key = key.encode('utf-8') - iv = iv.encode('utf-8') # CBC 模式下的偏移量 - data = self.pad(data) # 补位 - data = data.encode('utf-8') - aes = ucryptolib.aes(key,ucryptolib.MODE_CBC,iv) - result = base64.b64encode(aes.encrypt(data)) - return str(result, 'utf-8') # 以字符串的形式返回 - - # 解密函数 - def aes_CBC_Decrypt(self,data, key, iv): # CBC模式的解密函数,data为密文,key为16字节密钥 - key = key.encode('utf-8') - iv = iv.encode('utf-8') - - aes = ucryptolib.aes(key,ucryptolib.MODE_CBC,iv) #CBC模式 - - # decrypt AES解密 B64decode为base64 转码 - result = aes.decrypt(base64.b64decode(data)) - result = self.unpad(result) # 除去补16字节的多余字符 - return str(result, 'utf-8') # 以字符串的形式返回 - #激活接口 没有密码走激活 - def dev_active(self, event=None, msg=None): - signal = net.csqQueryPoll() - if signal == -1 or self.get_sim_Status() != 1:#网络不正常 - print("dev_active 无 SIM卡!!!!!!!!\r\n") - return - print("dev_active 1\r\n") - # 签名内容: = deviceId+pid+timeStamp - dev_pass = "" - dev_pass = EventMesh.publish("get_storage_config","dev_pass") - print("dev_pass:{}\r\n".format(dev_pass)) - if dev_pass == None: - dev_pass = "" - if dev_pass == "" or dev_pass == None: - try: - date_tmp = utime.localtime() #获取当前时间 - print("date_tmp:{}\r\n".format(date_tmp)) #转换时间戳s - timeStamp = (utime.mktime(date_tmp))*1000#获取时间戳ms - deviceId = self.deviceId #"876226002022574" #以imei号 - pid = self.pid - key = self.key - sign_data = "{}{}{}".format(deviceId,pid,timeStamp) #签名内容 - print("sign_data:{}\r\n".format(sign_data)) - sha256_hex = self.get_hmac_sha256(key,sign_data) - print("sha256_hex:{}\r\n".format(sha256_hex)) - - data = { - "deviceId":"{}".format(deviceId), #设备名 - "pid":pid, #产品PID - "sign":"{}".format(sha256_hex), #HMACSHA256签名后的数据 - "timeStamp":timeStamp, #要以ms的形式 - "signMethod":"HMACSHA256" #签名方式 HMACSHA256 - } - print(ujson.dumps(data)) - headers_T ={"Content-Type":"application/json"} - url = "http://dmp.raisound.com/bz-api/dev/auth/active" - data =ujson.dumps(data) - response = None - response_result = 0 - try: - response = request.put(url,data=data,headers = headers_T,timeout=5) - response_result = 1 - except Exception as e: - usys.print_exception(e) - print("put error!!!!!\r\n") - response_result = 0 - - IV = "" #偏移量 - PASSWORD= "" #服务器返回后的加密内容 密码 - if response_result == 1: #访问成功ip - if response.status_code == 200: - print("headers:{}".format(response.headers)) - content = response.content - c = next(content) - # "api.xcloudtech.com" - # d_server_port = 9000 - data = ujson.loads(c) - # data = response.json() - print("data-{}".format(data)) - if data != None: - if "success" in data: - if data['success'] == True: - if "data" in data: - data_tmp = data["data"] - if "nonce" in data_tmp: #偏移量 - IV = data_tmp["nonce"] - if "password" in data_tmp: - PASSWORD = data_tmp["password"] - # EventMesh.publish("set_storage_config",["dev_pass",PASS]) - if data["code"] == 20001:#鉴权成功 - pass - elif data["code"] > 50000:#时间错误 - self.res_error_count+=1 - if self.res_error_count>=3: - self.res_error_count = 0 - #EventMesh.publish("paly_device_res_error") - if data["code"] == 50003:#时间错误 - self.ntptime_flag = 0 - if PASSWORD != None and IV != None: - if len(PASSWORD) != 0 and len(IV) != 0: - password = PASSWORD - iv = IV - #解密 之后保存本地下一次登入做使用 - decrypt_data = self.aes_CBC_Decrypt(password, self.key, iv) #对服务器下发的密码进行解密 - print("decrypt_data {}".format(decrypt_data)) - EventMesh.publish("set_storage_config",["dev_pass",decrypt_data]) - print("IV:{}\r\n PASS:{}".format(IV,PASSWORD)) - if response != None: - response.close() - except Exception as e: - usys.print_exception(e) - print("dev_active end\r\n") - return [response_result,PASSWORD,IV] - #随机生成16个字节的字符串作为加密的IV 偏移量 - def generate_random_string(self,length=16): - random_str = "" - chars = 'abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789' - for i in range(length): - random_str+=chars[random.randint(0,length)] - return random_str - - #设备登入 没有Token 走登入获取token - def dev_sign_in(self, event=None, msg=None): - signal = net.csqQueryPoll() - if signal == -1 or self.get_sim_Status() != 1:#网络不正常 - print("dev_sign_in 无 SIM卡!!!!!!!!\r\n") - return - print("dev_sign_in 1") - token = "" - try: - token = self.dev_token - dev_pass = EventMesh.publish("get_storage_config","dev_pass") - #print("token:{}\r\n".format(token)) - if token == None: - token = "" - if dev_pass == None: - dev_pass = "" - if len(dev_pass) == 0:#没有密码 - return - #if token == None or token == "": - if 1: #返回结果成功 - #获取本地保存的密码 - decrypt_data=EventMesh.publish("get_storage_config","dev_pass") - # decrypt_data = self.aes_CBC_Decrypt(password, self.key, iv) #对服务器下发的密码进行解密 - print("decrypt_data {}".format(decrypt_data)) - #随机生成16个字符串 设备生成做加密使用 - random_string = self.generate_random_string(16) #随机的16个字符串 - enc_iv = random_string #加密的IV偏移量 - #设备端进行密码加密 - encrypt_data = self.aes_CBC_Encrypt(decrypt_data, self.key, enc_iv) - print("encrypt_data {}".format(encrypt_data)) - - #登入数据 - deviceId = self.deviceId - sign_in_data = { - "deviceId":"{}".format(deviceId), #设备ID - "password":"{}".format(encrypt_data), #加密的数据 - "nonce":"{}".format(random_string) #随机的16个字符串 - } - print(ujson.dumps(sign_in_data)) - sign_url = "http://dmp.raisound.com/bz-api/dev/auth/sign_in" #登入地址 - headers_T ={"Content-Type":"application/json"} - response_result = 0 - response = 0 - try: - response = request.post(sign_url,data=ujson.dumps(sign_in_data),headers = headers_T,timeout=5) - response_result = 1 - except Exception as e: - usys.print_exception(e) - print("post error!!!!!\r\n") - response_result = 0 - # {'msg': '', 'code': 20001, 'success': True, - # 'data': {'deviceId': '876226002022574', - # 'token': '95436a9e09fd0ff89feb8825257dca982f'} - # } - - #self.dev_token = "" - if response_result == 1: - if response.status_code == 200: - content = response.content - c = next(content) - data = ujson.loads(c) - print("data-{}".format(data)) - if data != None: - if "success" in data: - if data['success'] == True: #登入成功 - if "data" in data: - data_tmp = data["data"] - if "token" in data_tmp: #token - self.dev_token = data_tmp["token"] - if data["code"] == 50003:#时间错误 - self.ntptime_flag = 0 - print("token:{}\r\n".format(self.dev_token)) - if response != None: - response.close() - pass - except Exception as e: - print("post error!!!!!\r\n") - response_result = 0 - print("dev_sign_in end") - #获取新的令牌 更新token - def update_dev_token(self, event=None, msg=None): - print("update_dev_token") - try: - dev_pass = "" - dev_pass = EventMesh.publish("get_storage_config","dev_pass") - - if dev_pass == None: - dev_pass = "" - if len(dev_pass) == 0: #没有密码走激活 - print("no dev_pass:{}\r\n".format(dev_pass)) - EventMesh.publish("dev_active") - token = self.dev_token - if token == None: - token = "" - if len(token) == 0: #没有token走登入 - print("no dev_token:{}\r\n".format(token)) - #self.dev_sign_in() - EventMesh.publish("dev_sign_in") - dev_tokenip = "http://dmp.raisound.com/bz-api/dev/auth/token" #设备新令牌更新地址 - token = self.dev_token - if token == None: - token = "" - if len(token) != 0: - response_result=0 - response = None - headers_T = {"bz-dt":"{}".format(token)} - try: - response = request.get(dev_tokenip,headers = headers_T,timeout=5) - response_result = 1 - except Exception as e: - print("get error!!!!!\r\n") - response_result = 0 - if response_result == 1: - if response.status_code == 200: - try: - headers_data = response.headers - # print("headers_data!!!!! headers_data:{}\r\n".format(headers_data)) - if "bz-dt" in headers_data: #bz-dt字段是否在头部数据里面 如果有就需要更新 - bz_dt = headers_data["bz-dt"] - self.dev_token = bz_dt.replace(" ", "") #去掉所有的空格符 - print("update_dev_token:{}".format(self.dev_token)) - except Exception as e: - print("headers_data!!!!! error\r\n") - if response != None: - response.close() - except Exception as e: - usys.print_exception(e) - print("update_dev_token end") - -#OTA升级 -class OTA(): - def __init__(self): - #EventMesh.subscribe("min_sys_ota",self.min_sys_ota) - self.downloadFileVoURL1= "" - self.downloadFileVoURL2= "" - #小系统升级,返回0,没有升级;返回,1有升级,正在执行升级;返回2,电压不够 - def min_sys_ota(self,event=None,msg=None): - print("min_sys_ota") - signal = net.csqQueryPoll() - if signal == -1 or sim.getStatus() != 1:#网络不正常 - print("min_sys_ota 无 SIM卡!!!!!!!!\r\n") - return 0 - # return 0 - response = None - ret_str =0 - self.downloadFileVoURL1= "" - self.downloadFileVoURL2= "" - try: - sourceVersion = versions.Build_Time - sourceVersion = "7PIN-"+sourceVersion[:10]+"-"+sourceVersion[11:-3] - print("sourceVersion:{}".format(sourceVersion)) - sourceVersion = sourceVersion.replace(" ", "0") - print("sourceVersion2:{}".format(sourceVersion)) - #url = "http://iot.api.thisiot.com/ota/task?deviceId=860132060348836&sourceVersion=2024-12-20-15:35-1" - url = "http://dmp.raisound.com/bz-api/ota/task?deviceId={}&sourceVersion={}".format(modem.getDevImei(),sourceVersion) - print(url) - response = request.get(url,timeout=5) - if response.status_code == 200: - data = response.json() - print("min_sys_ota1:{}".format(data)) - - if data: - try: - if data["code"] == 20007:#有新版本 - if "fileList"in data["data"]: - if len(data["data"]["fileList"]) == 2: - for fileList in data["data"]["fileList"]: - if fileList["fileName"] == "dfota_2.bin": - self.downloadFileVoURL2 = fileList["url"] - elif fileList["fileName"] == "dfota_1.bin": - self.downloadFileVoURL1 = fileList["url"] - - if data["code"] == 20006:#已是最新版本 - ret_str = 0 - - except Exception as e: - usys.print_exception(e) - else: - print("min_sys_ota get error") - response.close() - except Exception as e: - usys.print_exception(e) - if response != None: - response.close() - - print("min_sys_ota:downloadFileVoURL1:{},\ndownloadFileVoURL2:{}".format(self.downloadFileVoURL1,self.downloadFileVoURL2)) - print("min_sys_ota end") - if self.downloadFileVoURL2!="" and self.downloadFileVoURL1!="": - battery = EventMesh.publish("get_battery") - if battery>=40: - self.ota_timer = osTimer() - self.ota_timer.start(15000, 0, self.ota_timer_cb) - ret_str = 1 - else: - ret_str = 2 - return ret_str - - def ota_timer_cb(self, *args, **kwargs): - import fota - fota_obj = fota() - fota_obj.httpDownload(url1=self.downloadFileVoURL1,url2=self.downloadFileVoURL2) - #ota升级结果返回,开机时调用一次即可 - def ota_result(self,event=None,msg=None): - response = None - try: - currentVersion = versions.Build_Time - currentVersion = "7PIN-"+currentVersion[:10]+"-"+currentVersion[11:-3] - print("currentVersion1:{}".format(currentVersion)) - currentVersion = currentVersion.replace(" ", "0") - print("currentVersion2:{}".format(currentVersion)) - url = "http://dmp.raisound.com/bz-api/ota/result?deviceId={}¤tVersion={}".format(modem.getDevImei(),currentVersion) - print(url) - response = request.post(url,timeout=5) - if response.status_code == 200: - data = response.json() - print("ota_result:{}".format(data)) - else: - print("ota_result error!!!!") - for i in response.text: - print(i) - response.close() - except Exception as e: - usys.print_exception(e) - if response != None: - response.close() - #ICCID上传 - def pots_ICCID(self,event=None,msg=None): - response = None - try: - iccid = sim.getIccid() - if iccid != -1 and len(iccid) > 5: - print("pots_ICCID:{}".format(iccid)) - #Headers = {'Transfer-Encodong':'chunked'} - #http://dmp.raisound.com/bz-api/dev/iccid?deviceId=866610001099679&iccid=89860002192307889057 - url = "http://dmp.raisound.com/bz-api/dev/iccid?deviceId={}&iccid={}".format(modem.getDevImei(),iccid) - print(url) - response = request.post(url,timeout=5) - if response.status_code == 200: - data = response.json() - print("pots_ICCID:{}".format(data)) - else: - print("pots_ICCID error!!!!") - for i in response.text: - print(i) - response.close() - except Exception as e: - usys.print_exception(e) - if response != None: - response.close() -#阿里VC状态枚举 -VC_State_None=0 -VC_State_Listening=1#听 -VC_State_SpeechStart=2#说开始 -VC_State_SpeechIng=3#正在说 -VC_State_SpeechEnd=4#说结束 -VC_State_RequestToRespond=5 #TTS请求或者chat请求 -VC_State_Thinking=6#想(chat) -VC_State_Responding=7#音频播放 -VC_State_TTSStart=8 -VC_State_TTSData=9 -VC_State_TTSFinish=10 -VC_State_TTSEnd=11 -VC_State_TTSError=12 -VC_State_DialogError=13 -VC_State_End=14 - -VC_record_TYPE_PCM = 0 -VC_record_TYPE_AMR = 1 -VC_play_TYPE_PCM = 0 -VC_play_TYPE_MP3 = 1 - -#websocket发送数据编号 -# AI_client_asr_num = 0 -# AI_client_chat_num = 1 -# AI_client_tts_num = 2 -AI_client_VC_num = 3 -AI_client_asr_num = 4 - - -class AI_VC(Abstract): - # AI - - def __init__(self): - try: - self.http_get_config()#获取/更新配置参数 - except Exception as e: - usys.print_exception(e) - self.VC_30S_timer = osTimer() - self.VC_30S_timer.start(30000, 1, self.VC_30S_timer_cb) - self.get_config_timer_count = 0 - self.record_data_save_flag = 0 #是否保存录音文件 - self.play_data_save_flag = 0 #是否保存tts数据到文件 - self.record_fd = None - self.play_fd = None - self.is_VC_ACK = 0 #是否开启ack应答模式 - self.is_long_record = 0 #是否开启长录音模式(语音打断模式) - self.ai_OTA = OTA() - self.is_auth = 0 #是否开启dmp鉴权 - #self.VC_mode = 0 #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.error_data = [] - self.asr_taskid = "" - self.VC_taskid = "" - self.VC_server = 2 #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="118.145.158.207:22083" - elif self.VC_server == 2:# - self.server_ip="118.145.158.207:22082" - elif self.VC_server == 4:# - self.server_ip="118.145.158.207:22084" - elif self.VC_server == 5:# - self.server_ip="amp-wss.raisound.com" - elif self.VC_server == 6:# - self.server_ip="118.145.158.207:22080" - else: - self.server_ip="sevenpin.qipai.com.cn" - - if dev_type == 'momo':# - self.server_ip="118.145.158.207:22080" - elif dev_type == "7PIN": - self.server_ip="sevenpin.qipai.com.cn" - elif dev_type == "sjgq": - self.server_ip="118.145.158.207:22084" - #开机提示音 - self.power_on_tone = EventMesh.publish("get_storage_config","power_on_tone")# - if dev_type != "7PIN": - self.power_on_tone = None - if self.power_on_tone == None: - if dev_type == "G10": - self.power_on_tone = "已开机,您好!我是北科瑞讯智能 AI bot_name" - elif dev_type == "7PIN_BK": - self.power_on_tone = "小瑞来了!我们一起来愉快地聊天吧!" - elif dev_type == "momo": - self.power_on_tone = "DuloDulo,我是上古神兽食梦貘,主人可以叫我momo,我来自《山海经》,是一只以梦为食的神秘灵兽,每当颜色朦胧、人们入睡时,我就会悄悄飞到人们的床头,用我长长的鼻子把噩梦统统吞噬掉,只留下甜甜的美梦。从今往后,就由我守护在主人身边,一起度过每一个星河璀璨的夜晚。" - elif dev_type == "sjgq": - self.power_on_tone = "您好!我是巴马四季甘泉的智能助手。我可以为你解答各种各样的问题,像是有关巴马四季甘泉知识库、中基长寿科学产品、卫斯曼院士国际先进医疗中心的问题,还有日常生活与工作、旅游信息、健康咨询、教育与学习、情感交流、全球资讯、世界文化等方面的问题哦。你有没有这方面的问题想要问我呀?" - else: - self.power_on_tone = "您好!我是世界首创柒牌男装AI生活好帮手-bot_name, 很高兴为您服务,我可以帮您解答柒牌公司知识库、日常生活与工作、旅游信息、健康与运动咨询、教育与学习、情感交流、全球资讯、世界文化等问题!请问您有什么需要我帮忙的吗?" - - - self.VC_record_TYPE = VC_record_TYPE_PCM #0:PCM 1:AMR - self.VC_play_TYPE = VC_play_TYPE_PCM #0:PCM 1:mp3 - self.VC_record_samplerate = 16000 - self.VC_play_samplerate = 16000 - - 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": - self.VC_TTS_voice_type = { - "女":{ - "bot_name":"小瑞", - "voice":"zh_female_wanwanxiaohe_moon_bigtts" , - "lang":"zh-cn" - }, - "男":{ - "bot_name":"小瑞", - "voice":"zh_male_wennuanahu_moon_bigtts" , - "lang":"zh-cn" - }, - "ç«¥":{ - "bot_name":"小瑞", - "voice":"ICL_zh_female_huoponvhai_tob" , - "lang":"zh-cn" - }, - "粤":{ - "bot_name":"小瑞", - "voice":"zh_female_wanqudashu_moon_bigtts" , - "lang":"zh-hk" - }, - "四川":{ - "bot_name":"小瑞", - "voice":"zh_female_daimengchuanmei_moon_bigtts", - "lang":"&lang=zh-cn-sc" - }, - "个性":{ - "bot_name":"小瑞", - "voice":"zh_male_sunwukong_mars_bigtts" , - "lang":"zh-cn" - } - - } - elif dev_type == 'momo': - self.VC_TTS_voice_type = { - "女":{ - "bot_name":"食梦貘", - "voice":"zh_female_shaoergushi_mars_bigtts" , - "lang":"zh-cn" - }, - "男":{ - "bot_name":"食梦貘", - "voice":"zh_male_yangguangqingnian_mars_bigtts" , - "lang":"zh-cn" - }, - "ç«¥":{ - "bot_name":"食梦貘", - "voice":"ICL_zh_female_huoponvhai_tob" , - "lang":"zh-cn" - }, - } - elif dev_type == 'sjgq': - self.VC_TTS_voice_type = { - "女":{ - "bot_name":"小巴", - "voice":"zh_female_wanwanxiaohe_moon_bigtts" , - "lang":"zh-cn" - }, - "男":{ - "bot_name":"小巴", - "voice":"zh_male_wennuanahu_moon_bigtts" , - "lang":"zh-cn" - }, - "ç«¥":{ - "bot_name":"小巴", - "voice":"ICL_zh_female_huoponvhai_tob" , - "lang":"zh-cn" - }, - } - else: - #女,男,童,粤,川,个性声 - self.VC_TTS_voice_type = { - "女":{ - "bot_name":"柒妹妹", - "voice":"huoshan::zh_female_wanwanxiaohe_moon_bigtts" , - "lang":"zh-cn" - }, - "男":{ - "bot_name":"柒先生", - "voice":"huoshan::zh_male_wennuanahu_moon_bigtts" , - "lang":"zh-cn" - }, - "ç«¥":{ - "bot_name":"柒乐乐", - "voice":"huoshan::ICL_zh_female_huoponvhai_tob" , - "lang":"zh-cn" - }, - "粤":{ - "bot_name":"柒先生", - "voice":"huoshan::zh_female_wanqudashu_moon_bigtts" , - "lang":"zh-hk" - }, - "四川":{ - "bot_name":"柒妹妹", - "voice":"huoshan::zh_female_daimengchuanmei_moon_bigtts", - "lang":"&lang=zh-cn-sc" - }, - "个性":{ - "bot_name":"柒先生", - "voice":"huoshan::zh_male_sunwukong_mars_bigtts" , - "lang":"zh-cn" - }, - "英语":{ - "bot_name":"柒先生", - "voice":"huoshan::en_male_smith_mars_bigtts" , - "lang":"zh-cn" - } - - - } - - # self.VC_TTS_voice_type = {0:"zh_female_xinlingjitang_moon_bigtts",1:"zh_male_wennuanahu_moon_bigtts",2:"ICL_zh_female_huoponvhai_tob", - # 3:"aliyun::longjiaxin",4:"zh_female_daimengchuanmei_moon_bigtts"} - #self.VC_TTS_voice_type = ["aliyun::longxiaoxia","aliyun::longnan","aliyun::longling"] - - #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": - self.VC_TTS_voice_key = "ç«¥" - elif dev_type == "momo": - self.VC_TTS_voice_key = "男" - else: - self.VC_TTS_voice_key = "男" - if self.VC_TTS_voice_key in self.VC_TTS_voice_type: - pass - else: - self.VC_TTS_voice_key = list(self.VC_TTS_voice_type.keys())[0] - print("音色配置:{}:{}\r\n\r\n".format(self.VC_TTS_voice_key,self.VC_TTS_voice_type[self.VC_TTS_voice_key])) - self.VC_TTS_volume = EventMesh.publish("get_storage_config","VC_TTS_volume")#音量配置 - except Exception as e: - usys.print_exception(e) - - if self.VC_TTS_volume == None: - self.VC_TTS_volume = 100 - self.AI_audio_queue_thread_id = 0 - self.AI_audio_queue_thread_lock = 0 - self.AI_VC_send_data_queue_thread_id = 0 - self.AI_VC_send_data_queue_thread_lock = 0 - self.AI_ASR_send_data_queue_thread_id = 0 - self.AI_ASR_send_data_queue_thread_lock = 0 - self.AI_record_tmp_queue = Queue(100) - self.AI_ASR_send_data_queue = Queue(200) - self.AI_VC_send_data_queue = Queue(100) - self.AI_audio_queue = Queue(100) - #self.AI_WS_connect_Queue = Queue(100) #释放用 - self.AI_TTS_str = "" - self.AI_ASR_str = "" - self.AI_ASR_flag = 0 - self.AI_ASR_str_tmp = "" - self.AI_ASR_send_buf_len = 0 - self.AI_ASR_text_tmp = "" - self.AI_ASR_text_repet_count = 0 - # #开始线程 - # if self.AI_audio_queue_thread_id ==0: - # self.AI_audio_queue_thread_id = _thread.start_new_thread(self.AI_audio_queue_thread, ()) - # else: - # print("AI_VC_start :AI_audio_queue_thread_id != 0 ") - # if self.AI_VC_send_data_queue_thread_id == 0: - # self.AI_VC_send_data_queue_thread_id = _thread.start_new_thread(self.AI_VC_send_data_queue_thread, ()) - - self.VC_state = VC_State_None #阿里ai VC状态 - self.VC_dialog_id = ""# - self.VC_message_id=None - self.VC_task_id =None - self.AI_client_VC = None - self.AI_client_VC_recv_id = 0 - self.AI_client_VC_recv_lock = 0 - self.AI_client_VC_isconnect =0 - self.AI_client_VC_debug =0 - - self.asr_state = VC_State_None #阿里VC_ASR VC状态 - self.key_state = 0 - - self.AI_client_asr = None - self.AI_client_asr_recv_id = 0 - self.AI_client_asr_recv_lock = 0 - self.AI_client_asr_isconnect =0 - self.AI_ASR_timer = osTimer() - self.AI_ASR_timer_count = 0 - self.AI_client_asr_debug =0 - self.AI_ASR_check_timeout = 0 - self.AI_ASR_error_timeout = 0 - self.VC_Thinking_timerout = 0 - self.VC_Speech_end_timerout = 0 - - self.record_pcm = None - self.play_pcm = None - self.VC_record_thread_id = 0 - self.VC_record_thread_lock = 0 - self.VC_pingping_timerout = 0 - self.asr_pingping_timerout = 0 - self.factory_timer = osTimer() - self._1S_timer = osTimer() - self.Audio_buf_size = 16*1024 - self.record = audio.Record() - #self.record.end_callback(self.record_callback) - self.record.gain_set(4,10) - #self.record.gain_set(4,12) - self.aud = audio.Audio(0) - self.aud.setCallback(self.audio_cb) - #self.aud.setVolume(self.VC_TTS_volume //10) - self.audio_play_state = 1 #音频播放完状态 - self.close_timerout = 0 - self.LocalRespondingEnded_timerout = 0 - - self.play_flag = 0 - self.VC_record_state_flag = 0 - self.AI_key_long_press_flag = 0 - self.websocket_error_count = 0 - - self.tts_in_data_len = 0 - self.tts_out_data_len = 0 - self.VC_satrt_flag = 0 - self.session_id = "" - EventMesh.subscribe("AI_key_press", self.AI_key_press) - EventMesh.subscribe("AI_key_release", self.AI_key_release) - EventMesh.subscribe("AI_key_long_press", self.AI_key_long_press) - EventMesh.subscribe("pwk_key_release", self.pwk_key_release) - EventMesh.subscribe("get_AI_audio_queue", self.get_AI_audio_queue) - EventMesh.subscribe("get_VC_satrt_flag", self.get_VC_satrt_flag) - EventMesh.subscribe("VC_error", self.VC_error) - - EventMesh.publish("close_led") - - self.bot_name = "柒先生" - try: - if "bot_name" in self.VC_TTS_voice_type[self.VC_TTS_voice_key]: - self.bot_name = self.VC_TTS_voice_type[self.VC_TTS_voice_key]["bot_name"] - else: - print("not bot_name!!!!!!!!!!!!!!!!!!!!!!") - except Exception as e: - usys.print_exception(e) - try: - if self.ai_OTA.min_sys_ota()==1: - #if 0: - self.AI_TTS_str = "检测到有新版本需要升级啦!升级时可千万别断电或乱按哦,升级完成后设备会自动重启,重启就代表升级成功" - EventMesh.publish("publish_AI_btnInfo",{"func":self.AI_VC_start}) - # if self.ai_OTA.min_sys_ota()==2: - # self.AI_TTS_str = "检测到有新版本需要升级啦!电量低于40%,无法保证升级正常执行,请充满电后重启设备再次升级!" - # EventMesh.publish("publish_AI_btnInfo",{"func":self.AI_VC_start}) - else: - try: - self.ai_OTA.ota_result() - self.ai_OTA.pots_ICCID() - except Exception as e: - usys.print_exception(e) - #开机提示语,如果联网失败,直接提示信号弱 - - #"voice":{"女":"柒妹妹-huoshan::zh_female_wanwanxiaohe_moon_bigtts","男":"柒先生-huoshan::zh_male_wennuanahu_moon_bigtts","ç«¥":"柒乐乐huoshan::ICL_zh_female_huoponvhai_tob","广东":"柒先生-huoshan::zh_female_wanqudashu_moon_bigtts","四川":"柒妹妹-huoshan::zh_female_daimengchuanmei_moon_bigtts","个性":"柒先生-zh_male_sunwukong_mars_bigtts"} - #EventMesh.publish("get_storage_config",["powerRestart",1]) - powerRestart = EventMesh.publish("get_storage_config","powerRestart")#=1非正常重启 - if powerRestart == None: - powerRestart = 0 - if powerRestart == 1: - EventMesh.publish("set_storage_config",["powerRestart",0]) - - else: - - 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}) - - - - except Exception as e: - usys.print_exception(e) - - - def post_processor_after_instantiation(self): - pass - def get_AI_audio_queue(self, event, msg): - return self.AI_audio_queue - def get_VC_satrt_flag(self, event, msg): - return self.VC_satrt_flag - - - def VC_30S_timer_cb(self, *args): # - EventMesh.publish("publish_AI_btnInfo",{"func":self.VC_30S_timer_cb_}) - - def VC_30S_timer_cb_(self): - self.get_config_timer_count += 1 - if self.get_config_timer_count >= 2*60*2:#2小时更新配置参数 - self.get_config_timer_count = 0 - try: - self.http_get_config()#获取/更新配置参数 - except Exception as e: - usys.print_exception(e) - #提交错误id - def ud_error(self,error_data): - response = None - if self.is_up_error == 1: - try: - # currentVersion = versions.Build_Time - # currentVersion = "7PIN-"+currentVersion[:10]+"-"+currentVersion[11:-3] - url = "http://{}/health?task_id={}".format(self.server_ip,error_data[0]+error_data[1]) - print(url) - response = request.get(url,timeout=5) - if response.status_code == 200: - - print("ud_error:ok") - else: - print("ud_error error!!!!") - for i in response.text: - print(i) - response.close() - except Exception as e: - usys.print_exception(e) - if response != None: - response.close() - #获取配置参数 - def http_get_config(self, event=None, msg=None): - print("http_get_config") - - response = None - #http://180.184.206.142/bz-api/dev/config?deviceId=xxx - try: - url = "http://dmp.raisound.com/bz-api/dev/config/{}".format(modem.getDevImei()) - print(url) - response = request.get(url,timeout=5) - if response.status_code == 200: - data = response.json() - print("http_get_config:{}".format(data)) - - if data: - try: - if data["code"] == 20000:#有配置 - if data["data"] : - if "version" in data["data"]: - config_version = EventMesh.publish("get_storage_config","config_version")#音量配置 - if config_version != data["data"]["version"]: - config_version = data["data"]["version"] - EventMesh.publish("set_storage_config",["config_version",config_version]) - if "VC_TTS_voice_type" in data["data"]: - self.VC_TTS_voice_type = data["data"]["VC_TTS_voice_type"] - EventMesh.publish("set_storage_config",["VC_TTS_voice_type",self.VC_TTS_voice_type]) - print("配置VC_TTS_voice_type成功") - if "server_ip" in data["data"]: - self.server_ip = data["data"]["server_ip"] - EventMesh.publish("set_storage_config",["server_ip",self.server_ip]) - print("配置server_ip成功") - if "power_on_tone" in data["data"]: - self.power_on_tone = data["data"]["power_on_tone"] - EventMesh.publish("set_storage_config",["power_on_tone",self.power_on_tone]) - print("配置power_on_tone成功") - - except Exception as e: - usys.print_exception(e) - else: - print("status_code:{}".format(response.status_code)) - print("http_get_config:error!!!!!!!!!!") - response.close() - except Exception as e: - usys.print_exception(e) - if response != None: - response.close() - - def audio_cb(self,event): - if event == 0: - self.audio_play_state =1 - #EventMesh.publish("set_audio_state", 1) - print('audio-play start.') - elif event == 7: - self.audio_play_state = 0 - #EventMesh.publish("set_audio_state", 0) - print('audio-play finish.!!!!!!') - - def AI_key_press(self, event, msg):#按键按下 - print("AI_key_press") - self.get_config_timer_count = 0 - self.key_state = 1 - #self.aud.aud_tone_play(10,200)#播放按键音 - self.AI_TTS_str = ""#"你好,有什么吩咐" - self.AI_ASR_str = "" - self.AI_ASR_str_tmp = "" - self.VC_state = VC_State_None - # if self.VC_state != VC_State_None: - # EventMesh.publish("publish_AI_btnInfo",{"func":self.Close}) - # EventMesh.publish("publish_AI_btnInfo",{"func":utime.sleep_ms,'data':(10)}) - #if self.VC_record_state_flag >1:#如果在录音,就先停止录音 - self.VC_Speech_End() - - self.VC_Speech_Start() - self.AI_VC_start() - # 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}) - #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}) - - 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}) - - - #self.VC_Speech_End() - def AI_key_long_press(self, event, msg):#按键长按 - print("AI_key_long_press") - self.AI_key_long_press_flag = 1 - - def pwk_key_release(self, event, msg):#电源键短按,关闭 - print("pwk_key_release") - EventMesh.publish("publish_AI_btnInfo",{"func":self.Close}) - - def key_prompt(self): - EventMesh.publish("audio_montage_play",["key_prompt.mp3"]) - #self.aud.play(1,1,'U:/static/key_prompt.mp3')#提示请您按住中间的按钮开始讲话,讲完松开即可 - 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: - - #self.VC_state = VC_State_SpeechStart - print("VC_Speech_Start VC_record_state_flag:{} self.AI_ASR_flag:{}!!!!!!!!".format(self.VC_record_state_flag,self.AI_ASR_flag)) - if self.AI_ASR_flag != 0: - 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,()) - _thread.stack_size(8*1024) - print("self.VC_record_thread_id:{}".format(self.VC_record_thread_id)) - try: - - if self.VC_record_TYPE == VC_record_TYPE_AMR : - try : - self.record.stream_start(audio.Record.AMRNB, self.VC_record_samplerate, 0) - except Exception as e: - usys.print_exception(e) - elif self.VC_record_TYPE == VC_record_TYPE_PCM: - print("record_pcm.stream_read_start()!!!!!!!!!!!!") - self.record.stream_start(audio.Record.WAV, self.VC_record_samplerate, 0) - # if self.record_pcm != None: - # try: - # self.record_pcm.stream_stop() - # self.record_pcm.close() - # self.record_pcm = None - # except Exception as e: - # usys.print_exception(e) - # if self.record_pcm == None: - # ret = self.record_pcm = audio.Audio.PCM(0,1,16000,0,1,2) - # print("audio.Audio.PCM:ret:{}".format(ret)) - # ret = self.record_pcm.stream_read_start() - # print("self.record_pcm.stream_read_start:ret:{}".format(ret)) - except Exception as e: - usys.print_exception(e) - - 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) - - #停止录音 - def VC_Speech_End(self): - try: - self.AI_ASR_flag = 0 - self.AI_ASR_str_tmp = "" - self.AI_ASR_str = "" - #EventMesh.publish("publish_AI_btnInfo",{"func":self.websocket_deconnect_asr}) - - if self.VC_record_state_flag == 0: - return - #self.AI_client_asr_StopTranscription_requset()#请求停止 - if self.VC_record_TYPE == VC_record_TYPE_AMR: - self.record.stream_stop() - self.record.stop()#关闭录音 - Record_read_buf = bytearray(self.Audio_buf_size) - for i in range(10): - Record_len = self.record.stream_read(Record_read_buf, self.Audio_buf_size) - print("Record_len:!!!!!!{}".format(Record_len)) - if Record_len <= 0: - break - elif self.VC_record_TYPE == VC_record_TYPE_PCM: - self.record.stream_stop() - self.record.stop()#关闭录音 - Record_read_buf = bytearray(self.Audio_buf_size) - for i in range(10): - Record_len = self.record.stream_read(Record_read_buf, self.Audio_buf_size) - print("Record_len:!!!!!!{}".format(Record_len)) - if Record_len <= 0: - break - # if self.record_pcm != None: - # try: - # self.record_pcm.stream_stop() - # self.record_pcm.close() - # self.record_pcm = None - # except Exception as e: - # usys.print_exception(e) - except Exception as e: - usys.print_exception(e) - 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)) - #关闭录音线程 - def VC_record_thread_close(self): - if self.VC_record_thread_id != 0: - count =50 - while True: - count -= 1 - if self.VC_record_thread_lock == 1: - self.VC_record_thread_lock = 2 - if self.VC_record_thread_lock == 0 or count <=0: - break - else: - print("VC_record_thread_thread going:{}...".format(count)) - utime.sleep_ms(1) - self.VC_record_thread_lock = 0 - print("VC_record_thread_thread_close") - try: - _thread.stop_thread(self.VC_record_thread_id) - except Exception as e: - usys.print_exception(e) - self.VC_record_thread_id = 0 - #获取录音数据 - def VC_record_thread(self): - ##return - print("VC_record_thread start!!!!!!!!!!!!!!!!!!!!\r\n") - count = 0 - # try: - # uos.remove('/usr/test.pcm') - # except Exception as e: - # usys.print_exception(e) - #record_data_queue = Queue(100) - #fd = open('/usr/test.pcm','w') - # if self.VC_record_TYPE == 1: - # h_data= [0x23,0x21 ,0x41 ,0x4D ,0x52 ,0x0A ] - # h_data_b = bytes(h_data) - # self.AI_client_VC_send(h_data_b) - AI_record_tmp_queue_len = 0 - while True: - try: - if self.VC_record_thread_lock == 2: - break - self.VC_record_thread_lock = 1 - # 死循环接收数据 - #if self.VC_state == VC_State_SpeechStart: - Record_read_buf = bytearray(self.Audio_buf_size) - - 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) - - else : - - Record_len = self.record.stream_read(Record_read_buf, self.Audio_buf_size) - utime.sleep_ms(600) - - #Record_len = 1024*2 - #print("VC_record_thread:{}".format(Record_len)) - if Record_len > 0: - read_buf = bytes(Record_read_buf[:Record_len]) - if self.record_data_save_flag == 1: - if self.record_fd == None: - try: - uos.remove('/usr/record_data.pcm') - except Exception as e: - usys.print_exception(e) - self.record_fd = open('/usr/record_data.pcm','w') - if self.record_fd != None: - self.record_fd.write(read_buf) - print("write record:{}".format(len(read_buf))) - # count+=Record_len - # 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) - AI_record_tmp_queue_len += len(read_buf) - else: - AI_record_tmp_queue_len = 0 - while True: - if self.AI_record_tmp_queue.empty() == True: - break - else: - self.AI_client_VC_input_audio_buffer_append(self.AI_record_tmp_queue.get()) - #self.AI_client_asr_send(self.AI_record_tmp_queue.get()) #发送之前存的数据 - #self.AI_client_asr_send(read_buf) - self.AI_client_VC_input_audio_buffer_append(read_buf) - #print("VC_record_thread:{}".format(len(read_buf))) - #count+=len(read_buf) - # if count>=500*1024:#结束 - # self.AI_client_VC_end_speech() - # break - # count+=1 - # if count %10 == 0: - # print("VC_record_thread on line {} asr recv :{} send:{}".format(self.VC_record_state_flag,_thread.threadIsRunning(self.AI_client_asr_recv_id),_thread.threadIsRunning(self.AI_VC_send_data_queue_thread_id))) - - # if self.VC_state >= VC_State_SpeechEnd: - # break - - except Exception as e: - usys.print_exception(e) - #break - self.VC_record_thread_lock = 0 - utime.sleep_ms(100) - #fd.close() - print("VC_record_thread:exit") - self.VC_record_thread_id = 0#线程退出 - self.VC_record_thread_lock = 0 -###################################################### VC ################################################################################### - def websocket_connect_VC(self): - print("websocket_connect_VC:{} e:{}!!!!!!!!!!!!!!!!!!!!!".format(self.AI_client_VC_isconnect,self.AI_client_VC_debug)) - if self.AI_client_VC_isconnect == 1: - return - # 创建VC客户端 - try: - signal = net.csqQueryPoll() - if signal == -1 or sim.getStatus() != 1:#网络正常 - self.websocket_error() - return - try: - if "bot_name" in self.VC_TTS_voice_type[self.VC_TTS_voice_key]: - self.bot_name = self.VC_TTS_voice_type[self.VC_TTS_voice_key]["bot_name"] - else: - print("not bot_name!!!!!!!!!!!!!!!!!!!!!!") - except Exception as e: - usys.print_exception(e) - - # Headers = {'X-NLS-Token':'0c8b8f05a46f423096be64a9c4c46310'} - # self.AI_client_VC = uwebsocket.Client.connect('wss://nls-gateway-cn-beijing.aliyuncs.com/ws/v1',headers=Headers, debug=False) - - url="wss://ws.coze.cn/v1/chat?bot_id=7481164663863459850" - print("VC VC:url{}".format(url)) - Headers = {"Authorization":"Bearer pat_SSaiOzccrRLaQEaB4sdshvHZQzqjeWD5jq2GWPVoWRx4N8XcdraHWYqdDjK5zpR1"} - self.AI_client_VC = uwebsocket.Client.connect(url, headers=Headers,debug=True) - #self.AI_WS_connect_Queue.put(self.AI_client_VC) - - - print("websocket_connect_VC:OK!!!!!!!!!!!!!!!!!!!!!") - except Exception as e: #网络连接异常 - usys.print_exception(e) - print("websocket_connect_VC error!!!\r\n") - str_error = str(e) - if str_error.find("[Errno 22] EINVAL")!= -1: - print("websocket_connect_VC:str_error:{}".format(str_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") - self.websocket_error() - EventMesh.publish("set_storage_config",["powerRestart",1])#调试临时关闭 - utime.sleep_ms(1000) - self.aud.stopPlayStream() - self.aud.stopAll() - Power.powerRestart() - - self.websocket_error() - return - #print("AI_client_VC:{}".format(self.AI_client_VC)) - if self.AI_client_VC == None: - EventMesh.publish("update_dev_token")#获取token - self.websocket_error() - return - self.AI_client_VC_debug+=1 - utime.sleep_ms(10) - #self.AI_client_VC.settimeout(5) - #self.AI_VC_send_data_queue_thread_close()#关闭发送线程 - if self.AI_VC_send_data_queue_thread_id == 0: - _thread.stack_size(self.Audio_buf_size+8*1024) - self.AI_VC_send_data_queue_thread_id = _thread.start_new_thread(self.AI_VC_send_data_queue_thread, ()) - _thread.stack_size(8*1024) - print("AI_VC_start :AI_VC_send_data_queue_thread_id :{} ".format(self.AI_VC_send_data_queue_thread_id)) - self.AI_client_VC_recv_thread_close()#关闭读线程 - # 线程接收数据 - _thread.stack_size(self.Audio_buf_size+8*1024) - self.AI_client_VC_recv_id = _thread.start_new_thread(self.AI_client_VC_recv, (self.AI_client_VC,)) - _thread.stack_size(8*1024) - self.AI_client_VC_isconnect = 1 - print("websocket_connect_VC end") - - def websocket_error(self,TTS_str=None): - print("websocket_error1!!!!") - self.Close() - print("websocket_error1.1!!!!") - print("websocket_error!!!!") - print("websocket_error!!!!") - self.VC_Thinking_timerout = 0 - self.VC_satrt_flag = 0 - self.AI_TTS_str = "" - self.AI_ASR_str = "" - self.AI_ASR_str_tmp = "" - self.AI_ASR_flag = 0 - self.VC_Speech_End() - EventMesh.publish("close_led") - if TTS_str == None: - self.websocket_error_count+=1 - # if self.websocket_error_count <=3: - # EventMesh.publish("audio_montage_play",["xinhaoruo1.mp3"]) - if self.websocket_error_count <10 : - EventMesh.publish("audio_montage_play",["xinhaoruo1.mp3"]) - elif self.websocket_error_count >=10: - EventMesh.publish("paly_iccid_imei") - # else: - # EventMesh.publish("audio_montage_play",["R_SIM_FAILE.mp3"]) - #self.aud.play(1,1,'U:/static/R_SIM_FAILE.mp3') - if self.websocket_error_count <3 : - utime.sleep_ms(3000) - EventMesh.publish("publish_AI_btnInfo",{"func":self.AI_VC_start}) - else: - print("websocket_error:tts:{}".format(TTS_str)) - self.AI_TTS_str = TTS_str - EventMesh.publish("publish_AI_btnInfo",{"func":self.AI_VC_start}) - print("websocket_error2") - - - print("websocket_error4") - - - def websocket_deconnect_VC(self): - #print("websocket_deconnect_VC {}!!!!!!!".format(self.AI_client_VC_isconnect)) - print("websocket_deconnect_VC!!!!!!!") - self.AI_client_VC_recv_thread_close()#关闭读线程 - self.AI_client_VC_recv_id = 0 - if self.AI_client_VC_isconnect == 1 or self.AI_client_VC!=None: - try: - self.AI_client_VC_isconnect = 0 - count = 500 - while True:#等待发完数据 - count-=1 - if count <=0 or self.AI_VC_send_data_queue_thread_lock == 0: - break - utime.sleep_ms(1) - - try: - self.AI_client_VC.close() - self.AI_client_VC_debug -=1 - #self.AI_client_VC=None - except Exception as e: - usys.print_exception(e) - try : - self.AI_client_VC.close() - self.AI_client_VC_debug -=1 - #self.AI_client_VC=None - except Exception as e: - usys.print_exception(e) - try : - self.AI_client_VC._close() - except Exception as e: - usys.print_exception(e) - self.AI_client_VC = None - except Exception as e: - usys.print_exception(e) - print("websocket_deconnect_VC {}!!!!!!!".format(self.AI_client_VC_isconnect)) - #websocket发送ping - def AI_client_VC_ping(self): - pass - 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") - - #websocket发送数据 - def AI_client_VC_send(self,data_str): - # if isinstance(data_str, str):#是字符串 - # print("AI_client_VC_send:{}".format(data_str)) - # pass - # else: - # print("AI_client_VC_send:len{}".format(len(data_str))) - self.AI_VC_send_data_queue.put([AI_client_VC_num,data_str]) - #关闭数据发送线程 - def AI_VC_send_data_queue_thread_close(self): - if self.AI_VC_send_data_queue_thread_id != 0: - count =500 - while True: - count -= 1 - if self.AI_VC_send_data_queue_thread_lock == 0 or count <=0: - break - else: - self.AI_VC_send_data_queue_thread_lock = 2 - print("AI_VC_send_data_queue_thread going:{}...".format(count)) - utime.sleep_ms(1) - if self.AI_VC_send_data_queue.empty()!=True: - self.AI_VC_send_data_queue.clear() - self.AI_VC_send_data_queue_thread_lock = 0 - print("AI_VC_send_data_queue_thread_close") - try: - _thread.stop_thread(self.AI_VC_send_data_queue_thread_id) - except Exception as e: - usys.print_exception(e) - self.AI_VC_send_data_queue_thread_id = 0 - #发送数据队列 - def AI_VC_send_data_queue_thread(self): - print("AI_VC_send_data_queue_thread:start") - count_t = 0 - while True: - if self.AI_VC_send_data_queue_thread_lock == 2: - print("AI_VC_send_data_queue_thread,该退出了") - break - if self.AI_VC_send_data_queue.empty() :#不能去掉,去掉会卡死 - self.AI_VC_send_data_queue_thread_lock = 0 - count_t+=1 - # if count_t%200 == 0: - # print("self.AI_VC_send_data_queue.empty") - utime.sleep_ms(1) - else: - #data[0]是websocket连接对象编号,data[1]是数据 - #print("AI_VC_send_data_queue_thread:get") - - self.AI_VC_send_data_queue_thread_lock = 1 - data = self.AI_VC_send_data_queue.get() - - - #print("AI_VC_send_data_queue_thread:num{} len{}".format(data[0],len(data[1]))) - if data != None: - try: - #data["func"](data["data"]) - # 发送数据 - #bytes_data = bytes(data[1]) - #data[0].send(data[1]) - #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):#是字符串 - if len(data[1])<600: - print("VC VC: send_data:{}".format(data[1])) - else: - pass - #print("VC VC: send_data:{}...".format(data[1][:300])) - #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: send_data end") - - #print("VC: send_data end") - except Exception as e: - print("DeviceInfo_queue_thread:ERROR:{}".format(e)) - usys.print_exception(e) - if data[0] == AI_client_VC_num: - #self.websocket_error() - pass - - - try: - if self.AI_client_VC_isconnect != 0: - print("VC发送数据错误,退出") - EventMesh.publish("publish_AI_btnInfo",{"func":self.websocket_error,"data":"VC发送出错了,请重试"}) - self.ud_error(["VC",self.VC_taskid]) - except Exception as e: #网络连接异常 - usys.print_exception(e) - - utime.sleep_ms(1) - self.AI_VC_send_data_queue_thread_lock = 0 - #VC关闭读线程 - def AI_client_VC_recv_thread_close(self): - if self.AI_client_VC_recv_id != 0: - count =500 - while True: - count -= 1 - if self.AI_client_VC_recv_lock == 1: - self.AI_client_VC_recv_lock = 2 - if self.AI_client_VC_recv_lock == 0 or count <=0: - break - else: - print("AI_client_VC_recv_thread going:{}...".format(count)) - utime.sleep_ms(1) - self.AI_client_VC_recv_lock = 0 - print("AI_client_VC_recv_thread_close") - try: - _thread.stop_thread(self.AI_client_VC_recv_id) - except Exception as e: - usys.print_exception(e) - self.AI_client_VC_recv_id = 0 - #Ai VC websocket返回数据 - def AI_client_VC_recv(self,cli): - count = 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 - utime.sleep_ms(1) - if self.VC_state < VC_State_TTSStart: - utime.sleep_ms(1) - recv_data = cli.recv() - if self.AI_client_VC_recv_lock == 2: - print("AI_client_VC_recv 该退出了") - break - self.AI_client_VC_recv_lock = 1 - self.close_timerout = 0#服务器有返回清零退出时间 - if recv_data == "websocket close": - # 服务器关闭连接 - print("VC 服务器关闭连接!!!!!!!!!!!!!!!!!!!!!!!!!!!") - #self.AI_client_VC_isconnect = 0 - #self.websocket_deconnect_VC() - #EventMesh.publish("publish_AI_btnInfo",{"func":self.websocket_deconnect_asr}) - # #EventMesh.publish("publish_AI_btnInfo",{"func":utime.sleep_ms,'data':(1500)}) - #EventMesh.publish("publish_AI_btnInfo",{"func":self.websocket_connect_asr}) - EventMesh.publish("publish_AI_btnInfo",{"func":self.websocket_error,"data":"VC连接断开了,请重试"}) - self.ud_error(["VC",self.VC_taskid]) - break - elif recv_data == "":#客户端关闭连接 - print("VC VC :客户端关闭连接") - EventMesh.publish("publish_AI_btnInfo",{"func":self.websocket_error,"data":"VC连接断开了,请重试"}) - self.ud_error(["VC",self.VC_taskid]) - break - try: - self.websocket_error_count = 0 - if isinstance(recv_data, str):#返回的是字符串 - if len(recv_data)<700: - print("VC VC:recv_data:{}".format(recv_data)) - else: - print("VC VC:recv_data long :{}".format(recv_data[:700])) - jsload_data = ujson.loads(recv_data) - #print("AI_client_VC_recv jsload_data = {}".format(jsload_data)) - if jsload_data["event_type"] == "chat.updated" :#会话开始 - print("VC:Started!!!!!!!!\r\n") - print("VC:Started!!!!!!!!\r\n") - print("VC:Started!!!!!!!!\r\n") - - self.AI_client_VC_send_speech()#开始上传语音 - elif jsload_data["event_type"] == "conversation.audio_transcript.update" :#音频转译 - #self.VC_Speech_end_timerout = 2 - self.AI_ASR_str = jsload_data["data"]['content'] - # if self.AI_ASR_str.find("。") != -1 or self.AI_ASR_str.find("?") != -1 or self.AI_ASR_str.find("!") != -1: - # self.VC_Speech_end_timerout = 0 - # self.AI_client_VC_end_speech()#发送说话终止 - - elif jsload_data["event_type"] == "conversation.chat.created" :#开始对话 - EventMesh.publish("publish_AI_btnInfo",{"func":self.send_tone}) - self.open_play_flag = 0 - 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') - - elif jsload_data["event_type"] == "conversation.message.delta":#返回大模型回答数据 - if self.open_play_flag == 0: - EventMesh.publish("publish_AI_btnInfo",{"func":self.VC_Play_Start})#打开播放 - self.open_play_flag =1 - elif jsload_data["event_type"] == "conversation.audio.delta":#下发音频数据 - - audio_data = ubinascii.a2b_base64(jsload_data["data"]['content']) - print("下发音频数据1:{}".format(len(audio_data))) - EventMesh.publish("publish_AI_btnInfo",{"func":self.put_record_data,"data":[audio_data,""]}) - if self.play_data_save_flag == 1: - if self.play_fd !=None: - self.play_fd.write(audio_data) - elif jsload_data["event_type"] == "conversation.audio.completed":#结束播放 - if self.play_data_save_flag == 1: - if self.play_fd !=None: - print("输出音频文件关闭") - self.play_fd.close() - - # 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) - - # pass - # else: - # pass - - # elif jsload_data["event"] == "SpeechEnded" :#服务器下发ASR说话结束 - # self.VC_state = VC_State_SpeechEnd - # elif jsload_data["event"] == "RespondingContent" :#chat回答 - # pass - - # 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_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') - - # pass - # elif jsload_data["event"] == "RespondingEnded" :#音频下发结束 - # #if self.VC_state == VC_State_TTSStart: - - # 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()#开始上传语音 - # pass - else:#下发音频数据 - #self.AI_ASR_str = ""#下发音频后清掉asr结果 - - 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: - #self.put_record_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: - #print("VC VC:recv TIMEDOUT 正常") - pass - else: - usys.print_exception(e) - #self.websocket_error() - print("VC VC :读数据报错,退出") - EventMesh.publish("publish_AI_btnInfo",{"func":self.websocket_error,"data":"VC出错了,请重试"}) - self.ud_error(["VC",self.VC_taskid]) - break - self.AI_client_VC_isconnect = 0 - self.AI_client_VC_recv_id = 0 - self.AI_client_VC_recv_lock = 0 - print("AI_client_VC_recv END!!!!!!!!!!!!!!!!!!!!!!!!!!!") - def put_record_data(self,data): - #print("下发音频数据1:{}".format(len(data[0]))) - 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 - try: - if isinstance(text, str): - if text.find("声音") != -1 and text.find("改") != -1: - 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]) - # EventMesh.publish("audio_montage_play",["peizhichenggong.mp3"]) - #self.aud.play(1,0,'U:/static/peizhichenggong.mp3')#切换成功 - 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]) - # EventMesh.publish("audio_montage_play",["peizhichenggong.mp3"]) - #self.aud.play(1,0,'U:/static/peizhichenggong.mp3')#切换成功 - 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]) - # EventMesh.publish("audio_montage_play",["peizhichenggong.mp3"]) - #self.aud.play(1,0,'U:/static/peizhichenggong.mp3')#切换成功 - 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]) - # EventMesh.publish("audio_montage_play",["peizhichenggong.mp3"]) - #self.aud.play(1,0,'U:/static/peizhichenggong.mp3')#切换成功 - 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]) - # EventMesh.publish("audio_montage_play",["peizhichenggong.mp3"]) - #self.aud.play(1,0,'U:/static/peizhichenggong.mp3')#切换成功 - 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]) - # EventMesh.publish("audio_montage_play",["peizhichenggong.mp3"]) - #self.aud.play(1,0,'U:/static/peizhichenggong.mp3')#切换成功 - 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]) - # EventMesh.publish("audio_montage_play",["peizhichenggong.mp3"]) - #self.aud.play(1,0,'U:/static/peizhichenggong.mp3')#切换成功 - 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]) - # EventMesh.publish("audio_montage_play",["peizhichenggong.mp3"]) - #self.aud.play(1,0,'U:/static/peizhichenggong.mp3')#切换成功 - - return 0 - if text.find("音量") != -1: - if text.find("加") != -1 : - self.VC_TTS_volume += 10 - if self.VC_TTS_volume > 100: - #EventMesh.publish("audio_montage_play",["yinliangyizuida.mp3"]) - #self.aud.play(1,0,'U:/static/yinliangyizuida.mp3')#音量已最大 - 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]) - #EventMesh.publish("audio_montage_play",["peizhichenggong.mp3"]) - #self.aud.play(1,0,'U:/static/peizhichenggong.mp3')#配置成功 - 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]) - #EventMesh.publish("audio_montage_play",["peizhichenggong.mp3"]) - #self.aud.play(1,0,'U:/static/peizhichenggong.mp3')#配置成功 - self.AI_TTS_str = "配置成功,当前音量 {}".format(self.VC_TTS_volume) - 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)<12 and (text.find("再见") != -1 or text.find("拜拜") != -1): - EventMesh.publish("publish_AI_btnInfo",{"func":self.Close}) - return 1 - except Exception as e: - usys.print_exception(e) - return -1 - #获取trace_id - def get_trace_id(self): - t = utime.mktime(utime.localtime()) - t = t*1000+urandom.randint(0, 1000) - md5_data = "{}".format(t)#md5签名 - sign_data = "" - hash_obj = uhashlib.md5(md5_data) - res = hash_obj.digest() - - # 转成十六进制表示 - sign_data = ubinascii.hexlify(res) - sign_data = sign_data.decode('ascii') - return sign_data - - def get_session_id(self,data = "session_id"): - t = utime.mktime(utime.localtime()) - t = t*1000+urandom.randint(0, 1000) - md5_data = "{}{}".format(data,t)#md5签名 - sign_data = "" - hash_obj = uhashlib.md5(md5_data) - res = hash_obj.digest() - - # 转成十六进制表示 - sign_data = ubinascii.hexlify(res) - sign_data = sign_data.decode('ascii') - return sign_data - - def get_new_message_id(self): - message_id = self.get_trace_id()+"aaa"+self.get_trace_id() - self.VC_message_id=message_id[:32] - return self.VC_message_id - def get_new_task_id(self): - task_id = self.get_trace_id()+"aaa"+self.get_trace_id() - self.VC_task_id=task_id[:32] - return self.VC_task_id - #开始播放声音 - def VC_Play_Start(self): - self.tts_in_data_len = 0 - self.tts_out_data_len = 0 - if self.VC_play_TYPE == VC_play_TYPE_PCM: - # if self.VC_play_samplerate == 8000: - # pass - # elif self.VC_play_samplerate == 16000: - # if self.play_pcm == None: - # self.play_pcm = audio.Audio.PCM(0,1,16000,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)) - if self.play_pcm == None: - self.aud.stopPlayStream() - self.aud.stopAll() - 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 - #停止播放声音 - def VC_Play_End(self): - if self.VC_play_TYPE == VC_play_TYPE_PCM: - if self.VC_play_samplerate == 8000: - self.aud.stopPlayStream() - self.aud.stopAll() - else: - if self.play_pcm != None: - print("Close:play_pcm.close()!!!!!!!!!!!!!!!!!!") - try: - self.play_pcm.stream_stop() - self.play_pcm.close() - except Exception as e: - usys.print_exception(e) - self.play_pcm=None - self.aud.stopPlayStream() - self.aud.stopAll() - elif self.VC_play_TYPE == VC_play_TYPE_MP3: - self.aud.stopPlayStream() - self.aud.stopAll() - - def _1S_timer_cb(self,*argc): - EventMesh.publish("publish_AI_btnInfo",{"func":self._1S_timer_cb_}) - - def _1S_timer_cb_(self): - - EventMesh.publish("system_sleep_rest")#防止黑屏 - self.close_timerout += 1 - if self.close_timerout > 60:#20秒没数据就close - - if self.VC_state >= VC_State_SpeechIng: - print("接口无响应,超时退出") - EventMesh.publish("publish_AI_btnInfo",{"func":self.websocket_error,"data":"接口超时了。请重试"}) - self.ud_error(["VC",self.VC_taskid]) - else: - EventMesh.publish("publish_AI_btnInfo",{"func":self.Close}) - # print("get_audio_state !!!!!{} {} {}\r\n".format(self.play_end,EventMesh.publish("get_audio_state"),self.play_flag)) - if self.LocalRespondingEnded_timerout>0 :# - self.LocalRespondingEnded_timerout -= 1 - print("LocalRespondingEnded_timerout:{}".format(self.LocalRespondingEnded_timerout)) - if self.LocalRespondingEnded_timerout <= 0 or (self.play_pcm != None and self.play_pcm.stream_is_empty() == 1) :#超时或者音频播放完, - self.LocalRespondingEnded_timerout = 0 - if self.VC_mode == 1 :#长按单次问答模式 - EventMesh.publish("publish_AI_btnInfo",{"func":self.Close}) - else: - EventMesh.publish("publish_AI_btnInfo",{"func":self.VC_Speech_Start})#开始录音 - #通知服务器播放结束 - 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() - 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.VC_Thinking_timerout == 0: - self.VC_Thinking_timerout = 100 - print("Thinking重试,重试!!!!!!!!!!!!!!!!!!!!!") - self.VC_state = VC_State_None - EventMesh.publish("publish_AI_btnInfo",{"func":self.AI_VC_start}) - pass - if self.VC_Speech_end_timerout >0: - self.VC_Speech_end_timerout-=1 - if self.VC_Speech_end_timerout <=0: - self.VC_Speech_end_timerout = 0 - self.AI_client_VC_end_speech()#发送说话终止 - #VC开始 - def AI_VC_start(self): - print("AI_VC_start1") - self.VC_satrt_flag = 1 - if self.VC_Thinking_timerout < 100: - self.VC_Thinking_timerout = 0 - EventMesh.publish("open_led_all") - self.VC_Play_End()#关闭音频播放 - print("AI_VC_start2") - #self.aud.aud_tone_play(16,200)#播放按键音 - self.LocalRespondingEnded_timerout = 0 - self.close_timerout = 0 - - - # - 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("异常状态") - #self.AI_client_VC_RequestToSpeak() - self.websocket_deconnect_VC() - self.websocket_connect_VC()#连接服务器 - self.AI_client_VC_start_requset() - if self.AI_client_VC_isconnect == 0: - return - print("AI_VC_start3") - - self.VC_state = VC_State_None - if self.AI_TTS_str == "":#没有tts要播放的时候才开始录音 - #开始asr录音 - self.VC_Speech_Start() - # pass - print("AI_VC_start4") - - #开始线程 - - # if self.AI_VC_send_data_queue_thread_id == 0: - # _thread.stack_size(self.Audio_buf_size+8*1024) - # self.AI_VC_send_data_queue_thread_id = _thread.start_new_thread(self.AI_VC_send_data_queue_thread, ()) - # _thread.stack_size(8*1024) - # print("AI_VC_start :AI_VC_send_data_queue_thread_id :{} ".format(self.AI_VC_send_data_queue_thread_id)) - - if self.AI_audio_queue_thread_id ==0: - _thread.stack_size(24*1024) - self.AI_audio_queue_thread_id = _thread.start_new_thread(self.AI_audio_queue_thread, ()) - _thread.stack_size(8*1024) - print("AI_VC_start :AI_audio_queue_thread_id :{} ".format(self.AI_audio_queue_thread_id)) - else: - print("AI_VC_start :AI_audio_queue_thread_id != 0 ") - self._1S_timer.start(1000,1,self._1S_timer_cb) - # self.VC_pingping_timerout = 0 - # self.asr_pingping_timerout = 0 - print("AI_VC_start5") - #开始会话 - def AI_client_VC_start_requset(self): - voice="huoshan::zh_male_wennuanahu_moon_bigtts" - try: - voice = self.VC_TTS_voice_type[self.VC_TTS_voice_key]["voice"] - except Exception as e: - usys.print_exception(e) - json_data =\ - { - "id": "event_id", - "event_type": "chat.update", - "data": { - "chat_config": { - "auto_save_history": True, #保存历史记录。默认 true - #"conversation_id": "1235984as1d54", #conversation_id - "user_id": "86952145024", #标识当前与智能体的用户,由使用方自行定义、生成与维护。user_id 用于标识对话中的不同用户,不同的 user_id,其对话的上下文消息、数据库等对话记忆数据互相隔离。如果不需要用户数据隔离,可将此参数固定为一个任意字符串 - "meta_data": {}, #附加信息,通常用于封装一些业务相关的字段。查看对话消息详情时,系统会透传此附加信息。 - "custom_variables": {}, #智能体中定义的变量。在智能体prompt中设置变量{{key}}后,可以通过该参数传入变量值,同时支持Jinja2语法。详细说明可参考变量示例。变量名只支持英文字母和下划线。 - "extra_params": {}, #附加参数,通常用于特殊场景下指定一些必要参数供模型判断,例如指定经纬度,并询问智能体此位置的天气。自定义键值对格式,其中键(key)仅支持设置为:latitude:纬度,此时值(Value)为纬度值,例如39.9800718。longitude:经度,此时值(Value)为经度值,例如116.309314。 - "parameters": {"custom_var_1": "测试"} - }, - "input_audio": { #输入音频格式 - "format": "pcm", #输入音频格式,支持 pcm/wav/ogg。默认 wav - #"codec": "pcm", #输入音频编码。 pcm/opus。默认 pcm - "samplate_rate": self.VC_record_samplerate, #采样率 - "channel": 1, #通道数 - "bit_depth": 16 #位深 - }, - "output_audio": { #输出音频格式 - - "codec": "pcm", #pcm/opus 输出音频格式, 默认 pcm - "pcm_config": { - "sample_rate": self.VC_play_samplerate, #码率 - - }, - "speech_rate": 50, #回复的语速,取值范围 [-50, 100],默认为 0,-50 表示 0.5 倍速,100 表示 2倍速 - #"voice_id": "zh_female_shaoergushi_mars_bigtts" - }, - "turn_detection": { - "type": "server_vad", - "prefix_padding_ms": 600, - "silence_duration_ms": 500, - }, - } - } - # 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' - 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 , - } - } - #self.AI_client_VC_send(ujson.dumps(json_data)) - self.VC_Speech_Start()#开启线程获取录音数据 - self.VC_state = VC_State_SpeechStart - def AI_client_VC_input_audio_buffer_append(self,data): - json_data = \ - { - "id": "event_id", - "event_type": "input_audio_buffer.append", - "data": { - "delta": ubinascii.b2a_base64(data) - } - } - self.AI_client_VC_send(ujson.dumps(json_data)) - #结束上传语音 - def AI_client_VC_end_speech(self): - json_data = \ - { - "id": "event_id", - "event_type": "input_audio_buffer.complete", - "data": {} - } - 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 = \ - { - "header":{ - "trace_id":self.get_trace_id(), - "event":"RequestToSpeak" - }, - "payload":{ - "dialog_id":self.VC_dialog_id, - "session_id": self.session_id , - } - } - print("AI_client_VC_RequestToSpeak!!!!!!!!!!!!!!!!!!!!!!!!!!!!!") - 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()#调试临时打开 - 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":"" - } - } - - print("AI_client_VC_RequestToRespond!!!!!!!!!!!!!!!!!!!!!!!!!!!!!") - # 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) - 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_close(self): - print("AI_audio_queue_thread_close1!!!!!!!!!!!!!!!!!!!!!!") - if self.AI_audio_queue_thread_id != 0: - count =500 - while True: - count -= 1 - if self.AI_audio_queue_thread_lock == 0 or count <=0: - break - else: - self.AI_audio_queue_thread_lock = 2 - print("AI_audio_queue_thread going:{}...".format(count)) - utime.sleep_ms(1) - self.AI_audio_queue_thread_lock = 0 - print("AI_audio_queue_thread_close2!!!!!!!!!!!!!!!!!") - try: - _thread.stop_thread(self.AI_audio_queue_thread_id) - except Exception as e: - usys.print_exception(e) - self.AI_audio_queue_thread_id = 0 - # 音频队列 - def AI_audio_queue_thread(self): - print("AI_audio_queue_thread start") - count = 0 - while True: - try: - if self.AI_audio_queue_thread_lock == 2: - print("AI_audio_queue_thread 该退出了") - break - # - count+=1 - if count%500 == 1: - print("AI_audio_queue_thread on") - utime.sleep_ms(1) - #print("AI_audio_queue_thread") - if self.AI_audio_queue.empty() : - self.AI_audio_queue_thread_lock = 0 - - - else: - self.AI_audio_queue_thread_lock = 1 - data = self.AI_audio_queue.get() - 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: - 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: - - - - write_buf = bytearray(data[0]) - #print("play_pcm.stream_write1!!") - if self.play_pcm != None: - print("play_pcm.stream_write !!!") - ret = self.play_pcm.stream_write(write_buf,len(write_buf)) - #ret= self.aud.playStream(1, data[0])#播放音频流 - self.tts_out_data_len += ret - #print("play_pcm.stream_write:{}".format(self.tts_out_data_len)) - elif self.VC_play_TYPE == VC_play_TYPE_MP3: - tmp= self.aud.playStream(3, data[0])#播放音频流 - - if tmp != 0: - print("2playStream:error tmp:{} data len:{}!!!!!!!!!!!!".format(tmp,len(data[0]))) - # # #播放失败的时候填充WAV头 - # data_len = len(data[0]) - # data_len_b = data_len.to_bytes(4,'little')#数据长度转16进制数组 - # h_data = [ 0x52 ,0x49 ,0x46 ,0x46 #,0x24 ,0x00 ,0x00 ,0x00 #文件标识、文件大小 - # ,0x57 ,0x41 ,0x56 ,0x45 ,0x66 ,0x6D ,0x74 ,0x20 #文件格式、格式块标识符 - # ,0x10 ,0x00 ,0x00 ,0x00 ,0x01 ,0x00 ,0x01 ,0x00 ,0x80 ,0x3E ,0x00 ,0x00 #格式块大小4、音频格式2、声道数2、采样率4 - # ,0x80 ,0x3E ,0x00 ,0x00 ,0x02 ,0x00 ,0x10 ,0x00 ,0x64 ,0x61 ,0x74 ,0x61]#每秒字节数4、数据块对齐2、位深度2、data4 - # h_data_b = bytes(h_data) - # file_len = data_len+len(h_data_b)+4+4 - # file_len_b = file_len.to_bytes(4,'little')#文件长度转16进制数组 - # h_data_b = h_data_b[:4]+file_len_b+h_data_b[4:]+data_len_b - # #self.aud.playStream(2, h_data_b)#播放音频流 - # tmp= self.aud.playStream(2, h_data_b+data[0])#播放音频流 - # print("3playStream:tmp:{} !!!!!!!!!!!!".format(tmp)) - - - mem = gc.mem_free() - #print('1剩余内存RAM:{} KB'.format(mem / 1024)) - except Exception as e: - print("AI_audio_queue_thread:ERROR:") - usys.print_exception(e) - - # if self.VC_state == VC_State_TTSEnd and self.AI_audio_queue.empty() :#self.AI_audio_queue为空且tts下发结束 - # #通知服务器播放结束 - # self.AI_client_VC_LocalRespondingEnded() - except Exception as e: - print("AI_audio_queue_thread:ERROR:") - usys.print_exception(e) - self.AI_audio_queue_thread_lock = 0 - #print("AI_audio_queue_thread:exit") - def factory_mode(self): - print("factory_mode") - EventMesh.publish("publish_AI_btnInfo",{"func":self.Close}) - EventMesh.publish("publish_AI_btnInfo",{"func":self.factory_start}) - def factory_start(self): - self.factory_timer.start(3000, 1, self.factory_timer_cb) - def factory_timer_cb(self, *args, **kwargs): - print("factory_timer_cb play......") - #self.aud.play(1,0,'U:/static/peizhichenggong.mp3')#切换成功 - EventMesh.publish("audio_montage_play",["xinhaoruo1.mp3"]) - - def Close(self): - self.VC_Thinking_timerout = 0 - self.VC_satrt_flag = 0 - self.AI_TTS_str = "" - self.AI_ASR_str = "" - self.AI_ASR_str_tmp = "" - self.AI_ASR_flag = 0 - self.AI_ASR_check_timeout = 0 - self.AI_ASR_error_timeout = 0 - print("ai_VC Close1!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!") - EventMesh.publish("close_led") - 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) - try: - self.AI_VC_send_data_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!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!") - - - self.AI_ASR_timer.stop() - self._1S_timer.stop() - self.factory_timer.stop() - - if self.record_data_save_flag == 1: - if self.record_fd : - self.record_fd.close() - self.record_fd = None - if self.play_data_save_flag == 1: - if self.play_fd !=None: - self.play_fd.close() - print("ai_VC Close3!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!\r\n") - - 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) - - # try: - # while True: - # if self.AI_WS_connect_Queue.empty()!=True: - # AI_WS_connect = self.AI_WS_connect_Queue.get() - # if AI_WS_connect : - # try: - # AI_WS_connect._close() - # AI_WS_connect = None - # except Exception as e: - # usys.print_exception(e) - # else: - # print("websocket链接已为空") - # else: - # break - # except Exception as e: - # usys.print_exception(e) - - def VC_init2(self): - self.VC_init() - - print("ai_VC VC_init2!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!") - try: - self.websocket_deconnect_VC() - except Exception as e: - usys.print_exception(e) - print("ai_VC Close3!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!\r\n") - 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() - def VC_init(self): - - print("VC_init:AI_VC_send_data_queue:size:{}".format(self.AI_VC_send_data_queue.size())) - - - print("VC_init2") - #self.VC_Speech_End() - print("VC_init3") - self.VC_Play_End() - print("VC_init4") - - if self.AI_audio_queue.empty()!=True: - self.AI_audio_queue.clear() - # num = EventMesh.publish("get_volum_size") - # if num == None: - # num = 8 - # self.aud.setVolume(num)#恢复原始音量 - \ No newline at end of file diff --git a/2.sdk/project/7PIN/sdk/services/microPython/ports/quectel/core/ai_VC_t.py b/2.sdk/project/7PIN/sdk/services/microPython/ports/quectel/core/ai_VC_t.py deleted file mode 100644 index cbd73085..00000000 --- a/2.sdk/project/7PIN/sdk/services/microPython/ports/quectel/core/ai_VC_t.py +++ /dev/null @@ -1,741 +0,0 @@ -from common import Abstract, LogAdapter -import EventMesh -import uwebsocket -import usys -import gc -import urandom -import uhashlib -import ubinascii -import ujson -import osTimer -import _thread -from queue import Queue -import utime -import audio -import uos -from machine import Pin -from machine import ExtInt -from machine import WDT -import modem -import sim -import net -import base64 -import ucryptolib -import urandom as random -import request -import ql_fs -class AI_led(Abstract): - def __init__(self): - self.led_red = Pin(Pin.GPIO36, Pin.OUT, Pin.PULL_PD, 0) - self.led_green = Pin(Pin.GPIO44, Pin.OUT, Pin.PULL_PD, 0) - self.led_white = Pin(Pin.GPIO21, Pin.OUT, Pin.PULL_PD, 0) - EventMesh.subscribe("open_led_red",self.open_led_red) - EventMesh.subscribe("open_led_white",self.open_led_white) - EventMesh.subscribe("open_led_green",self.open_led_green) - EventMesh.subscribe("close_led",self.close_led) - - def open_led_red(self,event,msg): - #self.led_red.write(0) - self.led_white.write(0) - self.led_green.write(0) - self.led_red.write(1) - - def open_led_white(self,event,msg): - self.led_red.write(0) - #self.led_white.write(0) - self.led_green.write(0) - self.led_white.write(1) - - def open_led_green(self,event,msg): - self.led_red.write(0) - self.led_white.write(0) - #self.led_green.write(0) - self.led_green.write(1) - - def close_led(self,event,msg): - self.led_red.write(0) - self.led_white.write(0) - self.led_green.write(0) - -class AI_dev(Abstract): - # AI - def __init__(self): - self.KeyAI_status = 0 - self.KeyAI_timer_count = 0 - self.KeyAI_long_press = 0 - self.KeyAI_press = 0 - self.KeyAI_timer = osTimer() - self.extint_AI = ExtInt(ExtInt.GPIO22,ExtInt.IRQ_RISING_FALLING, ExtInt.PULL_PU, self.keyAI_extint_cb) - self.extint_AI.enable() - self.GPIO26_status = 0 - self.GPIO26_timer_count = 0 - self.GPIO26_long_press = 0 - self.GPIO26_press = 0 - self.GPIO26_timer = osTimer() - self.pwk_key26 = ExtInt(ExtInt.GPIO41, ExtInt.IRQ_RISING_FALLING, ExtInt.PULL_PU, self.pwk_extint_cb) - self.pwk_key26.enable() - self.btnInfo_queue = Queue() - _thread.stack_size(10*1024) - _thread.start_new_thread(self.btnInfo_queue_thread, ()) - _thread.stack_size(8*1024) - EventMesh.subscribe("publish_AI_btnInfo",self.publish_AI_btnInfo) - #self.wdt = WDT(30) #开启看门狗 - self.wdt_timer = osTimer() - self.wdt_timer.start(10000, 1, self.wdt_timer_cb) - def btnInfo_queue_thread(self): - while True: - data = self.btnInfo_queue.get() - #EventMesh.debug_log("Info_queue:data = {}".format(data)) - if data != None: - try: - if "data" in data : - data["func"](data["data"]) - else : - data["func"]() - except Exception as e: - #EventMesh.debug_log("btnInfo_queue:ERROR:{}".format(e)) - usys.print_exception(e) - def publish_AI_btnInfo(self,event,msg): - self.btnInfo_queue.put(msg) - - def pwk_extint_cb(self,args):#pwk - try: - self.GPIO26_status = int(args[1]) - if self.GPIO26_status == 0: - self.GPIO26_status = 1 - else: - self.GPIO26_status = 0 - pass - if self.GPIO26_status == 0:#按下 - if self.GPIO26_press == 0 : - self.pwk_key26.disable() - self.GPIO26_press = 1 - self.GPIO26_long_press = 0 - self.GPIO26_timer.start(100, 1, self.GPIO26_timer_cb) - self.GPIO26_timer_count = 0 - #EventMesh.publish("AI_key_press") - - except Exception as e: - usys.print_exception(e) - def GPIO26_timer_cb(self, *args, **kwargs): - try: - self.GPIO26_status = self.extint_AI.read_level() - self.GPIO26_timer_count +=1 - if self.GPIO26_timer_count >= 10*3: #长按3s - if self.GPIO26_long_press == 0: - self.GPIO26_long_press = 1 - #EventMesh.publish("AI_key_long_press") - #EventMesh.publish("publish_AI_btnInfo",{"func":self.AI_key_long_press}) - if self.GPIO26_status == 1:#松开 - #print("GPIO26_timer_cb:{}".format(self.GPIO26_timer_count)) - if self.GPIO26_timer_count >= 5: #防抖200ms - #EventMesh.publish("AI_key_release") - EventMesh.publish("publish_AI_btnInfo",{"func":self.pwk_key_release}) - self.pwk_key26.enable() - self.GPIO26_timer.stop() - self.GPIO26_timer_count = 0 - self.GPIO26_press = 0 - - except Exception as e: - usys.print_exception(e) - - def keyAI_extint_cb(self,args):#call 2 - try: - #print("AI_btn:keyAI_extint_cb{}".format(args[1])) - self.KeyAI_status = int(args[1]) - if self.KeyAI_status == 0: - self.KeyAI_status = 1 - else: - self.KeyAI_status = 0 - - if self.KeyAI_status == 0:#按下 - if self.KeyAI_press == 0 : - self.extint_AI.disable() - self.KeyAI_press = 1 - self.KeyAI_long_press = 0 - self.KeyAI_timer.start(100, 1, self.KeyAI_timer_cb) - self.KeyAI_timer_count = 0 - #EventMesh.publish("AI_key_press") - EventMesh.publish("publish_AI_btnInfo",{"func":self.AI_key_press}) - except Exception as e: - usys.print_exception(e) - def KeyAI_timer_cb(self, *args, **kwargs): - try: - self.KeyAI_status = self.extint_AI.read_level() - self.KeyAI_timer_count +=1 - if self.KeyAI_timer_count >= 10*3: #长按3s - if self.KeyAI_long_press == 0: - self.KeyAI_long_press = 1 - #EventMesh.publish("AI_key_long_press") - EventMesh.publish("publish_AI_btnInfo",{"func":self.AI_key_long_press}) - if self.KeyAI_status == 1:#松开 - #print("KeyAI_timer_cb:{}".format(self.KeyAI_timer_count)) - if self.KeyAI_timer_count >= 5: #防抖200ms - #EventMesh.publish("AI_key_release") - EventMesh.publish("publish_AI_btnInfo",{"func":self.AI_key_release}) - self.extint_AI.enable() - self.KeyAI_timer.stop() - self.KeyAI_timer_count = 0 - self.KeyAI_press = 0 - - except Exception as e: - usys.print_exception(e) - - def AI_key_press(self): - #print("AI_key_press") - EventMesh.publish("AI_key_press") - def AI_key_long_press(self): - #print("AI_key_long_press") - EventMesh.publish("AI_key_long_press") - def AI_key_release(self): - #print("AI_key_release") - EventMesh.publish("AI_key_release") - def pwk_key_release(self): - #print("pwk_key_release") - EventMesh.publish("pwk_key_release") - def wdt_timer_cb(self, *args, **kwargs): - EventMesh.publish("publish_AI_btnInfo",{"func":self.wdt_feed}) - def wdt_feed(self): - #self.wdt.feed() - - pass -#存储信息 -class getStorageDataManager(Abstract):#获取内存数据 - def __init__(self): - self.config_data = {} - check = ql_fs.path_exists("/usr/static/storage_file/config.json") - if check == True: - with open("/usr/static/storage_file/config.json","r") as fd: - self.config_data = ujson.load(fd) - else : - self.config_data = {'old_time': 0, 'flip_sw': 0} - pass - - def post_processor_after_instantiation(self): - EventMesh.subscribe("set_storage_data", self.set_storage_data) - EventMesh.subscribe("set_storage_config", self.set_storage_config) - EventMesh.subscribe("get_storage_data", self.get_storage_data) - EventMesh.subscribe("get_storage_config", self.get_storage_config) - - def set_storage_data(self, event, msg): - # EventMesh.debug_log("set_storage_data:{}".format(msg)) - if msg != None: - self.config_data = msg - with open("/usr/static/storage_file/config.json",'w+',encoding="utf-8") as fd: - ujson.dump(self.config_data,fd) - - - def set_storage_config(self,event,msg): - # EventMesh.debug_log("set_storage_key_data1:{}".format(msg)) - if len(msg) >= 2: - self.config_data[msg[0]]=msg[1] - # EventMesh.debug_log("set_storage_key_data2:{}".format(self.config_data[msg[0]])) - EventMesh.publish("publish_message_event_ui",{"func":self.set_storage_save,"data":0}) - def set_storage_save(self, data): - with open("/usr/static/storage_file/config.json",'w+',encoding="utf-8") as fd: - ujson.dump(self.config_data,fd) - def get_storage_data(self, event, msg): - # EventMesh.debug_log("get_storage_data:{}".format(self.config_data)) - return self.config_data - def get_storage_config(self,event,msg): - # EventMesh.debug_log("get_storage_key_data1:{}".format(msg)) - b = msg in self.config_data.keys() - if b == True: - # EventMesh.debug_log("get_storage_key_data2:{}".format(self.config_data[msg])) - return self.config_data[msg] - else : - return None - # try: - # return self.config_data[msg] - # except: - # EventMesh.debug_log("get_storage_key_data:none key:{}",msg) - # return None -#设备资源授权平台 - -#阿里voice_chat状态枚举 -VC_State_None=0 -VC_State_Listening=1#听 -VC_State_SpeechStart=2#说开始 -VC_State_SpeechEnd=3#说结束 -VC_State_Thinking=4#想(chat) -VC_State_Responding=5#音频播放 -VC_State_TTSStart=6 -VC_State_TTSData=7 -VC_State_TTSFinish=8 -VC_State_TTSEnd=9 -VC_State_TTSError=10 -VC_State_DialogError=11 -VC_State_End=12 - -VC_record_TYPE_PCM = 0 -VC_record_TYPE_AMR = 1 -VC_play_TYPE_PCM = 0 -VC_play_TYPE_MP3 = 1 - -#websocket发送数据编号 -# AI_client_asr_num = 0 -# AI_client_chat_num = 1 -# AI_client_tts_num = 2 -AI_client_voice_chat_num = 3 -class AI_VC(Abstract): - # AI - def __init__(self): - self.AI_audio_queue_thread_id = 0 - self.AI_send_data_queue_thread_id = 0 - - self.AI_record_tmp_queue = Queue(100) - self.AI_send_data_queue = Queue(100) - self.AI_audio_queue = Queue(100) - # #开始线程 - # if self.AI_audio_queue_thread_id ==0: - # self.AI_audio_queue_thread_id = _thread.start_new_thread(self.AI_audio_queue_thread, ()) - # else: - # print("AI_VC_start :AI_audio_queue_thread_id != 0 ") - # if self.AI_send_data_queue_thread_id == 0: - # self.AI_send_data_queue_thread_id = _thread.start_new_thread(self.AI_send_data_queue_thread, ()) - - self.voice_chat_state = VC_State_None #阿里ai voice_chat状态 - self.VC_dialog_id = None - self.VC_message_id=None - self.VC_task_id =None - self.AI_client_voice_chat = None - self.AI_client_voice_chat_recv_id = 0 - self.AI_client_voice_chat_isconnect =0 - self.record_pcm = None - self.play_pcm = None - self.VC_record_thread_id = 0 - self.pingping_timerout = 0 - self.VC_record_TYPE = VC_record_TYPE_PCM #0:PCM 1:AMR - self.VC_play_TYPE = VC_play_TYPE_PCM #0:PCM 1:mp3 - self.VC_record_samplerate = 16000 - self.VC_play_samplerate = 16000 - self._1S_timer = osTimer() - self.Audio_buf_size = 16*1024 - self.record = audio.Record() - #self.record.end_callback(self.record_callback) - self.record.gain_set(4,10) - self.aud = audio.Audio(0) - self.aud.setCallback(self.audio_cb) - self.aud.setVolume(11)#恢复原始音量 - self.audio_play_state = 1 #音频播放完状态 - self.close_timerout = 0 - self.LocalRespondingEnded_timerout = 0 - - self.play_flag = 0 - self.VC_record_state_flag = 0 - self.AI_key_long_press_flag = 0 - EventMesh.subscribe("AI_key_press", self.AI_key_press) - EventMesh.subscribe("AI_key_release", self.AI_key_release) - EventMesh.subscribe("AI_key_long_press", self.AI_key_long_press) - EventMesh.subscribe("pwk_key_release", self.pwk_key_release) - EventMesh.subscribe("get_AI_audio_queue", self.get_AI_audio_queue) - self.aud.play(1,0,'U:/static/R_POWER_OFF_1.mp3')#开机音频 - self.test_timer = osTimer() - self.test_timer.start(6000, 1, self.test_timer_cb) - def test_timer_cb(self, *args, **kwargs): - self.aud.play(1,0,'U:/test.mp3')#开机音频 - print("test_timer_cb") - - def post_processor_after_instantiation(self): - pass - def get_AI_audio_queue(self, event, msg): - return self.AI_audio_queue - def audio_cb(self,event): - if event == 0: - self.audio_play_state =1 - #EventMesh.publish("set_audio_state", 1) - print('audio-play start.') - elif event == 7: - self.audio_play_state = 0 - #EventMesh.publish("set_audio_state", 0) - print('audio-play finish.!!!!!!') - - def AI_key_press(self, event, msg):#按键按下 - print("AI_key_press") - self.AI_VC_start() - self.AI_key_long_press_flag = 0 - - def AI_key_release(self, event, msg):#按键弹起 - print("AI_key_release") - EventMesh.publish("publish_AI_btnInfo",{"func":self.Close}) - - def AI_key_long_press(self, event, msg):#按键长按 - print("AI_key_long_press") - self.AI_key_long_press_flag = 1 - - def pwk_key_release(self, event, msg):#电源键短按,关闭 - print("pwk_key_release") - EventMesh.publish("publish_AI_btnInfo",{"func":self.VC_Play_Start}) - - - - - #开始播放声音 - def VC_Play_Start(self): - self.VC_init() - #开始线程 - if self.AI_audio_queue_thread_id ==0: - _thread.stack_size(24*1024) - self.AI_audio_queue_thread_id = _thread.start_new_thread(self.AI_audio_queue_thread, ()) - _thread.stack_size(8*1024) - print("AI_VC_start :AI_audio_queue_thread_id :{} ".format(self.AI_audio_queue_thread_id)) - else: - print("AI_VC_start :AI_audio_queue_thread_id != 0 ") - if self.AI_send_data_queue_thread_id == 0: - _thread.stack_size(self.Audio_buf_size+8*1024) - self.AI_send_data_queue_thread_id = _thread.start_new_thread(self.AI_send_data_queue_thread, ()) - _thread.stack_size(8*1024) - print("AI_VC_start :AI_send_data_queue_thread_id :{} ".format(self.AI_send_data_queue_thread_id)) - self._1S_timer.start(1000,1,self._1S_timer_cb) - self.pingping_timerout = 0 - size = 4*1024 - if self.VC_play_TYPE == VC_play_TYPE_PCM: - if self.VC_play_samplerate == 8000: - pass - elif self.VC_play_samplerate == 16000: - if self.play_pcm == None: - self.play_pcm = audio.Audio.PCM(0,1,16000,1,1,2) - self.play_pcm.setVolume(11) - ret = self.play_pcm.stream_write_start() - with open("/usr/test.pcm", "rb")as f: - while 1: - b = f.read(size) # read - if not b: - break - #aud.playStream(format, b) - #ret = self.play_pcm.stream_write(b,len(b)) - #ret= self.aud.playStream(1, data[0])#播放音频流 - #print("play_pcm.stream_write:{}".format(ret)) - ret=self.AI_audio_queue.put([b,""]) - utime.sleep_ms(100) - print("self.record_pcm.stream_write_start") - - elif self.VC_play_TYPE == VC_play_TYPE_MP3: - pass - #停止播放声音 - def VC_Play_End(self): - if self.VC_play_TYPE == VC_play_TYPE_PCM: - if self.VC_play_samplerate == 8000: - self.aud.stopPlayStream() - self.aud.stopAll() - elif self.VC_play_samplerate == 16000: - if self.play_pcm != None: - print("Close:play_pcm.close()!!!!!!!!!!!!!!!!!!") - try: - self.play_pcm.stream_stop() - self.play_pcm.close() - except Exception as e: - usys.print_exception(e) - self.play_pcm=None - self.aud.stopPlayStream() - self.aud.stopAll() - elif self.VC_play_TYPE == VC_play_TYPE_MP3: - self.aud.stopPlayStream() - self.aud.stopAll() - #开始录音 - def VC_Speech_Start(self): - #self.voice_chat_state = VC_State_SpeechStart - - if self.VC_record_state_flag == 0: - if self.VC_record_thread_id != 0: - try: - _thread.stop_thread(self.VC_record_thread_id) - except Exception as e: - usys.print_exception(e) - self.VC_record_thread_id = 0 - _thread.stack_size(self.Audio_buf_size+8*1024) - self.VC_record_thread_id = _thread.start_new_thread(self.VC_record_thread,()) - _thread.stack_size(8*1024) - print("self.VC_record_thread_id:{}".format(self.VC_record_thread_id)) - if self.VC_record_TYPE == VC_record_TYPE_AMR : - try : - self.record.stream_start(audio.Record.AMRNB, self.VC_record_samplerate, 0) - except Exception as e: - usys.print_exception(e) - elif self.VC_record_TYPE == VC_record_TYPE_PCM: - print("record_pcm.stream_read_start()!!!!!!!!!!!!") - self.record.stream_start(audio.Record.WAV, self.VC_record_samplerate, 0) - # if self.record_pcm != None: - # try: - # self.record_pcm.stream_stop() - # self.record_pcm.close() - # self.record_pcm = None - # except Exception as e: - # usys.print_exception(e) - # if self.record_pcm == None: - # ret = self.record_pcm = audio.Audio.PCM(0,1,16000,0,1,2) - # print("audio.Audio.PCM:ret:{}".format(ret)) - # ret = self.record_pcm.stream_read_start() - # print("self.record_pcm.stream_read_start:ret:{}".format(ret)) - self.VC_record_state_flag = 1 - #停止录音 - def VC_Speech_End(self): - try: - self.rec_fd.close() - if self.VC_record_TYPE == VC_record_TYPE_AMR: - - self.record.stream_stop() - self.record.stop()#关闭录音 - Record_read_buf = bytearray(self.Audio_buf_size) - for i in range(10): - Record_len = self.record.stream_read(Record_read_buf, self.Audio_buf_size) - print("Record_len:!!!!!!{}\r\n".format(Record_len)) - if Record_len <= 0: - break - elif self.VC_record_TYPE == VC_record_TYPE_PCM: - self.record.stream_stop() - self.record.stop()#关闭录音 - Record_read_buf = bytearray(self.Audio_buf_size) - for i in range(10): - Record_len = self.record.stream_read(Record_read_buf, self.Audio_buf_size) - print("Record_len:!!!!!!{}\r\n".format(Record_len)) - if Record_len <= 0: - break - # if self.record_pcm != None: - # try: - # self.record_pcm.stream_stop() - # self.record_pcm.close() - # self.record_pcm = None - # except Exception as e: - # usys.print_exception(e) - except Exception as e: - usys.print_exception(e) - self.voice_chat_state = VC_State_SpeechEnd - if self.VC_record_thread_id != 0: - try: - _thread.stop_thread(self.VC_record_thread_id) - except Exception as e: - usys.print_exception(e) - self.VC_record_thread_id = 0 - self.VC_record_state_flag = 0 - #获取录音数据 - def VC_record_thread(self): - ##return - print("VC_record_thread start!!!!!!!!!!!!!!!!!!!!\r\n") - count = 0 - try: - uos.remove('/usr/test.pcm') - except Exception as e: - usys.print_exception(e) - #record_data_queue = Queue(100) - self.rec_fd = open('/usr/test.pcm','w') - # if self.VC_record_TYPE == 1: - # h_data= [0x23,0x21 ,0x41 ,0x4D ,0x52 ,0x0A ] - # h_data_b = bytes(h_data) - # self.AI_client_voice_chat_send(h_data_b) - while True: - try: - # 死循环接收数据 - - Record_read_buf = bytearray(self.Audio_buf_size) - - 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) - - else : - - Record_len = self.record.stream_read(Record_read_buf, self.Audio_buf_size) - utime.sleep_ms(1000) - - #Record_len = 1024*2 - print("VC_record_thread:{}".format(Record_len)) - if Record_len > 0: - read_buf = bytes(Record_read_buf[:Record_len]) - self.rec_fd.write(read_buf) - #record_data_queue.put(read_buf) - - if self.voice_chat_state != VC_State_SpeechStart:#没发送前先存起来 - self.AI_record_tmp_queue.put(read_buf) - else: - while True: - if self.AI_record_tmp_queue.empty() == True: - break - else: - self.AI_client_voice_chat_send(self.AI_record_tmp_queue.get()) #发送之前存的数据 - self.AI_client_voice_chat_send(read_buf) - #print("VC_record_thread:{}".format(len(read_buf))) - count+=len(read_buf) - - utime.sleep_ms(40) - - except Exception as e: - usys.print_exception(e) - break - self.rec_fd.close() - - print("VC_record_thread:exit") - self.VC_record_thread_id = 0#线程退出 - def _1S_timer_cb(self,*argc): - EventMesh.publish("system_sleep_rest")#防止黑屏 - - #VC开始 - def AI_VC_start(self): - self.VC_init()#关闭一些资源 - #self.Close()#关闭一些资源 - #self.aud.aud_tone_play(16,200)#播放按键音 - #self.tts_fd = open('/usr/tts_tesr.pcm','w') - self.aud.play(1,0,'U:/tts_tesr.mp3')#开机音频 - #self.websocket_connect_voice_chat()#连接服务器 - #self.AI_client_voice_chat_start_requset() - self.close_timerout = 0 - self.voice_chat_state = VC_State_None - #开始录音 - self.VC_Speech_Start() - - #开始线程 - if self.AI_audio_queue_thread_id ==0: - _thread.stack_size(24*1024) - self.AI_audio_queue_thread_id = _thread.start_new_thread(self.AI_audio_queue_thread, ()) - _thread.stack_size(8*1024) - print("AI_VC_start :AI_audio_queue_thread_id :{} ".format(self.AI_audio_queue_thread_id)) - else: - print("AI_VC_start :AI_audio_queue_thread_id != 0 ") - if self.AI_send_data_queue_thread_id == 0: - _thread.stack_size(self.Audio_buf_size+8*1024) - self.AI_send_data_queue_thread_id = _thread.start_new_thread(self.AI_send_data_queue_thread, ()) - _thread.stack_size(8*1024) - print("AI_VC_start :AI_send_data_queue_thread_id :{} ".format(self.AI_send_data_queue_thread_id)) - self._1S_timer.start(1000,1,self._1S_timer_cb) - self.pingping_timerout = 0 - - - - #发送数据队列 - def AI_send_data_queue_thread(self): - print("AI_send_data_queue_thread:start") - count_t = 0 - while True: - if self.AI_send_data_queue.empty() : - count_t+=1 - # if count_t%200 == 0: - # print("self.AI_send_data_queue.empty") - utime.sleep_ms(5) - else: - #data[0]是websocket连接对象编号,data[1]是数据 - #print("AI_send_data_queue_thread:get") - data = self.AI_send_data_queue.get() - #print("AI_send_data_queue_thread:get2") - if data != None: - try: - #data["func"](data["data"]) - # 发送数据 - #bytes_data = bytes(data[1]) - #data[0].send(data[1]) - #print("AI_send_data_queue_thread:len:{}".format(len(data[1]))) - if data[0] == AI_client_voice_chat_num: - # if self.AI_client_voice_chat_isconnect == 0: - # try: - # self.websocket_connect_voice_chat() - # except Exception as e: #网络连接异常 - # usys.print_exception(e) - self.pingping_timerout = 0 - #print("VC: send_data len:{}".format(len(data[1]))) - if self.AI_client_voice_chat != None: - self.AI_client_voice_chat.send(data[1]) - #print("VC: send_data end") - except Exception as e: - print("DeviceInfo_queue_thread:ERROR:{}".format(e)) - usys.print_exception(e) - if data[0] == AI_client_voice_chat_num: - self.websocket_error_voice_chat() - #self.websocket_deconnect_voice_chat() - # self.AI_client_voice_chat_isconnect = 0 - # try: - # self.websocket_connect_voice_chat() - # except Exception as e: #网络连接异常 - # usys.print_exception(e) - - ############################################ - # 音频队列 - def AI_audio_queue_thread(self): - print("AI_audio_queue_thread start") - while True: - try: - # if self.AI_send_data_queue_thread_id == 0: - # break - # print("AI_audio_queue_thread") - if self.AI_audio_queue.empty() : - utime.sleep_ms(5) - else: - data = self.AI_audio_queue.get() - - #self.AI_client_tts_data_len=len(data) - print("\r\naudio_queue:len:{},data{}".format(len(data[0]),len(data[1]))) - if len(data[0]) > 10: - 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: - - write_buf = bytearray(data[0]) - #print("play_pcm.stream_write1!!") - if self.play_pcm != None: - ret = self.play_pcm.stream_write(write_buf,len(write_buf)) - #ret= self.aud.playStream(1, data[0])#播放音频流 - print("play_pcm.stream_write:{}".format(ret)) - elif self.VC_play_TYPE == VC_play_TYPE_MP3: - tmp= self.aud.playStream(3, data[0])#播放音频流 - - if tmp != 0: - print("2playStream:error tmp:{} data len:{}!!!!!!!!!!!!".format(tmp,len(data[0]))) - - - #print("出:{},{}!!!".format(len(data[0]),self.AI_client_tts_data_len)) - mem = gc.mem_free() - print('1剩余内存RAM:{} KB'.format(mem / 1024)) - except Exception as e: - print("AI_audio_queue_thread:ERROR:") - usys.print_exception(e) - - - except Exception as e: - print("AI_audio_queue_thread:ERROR:") - usys.print_exception(e) - #print("AI_audio_queue_thread:exit") - - def Close(self): - print("ai_VC Close!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!") - print("ai_VC Close!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!") - print("ai_VC Close!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!") - print("ai_VC Close!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!") - try: - #销毁线程 - if self.AI_audio_queue_thread_id != 0: - try: - _thread.stop_thread(self.AI_audio_queue_thread_id) - except Exception as e: - usys.print_exception(e) - self.AI_audio_queue_thread_id = 0 - if self.AI_send_data_queue_thread_id != 0: - try: - _thread.stop_thread(self.AI_send_data_queue_thread_id) - except Exception as e: - usys.print_exception(e) - self.AI_send_data_queue_thread_id = 0 - - - except Exception as e: - usys.print_exception(e) - - self.VC_init() - self._1S_timer.stop() - - def VC_init(self): - - - self.VC_Speech_End() - self.VC_Play_End() - - self.AI_send_data_queue.clear() - print("VC_init:AI_send_data_queue:size:{}".format(self.AI_send_data_queue.size())) - self.AI_audio_queue.clear() - EventMesh.publish("close_led") - # num = EventMesh.publish("get_volum_size") - # if num == None: - # num = 8 - # self.aud.setVolume(num)#恢复原始音量 - \ No newline at end of file