串口接收数据优化
authordxy <1731678236qq.com>
Mon, 15 Sep 2025 10:05:26 +0000 (18:05 +0800)
committerdxy <1731678236qq.com>
Mon, 15 Sep 2025 10:05:26 +0000 (18:05 +0800)
开始会话请求加token

2.sdk/project/7PIN_1_5/sdk/services/microPython/ports/quectel/core/ai_VC.py

index c8835a1..ebefc5a 100644 (file)
@@ -40,6 +40,7 @@ try:
 except Exception as e:
     usys.print_exception(e)
     import ai_alarm as _ai_alarm
+PRESS_AUDIO_MODE = 0 #是按键音 0 是使用音频文件
 # dev_type = "G10"
 #dev_type = "7PIN_BK"#小瑞
 #dev_type = "7PIN_BK_coze"#k扣子小瑞
@@ -214,6 +215,7 @@ DATA = {}
 class AI_UART():
     #串口命令通道
     def __init__(self):
+        self.send_count=0
         self.AI_uart = UART(UART.UART4, 230400, 8, 0, 1, 0)
         self.AI_uart.set_callback(self.uart_call)
         
@@ -244,12 +246,79 @@ class AI_UART():
         self.ping_json_str_tmp =""
         self.read_uart_data = ""
         self.bt_versions=""
+        
+        self.uart_send_queue = Queue(100)
+        self.uart_send_queue_thread_id = _thread.start_new_thread(self.uart_send_queue_thread, ())
+
+        self.uart_recv_queue = Queue(100)
+        self.uart_recv_queue_thread_id = _thread.start_new_thread(self.uart_recv_queue_thread, ())
         self.send_get_versions()#获取蓝牙版本
+    
+    def uart_send_queue_thread(self):
+        while True:
+            data = self.uart_send_queue.get()
+            
+            #EventMesh.debug_log("Info_queue:data = {}".format(data))
+            if data != None:
+                try:
+                    if len(data) != 0:
+                        print("send_queu_uart_data2:{} data:{}".format(data,data["data"]))
+                        # json_str  =ujson.dumps(data)
+                        if data["event"] == "uart_send_data":
+                            print("send_queu_uart_data sucess data:{} {}".format(data["data"],type(data["data"])))
+                            self.uart_queue_send_data(data["data"])
+                        if "resend_flag" in data:
+                            print("需要重发")
+                            print("send_reset_cb:{} {}".format(data["resend_flag"],data["ACK_time"]))
+                            if data["resend_flag"] == 1:
+                                self.send_count = 5#重试5次
+                                ack_timer = 0 #单次最大等待时间
+                                count = 0
+                                if "ACK_time" in data:
+                                    if data["ACK_time"] == None:
+                                        ack_timer = 100#最大重发5次,没ack或者返回error重发
+                                    else:
+                                        ack_timer = data["ACK_time"]
+                                if ack_timer > 0:
+                                    while self.send_count:
+                                        
+                                        if self.send_count <=0 or self.read_ack_flag == 1:
+                                            print("4G串口重发机制退出:{} self.read_ack_flag:{} json_str:{}".format(self.send_count,self.read_ack_flag,data["data"]))
+                                            break
+                                        if count >= ack_timer:
+                                            count = 0
+                                            print("串口异常,重发:")
+                                            self.uart_queue_send_data(data["data"])
+                                            self.send_count-=1
+                                        count += 1
+                                        utime.sleep_ms(1)
+
+                except Exception as e:
+                    usys.print_exception(e)
+                utime.sleep_ms(10)
+    
+    def uart_recv_queue_thread(self):
+        while True:
+            data = self.uart_recv_queue.get()
+            
+            #EventMesh.debug_log("Info_queue:data = {}".format(data))
+            if data != None:
+                try:
+                    if len(data) != 0:
+                        print("recv_queu_uart_data2:{}".format(data))
+                        # json_str  =ujson.dumps(data)
+                        # queue_data={"event":"uart_recv_data"}
+                        if data["event"] == "uart_recv_data":
+                            print("recv_queu_uart_data sucess data:{}".format(type(data["event"])))
+                            self.pares_uart_data()
+                except Exception as e:
+                    usys.print_exception(e)
 
     def send_imei_to_ble(self,event,msg):
         EventMesh.publish("publish_AI_btnInfo",{"func":self.send_imei_to_ble_cb})
 
     def send_imei_to_ble_cb(self):
+        self.read_ack_flag=0
         imei  = modem.getDevImei()
         json_data = \
         {
@@ -263,22 +332,27 @@ class AI_UART():
         self.send_data(json_str)
         pass
     def send_connect_bt_mac(self,event,msg):
+        self.read_ack_flag=0
         json_data = \
         {
             "event": "connect_bt",
             "data":msg
         }
         json_str =ujson.dumps(json_data)
-        self.send_data(json_str)
+        self.send_data(json_str,1,2000)
+        # self.send_reset_cb(json_str,0,2000) #每2s发送一次 10ms为单位
         pass
     def send_disconnect_bt_mac(self,event,msg):
+        self.read_ack_flag=0
         json_data = \
         {
             "event": "disconnect_bt",
             "data":msg
         }
         json_str =ujson.dumps(json_data)
-        self.send_data(json_str)
+        self.send_data(json_str,1)
+        # self.send_reset_cb(json_str)
+
         pass
     def uart_timer_cb(self, *args, **kwargs):
         self.uart_timer_count+=1
@@ -318,8 +392,14 @@ class AI_UART():
         return json_list
     
     def uart_call(self,para):
-        EventMesh.publish("publish_AI_btnInfo",{"func":self.pares_uart_data})
+        queue_data={"event":"uart_recv_data"}
+
+        self.uart_recv_queue.put(queue_data)
+        # print("uart_call start")
+        # EventMesh.publish("publish_AI_btnInfo",{"func":self.pares_uart_data})
+        # print("uart_call end")
         #print("ai_uart:{}".format(para))  
+    #[{"event":""},{},{}]
     def pares_uart_data(self):  
         uart_data = self.AI_uart.read()
         self.uart_timer.start(10, 1, self.uart_timer_cb)
@@ -327,9 +407,9 @@ class AI_UART():
         ack_flag = 0#是否要返回ack
         print("uart_data:{}",uart_data)
         uart_data_str = uart_data.decode('utf-8')
+    
         self.read_uart_data = self.read_uart_data +uart_data_str
         try:
-
             ujson.loads(self.read_uart_data)
         except Exception as e:
             print("json数据不完整:self.read_uart_data{}".format(self.read_uart_data))
@@ -394,6 +474,9 @@ class AI_UART():
             if jsload_data["event"] == "AI_KEY_PRESS" :#AI按键按下
                 EventMesh.publish("publish_AI_btnInfo",{"func":self.AI_key_press})  
                 ack_flag = 1
+            elif jsload_data["event"] == "BT_AI_KEY_PRESS" :#蓝牙耳机key ai对话模式不支持长按对话模式 只支持短按按键对话模式 重新定义按键
+                EventMesh.publish("publish_AI_btnInfo",{"func":self.BT_AI_key_press})  
+                ack_flag = 1
             elif jsload_data["event"] == "AI_PWR_PRESS" :#电源按键按下
                 EventMesh.publish("publish_AI_btnInfo",{"func":self.pwk_key_release})  
                 ack_flag = 1
@@ -409,7 +492,6 @@ class AI_UART():
                 EventMesh.publish("save_bt_connect_list",jsload_data)
                 EventMesh.publish("send_bt_connect_list")
                 ack_flag=1
-            
             elif jsload_data["event"]=="get_ble_switch":
                 ble_switch_flag =  EventMesh.publish("get_storage_config","switch_ble_state")#ble开关
                 if ble_switch_flag == None:
@@ -467,6 +549,7 @@ class AI_UART():
         print("clear_earphone_record{}".format(json_str))
         self.send_data(json_str)
     def adjust_volume_toBle(self,event,msg): #
+        self.read_ack_flag=0
         volume = int(msg)
         if volume <= 10:
             volume = 10
@@ -477,7 +560,7 @@ class AI_UART():
         }
         json_str  =ujson.dumps(json_data)
         print("adjust_volume_toBle{}".format(json_str))
-        self.send_data(json_str)
+        self.send_data(json_str,1)
 
     def AI_send_bt_ble_switch_toble(self,event,msg):
         # // {
@@ -501,6 +584,7 @@ class AI_UART():
             json_str  =ujson.dumps(json_data)
             print("switch_ble_state{}".format(json_str))
             self.send_data(json_str)
+
         elif  msg == 2: #AI对话开启蓝牙
             json_data = \
             {
@@ -522,11 +606,11 @@ class AI_UART():
                 "data":{
                     "switch_bt_state":"1"
                 }   
-            
             }
             json_str  =ujson.dumps(json_data)
             print("switch_bt_state{}".format(json_str))
             self.send_data(json_str)
+
         elif  msg == 4: #AI对话开启蓝牙
             json_data = \
             {
@@ -550,7 +634,7 @@ class AI_UART():
         #     //         "switch_bt_state":"0"
         #     //     }
         #     // } #格式
-
+        self.read_ack_flag=0
         json_data = \
         {
             
@@ -563,6 +647,7 @@ class AI_UART():
         json_str  =ujson.dumps(json_data)
         print("send_bt_switch_toble{}".format(json_str))
         self.send_data(json_str)
+
     def send_ble_switch_toble(self,event,msg):
         EventMesh.publish("publish_AI_btnInfo",{"func":self.send_ble_switch_toble_cb,"data":msg})
     def send_ble_switch_toble_cb(self,data):
@@ -576,32 +661,32 @@ class AI_UART():
         self.read_ack_flag=0
         json_data = \
         {
-            
             "event": "switch_ble_state",
             "data":{
                 "switch_ble_state":str(data)
             }   
-           
         }
         json_str  =ujson.dumps(json_data)
         print("send_ble_switch_toble{}".format(json_str))
         self.send_data(json_str)    
-        
-    def send_reset_cb(self):
-        send_count = 5#最大重发5次,没ack或者返回error重发
-        while 1:
-            send_count-=1
-            self.read_ack_flag = 0
-            #utime.sleep_ms(100)
-            count =100
-            while True:
-                count -=1
-                if count <=0 or self.read_ack_flag != 0 :
-                    break
-                utime.sleep_ms(10)
-            # print("ota_data:{} count:{}".format(len(json_str),count))
-            if send_count <=0 or self.read_ack_flag == 1:
+
+    # 重发机制
+    def send_reset_cb(self,json_str,need_resend = None,timeOut=None):
+        print("send_reset_cb:{} {} {}".format(json_str,need_resend,timeOut))
+        if timeOut == None:
+            self.send_count = 100#最大重发5次,没ack或者返回error重发
+        else:
+            self.send_count = timeOut
+
+        while self.send_count:
+            self.send_count-=1
+            utime.sleep_ms(10)
+            if self.send_count <=0 or self.read_ack_flag == 1:
+                print("4G串口重发机制退出:{} self.read_ack_flag:{} json_str:{}".format(self.send_count,self.read_ack_flag,json_str))
                 break
+            if self.send_count%(self.send_count//10) == 0:
+                print("串口异常,重发:")
+                self.send_data(json_str)
 
         pass
     def send_get_connect_bt_state(self,event,msg):
@@ -622,10 +707,11 @@ class AI_UART():
         self.get_bt_connect_flag = 0
         pass
     def send_ble_scan(self,event,msg):
+        self.read_ack_flag=0
         # // {
-        #     //     "event":"switch_bt_state",
+        #     //     "event":"send_ble_scan",
         #     //     "data":{
-        #     //         "switch_bt_state":"0"
+        #     //         "send_ble_scan":"0"
         #     //     }
         #     // } #格式
         json_data = \
@@ -637,13 +723,25 @@ class AI_UART():
         }
         json_str  =ujson.dumps(json_data)
         print("send_ble_scan{}".format(json_str))
-        self.send_data(json_str)
-        pass
-    def send_data(self,str_data):
+        self.send_data(json_str,1)
+        # self.send_reset_cb(json_str)
+
+        print("bt_send_end")
+    def send_data(self,str_data,need_resend = None,ACK_time =None):
+        print("send_data{} {} {}".format(str_data,need_resend,ACK_time))
+        queue_data={"event":"uart_send_data","data":str_data}
+        if need_resend != None:
+            queue_data={"event":"uart_send_data","data":str_data,"resend_flag":1,"ACK_time":ACK_time}
+
+        self.uart_send_queue.put(queue_data)
+    def uart_queue_send_data(self,str_data):
         if self.bt_ota_flag == 1:
             return
-        EventMesh.publish("wakeup_BT")
+        #EventMesh.publish("wakeup_BT")
+        print("bt_seuart_queue_send_data start {}".format(str_data))
+        EventMesh.publish(constants.EVENT.SYSTEM_UP)#唤醒休眠
         self.AI_uart.write(str_data)
+        print("bt_seuart_queue_send_data end {}".format(str_data))
     def led_r_open(self,event=None,msg=None):
         json_data = \
         {
@@ -710,6 +808,10 @@ class AI_UART():
         self.check_rest_timer_count = 0
         print("AI_key_press")
         EventMesh.publish("AI_key_press")
+    def BT_AI_key_press(self):
+        self.check_rest_timer_count = 0
+        print("BT_AI_key_press")
+        EventMesh.publish("BT_AI_key_press")
 
     def pwk_key_release(self):
         self.check_rest_timer_count = 0
@@ -730,7 +832,8 @@ class AI_UART():
 
         pass
     def start_ota(self,event=None,msg=None):#通过串口给蓝牙升级
-        EventMesh.publish("wakeup_BT") 
+        #EventMesh.publish("wakeup_BT") 
+        EventMesh.publish(constants.EVENT.SYSTEM_UP)#唤醒休眠
         print("start_ota!!!")
         print("start_ota!!!")
         json_data = \
@@ -749,7 +852,8 @@ class AI_UART():
         print("start_ota count:{}!!!".format(count))
 
     def end_ota(self,event=None,msg=None):#通过串口给蓝牙升级
-        EventMesh.publish("wakeup_BT") 
+        #EventMesh.publish("wakeup_BT") 
+        EventMesh.publish(constants.EVENT.SYSTEM_UP)#唤醒休眠
         print("end_ota!!!")
         print("end_ota!!!")
         json_data = \
@@ -980,7 +1084,7 @@ class AI_dev(Abstract):
         if bt_switch_flag == None:
             bt_switch_flag = "1"
         EventMesh.publish("send_bt_switch_toble",str(bt_switch_flag))
-        EventMesh.publish("send_imei_to_ble")
+        # EventMesh.publish("send_imei_to_ble")
         ble_switch_flag =  EventMesh.publish("get_storage_config","switch_ble_state")#ble开关
         if ble_switch_flag == None:
             ble_switch_flag = "1"
@@ -988,7 +1092,7 @@ class AI_dev(Abstract):
         vc_tts_volume = EventMesh.publish("get_storage_config","VC_TTS_volume")
         if vc_tts_volume == None:
             vc_tts_volume=100
-        EventMesh.publish("adjust_volume_toBle",str(vc_tts_volume))
+        # EventMesh.publish("adjust_volume_toBle",str(vc_tts_volume))
 
         pass
         print("ble_switch_flag_time_cb!!!!!!!")
@@ -1103,6 +1207,7 @@ class AI_dev(Abstract):
         wakeup_cta1_io = self.extint_wakeup_cta1.read_level()
         if wakeup_cta1_io == 1:
             return 1
+        self.PIN_wakeup_bt.write(0)
         count = 5
         while(True):
             count-=1
@@ -1115,9 +1220,9 @@ class AI_dev(Abstract):
                 return 1
             utime.sleep_ms(100)
             if count%2 == 0:
-                self.PIN_wakeup_bt.write(0)
-            else:
                 self.PIN_wakeup_bt.write(1)
+            else:
+                self.PIN_wakeup_bt.write(0)
 
         
     def sleep_BT(self,event=None,msg=None):#使蓝牙休眠
@@ -1337,7 +1442,7 @@ class AI_dev(Abstract):
     def AI_key_long_press(self):
         self.check_rest_timer_count = 0
         print("AI_key_long_press")
-        EventMesh.publish("wakeup_BT")
+
         EventMesh.publish("AI_key_long_press")
         
     def AI_key_release(self):
@@ -2710,6 +2815,7 @@ class AI_VC(Abstract):
         self.VC_satrt_kws_flag = 0
         self.session_id = ""
         EventMesh.subscribe("AI_key_press", self.AI_key_press)
+        EventMesh.subscribe("BT_AI_key_press", self.BT_AI_key_press)
         EventMesh.subscribe("stop_AI_record", self.stop_AI_record)
         EventMesh.subscribe("AI_key_release", self.AI_key_release)
         EventMesh.subscribe("AI_key_long_press", self.AI_key_long_press)
@@ -2953,13 +3059,62 @@ class AI_VC(Abstract):
         print("AI_key_press")
         self.get_config_timer_count = 0
         self.key_state = 1
-        if dev_type == "7PIN":
-            # self.record.stream_stop()
-            # self.record.stop()#关闭录音
-            # self.aud.stopPlayStream()
-            # self.aud.stopAll()
-            self.aud.aud_tone_play(10,200)#播放按键音
+        if PRESS_AUDIO_MODE == 1:
+            if dev_type == "7PIN":
+                self.aud.aud_tone_play(10,200)#播放按键音
         self.Close()
+        if PRESS_AUDIO_MODE == 0:
+            if dev_type == "7PIN":
+                self.chenggong_tone()
+        # if dev_type == "7PIN":
+        #     self.chenggong_tone()
+        #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 BT_AI_key_press(self, event=None, msg = None):#按键按下
+        EventMesh.publish(constants.EVENT.SYSTEM_UP)#唤醒休眠
+        if EventMesh.publish("get_sos_flag")== 1:
+            return
+        if self.voice_flag == 1: #语音留言模式
+           # EventMesh.publish("stop_AI_record")
+            self.Close()
+            EventMesh.publish("open_led_green")
+            EventMesh.publish("start_voice_record",2)#停止静默录音
+            return
+        
+        EventMesh.publish("stop_voice_record") #开启静默需要关闭
+        print("AI_key_press")
+        self.get_config_timer_count = 0
+        self.key_state = 1
+        if PRESS_AUDIO_MODE == 1:
+            if dev_type == "7PIN":
+                self.aud.aud_tone_play(10,200)#播放按键音
+        self.Close()
+        if PRESS_AUDIO_MODE == 0:
+            if dev_type == "7PIN":
+                self.chenggong_tone()
+        
+        if self.VC_mode == 1: #长按对话模式 接收到蓝牙耳机按键事件
+            
+            tts_str = "请您按住中间的按钮开始讲话,讲完松开即可 "
+            EventMesh.publish("play_tts",[tts_str,1])
+            return
         # if dev_type == "7PIN":
         #     self.chenggong_tone()
         #self.aud.aud_tone_play(10,200)#播放按键音
@@ -4749,7 +4904,9 @@ class AI_VC(Abstract):
         except Exception as e:
             usys.print_exception(e)    
         #voice="zh_female_dongmanxiaoyang_moon_bigtts"
- 
+        token = EventMesh.publish("get_dev_token")
+        if token ==None:
+            token = ""
         json_data = \
         {
             "header": {
@@ -4769,6 +4926,7 @@ class AI_VC(Abstract):
                         "disable_empty_prompt" : True,#拦截空字符请求大模型
                         "custom_variables": {
                             "name": self.bot_name,
+                            "devToken":token,
                             },
                         "greeting":{
                             "enabled":False,
@@ -5004,16 +5162,23 @@ class AI_VC(Abstract):
         if EventMesh.publish("get_sos_flag") == 1:
             return
         print("kws_even_cb")
-        if EventMesh.publish("get_voice_record_flag") == 1:#停止静默录音
-            if EventMesh.publish("get_voice_record_mode") == 2:#语音留言不能被打断
-                return
-            elif  EventMesh.publish("get_voice_record_mode") == 1: #静默录音需要打断
-                EventMesh.publish("stop_voice_record")#停止静默录音
-                
+        if self.VC_mode == 1: 
+            tts_str = "请您按住中间的按钮开始讲话,讲完松开即可 "
+            EventMesh.publish("play_tts",[tts_str,1]) 
+            return
         if self.VC_mode == 0:
+            if EventMesh.publish("get_voice_record_flag") == 1:#停止静默录音
+                if EventMesh.publish("get_voice_record_mode") == 2:#语音留言不能被打断
+                    return
+                elif  EventMesh.publish("get_voice_record_mode") == 1: #静默录音需要打断
+                    EventMesh.publish("stop_voice_record")#停止静默录音
+            if PRESS_AUDIO_MODE == 1:
+                if dev_type == "7PIN":
+                    self.aud.aud_tone_play(10,200)
             self.Close()
-            if dev_type == "7PIN":
-                self.chenggong_tone()
+            if PRESS_AUDIO_MODE == 0:
+                if dev_type == "7PIN":
+                    self.chenggong_tone()
             # if dev_type == "7PIN" :
             #     self.aud.aud_tone_play(10,400)#播放按键音
             #self.aud.aud_tone_play(10,200)#播放按键音