柒牌提交
authorp15692025051 <846603105@qq.com>
Wed, 11 Jun 2025 02:26:56 +0000 (10:26 +0800)
committerp15692025051 <846603105@qq.com>
Wed, 11 Jun 2025 02:26:56 +0000 (10:26 +0800)
12 files changed:
2.sdk/project/7PIN/list.json
2.sdk/project/7PIN/sdk/services/microPython/ports/quectel/core/Makefile
2.sdk/project/7PIN/sdk/services/microPython/ports/quectel/core/ai_VC.py
2.sdk/project/7PIN/sdk/services/microPython/ports/quectel/core/ai_VC_7PIN.py
2.sdk/project/7PIN/sdk/services/microPython/ports/quectel/core/ai_VC_G15.py
2.sdk/project/7PIN/sdk/services/microPython/ports/quectel/core/ai_VC_t.py
2.sdk/project/7PIN/sdk/services/microPython/ports/quectel/core/main_init.py
2.sdk/project/7PIN/sdk/system/platform/ASR_1606/boards/EG810MCN_GA_VOLTE/EG810MCN_GA_VOLTE.mk
2.sdk/project/7PIN/sdk/system/platform/ASR_1606/boards/EG810MCN_GA_VOLTE/config/autoconf.h
2.sdk/project/7PIN/sdk/system/platform/ASR_1606/boards/EG810MCN_GA_VOLTE/config/config.mk
2.sdk/project/7PIN/sdk/system/platform/ASR_1606/boards/EG810MCN_GA_VOLTE/images/firmware_base_release_pack.zip
2.sdk/project/7PIN/usr/static/audio.bin

index 64adee5..61c7c22 100644 (file)
@@ -1 +1 @@
-['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', 'shouhou', 'xinhaoruo1', 'zhengzaiguanji']
\ No newline at end of file
+['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']
\ No newline at end of file
index 2596118..207c41a 100644 (file)
@@ -380,6 +380,7 @@ SRC_QSTR += \
                        source/modwlan.c\
                        source/modwlan.c \
                        source/modmask.c \
+                       source/modVad.c \
                        source/machine_one_wire.c
 
 
index 53d5d7a..cbfb134 100644 (file)
@@ -40,7 +40,7 @@ dev_type = "7PIN"#柒牌
 #dev_type = 'sjgq'#四季甘泉
 #dev_type = 'szbst'#深圳百事通
 #dev_type = 'jswm'#金三完美
-#dev_type = 'jswm_BOX'#金三完美盒子
+#dev_type = 'jswm_BOX'#金三完美柒牌盒子
 #dev_type = 'csh'#慈善会
 class AI_led(Abstract):
     def __init__(self):
@@ -198,8 +198,8 @@ audio_buf = ['chenggong', 'didianguanji', 'IMEIhao', 'jianquancuowu', 'key_promp
 class AI_dev(Abstract):
     # AI
     def __init__(self):
-        if(dev_type != "7PIN"):
-            set_ipv4_datacall()
+        # if(dev_type != "7PIN"):
+        #     set_ipv4_datacall()
         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,}
@@ -438,11 +438,20 @@ class AI_dev(Abstract):
         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_timer_count >= 10*1 : #长按1s 
                 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})  
+                    self.KeyAI_long_press = 1
+                    #EventMesh.publish("AI_key_long_press")
+                    EventMesh.publish("publish_AI_btnInfo",{"func":self.AI_key_long_press})  
+            elif self.KeyAI_timer_count >= 10*8:#关机
+                if dev_type == 'jswm' or dev_type == 'jswm_BOX':
+                    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()
             if self.KeyAI_status == 1:#松开
                 #print("KeyAI_timer_cb:{}".format(self.KeyAI_timer_count))
                 key_count = 5
@@ -1081,13 +1090,16 @@ 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":#柒牌
+                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)
+
             print(url)
             response = request.get(url,timeout=5)
             if response.status_code == 200:
                 data = response.json()
-                print("min_sys_ota1:{}".format(data))
+                print("OTA升级请求:{}".format(data))
                 
                 if data:
                     try:
@@ -1141,13 +1153,15 @@ class OTA():
             url =None
             if dev_type == "7PIN_BK_EU":#英文小瑞
                 url = "http://dmp-global.raisound.com/bz-api/ota/result?deviceId={}&currentVersion={}".format(modem.getDevImei(),currentVersion)
+            if dev_type == "7PIN":#柒牌
+                url = "http://ota.qipai.com/bz-cmp-api/api/result?deviceId={}&currentVersion={}".format(modem.getDevImei(),currentVersion)
             else:
                 url = "http://dmp.raisound.com/bz-api/ota/result?deviceId={}&currentVersion={}".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))
+                print("OTA升级结果上报:{}".format(data))
             else:
                 print("ota_result  error!!!!")
                 for i in response.text:
@@ -1971,6 +1985,8 @@ class AI_VC(Abstract):
                 url = "http://dmp-global.raisound.com/bz-api/dev/config/{}".format(modem.getDevImei())
             else:
                 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:
@@ -2079,7 +2095,10 @@ class AI_VC(Abstract):
                 #self.VC_Speech_End()
     def AI_key_long_press(self, event, msg):#按键长按
         print("AI_key_long_press")
-        self.AI_key_long_press_flag = 1
+        if dev_type == 'jswm' or dev_type == 'jswm_BOX'  :
+            self.Close()
+        else:
+            self.AI_key_long_press_flag = 1
 
     def pwk_key_release(self, event, msg):#电源键短按,关闭
         print("pwk_key_release")
@@ -2869,8 +2888,8 @@ class AI_VC(Abstract):
             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 正常")
+                    if error_str.find("[Errno 110] ETIMEDOUT")!= -1 or error_str.find("[Errno 115] ")!= -1:
+                        print("VC VC:recv 正常报错:{}".format(error_str))
                         pass
                     else:
                         usys.print_exception(e)
index 45d91bc..75c0948 100644 (file)
@@ -27,58 +27,180 @@ 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):
-        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_white = Pin(Pin.GPIO19, Pin.OUT, Pin.PULL_PD, 1)
+        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_white",self.open_led_white)
+        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_white.write(0)
+        self.led_blue.write(0)
         self.led_green.write(0)
         self.led_red.write(1)
 
-    def open_led_white(self,event,msg):
+    def open_led_blue(self,event,msg):
+        #print("open_led_blue")
+        self.led_flicker_flag = 0
         self.led_red.write(0)
-        #self.led_white.write(0)
+        #self.led_blue.write(0)
         self.led_green.write(0)
-        self.led_white.write(1)
+        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_white.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_white.write(1)
+        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_white.write(0)
+        self.led_blue.write(0)
         self.led_green.write(0)
-audio_buf = ['dianliangshengyu10', 'dianliangshengyu100', 'dianliangshengyu20', 'dianliangshengyu40', 'dianliangshengyu60', 'dianliangshengyu80', 'dianliangshengyu90', 'IMEIhao', 'jianquancuowu', 'key_prompt', 'liuliangtishi', 'Low_power_warning', 'peizhichenggong', 'qiehuanchenggong', 'R_CHARGE_FULL', 'R_CHARGE_IN', 'R_CHARGE_OUT', 'R_POWER_OFF_1', '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_SIM_FAILE', 'xianyikaiji', 'xinhaoruo1', 'xinhaoruo2', 'yinliangyizuida', 'yinliangyizuixiao', 'zhengzaiguanji']
 
+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.VBATT_tab = {"charge_full":4300,100 :4250 ,  90:3994 , 80:3883, 60: 3707, 40:3604, 20:3537,  10:3486,}
+        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()
-        #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)
+        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
@@ -86,57 +208,78 @@ class AI_dev(Abstract):
         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 = ExtInt(ExtInt.GPIO41, ExtInt.IRQ_RISING_FALLING, ExtInt.PULL_PU, self.pwk_extint_cb)
+        
         self.pwk_key.enable() 
-        self.btnInfo_queue = Queue()
-        _thread.stack_size(10*1024)
-        _thread.start_new_thread(self.btnInfo_queue_thread, ())
+        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)
-        
-        self.wdt = WDT(30) #开启看门狗
-        # self.wdt_timer = osTimer()
-        # self.wdt_timer.start(10000, 1, self.wdt_timer_cb)
+        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
-            self.aud.stop()
-            #self.aud.play(1,1,'U:/static/R_CHARGE_IN.mp3')
-            EventMesh.publish("audio_montage_play",["R_CHARGE_IN.mp3"])
+            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
-            self.aud.stop()
-            EventMesh.publish("audio_montage_play",["R_CHARGE_OUT.mp3"])
-            #self.aud.play(1,1,'U:/static/R_CHARGE_OUT.mp3')
+            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:
@@ -148,7 +291,27 @@ class AI_dev(Abstract):
                     #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))
 
@@ -161,6 +324,7 @@ class AI_dev(Abstract):
                 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
@@ -168,10 +332,11 @@ class AI_dev(Abstract):
                     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
@@ -180,10 +345,22 @@ class AI_dev(Abstract):
                 if self.pwk_key_long_press == 0:
                         self.pwk_key_long_press = 1
                         #EventMesh.publish("AI_key_long_press")
-                        EventMesh.publish("publish_AI_btnInfo",{"func":self.pwk_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))
-                if self.pwk_key_timer_count >= 5: #防抖200ms
+                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()
@@ -205,16 +382,21 @@ class AI_dev(Abstract):
             
             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
@@ -225,7 +407,10 @@ class AI_dev(Abstract):
                         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
+                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()
@@ -237,16 +422,21 @@ class AI_dev(Abstract):
             usys.print_exception(e) 
        
     def AI_key_press(self):
-        #print("AI_key_press")
+        self.check_rest_timer_count = 0
+        print("AI_key_press")
         EventMesh.publish("AI_key_press")
+
     def AI_key_long_press(self):
-        #print("AI_key_long_press")
+        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")
+        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!!!!!!!")
         
@@ -256,46 +446,79 @@ class AI_dev(Abstract):
         #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):
-        self.wdt.feed()
+        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_charge_flag == 0 and self.usb_status == 1 and Vbatt>=self.VBATT_tab["charge_full"]:#充电充满
-            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_charge_flag == 0 and self.usb_status == 0 and Vbatt<self.VBATT_tab[10]:#低电报警
+        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<self.VBATT_tab["20"]and VC_satrt_flag == 0 and self.Low_power_warning_flag ==0:#低电报警
+            self.Low_power_warning_flag  = 1
+            EventMesh.publish("flicker_led_red")
             #self.aud.play(1,0,'Low_power_warning.mp3')
+            # self.Low_power_warning_timer+=1
+            # if self.Low_power_warning_timer >= 2:
+            #     self.Low_power_warning_timer = 0
             EventMesh.publish("audio_montage_play",["Low_power_warning.mp3"])
-            self.usb_charge_flag = 1
-        pass
+
+        if  self.usb_status == 0 and Vbatt<self.VBATT_tab["5"]:    
+            EventMesh.publish("audio_montage_play",["didianguanji.mp3"])
+            utime.sleep_ms(4500)
+            self.aud.stopPlayStream()
+            self.aud.stopAll()
+            Power.powerDown()
+
+        self.check_rest_timer_count += 1
+        if self.check_rest_timer_count >= 8640:#24小时没按键,则关机
+            self.pwk_key_Long_Press()
+        
     def get_battery(self, event=None, msg=None):
         Vbatt = Power.getVbatt()
-        if Vbatt>self.VBATT_tab[90]:
+        if Vbatt>self.VBATT_tab["90"]:
             return 100
-        if Vbatt>self.VBATT_tab[80]:
+        if Vbatt>self.VBATT_tab["80"]:
             return 90
-        if Vbatt>self.VBATT_tab[60]:
+        if Vbatt>self.VBATT_tab["60"]:
             return 80
-        if Vbatt>self.VBATT_tab[40]:
+        if Vbatt>self.VBATT_tab["40"]:
             return 60
-        if Vbatt>self.VBATT_tab[20]:
+        if Vbatt>self.VBATT_tab["20"]:
             return 40
-        if Vbatt>self.VBATT_tab[10]:
+        if Vbatt>self.VBATT_tab["10"]:
             return 20
-        if Vbatt<=self.VBATT_tab[10]:
+        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:
@@ -306,28 +529,30 @@ class AI_dev(Abstract):
         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()
-        if len(iccid) > 5:
-            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(iccid[0]))\
+        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])))
-        str_data += '{}.mp3+'.format(audio_buf.index("IMEIhao"))#IMEI号为:
-        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))
+                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])),\
@@ -335,6 +560,7 @@ class AI_dev(Abstract):
                 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):
@@ -390,6 +616,7 @@ class getStorageDataManager(Abstract):#获取内存数据
 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
@@ -408,62 +635,97 @@ class device_res_author(Abstract):
         self.pid = "cqxJZi5CNgzjS3mX21Zw"
         
         self.dev_res_timer = osTimer()
-        self.dev_res_timer.start(10000, 1, self.dev_timer_cb)
+        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(30000, 1, self.ud_token_timer_cb)
+        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() #设备登入
-        self.ntptime_flag = 0
+        print("device_res_author __init__ end !!!!!!!!!!!!!!!!!")
 
     def get_dev_token(self, event, msg): 
         return self.dev_token
     #网络校时
-    def dev_NTP(self):
-        url = "http://dmp.raisound.com/bz-api/dev/time"
-        response = request.get(url)
-        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))
-            except Exception as e:
-                    usys.print_exception(e)
+    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:
-        if self.dev_token == None:
-            if self.ntptime_flag == 0:
-                self.ntptime_flag  = 1
-                EventMesh.publish("publish_AI_btnInfo",{"func":self.dev_NTP})
-            print("timer:{}!!!!!!!!\r\n".format(utime.localtime()))
-            self.dev_active() #设备激活
-            self.dev_sign_in() #设备登入
-            self.dev_res_timerCount+=1
-            if self.dev_res_timerCount > 6: #开机一分钟内没有获取到密码和token 等下一次更新令牌在走登入 激活流程
-                self.dev_res_timerCount=0
-                self.dev_res_timer.stop()
+        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):   
-        #print("ud_token_timer_!!!!")
-        self.ud_token_timer_Count+=1
-        if self.ud_token_timer_Count >= 20: #定时30*200s时更新token
-            self.ud_token_timer_Count = 0
-            EventMesh.publish("update_dev_token")
-            
+        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):
@@ -503,11 +765,12 @@ class device_res_author(Abstract):
         result = self.unpad(result)  # 除去补16字节的多余字符
         return str(result, 'utf-8')  # 以字符串的形式返回
     #激活接口 没有密码走激活
-    def dev_active(self):
+    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")
@@ -515,79 +778,84 @@ class device_res_author(Abstract):
         if dev_pass == None:
             dev_pass = ""
         if dev_pass == "" or dev_pass == None:
-            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 = 0
-            response_result = 0
             try:
-                response = request.put(url,data=data,headers = headers_T)
-                response_result = 1
-            except Exception as e:
-                print("put error!!!!!\r\n")
+                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
-            
-            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)) 
+                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): 
@@ -598,22 +866,24 @@ class device_res_author(Abstract):
         return random_str
 
     #设备登入 没有Token 走登入获取token
-    def dev_sign_in(self):
+    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 = ""
-        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 == "":
+        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")
@@ -639,16 +909,18 @@ class device_res_author(Abstract):
                 response_result = 0
                 response = 0
                 try:
-                    response = request.post(sign_url,data=ujson.dumps(sign_in_data),headers = headers_T)
+                    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'}
                 # }
-                token = ""
+                
+                #self.dev_token = ""
                 if response_result == 1:
                     if response.status_code == 200:
                         content = response.content
@@ -664,71 +936,200 @@ class device_res_author(Abstract):
                                             self.dev_token = data_tmp["token"]
                                 if data["code"] == 50003:#时间错误
                                     self.ntptime_flag  = 0
-                print("token:{}\r\n".format(token))
+                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, msg):
+    def update_dev_token(self, event=None, msg=None):
         print("update_dev_token")
-        dev_pass = ""
-        dev_pass = EventMesh.publish("get_storage_config","dev_pass")
-        
-        if dev_pass == None:
+        try:
             dev_pass = ""
-        if len(dev_pass) == 0: #没有密码走激活
-            print("no dev_pass:{}\r\n".format(dev_pass))
-            self.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()
-
-        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 = 0
-            headers_T = {"bz-dt":"{}".format(token)}
-            try:
-                response = request.get(dev_tokenip,headers = headers_T)
-                response_result = 1
-            except Exception as e:
-                print("get error!!!!!\r\n")
-                response_result = 0
-            if response_result == 1:
-                if response.status_code == 200:
+            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:
-                        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))
+                        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:
-                        print("headers_data!!!!! error\r\n")
+                            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()
         
-        pass
-
-
-
-
-#阿里voice_chat状态枚举
+        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={}&currentVersion={}".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_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_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
@@ -739,74 +1140,289 @@ VC_play_TYPE_MP3 = 1
 # AI_client_asr_num = 0
 # AI_client_chat_num = 1
 # AI_client_tts_num = 2
-AI_client_voice_chat_num = 3
+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")#音色配置
+        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_server = 2 #0正式服务器,1:测试服务器1,2:测试服务器2
         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 = {0:"huoshan::zh_female_xinlingjitang_moon_bigtts",1:"huoshan::zh_male_wennuanahu_moon_bigtts",2:"huoshan::ICL_zh_female_huoponvhai_tob",
-                                  3:"aliyun::longjiaxin",4:"huoshan::zh_female_daimengchuanmei_moon_bigtts"}
-        #self.VC_TTS_voice_type = ["aliyun::longxiaoxia","aliyun::longnan","aliyun::longling"]
-        self.VC_TTS_voice_num = EventMesh.publish("get_storage_config","VC_TTS_voice_num")#音色配置
-        if self.VC_TTS_voice_num == None or self.VC_TTS_voice_num>=len(self.VC_TTS_voice_type):
-            self.VC_TTS_voice_num = 0
-         
-        self.VC_TTS_volume =  EventMesh.publish("get_storage_config","VC_TTS_volume")#音量配置
+        
+        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_send_data_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_send_data_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_send_data_queue_thread_id == 0:    
-        #     self.AI_send_data_queue_thread_id = _thread.start_new_thread(self.AI_send_data_queue_thread, ())
+        # 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.voice_chat_state = VC_State_None #阿里ai voice_chat状态
-        self.VC_dialog_id = ""
+        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_voice_chat = None
-        self.AI_client_voice_chat_recv_id = 0
-        self.AI_client_voice_chat_isconnect =0
+        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_isconnect =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.pingping_timerout = 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.aud.setVolume(self.VC_TTS_volume //10)
         self.audio_play_state = 1 #音频播放完状态
         self.close_timerout = 0
         self.LocalRespondingEnded_timerout = 0
@@ -814,31 +1430,154 @@ class AI_VC(Abstract):
         self.play_flag = 0
         self.VC_record_state_flag = 0
         self.AI_key_long_press_flag = 0
-        self.websocket_error_voice_chat_count = 0
-        self.play_data_len = 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 = "柒先生"
-        if self.VC_TTS_voice_num == 0 or self.VC_TTS_voice_num == 3 or self.VC_TTS_voice_num == 4:
-            self.bot_name = "柒妹妹"
-        elif self.VC_TTS_voice_num == 1:
-            self.bot_name = "柒先生"
-        elif self.VC_TTS_voice_num == 2:
-            self.bot_name = "柒思思"
-        self.AI_TTS_str = "您好!我是柒牌 AI 智能男装生活好帮手-{}, 很高兴为您服务,我可以帮您解答日常生活、工作,旅游信息、健康咨询、教育与学习、情感交流、全球资讯等问题!请问您有什么需要我帮忙的吗?".format(self.bot_name )
-        EventMesh.publish("publish_AI_btnInfo",{"func":self.AI_VC_start}) 
+        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
@@ -850,28 +1589,51 @@ class AI_VC(Abstract):
             print('audio-play finish.!!!!!!')
 
     def AI_key_press(self, event, msg):#按键按下
-        print("AI_key_press voiceCall")
-        self.aud.aud_tone_play(16,200)#播放按键音
-        # import voiceCall
-        # voiceCall.callStart("10086")
-        # return 
-        EventMesh.publish("publish_AI_btnInfo",{"func":self.AI_VC_start}) 
+        print("AI_key_press")
+        self.get_config_timer_count = 0
+        self.key_state = 1
+        #self.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_voice_chat_end_speech()
+            #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 :#长按单次问答模式
-                EventMesh.publish("audio_montage_play",["key_prompt.mp3"])
-                #self.aud.play(1,1,'U:/static/key_prompt.mp3')#提示请您按住中间的按钮开始讲话,讲完松开即可
-                self.AI_send_data_queue.clear()
-                try:
-                    self.websocket_deconnect_voice_chat()
-                except Exception as e:
-                    usys.print_exception(e)
-                self.VC_Speech_End()
+                # 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
@@ -879,554 +1641,540 @@ class AI_VC(Abstract):
     def pwk_key_release(self, event, msg):#电源键短按,关闭
         print("pwk_key_release")
         EventMesh.publish("publish_AI_btnInfo",{"func":self.Close}) 
-#**********************************ASR连接**********************************************************
-    def websocket_connect_ASR(self):
-        print("websocket_connect_ASR:{}!!!!!!!!!!!!!!!!!!!!!".format(self.AI_client_ASR_isconnect))
-        if self.AI_client_ASR_isconnect == 1:
+
+    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
-        # 创建VC客户端
+        # 创建ASR客户端
         try:
             signal = net.csqQueryPoll()
             if signal == -1 or sim.getStatus() != 1:#网络正常
-                self.websocket_error_ASR()
+                self.websocket_error()
                 return
-            # Headers = {'X-NLS-Token':'0c8b8f05a46f423096be64a9c4c46310'}
-            # self.AI_client_ASR = uwebsocket.Client.connect('wss://nls-gateway-cn-beijing.aliyuncs.com/ws/v1',headers=Headers, debug=False)
-            if self.VC_server == 1 or self.VC_server == 2:# 
-                self.AI_client_ASR = uwebsocket.Client.connect('ws://amp.raisound.com/asr/ws', debug=False)#测试环境
-            else:
-                token = EventMesh.publish("get_dev_token")
-                print("token:{}".format(token))
-                if token != None:
-                    self.AI_client_ASR = uwebsocket.Client.connect('ws://amp.raisound.com/asr/ws?dt={}'.format(token), debug=False)
+
+            # 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:
-                    self.websocket_error_ASR()
+                    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)
             
+            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()
             
-        if self.AI_client_ASR == None:
-            EventMesh.publish("update_dev_token")#获取token
             return
-        
-        # 线程接收数据
-        if self.AI_client_ASR_recv_id != 0:
-            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
+        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,))
+        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
-    def websocket_error_ASR(self):
-        print("websocket_error_ASR!!!!")
-        print("websocket_error_ASR!!!!")
-        EventMesh.publish("audio_montage_play",["R_SIM_FAILE.mp3"])
-        #self.aud.play(1,1,'U:/static/R_SIM_FAILE.mp3')
-        self.AI_send_data_queue.clear()
-        self.AI_audio_queue.clear()
-        self.VC_Speech_End()
-        EventMesh.publish("close_led")
-        try:
-            self.websocket_deconnect_ASR()
-        except Exception as e:
-                usys.print_exception(e)
+        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!!!!!!!")
-        if self.AI_client_ASR_recv_id != 0:#关闭线程
+    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:
-                _thread.stop_thread(self.AI_client_ASR_recv_id)
-            except Exception as e:
-                usys.print_exception(e)
-        self.AI_client_ASR_recv_id = 0
-        if self.AI_client_ASR_isconnect == 1:
-            self.AI_client_ASR_isconnect = 0
-            self.AI_client_ASR.close()
-        print("websocket_deconnect_ASR {}!!!!!!!".format(self.AI_client_ASR_isconnect))
-        #Ai ASR websocket返回数据       
-    def AI_client_ASR_recv(self,cli):
-        while True:
-            try:
-                # 死循环接收数据
-                utime.sleep_ms(1)
-                recv_data = cli.recv()
-                self.close_timerout = 0#服务器有返回清零退出时间
-                if not recv_data:
-                    # 服务器关闭连接或客户端关闭连接
-                    print("AI_client_ASR_recv close!!!!!!!!!!!!!!!!!!!!!!!!!!!")
-                    #self.AI_client_ASR_isconnect = 0
-                    #self.websocket_deconnect_ASR()
-                    break
+                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:
-                    if isinstance(recv_data, str):#返回的是字符串
-                        print("ASR:recv_data:{}".format(recv_data))
-                        jsload_data =  ujson.loads(recv_data)
+                    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)
-                    #self.websocket_error_ASR()
-                    
-                    break
-        self.AI_client_ASR_isconnect = 0
-        self.AI_client_ASR_recv_id = 0 
-    
-#****************************************VC连接**********************************************************************
-    def websocket_connect_voice_chat(self):
-        print("websocket_connect_voice_chat:{}!!!!!!!!!!!!!!!!!!!!!".format(self.AI_client_voice_chat_isconnect))
-        if self.AI_client_voice_chat_isconnect == 1:
-            return
-        # 创建VC客户端
-        try:
-            signal = net.csqQueryPoll()
-            if signal == -1 or sim.getStatus() != 1:#网络正常
-                self.websocket_error_voice_chat()
-                return
-            # Headers = {'X-NLS-Token':'0c8b8f05a46f423096be64a9c4c46310'}
-            # self.AI_client_voice_chat = uwebsocket.Client.connect('wss://nls-gateway-cn-beijing.aliyuncs.com/ws/v1',headers=Headers, debug=False)
-            if self.VC_server == 1:# 
-                self.AI_client_voice_chat = uwebsocket.Client.connect('ws://118.145.158.207:22080/voice-chat/ws', debug=False)#测试环境
-            elif self.VC_server == 2:# 
-                if self.VC_TTS_voice_num <= 2:
-                    self.AI_client_voice_chat = uwebsocket.Client.connect('ws://118.145.158.207:22080/voice-chat/ws?is_auth=0&platform=raisound&lang=zh-cn', debug=False)#普通话测试环境
-                elif self.VC_TTS_voice_num == 3:
-                    self.AI_client_voice_chat = uwebsocket.Client.connect('ws://118.145.158.207:22080/voice-chat/ws?is_auth=0&platform=raisound&lang=zh-hk', debug=False)#粤语测试环境
-                elif self.VC_TTS_voice_num == 4:
-                    self.AI_client_voice_chat = uwebsocket.Client.connect('ws://118.145.158.207:22080/voice-chat/ws?is_auth=0&platform=raisound&lang=zh-cn-sc', debug=False)#四川话测试环境
+                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_client_voice_chat = uwebsocket.Client.connect('ws://118.145.158.207:22080/voice-chat/ws?is_auth=0&platform=raisound&lang=zh-cn', debug=False)#普通话测试环境
-            else:
-                token = EventMesh.publish("get_dev_token")
-                print("token:{}".format(token))
-                if token != None:
-                    self.AI_client_voice_chat = uwebsocket.Client.connect('ws://amp.raisound.com/voice-chat/ws?dt={}'.format(token), debug=False)
+                    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.websocket_error_voice_chat()
-                    return
-        except Exception as e: #网络连接异常
-            usys.print_exception(e)
-            print("websocket_connect_voice_chat error!!!\r\n")
-            #self.connect_timerout_popup(2)
-            self.websocket_error_voice_chat()
-            return
-        if self.AI_client_voice_chat == None:
-            EventMesh.publish("update_dev_token")#获取token
-            self.websocket_error_voice_chat()
-            return
-        
-        # 线程接收数据
-        if self.AI_client_voice_chat_recv_id != 0:
+                    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_client_voice_chat_recv_id)
+                _thread.stop_thread(self.AI_ASR_send_data_queue_thread_id)
             except Exception as e:
-                    usys.print_exception(e)
-            self.AI_client_voice_chat_recv_id = 0
-        _thread.stack_size(self.Audio_buf_size+8*1024)
-        self.AI_client_voice_chat_recv_id = _thread.start_new_thread(self.AI_client_voice_chat_recv, (self.AI_client_voice_chat,))
-        _thread.stack_size(8*1024)
-        self.AI_client_voice_chat_isconnect = 1
-    def websocket_error_voice_chat(self):
-        print("websocket_error_voice_chat!!!!")
-        print("websocket_error_voice_chat!!!!")
-        print("websocket_error_voice_chat!!!!")
-        print("websocket_error_voice_chat!!!!")
-        self.websocket_error_voice_chat_count+=1
-        if self.websocket_error_voice_chat_count <=3:
-            EventMesh.publish("audio_montage_play",["xinhaoruo1.mp3"])
-        elif self.websocket_error_voice_chat_count <10 :
-            EventMesh.publish("audio_montage_play",["xinhaoruo2.mp3"])
-        elif self.websocket_error_voice_chat_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')
-        self.AI_send_data_queue.clear()
-        self.AI_audio_queue.clear()
-        self.VC_Speech_End()
-        EventMesh.publish("close_led")
-        try:
-            self.websocket_deconnect_voice_chat()
-        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    
 
-    def websocket_deconnect_voice_chat(self):
-        print("websocket_deconnect_voice_chat {}!!!!!!!".format(self.AI_client_voice_chat_isconnect))
-        print("websocket_deconnect_voice_chat!!!!!!!")
-        if self.AI_client_voice_chat_recv_id != 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_voice_chat_recv_id)
+                _thread.stop_thread(self.AI_client_asr_recv_id)
             except Exception as e:
                 usys.print_exception(e)
-        self.AI_client_voice_chat_recv_id = 0
-        if self.AI_client_voice_chat_isconnect == 1:
-            self.AI_client_voice_chat_isconnect = 0
-            self.AI_client_voice_chat.close()
-        print("websocket_deconnect_voice_chat {}!!!!!!!".format(self.AI_client_voice_chat_isconnect))
-    #websocket发送ping
-    def AI_client_voice_chat_ping(self):
-        pass
-        if self.AI_client_voice_chat_isconnect == 1:
-            #self.AI_client_voice_chat.write_frame(0x09,b'ping ping')
-            self.AI_client_voice_chat_send("ping")
-            #print("websocket ping ping")
+        self.AI_client_asr_recv_id = 0
 
-    #websocket发送数据    
-    def AI_client_voice_chat_send(self,data_str):
-        if isinstance(data_str, str):#是字符串
-            print("AI_client_voice_chat_send:{}".format(data_str))
-            pass
-        # else:
-        #     print("AI_client_voice_chat_send:len{}".format(len(data_str)))
-        self.AI_send_data_queue.put([AI_client_voice_chat_num,data_str]) 
-    
-    #Ai VC websocket返回数据       
-    def AI_client_voice_chat_recv(self,cli):
+    #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 not recv_data:
-                    # 服务器关闭连接或客户端关闭连接
-                    print("AI_client_voice_chat_recv close!!!!!!!!!!!!!!!!!!!!!!!!!!!")
-                    #self.AI_client_voice_chat_isconnect = 0
-                    #self.websocket_deconnect_voice_chat()
-                    EventMesh.publish("publish_AI_btnInfo",{"func":self.websocket_error_voice_chat}) 
-                    EventMesh.publish("publish_AI_btnInfo",{"func":utime.sleep_ms,'data':(1000)})
-                    EventMesh.publish("publish_AI_btnInfo",{"func":self.AI_VC_start}) 
+                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:
-                    self.websocket_error_voice_chat_count = 0
-                    print("AI_client_voice_chat_recv 1")
-                    if isinstance(recv_data, str):#返回的是字符串
-                        print("VC:recv_data:{}".format(recv_data))
+                    if isinstance(recv_data, str):
                         jsload_data =  ujson.loads(recv_data)
-                        #print("AI_client_voice_chat_recv jsload_data = {}".format(jsload_data))
+                        print("ASR ASR recv_data: {}".format(jsload_data))
                         if jsload_data["status"] != 20000000:#返回错误
-                            self.websocket_error_voice_chat()
+                            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["event"] == "Started" :#会话开始
-                            payload = jsload_data["payload"]
-                            self.VC_dialog_id = payload["dialog_id"] 
-                            self.VC_task_id = jsload_data["task_id"] 
-                            print("VC:Started!!!!!!!!\r\n")
-                        if jsload_data["event"]  == "SpeechContent" :#asr转译
-                            print("VC:SpeechContent!!!!!!!!\r\n")
-                            payload = jsload_data["payload"]
-                            
-                            
-                            if(payload['finished'] == True):#asr结束
-                                self.voice_chat_state =  VC_State_SpeechEnd
-                                self.VC_Speech_End()#停止录音
-                                text = payload["text"]
-                                if self.check_text(text) == 0:
-                                    print("check_text ok:{}".format(text))
-                                    self.AI_send_data_queue.clear()
-                                    EventMesh.publish("open_led_all")
-                                    try:
-                                        EventMesh.publish("publish_AI_btnInfo",{"func":self.websocket_deconnect_voice_chat}) 
-                                        #EventMesh.publish("publish_AI_btnInfo",{"func":utime.sleep_ms,'data':(1500)})
-                                        EventMesh.publish("publish_AI_btnInfo",{"func":self.AI_VC_start}) 
-                                    except Exception as e:
-                                        usys.print_exception(e)
+                        
+                        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
-                            else:
-                                self.AI_listen_end = 0
-
-                        if jsload_data["event"]  == "SpeechEnded" :#服务器下发ASR说话结束
-                            self.voice_chat_state =  VC_State_SpeechEnd
-                        if jsload_data["event"]  == "RespondingContent" :#chat回答      
-                            
-                            payload = jsload_data["payload"]
-                            self.AI_label_str=str(payload['text'])#chat文本
-                            self.AI_client_chat_play_str=str(payload['text'])
-                            self.AI_client_tts_str_sen = str(payload['text'])
 
-                            if(payload['finished'] == True):#chat回答 结束,开始tts
-                                pass
-                            #utime.sleep_ms(5)
-                            
-                        if jsload_data["event"]  == "RespondingStarted" :#音频开始下发
-                            self.play_flag = 0
-                            self.voice_chat_state = VC_State_TTSStart
-                            self.VC_Play_Start()
-                            self.play_data_len = 0
-                            #self.tts_fd = open('/usr/tts_tesr.pcm','w')
-                            pass
-                        if jsload_data["event"]  == "RespondingEnded" :#音频下发结束
-                            if self.voice_chat_state == VC_State_TTSStart:
-                                self.voice_chat_state = VC_State_TTSEnd
-                            #self.tts_fd.close()
-                            pass
-                        elif jsload_data["event"]  == "DialogStateChanged" :#状态切换事件
-                            payload = jsload_data["payload"]
-                            if payload["state"] == "Listening":
-                                self.voice_chat_state = VC_State_Listening
-                                if self.AI_TTS_str != "":#有tts数据,则请求TTS数据,没有就请求开始上传语音
-                                    self.AI_client_voice_chat_RequestToRespond(self.AI_TTS_str)
-                                    self.AI_TTS_str = ""
-                                else:
-                                    self.AI_client_voice_chat_send_speech()#开始上传语音
-                                EventMesh.publish("open_led_red")
-                            if payload["state"] == "Thinking":#准备开始TTS
-                                self.voice_chat_state = VC_State_Thinking
+                            elif jsload_data["event"] == "Changed" or jsload_data["event"] == "SentenceEnd" : #开始录音Changed
+                                # if self.VC_record_state_flag == 2:
+                                #     
                                 
-                                self.AI_label_str = ""
-                                EventMesh.publish("open_led_all")
-                            if payload["state"] == "Responding":
-                                self.voice_chat_state = VC_State_Responding
-                                EventMesh.publish("open_led_green")
-                        elif jsload_data["event"]  == "RequestAccepted" :#请求上传语音被允许
-                            #self.voice_chat_state =  VC_State_Responding
-                            #self.AI_client_voice_chat_send_speech()#开始上传语音
-                            pass
-                    else:#下发音频数据
-                        self.play_data_len += len(recv_data)
-                        print("下发音频数据1:{} all:{}".format(len(recv_data),self.play_data_len))
-                        if self.voice_chat_state >= VC_State_TTSStart:
-                            EventMesh.publish("publish_AI_btnInfo",{"func":self.put_record_data,"data":[recv_data,""]}) 
-                    print("AI_client_voice_chat_recv 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:
-                    usys.print_exception(e)
-                    #self.websocket_error_voice_chat()
-                    EventMesh.publish("publish_AI_btnInfo",{"func":self.websocket_error_voice_chat}) 
-                    break
-        self.AI_client_voice_chat_isconnect = 0
-        self.AI_client_voice_chat_recv_id = 0 
-        print("AI_client_voice_chat_recv END!!!!!!!!!!!!!!!!!!!!!!!!!!!")
-    def put_record_data(self,data):
-        ret=self.AI_audio_queue.put(data)
-        print("下发音频数据2:{}".format(len(data[0])))
-    def check_text(self,text):
-        if len(text)>60:
-            return -1
-        try:
-            if isinstance(text, str): 
-                if text.find("更改声音") != -1:
-                    self.VC_TTS_voice_num += 1
-                    if self.VC_TTS_voice_num >= len(self.VC_TTS_voice_type):
-                        self.VC_TTS_voice_num = 0
-                    EventMesh.publish("set_storage_config",["VC_TTS_voice_num",self.VC_TTS_voice_num])
-                    # 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 and (text.find("男声") != -1 or text.find("男生") != -1 ):
-                    self.VC_TTS_voice_num = 1
-                    
-                    EventMesh.publish("set_storage_config",["VC_TTS_voice_num",self.VC_TTS_voice_num])
-                    # 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 and  (text.find("女声") != -1 or text.find("女生") != -1 ):
-                    self.VC_TTS_voice_num = 0
-                    
-                    EventMesh.publish("set_storage_config",["VC_TTS_voice_num",self.VC_TTS_voice_num])
-                    # 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 and  (text.find("同声") != -1 or text.find("童声") != -1 ):
-                    self.VC_TTS_voice_num = 2
-                    
-                    EventMesh.publish("set_storage_config",["VC_TTS_voice_num",self.VC_TTS_voice_num])
-                    # 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 and  (text.find("粤语") != -1 or text.find("越野") != -1 ):
-                    self.VC_TTS_voice_num = 3
-                    
-                    EventMesh.publish("set_storage_config",["VC_TTS_voice_num",self.VC_TTS_voice_num])
-                    # 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 and text.find("四川话") != -1 :
-                    self.VC_TTS_voice_num = 4
-                    
-                    EventMesh.publish("set_storage_config",["VC_TTS_voice_num",self.VC_TTS_voice_num])
-                    # 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 self.VC_mode == 0:
-                       self.VC_mode = 1
-                       self.AI_TTS_str = "已切换到单对话模式" 
+                    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:
-                        self.VC_mode = 0 
-                        self.AI_TTS_str = "已切换到长对话模式" 
-                    EventMesh.publish("set_storage_config",["VC_TTS_voice_num",self.VC_mode])
-                    # EventMesh.publish("audio_montage_play",["peizhichenggong.mp3"])
-                    #self.aud.play(1,0,'U:/static/peizhichenggong.mp3')#切换成功
+                        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()
+                }
+        }
 
-                    return 0
-                if text.find("音量") != -1 and 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 and 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 and text.find("查询") != -1:
-                    battery = EventMesh.publish("get_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 and 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 :
-                    self.factory_mode()
-                    return -1
-                if text.find("信号") != -1 and text.find("查询") != -1:
-                    signal = net.csqQueryPoll()
-                    
-                    self.AI_TTS_str = "当前信号{}".format(signal)
-                    return 0
+        #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))
                 
-                if text.find("再见") != -1 or text.find("拜拜") != -1:
-                    EventMesh.publish("publish_AI_btnInfo",{"func":self.Close}) 
-        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_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):
-        
-        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))
-        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
-        print("VC_Speech_Start VC_record_state_flag:{}!!!!!!!!".format(self.VC_record_state_flag))  
-        if self.VC_record_state_flag  == 0:
-            if self.VC_record_thread_id != 0:
+        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:
-                    _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)
+                    
+                    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)
-            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))
+                    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()#关闭录音
@@ -1454,16 +2202,35 @@ class AI_VC(Abstract):
                 #         usys.print_exception(e)
         except Exception as e:
             usys.print_exception(e)
-        self.voice_chat_state =  VC_State_SpeechEnd
+        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
-        
-        self.VC_record_state_flag = 0
-        print("VC_Speech_End VC_record_state_flag:{}!!!!!!!!".format(self.VC_record_state_flag))   
+                usys.print_exception(e)
+        self.VC_record_thread_id = 0
     #获取录音数据
     def VC_record_thread(self):
         ##return
@@ -1478,136 +2245,950 @@ class AI_VC(Abstract):
         # 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)
+        #     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.voice_chat_state ==  VC_State_SpeechStart:
+                #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)
-                    # if self.record_pcm ==None:
-                    #     break
-                    # Record_len = self.record_pcm.stream_read(Record_read_buf, self.Audio_buf_size)
-                    # if Record_len <= 0:
-                    #     try:
-                    #         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)
                     utime.sleep_ms(20)
                     
                 else :
                     
                     Record_len = self.record.stream_read(Record_read_buf, self.Audio_buf_size)
-                    utime.sleep_ms(1000)
+                    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
 
-                #Record_len = 1024*2
-                #print("VC_record_thread:{}".format(Record_len))
-                if Record_len > 0:
-                    read_buf = bytes(Record_read_buf[:Record_len])
-                    #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)
+                    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:
-                        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)
-                # if count>=500*1024:#结束
-                #     self.AI_client_voice_chat_end_speech()
-                #     break
-                utime.sleep_ms(40)
-                if self.voice_chat_state >=  VC_State_SpeechEnd:
-                    break
-            except Exception as e:
-                    usys.print_exception(e)
-                    break
-        # while True:
-        #     if record_data_queue.empty()!=True:
-        #         self.AI_client_voice_chat_send(record_data_queue.get())   
-        #     else:
-        #         break
-        #self.AI_client_voice_chat_end_speech()
-        #fd.close()
+                        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()
 
-        #if self.AI_TYPE == AI_TYPE_voice_chat:
-        
-        print("VC_record_thread:exit")
-        self.VC_record_thread_id = 0#线程退出
+        # 转成十六进制表示
+        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 > 30:#20秒没数据就close
-            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))
-        #self.LocalRespondingEnded_timerout+=1
-        if self.voice_chat_state == VC_State_TTSEnd and self.AI_audio_queue.empty()  :#self.AI_audio_queue为空且tts下发结束
-            self.LocalRespondingEnded_timerout += 1
-        if self.LocalRespondingEnded_timerout >= 3:
-            self.LocalRespondingEnded_timerout = 0
-            if self.VC_mode == 1 :#长按单次问答模式
-                EventMesh.publish("publish_AI_btnInfo",{"func":self.Close}) 
+        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:
-                #通知服务器播放结束
-                self.AI_client_voice_chat_LocalRespondingEnded()
-        self.pingping_timerout+=1
-        if self.pingping_timerout>5:
-            self.pingping_timerout=0
-            self.AI_client_voice_chat_ping()
-        
+                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()#关闭音频播放
-        #self.VC_init()#关闭一些资源
-        if self.VC_mode == 1:
-            if self.AI_TTS_str == "":
-                self.VC_init2()#关闭一些资源
-        
+        print("AI_VC_start2")
         #self.aud.aud_tone_play(16,200)#播放按键音
         self.LocalRespondingEnded_timerout = 0
         self.close_timerout = 0
+
         
-        #utime.sleep_ms(50)
-        if self.AI_client_voice_chat_isconnect == 0:#没连接的时候请求开始
-            self.websocket_connect_voice_chat()#连接服务器
-            self.AI_client_voice_chat_start_requset()
+        #
+        if self.AI_client_VC_isconnect == 0:#没连接的时候请求开始
+            self.websocket_connect_VC()#连接服务器
+            
+            #utime.sleep_ms(50)
         else:
-            print("self.voice_chat_state :{}".format(self.voice_chat_state ))
-            if self.voice_chat_state > VC_State_SpeechStart:
+            print("self.VC_state :{}".format(self.VC_state ))
+            if self.VC_state > VC_State_SpeechStart:
                 #客户端打断对话
-                self.AI_client_voice_chat_RequestToSpeak()
-            else:#本身处于录音状态
-                return
-
-        self.voice_chat_state = VC_State_None
+                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()
-        #self.websocket_connect_voice_chat()#连接服务器
-        #self.AI_client_voice_chat_start_requset()
-        
+        #     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, ())
@@ -1615,56 +3196,75 @@ class AI_VC(Abstract):
             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
-        
-        
+        # self.VC_pingping_timerout = 0
+        # self.asr_pingping_timerout = 0
+        print("AI_VC_start5")
     #开始会话
-    def AI_client_voice_chat_start_requset(self):
-        
-        json_data = \
-        {
-            "header":{
-                "trace_id":self.get_trace_id(),
-                "event":"Start"
+    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" 
                 },
-            "payload":{
-                "dialog_id":self.VC_dialog_id,
-                "device_id":modem.getDevImei(),
-                "user_agent":"python",
-                "in_format":"pcm",
-                "out_format":"mp3",
-                "in_sample_rate":self.VC_record_samplerate,
-                "sample_rate":self.VC_play_samplerate,
-                "space_time": 100,
-                "volume": str(self.VC_TTS_volume),
-                "voice":self.VC_TTS_voice_type[self.VC_TTS_voice_num],
-                "voice_detection":"enabled",
-                "simple_response":True,
-                "custom_variables":{
-                "bot_name":"{}".format(self.bot_name)
+                "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.voice_chat_state = VC_State_None
-        self.AI_client_voice_chat_send(ujson.dumps(json_data))
+        # 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_voice_chat_send_speech(self):
+    def AI_client_VC_send_speech(self):
         json_data = \
         {
             "header":{
@@ -1673,29 +3273,37 @@ class AI_VC(Abstract):
                 },
             "payload":
             {
-                "dialog_id":self.VC_dialog_id
+                "dialog_id":self.VC_dialog_id,
+                "session_id": self.session_id ,
             }
         }
-        self.AI_client_voice_chat_send(ujson.dumps(json_data))
+        #self.AI_client_VC_send(ujson.dumps(json_data))
         self.VC_Speech_Start()#开启线程获取录音数据
-        self.voice_chat_state =  VC_State_SpeechStart
+        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_voice_chat_end_speech(self):
+    def AI_client_VC_end_speech(self):
         json_data = \
         {
-            "header":{
-                "trace_id":self.get_trace_id(),
-                "event":"StopSpeech"
-                },
-            "payload":{
-                "dialog_id":self.VC_dialog_id
-                }
+            "id": "event_id",
+            "event_type": "input_audio_buffer.complete",
+            "data": {}
         }
-        self.AI_client_voice_chat_send(ujson.dumps(json_data))
-        self.VC_Speech_End()#停止线程录音
+        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_voice_chat_LocalRespondingStarted(self):
+    def AI_client_VC_LocalRespondingStarted(self):
         json_data = \
         {
             "header":{
@@ -1703,12 +3311,13 @@ class AI_VC(Abstract):
                 "event":"LocalRespondingStarted"
                 },
             "payload":{
-                "dialog_id":self.VC_dialog_id
+                "dialog_id":self.VC_dialog_id,
+                "session_id": self.session_id ,
                 }
         }
-        self.AI_client_voice_chat_send(ujson.dumps(json_data))
+        self.AI_client_VC_send(ujson.dumps(json_data))
     #通知服务器播放结束
-    def AI_client_voice_chat_LocalRespondingEnded(self):
+    def AI_client_VC_LocalRespondingEnded(self):
         json_data = \
         {
             "header":{
@@ -1716,16 +3325,29 @@ class AI_VC(Abstract):
                 "event":"LocalRespondingEnded"
                 },
             "payload":{
-                "dialog_id":self.VC_dialog_id
+                "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_voice_chat_send,"data":ujson.dumps(json_data)}) 
+        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_voice_chat_send(ujson.dumps(json_data))
-        self.voice_chat_state = VC_State_End
+        # self.AI_client_VC_send(ujson.dumps(json_data))
+        self.VC_state = VC_State_End
     #客户端打断对话
-    def AI_client_voice_chat_RequestToSpeak(self):
+    def AI_client_VC_RequestToSpeak(self):
         json_data = \
         {
             "header":{
@@ -1733,15 +3355,17 @@ class AI_VC(Abstract):
                 "event":"RequestToSpeak"
                 },
             "payload":{
-                "dialog_id":self.VC_dialog_id
+                "dialog_id":self.VC_dialog_id,
+                "session_id": self.session_id ,
                 }
         }
-        print("AI_client_voice_chat_RequestToSpeak!!!!!!!!!!!!!!!!!!!!!!!!!!!!!")
+        print("AI_client_VC_RequestToSpeak!!!!!!!!!!!!!!!!!!!!!!!!!!!!!")
         EventMesh.publish("publish_AI_btnInfo",{"func":self.VC_init}) 
-        EventMesh.publish("publish_AI_btnInfo",{"func":self.AI_client_voice_chat_send,"data":ujson.dumps(json_data)}) 
+        EventMesh.publish("publish_AI_btnInfo",{"func":self.AI_client_VC_send,"data":ujson.dumps(json_data)}) 
         # utime.sleep_ms(1)
-    #请求TTS事件
-    def AI_client_voice_chat_RequestToRespond(self,text):
+    #请求TTS或者chat事件
+    def AI_client_VC_RequestToRespond(self):
+        self.session_id  = self.get_session_id()#调试临时打开
         json_data = \
         {
             "header":{
@@ -1750,116 +3374,128 @@ class AI_VC(Abstract):
                 },
             "payload":{
                 "dialog_id":self.VC_dialog_id,
+                "session_id": self.session_id ,
                 "type":"transcript",#prompt是跳过asr,transcript是跳过asr和大模型
-                "text":text
+                "text":""
                 }
         }
-        print("AI_client_voice_chat_RequestToRespond!!!!!!!!!!!!!!!!!!!!!!!!!!!!!")
-        EventMesh.publish("publish_AI_btnInfo",{"func":self.VC_init}) 
-        EventMesh.publish("publish_AI_btnInfo",{"func":self.AI_client_voice_chat_send,"data":ujson.dumps(json_data)}) 
+
+        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 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 and self.AI_client_voice_chat_isconnect == 1:
-                                self.AI_client_voice_chat.send(data[1])
-                                #print("VC: send_data len:{}".format(len(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()
-                            pass
-                            #self.websocket_deconnect_voice_chat()
-                            self.AI_client_voice_chat_isconnect = 0
-                            try:
-                                EventMesh.publish("publish_AI_btnInfo",{"func":self.websocket_error_voice_chat}) 
-                                EventMesh.publish("publish_AI_btnInfo",{"func":utime.sleep_ms,'data':(1000)})
-                                EventMesh.publish("publish_AI_btnInfo",{"func":self.AI_VC_start}) 
-                            except Exception as e: #网络连接异常
-                                usys.print_exception(e) 
-                         
+    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_send_data_queue_thread_id == 0:
-                #     break
-                # print("AI_audio_queue_thread")
+                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() :
-                    utime.sleep_ms(5)
-                    count+=1
-                    if count%1000 == 1:
-                        print("AI_audio_queue_thread on")
+                    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_voice_chat_LocalRespondingStarted!!!")
-                        self.AI_client_voice_chat_LocalRespondingStarted()#通知服务器开始播放
-                    print("\r\naudio_queue:len:{},data{}".format(len(data[0]),len(data[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] )
-                                elif self.VC_play_samplerate == 16000:
-                                # if tmp != 0:
-                                #     print("playStream:WAV: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("playStream2:WAV:tmp:{} !!!!!!!!!!!!".format(tmp))
-                                
-                                    
+                                # if self.VC_play_samplerate == 8000:
+                                #     tmp= self.aud.playStream(1,data[0] )
+                                # else:
                                     write_buf = bytearray(data[0])
-                                    #print("play_pcm.stream_write1!!")
+                                    #print("play_pcm.stream_write1 len:{}".format(len(write_buf)))
                                     if self.play_pcm != None:
+                                        #print("play_pcm.stream_write !!!")
                                         ret = self.play_pcm.stream_write(write_buf,len(write_buf))
                                         #ret= self.aud.playStream(1, data[0])#播放音频流
-                                        print("play_pcm.stream_write:{}".format(ret))
+                                        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])#播放音频流
                                 
@@ -1880,86 +3516,145 @@ class AI_VC(Abstract):
                                     # tmp= self.aud.playStream(2, h_data_b+data[0])#播放音频流
                                     # print("3playStream:tmp:{} !!!!!!!!!!!!".format(tmp))
                             
-                            print("出:{}!!!".format(len(data[0])))
+                            
                             mem = gc.mem_free()
-                            print('1剩余内存RAM:{} KB'.format(mem / 1024))
+                            #print('1剩余内存RAM:{} KB'.format(mem / 1024))
                         except Exception as e:
                             print("AI_audio_queue_thread:ERROR:")
                             usys.print_exception(e)
                     
-                    # if self.voice_chat_state == VC_State_TTSEnd and self.AI_audio_queue.empty() :#self.AI_audio_queue为空且tts下发结束
+                    # if self.VC_state == VC_State_TTSEnd and self.AI_audio_queue.empty() :#self.AI_audio_queue为空且tts下发结束
                     #     #通知服务器播放结束
-                    #     self.AI_client_voice_chat_LocalRespondingEnded()
+                    #     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(1000, 1, self.factory_timer_cb)
+        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')#切换成功
+        #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()
-        if self.AI_send_data_queue.empty()!=True:
-            self.AI_send_data_queue.clear()
+        
+        print("ai_VC Close1.2!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!")
+        
         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
-            
-
+            self.websocket_deconnect_asr()
         except Exception as e:
             usys.print_exception(e)
-        print("ai_VC Close2!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!")
         try:
-            self.websocket_deconnect_voice_chat()
+            self.websocket_deconnect_VC()
         except Exception as e:
             usys.print_exception(e)
-        print("ai_VC Close3!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!\r\n")
+        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_voice_chat()
+            self.websocket_deconnect_VC()
         except Exception as e:
             usys.print_exception(e)
         print("ai_VC Close3!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!\r\n")
         self._1S_timer.stop()
-
-    def VC_init(self):
-        
-        print("VC_init:AI_send_data_queue:size:{}".format(self.AI_send_data_queue.size()))
+        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()))
+        
         
-        self.AI_TTS_str = ""
         print("VC_init2")
-        self.VC_Speech_End()
+        #self.VC_Speech_End()
         print("VC_init3")
         self.VC_Play_End()
         print("VC_init4")
         
-        EventMesh.publish("close_led")
+        if self.AI_audio_queue.empty()!=True:
+            self.AI_audio_queue.clear()
         # num = EventMesh.publish("get_volum_size")
         # if num == None:
         #     num = 8
index 40ecbb8..7b0ce78 100644 (file)
@@ -27,11 +27,26 @@ 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):
-        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.GPIO44, Pin.OUT, Pin.PULL_PD, 1)
+        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
@@ -66,8 +81,8 @@ class AI_led(Abstract):
         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.AI_dev_timer_event})  
+    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()
@@ -151,33 +166,54 @@ class AI_led(Abstract):
         self.led_blue.write(0)
         self.led_green.write(0)
 
-audio_buf = ['dianliangshengyu10', 'dianliangshengyu100', 'dianliangshengyu20', 'dianliangshengyu40', 'dianliangshengyu60', 'dianliangshengyu80', 'dianliangshengyu90', 'IMEIhao', 'jianquancuowu', 'key_prompt', 'liuliangtishi', 'Low_power_warning', 'peizhichenggong', 'qiehuanchenggong', 'R_CHARGE_FULL', 'R_CHARGE_IN', 'R_CHARGE_OUT', 'R_POWER_OFF_1', '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_SIM_FAILE', 'xianyikaiji', 'xinhaoruo1', 'xinhaoruo2', 'yinliangyizuida', 'yinliangyizuixiao', 'zhengzaiguanji']
-
+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 = 1 #是否开启看门狗
-        self.VBATT_tab = {"charge_full":4300,100 :4250 ,  90:3994 , 80:3883, 60: 3707, 40:3604, 20:3537,  10:3486,}
+        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()
-        #self.extint_AI = ExtInt(ExtInt.GPIO19,ExtInt.IRQ_RISING_FALLING, ExtInt.PULL_PU, self.keyAI_extint_cb)
-        self.extint_AI = ExtInt(ExtInt.GPIO20,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)
+        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 = ExtInt(ExtInt.GPIO41, ExtInt.IRQ_RISING_FALLING, ExtInt.PULL_PU, self.pwk_extint_cb)
+        #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(10*1024)
+        _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)
@@ -185,19 +221,19 @@ class AI_dev(Abstract):
         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)
-        if self.is_wdt == 1:
-            self.wdt = WDT(30) #开启看门狗
-        # self.wdt_timer = osTimer()
-        # self.wdt_timer.start(5000, 1, self.wdt_timer_cb)
+        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
@@ -205,6 +241,8 @@ class AI_dev(Abstract):
         #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()))
@@ -226,6 +264,7 @@ class AI_dev(Abstract):
                 #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
@@ -252,6 +291,7 @@ class AI_dev(Abstract):
                     #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:
@@ -267,9 +307,11 @@ class AI_dev(Abstract):
             # 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))
 
@@ -282,6 +324,7 @@ class AI_dev(Abstract):
                 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
@@ -289,7 +332,6 @@ class AI_dev(Abstract):
                     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):
@@ -303,10 +345,22 @@ class AI_dev(Abstract):
                 if self.pwk_key_long_press == 0:
                         self.pwk_key_long_press = 1
                         #EventMesh.publish("AI_key_long_press")
-                        EventMesh.publish("publish_AI_btnInfo",{"func":self.pwk_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))
-                if self.pwk_key_timer_count >= 5: #防抖200ms
+                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()
@@ -328,13 +382,15 @@ class AI_dev(Abstract):
             
             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")
-                    self.aud.aud_tone_play(10,200)#播放按键音
+                    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)
@@ -351,7 +407,10 @@ class AI_dev(Abstract):
                         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
+                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()
@@ -363,16 +422,21 @@ class AI_dev(Abstract):
             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!!!!!!!")
         
@@ -382,11 +446,14 @@ class AI_dev(Abstract):
         #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")
 
@@ -394,8 +461,9 @@ class AI_dev(Abstract):
     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")
+        #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:
@@ -412,31 +480,45 @@ class AI_dev(Abstract):
                 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<self.VBATT_tab[20]and VC_satrt_flag == 0:#低电报警
+        if  self.usb_status == 0 and Vbatt<self.VBATT_tab["20"]and VC_satrt_flag == 0 and self.Low_power_warning_flag ==0:#低电报警
+            self.Low_power_warning_flag  = 1
             EventMesh.publish("flicker_led_red")
             #self.aud.play(1,0,'Low_power_warning.mp3')
-            if self.usb_charge_flag == 0 :
-                EventMesh.publish("audio_montage_play",["Low_power_warning.mp3"])
-                self.usb_charge_flag = 1
+            # self.Low_power_warning_timer+=1
+            # if self.Low_power_warning_timer >= 2:
+            #     self.Low_power_warning_timer = 0
+            EventMesh.publish("audio_montage_play",["Low_power_warning.mp3"])
+
+        if  self.usb_status == 0 and Vbatt<self.VBATT_tab["5"]:    
+            EventMesh.publish("audio_montage_play",["didianguanji.mp3"])
+            utime.sleep_ms(4500)
+            self.aud.stopPlayStream()
+            self.aud.stopAll()
+            Power.powerDown()
+
+        self.check_rest_timer_count += 1
+        if self.check_rest_timer_count >= 8640:#24小时没按键,则关机
+            self.pwk_key_Long_Press()
         
     def get_battery(self, event=None, msg=None):
         Vbatt = Power.getVbatt()
-        if Vbatt>self.VBATT_tab[90]:
+        if Vbatt>self.VBATT_tab["90"]:
             return 100
-        if Vbatt>self.VBATT_tab[80]:
+        if Vbatt>self.VBATT_tab["80"]:
             return 90
-        if Vbatt>self.VBATT_tab[60]:
+        if Vbatt>self.VBATT_tab["60"]:
             return 80
-        if Vbatt>self.VBATT_tab[40]:
+        if Vbatt>self.VBATT_tab["40"]:
             return 60
-        if Vbatt>self.VBATT_tab[20]:
+        if Vbatt>self.VBATT_tab["20"]:
             return 40
-        if Vbatt>self.VBATT_tab[10]:
+        if Vbatt>self.VBATT_tab["10"]:
             return 20
-        if Vbatt<=self.VBATT_tab[10]:
+        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:
@@ -447,28 +529,30 @@ class AI_dev(Abstract):
         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:
-            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(iccid[0]))\
+            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])))
-        str_data += '{}.mp3+'.format(audio_buf.index("IMEIhao"))#IMEI号为:
-        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))
+                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])),\
@@ -476,6 +560,7 @@ class AI_dev(Abstract):
                 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):
@@ -531,6 +616,7 @@ class getStorageDataManager(Abstract):#获取内存数据
 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
@@ -549,10 +635,10 @@ class device_res_author(Abstract):
         self.pid = "cqxJZi5CNgzjS3mX21Zw"
         
         self.dev_res_timer = osTimer()
-        self.dev_res_timer.start(10000, 1, self.dev_timer_cb)
+        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(30000, 1, self.ud_token_timer_cb)
+        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
@@ -562,67 +648,84 @@ class device_res_author(Abstract):
         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_active() #设备激活
-        # self.dev_sign_in() #设备登入
-        
+        #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, msg):
-        url = "http://dmp.raisound.com/bz-api/dev/time"
-        response = request.get(url)
-        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)
+    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:
-        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 > 6: #开机一分钟内没有获取到密码和token 等下一次更新令牌在走登入 激活流程
-                self.dev_res_timerCount=0
-                self.dev_res_timer.stop()
+        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):   
-        #print("ud_token_timer_!!!!")
-        self.ud_token_timer_Count+=1
-        if self.ud_token_timer_Count >= 20: #定时30*200s时更新token
-            self.ud_token_timer_Count = 0
-            EventMesh.publish_async("update_dev_token",thread_size = 8192)
-            
+        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):
@@ -662,11 +765,12 @@ class device_res_author(Abstract):
         result = self.unpad(result)  # 除去补16字节的多余字符
         return str(result, 'utf-8')  # 以字符串的形式返回
     #激活接口 没有密码走激活
-    def dev_active(self, event, msg):
+    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")
@@ -674,79 +778,84 @@ class device_res_author(Abstract):
         if dev_pass == None:
             dev_pass = ""
         if dev_pass == "" or dev_pass == None:
-            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 = 0
-            response_result = 0
             try:
-                response = request.put(url,data=data,headers = headers_T)
-                response_result = 1
-            except Exception as e:
-                print("put error!!!!!\r\n")
+                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
-            
-            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)) 
+                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): 
@@ -757,22 +866,24 @@ class device_res_author(Abstract):
         return random_str
 
     #设备登入 没有Token 走登入获取token
-    def dev_sign_in(self, event, msg):
+    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 = ""
-        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 == "":
+        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")
@@ -798,16 +909,18 @@ class device_res_author(Abstract):
                 response_result = 0
                 response = 0
                 try:
-                    response = request.post(sign_url,data=ujson.dumps(sign_in_data),headers = headers_T)
+                    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'}
                 # }
-                token = ""
+                
+                #self.dev_token = ""
                 if response_result == 1:
                     if response.status_code == 200:
                         content = response.content
@@ -823,71 +936,200 @@ class device_res_author(Abstract):
                                             self.dev_token = data_tmp["token"]
                                 if data["code"] == 50003:#时间错误
                                     self.ntptime_flag  = 0
-                print("token:{}\r\n".format(token))
+                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, msg):
+    def update_dev_token(self, event=None, msg=None):
         print("update_dev_token")
-        dev_pass = ""
-        dev_pass = EventMesh.publish("get_storage_config","dev_pass")
-        
-        if dev_pass == None:
+        try:
             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 = 0
-            headers_T = {"bz-dt":"{}".format(token)}
-            try:
-                response = request.get(dev_tokenip,headers = headers_T)
-                response_result = 1
-            except Exception as e:
-                print("get error!!!!!\r\n")
-                response_result = 0
-            if response_result == 1:
-                if response.status_code == 200:
+            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:
-                        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))
+                        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:
-                        print("headers_data!!!!! error\r\n")
+                            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()
         
-        pass
-
-
-
-
-#阿里voice_chat状态枚举
+        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={}&currentVersion={}".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_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_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
@@ -898,89 +1140,277 @@ VC_play_TYPE_MP3 = 1
 # AI_client_asr_num = 0
 # AI_client_chat_num = 1
 # AI_client_tts_num = 2
-AI_client_voice_chat_num = 3
+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")#音色配置
+        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_server = 2 #0正式服务器,1:测试服务器1,2:测试服务器2
         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:
-            #女,男,童,粤,川
-            self.VC_TTS_voice_type = {"0":"huoshan::zh_female_wanwanxiaohe_moon_bigtts","1":"huoshan::zh_male_wennuanahu_moon_bigtts","2":"huoshan::ICL_zh_female_huoponvhai_tob",
-                                    "3":"aliyun::longjiaxin","4":"huoshan::zh_female_daimengchuanmei_moon_bigtts"}
+        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])
+            
+            #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)
 
-        self.VC_TTS_voice_num = EventMesh.publish("get_storage_config","VC_TTS_voice_num")#音色配置
-        if self.VC_TTS_voice_num == None or self.VC_TTS_voice_num>=len(self.VC_TTS_voice_type):
-            self.VC_TTS_voice_num = 1
-         
-        self.VC_TTS_volume =  EventMesh.publish("get_storage_config","VC_TTS_volume")#音量配置
         if self.VC_TTS_volume == None:
             self.VC_TTS_volume = 100
         self.AI_audio_queue_thread_id = 0
-        self.AI_send_data_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_send_data_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_send_data_queue_thread_id == 0:    
-        #     self.AI_send_data_queue_thread_id = _thread.start_new_thread(self.AI_send_data_queue_thread, ())
+        # 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.voice_chat_state = VC_State_None #阿里ai voice_chat状态
-        self.VC_dialog_id = ""
+        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_voice_chat = None
-        self.AI_client_voice_chat_recv_id = 0
-        self.AI_client_voice_chat_isconnect =0
-        self.AI_client_voice_chat_debug =0
-
-        self.asr_state = VC_State_None #阿里VC_ASR voice_chat状态
-        self.VC_asr_dialog_id = ""
-        self.VC_asr_message_id=None
-        self.VC_asr_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.asr_satrt_flag = 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()
@@ -989,6 +1419,7 @@ class AI_VC(Abstract):
         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)
@@ -1004,6 +1435,7 @@ class AI_VC(Abstract):
         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)
@@ -1011,35 +1443,141 @@ class AI_VC(Abstract):
         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 = "柒先生"
-        if self.VC_TTS_voice_num == 0 or self.VC_TTS_voice_num == 3 or self.VC_TTS_voice_num == 4:
-            self.bot_name = "柒妹妹"
-        elif self.VC_TTS_voice_num == 1:
-            self.bot_name = "柒先生"
-        elif self.VC_TTS_voice_num == 2:
-            self.bot_name = "柒乐乐"
-        #EventMesh.publish("get_storage_config",["powerRestart",1])
-        powerRestart =  EventMesh.publish("get_storage_config","powerRestart")#音量配置
-        if powerRestart == None:
-            powerRestart = 0
-        if powerRestart == 1:
-            EventMesh.publish("get_storage_config",["powerRestart",0])
-            
-        else:
-            self.AI_TTS_str = "已开机,您好!我是柒牌 AI 智能男装生活好帮手-{}, 很高兴为您服务,我可以帮您解答日常生活、工作,旅游信息、健康咨询、教育与学习、情感交流、全球资讯等问题!请问您有什么需要我帮忙的吗?".format(self.bot_name )
-            EventMesh.publish("publish_AI_btnInfo",{"func":self.AI_VC_start}) 
+        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
@@ -1052,34 +1590,47 @@ class AI_VC(Abstract):
 
     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.asr_satrt_flag = 1#
         self.AI_TTS_str = ""#"你好,有什么吩咐"
         self.AI_ASR_str = ""
         self.AI_ASR_str_tmp = ""
-        # if self.voice_chat_state != VC_State_None:
+        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:#如果在录音,就先停止录音
-            EventMesh.publish("publish_AI_btnInfo",{"func":self.VC_Speech_End})  
-            
-        EventMesh.publish("publish_AI_btnInfo",{"func":self.AI_VC_start}) 
+        #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_voice_chat_end_speech()
+            #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("audio_montage_play",["key_prompt.mp3"])
-                #self.aud.play(1,1,'U:/static/key_prompt.mp3')#提示请您按住中间的按钮开始讲话,讲完松开即可
+                # 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()
@@ -1091,52 +1642,68 @@ class AI_VC(Abstract):
         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
-        # 创建VC客户端
+        # 创建ASR客户端
         try:
             signal = net.csqQueryPoll()
             if signal == -1 or sim.getStatus() != 1:#网络正常
                 self.websocket_error()
                 return
-            # Headers = {'X-NLS-Token':'0c8b8f05a46f423096be64a9c4c46310'}
+
             # self.AI_client_asr = uwebsocket.Client.connect('wss://nls-gateway-cn-beijing.aliyuncs.com/ws/v1',headers=Headers, debug=False)
-            if self.VC_server == 1:# 
-                self.AI_client_asr = uwebsocket.Client.connect('ws://118.145.158.207:22080/asr/ws', debug=True)#测试环境
-            elif self.VC_server == 2:# 
-                if self.VC_TTS_voice_num <= 2:
-                    self.AI_client_asr = uwebsocket.Client.connect('ws://118.145.158.207:22080/asr/ws?platform=huoshao&lang=zh-cn', debug=True)#普通话测试环境
-                elif self.VC_TTS_voice_num == 3:
-                    self.AI_client_asr = uwebsocket.Client.connect('ws://118.145.158.207:22080/asr/ws?platform=huoshan&lang=zh-hk', debug=True)#粤语测试环境
-                elif self.VC_TTS_voice_num == 4:
-                    self.AI_client_asr = uwebsocket.Client.connect('ws://118.145.158.207:22080/asr/ws?platform=huoshan&lang=zh-cn-sc', debug=True)#四川话测试环境
-                else :
-                    self.AI_client_asr = uwebsocket.Client.connect('ws://118.145.158.207:22080/asr/ws?platform=huoshan&lang=zh-cn', debug=True)#普通话测试环境
-            else:
-                token = EventMesh.publish("get_dev_token")
-                print("token:{}".format(token))
-                if token != None:
-                    self.AI_client_asr = uwebsocket.Client.connect('ws://amp.raisound.com/asr/ws?dt={}'.format(token), debug=True)
+            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:
-                    pass
-                    return
+                    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_voice_chat error!!!\r\n")
+            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()
-                EventMesh.publish("set_storage_config",["powerRestart",1])
+                
             self.websocket_error()
             
             return
@@ -1145,34 +1712,64 @@ class AI_VC(Abstract):
             return 
         self.AI_client_asr_debug+=1
         utime.sleep_ms(10)
-        self.AI_client_asr.settimeout(6)
-        # 线程接收数据
-        if self.AI_client_asr_recv_id != 0:
-            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
+        #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!!!!!!!")
-        if self.AI_client_asr_recv_id != 0:#关闭线程
+        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:
-                _thread.stop_thread(self.AI_client_asr_recv_id)
+                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)
-        self.AI_client_asr_recv_id = 0
-        if self.AI_client_asr_isconnect == 1 or self.AI_client_asr!= None:
-            self.AI_client_asr_isconnect = 0
-            self.AI_client_asr.close()
-            self.AI_client_asr = None
-            self.AI_client_asr_debug-=1
         print("websocket_deconnect_asr {}!!!!!!!".format(self.AI_client_asr_isconnect))
 
     #websocket发送数据    
@@ -1183,134 +1780,306 @@ class AI_VC(Abstract):
         # else:
         #     pass
         #     #print("ASR ASR AI_client_asr_send:len:{}".format(len(data_str)))
-        self.AI_send_data_queue.put([AI_client_asr_num,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.VC_record_state_flag == 3:
-            self.AI_ASR_timer_count+=1
-            if self.AI_ASR_timer_count >=10 :#10*500ms终止asr
-                print("AI_ASR_timer_count timerout!!!!!")
-                #self.AI_client_asr_StopTranscription_requset()
+        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])))
 
-                self.AI_ASR_timer.stop()
-        else:
-            self.AI_ASR_timer.stop()
-    #Ai VC websocket返回数据       
+                    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 not recv_data:
-                    # 服务器关闭连接或客户端关闭连接
-                    print("AI_client_asr_recv close!!!!!!!!!!!!!!!!!!!!!!!!!!!")
-                    #self.AI_client_voice_chat_isconnect = 0
-                    #self.websocket_deconnect_voice_chat()
-                    #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}) 
+                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:#返回错误
-                            EventMesh.publish("publish_AI_btnInfo",{"func":self.websocket_error}) 
+                            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
-                        if jsload_data["event"] == "Changed" or jsload_data["event"] == "SentenceEnd" : #开始录音Changed
-                            if self.VC_record_state_flag == 2:
-                                self.AI_ASR_timer.start(500, 1, self.AI_ASR_timer_cb)
-                            
-                            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.voice_chat_state :{}".format(self.voice_chat_state))
-                                if self.voice_chat_state >= VC_State_TTSStart:#开始播音后不响应asr结果
-                                    print("asr continue")
-                                    continue
-                                EventMesh.publish("open_led_blue")
-                                if jsload_data["result"]["is_end"] == True:  #asr结束
-                                    self.VC_record_state_flag = 4
-                                    ret= self.check_text(text)
-                                    if ret == 0:#配置指令
-                                        #print("check_text ok:{} self.VC_TTS_voice_num:{},{}".format(text,self.VC_TTS_voice_num,self.VC_TTS_voice_type[self.VC_TTS_voice_num]))
-                                        if self.AI_send_data_queue.empty()!=True:
-                                            self.AI_send_data_queue.clear()
-                                        EventMesh.publish("open_led_all")
-                                        try:
-                                            EventMesh.publish("publish_AI_btnInfo",{"func":self.VC_Speech_End}) 
-                                            EventMesh.publish("publish_AI_btnInfo",{"func":self.websocket_deconnect_voice_chat}) 
-                                            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
-                                        self.AI_ASR_str = text#
-                                        if self.AI_ASR_flag == 0:#d第一次识别,没有打断
-                                            self.AI_ASR_str_tmp = self.AI_ASR_str
-                                            self.AI_ASR_flag  = 1
-                                        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
-                                            #EventMesh.publish("publish_AI_btnInfo",{"func":self.websocket_deconnect_voice_chat})#关闭vc连接
-                                        self.AI_ASR_str+="\r\n\r\n"
-                                        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 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:
                                         
-                                elif jsload_data["result"]["is_end"] == False:
-                                    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 = ""
-                                        # EventMesh.publish("publish_AI_btnInfo",{"func":self.websocket_deconnect_voice_chat})#关闭vc连接
-                                        # EventMesh.publish("publish_AI_btnInfo",{"func":self.websocket_connect_voice_chat})#连接服务器
-                                        # EventMesh.publish("publish_AI_btnInfo",{"func":self.AI_client_voice_chat_start_requset})#请求
-                                        EventMesh.publish("publish_AI_btnInfo",{"func":self.AI_VC_start}) 
-                                        EventMesh.publish("publish_AI_btnInfo",{"func":EventMesh.publish,"data":"open_led_blue"})#
-                                    pass
+                                        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))
-                    if error_str.find("[Errno 110] ETIMEDOUT")!= -1:
-                        print("ASR ASR:recv TIMEDOUT 正常")
+                    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()
-                        EventMesh.publish("publish_AI_btnInfo",{"func":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":{
@@ -1320,19 +2089,19 @@ class AI_VC(Abstract):
             "payload":{
                 "format":"pcm",
                 "sample_rate":self.VC_record_samplerate,
-                "voice_detection":"enabled",
+                 "session_id": self.session_id ,
                 }
             
         }
         if self.VC_record_TYPE == VC_record_TYPE_AMR :
             json_data["payload"]["format"]='amr'
             pass
-        # if self.VC_mode == 1:
-        #json_data["payload"]["voice_detection"]='disable'
-
+        
+        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":{
@@ -1341,56 +2110,68 @@ class AI_VC(Abstract):
                 }
         }
 
-        self.AI_client_asr_send(ujson.dumps(json_data))
-    
+        #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):
-        #self.voice_chat_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:
-            self.websocket_connect_asr()
-            self.AI_client_asr_start_requset()#开始请求
-            if self.VC_record_thread_id != 0:
+        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:
-                    _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)
+                    
+                    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)
-            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))
+                    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})
-            #self.websocket_deconnect_asr()
+            #EventMesh.publish("publish_AI_btnInfo",{"func":self.websocket_deconnect_asr})
+              
             if self.VC_record_state_flag == 0:
                 return
             #self.AI_client_asr_StopTranscription_requset()#请求停止
@@ -1421,15 +2202,35 @@ class AI_VC(Abstract):
                 #         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
-        
-        self.VC_record_state_flag = 0
-        print("VC_Speech_End VC_record_state_flag:{}!!!!!!!!".format(self.VC_record_state_flag))   
+                usys.print_exception(e)
+        self.VC_record_thread_id = 0
     #获取录音数据
     def VC_record_thread(self):
         ##return
@@ -1444,14 +2245,15 @@ class AI_VC(Abstract):
         # 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)
-        
-        count = 0
+        #     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.voice_chat_state ==  VC_State_SpeechStart:
+                #if self.VC_state ==  VC_State_SpeechStart:
                 Record_read_buf = bytearray(self.Audio_buf_size)
                 
                 Record_len = 0
@@ -1468,43 +2270,61 @@ class AI_VC(Abstract):
                 #print("VC_record_thread:{}".format(Record_len))
                 if Record_len > 0:
                     read_buf = bytes(Record_read_buf[:Record_len])
-                    if self.record_fd != None:
-                        self.record_fd.write(read_buf)
-                        print("write record:{}".format(len(read_buf)))
-                    if self.VC_record_state_flag >= 2:
-                        self.AI_client_asr_send(read_buf)
+                    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.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)   
+                    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)
+                    #count+=len(read_buf)
                 # if count>=500*1024:#结束
-                #     self.AI_client_voice_chat_end_speech()
+                #     self.AI_client_VC_end_speech()
                 #     break
-                utime.sleep_ms(40)
-                # if self.voice_chat_state >=  VC_State_SpeechEnd:
+                # 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
-                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_send_data_queue_thread_id)))
+                
             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_voice_chat(self):
-        print("websocket_connect_voice_chat:{} e:{}!!!!!!!!!!!!!!!!!!!!!".format(self.AI_client_voice_chat_isconnect,self.AI_client_voice_chat_debug))
-        if self.AI_client_voice_chat_isconnect == 1:
+    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:
@@ -1512,80 +2332,67 @@ class AI_VC(Abstract):
             if signal == -1 or sim.getStatus() != 1:#网络正常
                 self.websocket_error()
                 return
-            #女,男,童,粤,川
-            self.bot_name = "柒先生"
-            if self.VC_TTS_voice_num == 0 or self.VC_TTS_voice_num == 3 or self.VC_TTS_voice_num == 4:
-                self.bot_name = "柒妹妹"
-            elif self.VC_TTS_voice_num == 1:
-                self.bot_name = "柒先生"
-            elif self.VC_TTS_voice_num == 2:
-                self.bot_name = "柒乐乐"
-            req_str = ""
-            ack = ""
-            if self.is_VC_ACK == 1:
-                ack = "&ack=1"
-            lang = "&lang=zh-cn"#普通话测试环境
-            if self.VC_TTS_voice_num <= 2:
-                lang = "&lang=zh-cn"#普通话测试环境
-            elif self.VC_TTS_voice_num == 3:
-                lang = "&lang=zh-hk"#粤语测试环境
-            elif self.VC_TTS_voice_num == 4:
-                lang = "&lang=zh-cn-sc"#四川话测试环境
-            #platform = "&platform=huoshan&is_bot=1"
-            platform = "&platform=raisound"
-            req_str = "is_auth=0{}{}{}".format(platform,ack,lang)
-            print("req_str:{}".format(req_str))
-            # Headers = {'X-NLS-Token':'0c8b8f05a46f423096be64a9c4c46310'}
-            # self.AI_client_voice_chat = uwebsocket.Client.connect('wss://nls-gateway-cn-beijing.aliyuncs.com/ws/v1',headers=Headers, debug=False)
-            if self.VC_server == 1:# 
-                self.AI_client_voice_chat = uwebsocket.Client.connect('ws://118.145.158.207:22080/voice-chat/ws', debug=False)#测试环境
-            elif self.VC_server == 2:# 
-                self.AI_client_voice_chat = uwebsocket.Client.connect('ws://118.145.158.207:22080/voice-chat/ws?{}'.format(req_str), debug=False)
-                
-            else:
-                token = EventMesh.publish("get_dev_token")
-                print("token:{}".format(token))
-                if token != None:
-                    self.AI_client_voice_chat = uwebsocket.Client.connect('ws://amp.raisound.com/voice-chat/ws?dt={}'.format(token), debug=False)
+            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:
-                    self.websocket_error()
-                    return
-            print("websocket_connect_voice_chat:OK!!!!!!!!!!!!!!!!!!!!!")
+                    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_voice_chat error!!!\r\n")
+            print("websocket_connect_VC error!!!\r\n")
             str_error = str(e)
             if str_error.find("[Errno 22] EINVAL")!= -1: 
-                print("websocket_connect_voice_chat:str_error:{}".format(str_error))
+                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()
-                EventMesh.publish("set_storage_config",["powerRestart",1])
+                
             self.websocket_error()
             return
-        print("AI_client_voice_chat:{}".format(self.AI_client_voice_chat))
-        if self.AI_client_voice_chat == None:
+        #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_voice_chat_debug+=1
+        self.AI_client_VC_debug+=1
         utime.sleep_ms(10)
-        self.AI_client_voice_chat.settimeout(6)
+        #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()#关闭读线程
         # 线程接收数据
-        if self.AI_client_voice_chat_recv_id != 0:
-            try:
-                _thread.stop_thread(self.AI_client_voice_chat_recv_id)
-            except Exception as e:
-                    usys.print_exception(e)
-            self.AI_client_voice_chat_recv_id = 0
         _thread.stack_size(self.Audio_buf_size+8*1024)
-        self.AI_client_voice_chat_recv_id = _thread.start_new_thread(self.AI_client_voice_chat_recv, (self.AI_client_voice_chat,))
+        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_voice_chat_isconnect = 1
-        print("websocket_connect_voice_chat end")
-    def websocket_error(self):
-        
+        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!!!!")
@@ -1598,269 +2405,485 @@ class AI_VC(Abstract):
         self.AI_ASR_str_tmp = ""
         self.AI_ASR_flag  = 0
         self.VC_Speech_End()
-        self.websocket_error_count+=1
-        if self.websocket_error_count <=3:
-            EventMesh.publish("audio_montage_play",["xinhaoruo1.mp3"])
-        elif self.websocket_error_count <10 :
-            EventMesh.publish("audio_montage_play",["xinhaoruo2.mp3"])
-        elif self.websocket_error_count >=10:
-            EventMesh.publish("paly_iccid_imei")    
+        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:
-            EventMesh.publish("audio_montage_play",["R_SIM_FAILE.mp3"])
-        #self.aud.play(1,1,'U:/static/R_SIM_FAILE.mp3')
-        
+            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")
-        #self.VC_Speech_End()
-        EventMesh.publish("close_led")
+       
         
         print("websocket_error4")
-        if self.websocket_error_count <3 :
-            utime.sleep_ms(3000)
-            EventMesh.publish("publish_AI_btnInfo",{"func":self.AI_VC_start})
+        
 
-    def websocket_deconnect_voice_chat(self):
-        print("websocket_deconnect_voice_chat {}!!!!!!!".format(self.AI_client_voice_chat_isconnect))
-        print("websocket_deconnect_voice_chat!!!!!!!")
-        if self.AI_client_voice_chat_recv_id != 0:#关闭线程
+    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:
-                _thread.stop_thread(self.AI_client_voice_chat_recv_id)
+                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)
-        self.AI_client_voice_chat_recv_id = 0
-        if self.AI_client_voice_chat_isconnect == 1 or self.AI_client_voice_chat!=None:
-            self.AI_client_voice_chat_isconnect = 0
-            self.AI_client_voice_chat.close()
-            self.AI_client_voice_chat_debug -=1
-            self.AI_client_voice_chat=None
-        print("websocket_deconnect_voice_chat {}!!!!!!!".format(self.AI_client_voice_chat_isconnect))
+        print("websocket_deconnect_VC {}!!!!!!!".format(self.AI_client_VC_isconnect))
     #websocket发送ping
-    def AI_client_voice_chat_ping(self):
+    def AI_client_VC_ping(self):
         pass
-        if self.AI_client_voice_chat_isconnect == 1:
-            #self.AI_client_voice_chat.write_frame(0x09,b'ping ping')
-            self.AI_client_voice_chat_send("ping")
+        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_voice_chat_send(self,data_str):
+    def AI_client_VC_send(self,data_str):
         # if isinstance(data_str, str):#是字符串
-        #     print("AI_client_voice_chat_send:{}".format(data_str))
+        #     print("AI_client_VC_send:{}".format(data_str))
         #     pass
         # else:
-        #     print("AI_client_voice_chat_send:len{}".format(len(data_str)))
-        self.AI_send_data_queue.put([AI_client_voice_chat_num,data_str]) 
+        #     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_voice_chat_recv(self,cli):
+    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_voice_chat_Read()
-                #EventMesh.publish("publish_AI_btnInfo",{"func":self.AI_client_voice_chat_Read})
+                    self.AI_client_VC_Read()
+                #EventMesh.publish("publish_AI_btnInfo",{"func":self.AI_client_VC_Read})
                 count+=1
-                if self.voice_chat_state >= VC_State_TTSStart and (self.tts_in_data_len - self.tts_out_data_len > 64*1024 or count>3):
+                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 not recv_data:
-                    # 服务器关闭连接或客户端关闭连接
-                    print("服务器主动关闭连接!!!!!!!!!!!!!!!!!!!!!!!!!!!")
-                    #self.AI_client_voice_chat_isconnect = 0
-                    #self.websocket_error()
-                    EventMesh.publish("publish_AI_btnInfo",{"func":self.websocket_error}) 
-                    #EventMesh.publish("publish_AI_btnInfo",{"func":utime.sleep_ms,'data':(1500)})
-                    
+                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):#返回的是字符串
-                        print("VC VC:recv_data:{}".format(recv_data))
+                        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_voice_chat_recv jsload_data = {}".format(jsload_data))
-                        if jsload_data["status"] != 20000000:#返回错误
-                            EventMesh.publish("publish_AI_btnInfo",{"func":self.websocket_error}) 
-                            break
-                        if jsload_data["event"] == "Started" :#会话开始
-                            payload = jsload_data["payload"]
-                            self.VC_dialog_id = payload["dialog_id"] 
-                            self.VC_task_id = jsload_data["task_id"] 
+                        #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")
-                        elif jsload_data["event"]  == "SpeechContent" :#asr转译
-                            print("VC:SpeechContent!!!!!!!!\r\n")
-                            payload = jsload_data["payload"]
-                            
-                            
-                            if(payload['finished'] == True):#asr结束
-                                self.voice_chat_state =  VC_State_SpeechEnd
-                                #self.VC_Speech_End()#停止录音
-                                text = payload["text"]
-                                if self.check_text(text) == 0:
-                                    #print("check_text ok:{} self.VC_TTS_voice_num:{},{}".format(text,self.VC_TTS_voice_num,self.VC_TTS_voice_type[self.VC_TTS_voice_num]))
-                                    
-                                    #EventMesh.publish("open_led_all")
-
-                                    if self.AI_send_data_queue.empty()!=True:
-                                            self.AI_send_data_queue.clear()
-                                    EventMesh.publish("open_led_all")
-                                    try:
-                                        EventMesh.publish("publish_AI_btnInfo",{"func":self.VC_Speech_End}) 
-                                        EventMesh.publish("publish_AI_btnInfo",{"func":self.websocket_deconnect_voice_chat}) 
-                                        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.voice_chat_state =  VC_State_SpeechEnd
-                        elif jsload_data["event"]  == "RespondingContent" :#chat回答      
-                            pass
                             
-                        elif jsload_data["event"]  == "RespondingStarted" :#音频开始下发
-                            self.play_flag = 0
-                            self.voice_chat_state = VC_State_TTSStart
-                            EventMesh.publish("publish_AI_btnInfo",{"func":self.VC_Speech_End})
-                            EventMesh.publish("publish_AI_btnInfo",{"func":self.VC_Play_Start})
-                            self.VC_Thinking_timerout = 0#关闭超时重试
-                            # self.VC_Speech_End()#停止录音
-                            # self.VC_Play_Start()
-                            EventMesh.publish("open_led_green")#绿色
-                            #self.tts_fd = open('/usr/tts_tesr.pcm','w')
+                            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":#下发音频数据
                             
-                            pass
-                        elif jsload_data["event"]  == "RespondingEnded" :#音频下发结束
-                            #if self.voice_chat_state == VC_State_TTSStart:
-                            print("RespondingEnded!!!!!!" )
-                            self.voice_chat_state = VC_State_TTSEnd
-                            if self.asr_satrt_flag == 0 :
-                                self.asr_satrt_flag =1
+                            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()
-                            #self.tts_fd.close()
-                            #pass
-                        elif jsload_data["event"]  == "DialogStateChanged" :#状态切换事件
-                            payload = jsload_data["payload"]
-                            if payload["state"] == "Listening":#可以说了
-                                self.voice_chat_state = VC_State_Listening
-                                if self.AI_TTS_str != "" or self.AI_ASR_str != "":#有tts数据,则请求TTS数据,没有就请求开始上传语音
-                                    self.AI_client_voice_chat_RequestToRespond()
-                                else:
-                                    #self.VC_Speech_Start()#开启线程获取录音数据
-                                    EventMesh.publish("publish_AI_btnInfo",{"func":self.VC_Speech_Start})#
-                                    #self.AI_client_voice_chat_send_speech()#开始上传语音
+
+                        # 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)
                                 
-                                #EventMesh.publish("open_led_red")
-                            if payload["state"] == "Thinking":#思考
-                                self.voice_chat_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.voice_chat_state = VC_State_Responding#
-                                pass
-                        elif jsload_data["event"]  == "RequestAccepted" :#请求上传语音被允许
-                            #self.voice_chat_state =  VC_State_Responding
-                            #self.AI_client_voice_chat_send_speech()#开始上传语音
-                            pass
+                        #         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.voice_chat_state >= VC_State_TTSStart:
-                            self.put_record_data([recv_data,""])
-                        #EventMesh.publish("publish_AI_btnInfo",{"func":self.put_record_data,"data":[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))
+                    #print("VC VC:e:{}".format(error_str))
                     if error_str.find("[Errno 110] ETIMEDOUT")!= -1:
-                        print("VC VC:recv TIMEDOUT 正常")
+                        #print("VC VC:recv TIMEDOUT 正常")
+                        pass
                     else:
                         usys.print_exception(e)
                         #self.websocket_error()
-                        EventMesh.publish("publish_AI_btnInfo",{"func":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_voice_chat_isconnect = 0
-        self.AI_client_voice_chat_recv_id = 0 
-        print("AI_client_voice_chat_recv END!!!!!!!!!!!!!!!!!!!!!!!!!!!")
+        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))
+        #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:
-                    self.VC_TTS_voice_num += 1
-                    if self.VC_TTS_voice_num >= len(self.VC_TTS_voice_type):
-                        self.VC_TTS_voice_num = 0
-                    EventMesh.publish("set_storage_config",["VC_TTS_voice_num",self.VC_TTS_voice_num])
-                    # 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 and text.find("改") != -1 and (text.find("男声") != -1 or text.find("男") != -1 ):
-                    self.VC_TTS_voice_num = 1
-                    
-                    EventMesh.publish("set_storage_config",["VC_TTS_voice_num",self.VC_TTS_voice_num])
-                    # 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 and text.find("改") != -1 and  (text.find("女声") != -1 or text.find("女") != -1 ):
-                    self.VC_TTS_voice_num = 0
-                    
-                    EventMesh.publish("set_storage_config",["VC_TTS_voice_num",self.VC_TTS_voice_num])
-                    # 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 and text.find("改") != -1 and  (text.find("同声") != -1 or text.find("童") != -1 ):
-                    self.VC_TTS_voice_num = 2
-                    
-                    EventMesh.publish("set_storage_config",["VC_TTS_voice_num",self.VC_TTS_voice_num])
-                    # 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 and text.find("改") != -1 and  (text.find("粤") != -1 or text.find("越野") != -1 ):
-                    self.VC_TTS_voice_num = 3
-                    
-                    EventMesh.publish("set_storage_config",["VC_TTS_voice_num",self.VC_TTS_voice_num])
-                    # 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 and text.find("改") != -1 and text.find("四川话") != -1 :
-                    self.VC_TTS_voice_num = 4
-                    
-                    EventMesh.publish("set_storage_config",["VC_TTS_voice_num",self.VC_TTS_voice_num])
-                    # EventMesh.publish("audio_montage_play",["peizhichenggong.mp3"])
-                    #self.aud.play(1,0,'U:/static/peizhichenggong.mp3')#切换成功
-                    self.AI_TTS_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:
@@ -1869,59 +2892,94 @@ class AI_VC(Abstract):
                     else:
                         self.VC_mode = 0 
                         self.AI_TTS_str = "已切换到长对话模式" 
-                    EventMesh.publish("set_storage_config",["VC_TTS_voice_num",self.VC_mode])
+                    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 and 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 and 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 and text.find("查询") != -1:
-                    battery = EventMesh.publish("get_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 and 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:
+                    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 and text.find("查询") != -1:
-                    signal = net.csqQueryPoll()
-                    
-                    self.AI_TTS_str = "当前信号{}".format(signal)
+                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):
@@ -1943,6 +3001,20 @@ class AI_VC(Abstract):
         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]
@@ -1956,14 +3028,21 @@ class AI_VC(Abstract):
         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.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
     #停止播放声音
@@ -1972,7 +3051,7 @@ class AI_VC(Abstract):
             if self.VC_play_samplerate == 8000:
                 self.aud.stopPlayStream()
                 self.aud.stopAll()
-            elif self.VC_play_samplerate == 16000:
+            else:
                 if self.play_pcm != None:
                     print("Close:play_pcm.close()!!!!!!!!!!!!!!!!!!")
                     try:
@@ -1994,29 +3073,32 @@ class AI_VC(Abstract):
     
         EventMesh.publish("system_sleep_rest")#防止黑屏
         self.close_timerout += 1
-        if self.close_timerout > 30:#20秒没数据就close
+        if self.close_timerout > 60:#20秒没数据就close
             
-            if self.voice_chat_state >= VC_State_Thinking:
-                EventMesh.publish("publish_AI_btnInfo",{"func":self.websocket_error}) 
+            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))
-        #self.LocalRespondingEnded_timerout+=1
-        if self.voice_chat_state == VC_State_TTSEnd and self.AI_audio_queue.empty()  :#self.AI_audio_queue为空且tts下发结束
-            self.LocalRespondingEnded_timerout += 1
-        if self.LocalRespondingEnded_timerout >= 4:
-            self.LocalRespondingEnded_timerout = 0
-            if self.VC_mode == 1 :#长按单次问答模式
-                EventMesh.publish("publish_AI_btnInfo",{"func":self.Close}) 
-            else:
-                #通知服务器播放结束
-                self.AI_client_voice_chat_LocalRespondingEnded()
+        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>5:
+        if self.VC_pingping_timerout>3:
             self.VC_pingping_timerout=0
-            self.AI_client_voice_chat_ping()
+            #self.AI_client_VC_ping()
         self.asr_pingping_timerout += 1
-        if self.asr_pingping_timerout>5:
+        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超时后重新开始
@@ -2025,10 +3107,14 @@ class AI_VC(Abstract):
             if self.VC_Thinking_timerout == 0:
                 self.VC_Thinking_timerout = 100
                 print("Thinking重试,重试!!!!!!!!!!!!!!!!!!!!!")
-                self.voice_chat_state = VC_State_None
+                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")
@@ -2041,51 +3127,52 @@ class AI_VC(Abstract):
         #self.aud.aud_tone_play(16,200)#播放按键音
         self.LocalRespondingEnded_timerout = 0
         self.close_timerout = 0
+
         
-        
-        if self.record_data_save_flag == 1:
-            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.AI_client_voice_chat_isconnect == 0:#没连接的时候请求开始
-            self.websocket_connect_voice_chat()#连接服务器
-            self.AI_client_voice_chat_start_requset()
+        if self.AI_client_VC_isconnect == 0:#没连接的时候请求开始
+            self.websocket_connect_VC()#连接服务器
+            self.AI_client_VC_start_requset()
             #utime.sleep_ms(50)
         else:
-            print("self.voice_chat_state :{}".format(self.voice_chat_state ))
-            if self.voice_chat_state > VC_State_SpeechStart:
+            print("self.VC_state :{}".format(self.VC_state ))
+            if self.VC_state > VC_State_SpeechStart:
                 #客户端打断对话
                 print("打断对话")
-                # self.websocket_deconnect_voice_chat()
-                # self.websocket_connect_voice_chat()#连接服务器
-                # self.AI_client_voice_chat_start_requset()
-                self.AI_client_voice_chat_RequestToSpeak()
-            elif self.voice_chat_state == VC_State_Listening:
+                # 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_voice_chat_RequestToRespond()
+                self.AI_client_VC_RequestToRespond()
+                return 
             else:
                 print("异常状态")
-                #self.AI_client_voice_chat_RequestToSpeak()
-                self.websocket_deconnect_voice_chat()
-                self.websocket_connect_voice_chat()#连接服务器
-                self.AI_client_voice_chat_start_requset()
-        if self.AI_client_voice_chat_isconnect == 0:
+                #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.voice_chat_state = VC_State_None
+         
+        self.VC_state = VC_State_None
         if self.AI_TTS_str == "":#没有tts要播放的时候才开始录音
-            self.websocket_connect_asr()
-            if self.AI_client_asr_isconnect == 0:
-                return
             #开始asr录音
             self.VC_Speech_Start()
-            pass
+        #     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, ())
@@ -2093,55 +3180,67 @@ class AI_VC(Abstract):
             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.VC_pingping_timerout = 0
-        self.asr_pingping_timerout = 0
+        # self.VC_pingping_timerout = 0
+        # self.asr_pingping_timerout = 0
         print("AI_VC_start5")
     #开始会话
-    def AI_client_voice_chat_start_requset(self):
-        
-        json_data = \
+    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 =\
         {
-            "header":{
-                "trace_id":self.get_trace_id(),
-                "event":"Start"
+            "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": "测试"}
                 },
-            "payload":{
-                "dialog_id":self.VC_dialog_id,
-                "device_id":modem.getDevImei(),
-                "user_agent":"python",
-                "in_format":"pcm",
-                "out_format":"mp3",
-                "in_sample_rate":self.VC_record_samplerate,
-                "sample_rate":self.VC_play_samplerate,
-                "space_time": 150,
-                "volume": str(self.VC_TTS_volume),
-                "voice":self.VC_TTS_voice_type[str(self.VC_TTS_voice_num)],
-                "voice_detection":"enabled",
-                "simple_response":True,
-                "custom_variables":{
-                    "bot_name":"{}".format(self.bot_name)
-                    }
+                "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.voice_chat_state = VC_State_None
-        self.AI_client_voice_chat_send(ujson.dumps(json_data))
+        # 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_voice_chat_send_speech(self):
+    def AI_client_VC_send_speech(self):
         json_data = \
         {
             "header":{
@@ -2150,30 +3249,37 @@ class AI_VC(Abstract):
                 },
             "payload":
             {
-                "dialog_id":self.VC_dialog_id
+                "dialog_id":self.VC_dialog_id,
+                "session_id": self.session_id ,
             }
         }
-        self.AI_client_voice_chat_send(ujson.dumps(json_data))
+        #self.AI_client_VC_send(ujson.dumps(json_data))
         self.VC_Speech_Start()#开启线程获取录音数据
-        self.voice_chat_state =  VC_State_SpeechStart
+        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_voice_chat_end_speech(self):
+    def AI_client_VC_end_speech(self):
         json_data = \
         {
-            "header":{
-                "trace_id":self.get_trace_id(),
-                "event":"StopSpeech"
-                },
-            "payload":{
-                "dialog_id":self.VC_dialog_id
-                }
+            "id": "event_id",
+            "event_type": "input_audio_buffer.complete",
+            "data": {}
         }
-        self.AI_client_voice_chat_send(ujson.dumps(json_data))
+        self.AI_client_VC_send(ujson.dumps(json_data))
         EventMesh.publish("publish_AI_btnInfo",{"func":self.VC_Speech_End})
-        #self.VC_Speech_End()#停止线程录音
+        
 
     #通知服务器开始播放
-    def AI_client_voice_chat_LocalRespondingStarted(self):
+    def AI_client_VC_LocalRespondingStarted(self):
         json_data = \
         {
             "header":{
@@ -2181,12 +3287,13 @@ class AI_VC(Abstract):
                 "event":"LocalRespondingStarted"
                 },
             "payload":{
-                "dialog_id":self.VC_dialog_id
+                "dialog_id":self.VC_dialog_id,
+                "session_id": self.session_id ,
                 }
         }
-        self.AI_client_voice_chat_send(ujson.dumps(json_data))
+        self.AI_client_VC_send(ujson.dumps(json_data))
     #通知服务器播放结束
-    def AI_client_voice_chat_LocalRespondingEnded(self):
+    def AI_client_VC_LocalRespondingEnded(self):
         json_data = \
         {
             "header":{
@@ -2194,16 +3301,29 @@ class AI_VC(Abstract):
                 "event":"LocalRespondingEnded"
                 },
             "payload":{
-                "dialog_id":self.VC_dialog_id
+                "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_voice_chat_send,"data":ujson.dumps(json_data)}) 
+        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_voice_chat_send(ujson.dumps(json_data))
-        self.voice_chat_state = VC_State_End
+        # self.AI_client_VC_send(ujson.dumps(json_data))
+        self.VC_state = VC_State_End
     #客户端打断对话
-    def AI_client_voice_chat_RequestToSpeak(self):
+    def AI_client_VC_RequestToSpeak(self):
         json_data = \
         {
             "header":{
@@ -2211,15 +3331,17 @@ class AI_VC(Abstract):
                 "event":"RequestToSpeak"
                 },
             "payload":{
-                "dialog_id":self.VC_dialog_id
+                "dialog_id":self.VC_dialog_id,
+                "session_id": self.session_id ,
                 }
         }
-        print("AI_client_voice_chat_RequestToSpeak!!!!!!!!!!!!!!!!!!!!!!!!!!!!!")
+        print("AI_client_VC_RequestToSpeak!!!!!!!!!!!!!!!!!!!!!!!!!!!!!")
         EventMesh.publish("publish_AI_btnInfo",{"func":self.VC_init}) 
-        EventMesh.publish("publish_AI_btnInfo",{"func":self.AI_client_voice_chat_send,"data":ujson.dumps(json_data)}) 
+        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_voice_chat_RequestToRespond(self):
+    def AI_client_VC_RequestToRespond(self):
+        self.session_id  = self.get_session_id()#调试临时打开
         json_data = \
         {
             "header":{
@@ -2228,27 +3350,38 @@ class AI_VC(Abstract):
                 },
             "payload":{
                 "dialog_id":self.VC_dialog_id,
+                "session_id": self.session_id ,
                 "type":"transcript",#prompt是跳过asr,transcript是跳过asr和大模型
                 "text":""
                 }
         }
 
-        print("AI_client_voice_chat_RequestToRespond!!!!!!!!!!!!!!!!!!!!!!!!!!!!!")
+        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_voice_chat_send,"data":ujson.dumps(json_data)}) 
+            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_voice_chat_send,"data":ujson.dumps(json_data)})
+            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_voice_chat_Read(self):
+    def AI_client_VC_Read(self):
         json_data = \
         {
             "header":{
@@ -2259,99 +3392,70 @@ class AI_VC(Abstract):
                 "dialog_id":self.VC_dialog_id
                 }
         }
-        print("AI_client_voice_chat_Read!!!!!!!!!!!!!!!!!!!!!!!!!!!!!")
+        print("AI_client_VC_Read!!!!!!!!!!!!!!!!!!!!!!!!!!!!!")
         
         #for i in range(6): 
-            #EventMesh.publish("publish_AI_btnInfo",{"func":self.AI_client_voice_chat_send,"data":ujson.dumps(json_data)}) 
+            #EventMesh.publish("publish_AI_btnInfo",{"func":self.AI_client_VC_send,"data":ujson.dumps(json_data)}) 
         # utime.sleep_ms(1)
-        if self.AI_client_voice_chat != None and self.AI_client_voice_chat_isconnect == 1:
-            self.AI_client_voice_chat.send(ujson.dumps(json_data))
-    #发送数据队列
-    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(1)
-            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: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_send_data_queue_thread:len:{}".format(len(data[1])))
-                        #print("AI_send_data_queue_thread on line asr recv :{} vc recv:{}".format(_thread.threadIsRunning(self.AI_client_asr_recv_id),_thread.threadIsRunning(self.AI_client_voice_chat_recv_id)))
-                        if data[0] == AI_client_voice_chat_num:
-                            self.VC_pingping_timerout = 0
-                            if isinstance(data[1], str):#是字符串
-                                print("VC VC: send_data:{}".format(data[1]))
-                            #print("VC: send_data len:{}".format(len(data[1])))
-                            if self.AI_client_voice_chat != None and self.AI_client_voice_chat_isconnect == 1:
-                                self.AI_client_voice_chat.send(data[1])
-                            #print("VC: send_data end")
-
-                        if data[0] == AI_client_asr_num:
-                            self.asr_pingping_timerout = 0
-                            if isinstance(data[1], str):#是字符串
-                                print("ASR ASR: send_data:{}".format(data[1]))
-                            if self.AI_client_asr != None and self.AI_client_asr_isconnect == 1:
-                                self.AI_client_asr.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()
-                            pass
-                            #self.websocket_deconnect_voice_chat()
-                            self.AI_client_voice_chat_isconnect = 0
-                            try:
-                                EventMesh.publish("publish_AI_btnInfo",{"func":self.websocket_error}) 
-                                #self.websocket_deconnect_voice_chat()
-                            except Exception as e: #网络连接异常
-                                usys.print_exception(e)
-                        if data[0] == AI_client_asr_num: 
-                            EventMesh.publish("publish_AI_btnInfo",{"func":self.websocket_error}) 
-                            #EventMesh.publish("publish_AI_btnInfo",{"func":self.websocket_connect_asr}) #重连
-                         
+        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_send_data_queue_thread_id == 0:
-                #     break
-                # print("AI_audio_queue_thread")
+                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() :
-                    utime.sleep_ms(1)
-                    count+=1
-                    if count%5000 == 1:
-                        print("AI_audio_queue_thread on")
+                    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_voice_chat_LocalRespondingStarted!!!")
-                        self.AI_client_voice_chat_LocalRespondingStarted()#通知服务器开始播放
+                        print("AI_client_VC_LocalRespondingStarted!!!")
+                        self.AI_client_VC_LocalRespondingStarted()#通知服务器开始播放
                     #self.AI_client_tts_data_len=len(data)
-                    print("audio_queue:len:{},data{}".format(len(data[0]),len(data[1])))
+                    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:
+                                # if self.VC_play_samplerate == 8000:
+                                #     tmp= self.aud.playStream(1,data[0] )
+                                # elif self.VC_play_samplerate == 16000:
                                 
                                 
                                     
@@ -2362,7 +3466,7 @@ class AI_VC(Abstract):
                                         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))
+                                        #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])#播放音频流
                                 
@@ -2383,29 +3487,31 @@ class AI_VC(Abstract):
                                     # tmp= self.aud.playStream(2, h_data_b+data[0])#播放音频流
                                     # print("3playStream:tmp:{} !!!!!!!!!!!!".format(tmp))
                             
-                            #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)
                     
-                    # if self.voice_chat_state == VC_State_TTSEnd and self.AI_audio_queue.empty() :#self.AI_audio_queue为空且tts下发结束
+                    # if self.VC_state == VC_State_TTSEnd and self.AI_audio_queue.empty() :#self.AI_audio_queue为空且tts下发结束
                     #     #通知服务器播放结束
-                    #     self.AI_client_voice_chat_LocalRespondingEnded()
+                    #     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(1000, 1, self.factory_timer_cb)
+        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')#切换成功
+        #self.aud.play(1,0,'U:/static/peizhichenggong.mp3')#切换成功
+        EventMesh.publish("audio_montage_play",["xinhaoruo1.mp3"])
 
     def Close(self):
         self.VC_Thinking_timerout = 0
@@ -2414,47 +3520,45 @@ class AI_VC(Abstract):
         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()
-        self.VC_Speech_End()
+        
         print("ai_VC Close1.2!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!")
-        if self.AI_send_data_queue.empty()!=True:
-            self.AI_send_data_queue.clear()
         
-        print("ai_VC Close1.3!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!")
         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)
-        print("ai_VC Close2!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!")
-        try:
-            self.websocket_deconnect_voice_chat()
+            self.websocket_deconnect_asr()
         except Exception as e:
             usys.print_exception(e)
-        print("ai_VC Close3!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!\r\n")
         try:
-            self.websocket_deconnect_asr()
+            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()
@@ -2466,25 +3570,53 @@ class AI_VC(Abstract):
         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()
-        if self.AI_send_data_queue.empty()!=True:
-            self.AI_send_data_queue.clear()
+        
         print("ai_VC VC_init2!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!")
         try:
-            self.websocket_deconnect_voice_chat()
+            self.websocket_deconnect_VC()
         except Exception as e:
             usys.print_exception(e)
         print("ai_VC Close3!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!\r\n")
         self._1S_timer.stop()
-
-
-    def VC_init(self):
-        
-        print("VC_init:AI_send_data_queue:size:{}".format(self.AI_send_data_queue.size()))
+        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()
@@ -2492,7 +3624,8 @@ class AI_VC(Abstract):
         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
index 9455358..cbd7308 100644 (file)
@@ -316,6 +316,7 @@ class AI_VC(Abstract):
         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
index e90a6ed..73c9839 100644 (file)
@@ -163,22 +163,19 @@ def main_init():
                 import usr.ai_VC as _ai
             except Exception as e:
                 usys.print_exception(e) 
-                try:
-                    import ai_VC as _ai
-                except Exception as e:
-                    usys.print_exception(e)    
+                   
                 try:
                     import usr.ai_VC_7PIN as _ai
                 except Exception as e:
                     usys.print_exception(e) 
-                    try:
-                        import ai_VC as _ai
-                    except Exception as e:
-                        usys.print_exception(e) 
                     try:
                         import usr.ai_VC_G15 as _ai
                     except Exception as e:
                         usys.print_exception(e) 
+                        try:
+                            import ai_VC as _ai
+                        except Exception as e:
+                            usys.print_exception(e) 
 
         #app.append_manager(intervManager())
         try:
index 9aa5365..a066ee2 100644 (file)
Binary files a/2.sdk/project/7PIN/sdk/system/platform/ASR_1606/boards/EG810MCN_GA_VOLTE/images/firmware_base_release_pack.zip and b/2.sdk/project/7PIN/sdk/system/platform/ASR_1606/boards/EG810MCN_GA_VOLTE/images/firmware_base_release_pack.zip differ
index f6f0bfe..cc9f05f 100644 (file)
Binary files a/2.sdk/project/7PIN/usr/static/audio.bin and b/2.sdk/project/7PIN/usr/static/audio.bin differ