完善了历史留言查询的接口
authorazao <821478748@qq.com>
Wed, 19 Nov 2025 09:04:42 +0000 (17:04 +0800)
committerazao <821478748@qq.com>
Wed, 26 Nov 2025 10:11:08 +0000 (18:11 +0800)
以及未读留言机制

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

index bd62d38..0c6b10b 100644 (file)
@@ -529,8 +529,8 @@ class AI_UART():
                 print("当前蓝牙版本是:{}".format(self.bt_versions))
                 self.read_ack_flag = 1
 
-            elif jsload_data["event"] == "kws" :#
-                EventMesh.publish("kws_even")
+            # elif jsload_data["event"] == "kws" :#
+            #     EventMesh.publish("kws_even")
             elif jsload_data["event"] == "ack" :#
                 self.read_ack_flag = 1
             if ack_flag == 1:
@@ -1330,8 +1330,12 @@ class AI_dev(Abstract):
         except Exception as e: 
             usys.print_exception(e)
     def pwk_key_timer_cb(self, *args, **kwargs):
-        if EventMesh.publish("get_play_new_voice_state") == 1:
-            EventMesh.publish("set_play_new_voice_state",0)
+        EventMesh.publish("set_wait_first_flag",0)
+        EventMesh.publish("set_history_board_flag",0)
+        EventMesh.publish("set_play_new_voice_state",0)
+        EventMesh.publish("set_history_voice_flag",0)
+        EventMesh.publish("set_wait_voice_flag",0)
+        EventMesh.publish("set_stop_play",0)
     #     EventMesh.publish("publish_AI_btnInfo",{"func":self.pwk_key_timer_cb_})
     # def pwk_key_timer_cb_(self) :
         try:
@@ -1383,7 +1387,10 @@ class AI_dev(Abstract):
                     print("收到留言")
                     EventMesh.publish("set_voicerupt_flag",1)
                     return
-                print("没收到留言")
+                if EventMesh.publish("get_wait_voice_flag") == 1:
+                    print("播放未读")
+                    EventMesh.publish("set_voicerupt_flag",1)
+                    return
                 if self.KeyAI_press == 0 :
                     EventMesh.publish(constants.EVENT.SYSTEM_UP)#唤醒休眠
                     if EventMesh.publish("get_play_new_voice_state") == 1:
@@ -2491,7 +2498,7 @@ class AI_VC(Abstract):
         self.VC_30S_timer = osTimer()
         self.ai_key_press_audio = osTimer()
         self.VC_30S_timer.start(30000, 1, self.VC_30S_timer_cb)
-        self.online_kws = 1#是否开启线上关键词
+        self.online_kws = 0#是否开启线上关键词
         self.get_config_timer_count = 0
         self.record_data_save_flag = 0 #是否保存录音文件
         self.play_data_save_flag = 0#是否保存tts数据到文件
@@ -2509,17 +2516,23 @@ class AI_VC(Abstract):
         self.Close_flag =0 #=1时,连续对话播放完音频就退出
 
         self.play_new_voice_flag =0 #播放文字留言flag
+
+        self.wait_first_flag = 0#是否进入未读判定(只播报一次)
         EventMesh.subscribe("play_tts",self.play_tts)
         EventMesh.subscribe("play_new_voice",self.play_new_voice)
+        EventMesh.subscribe("play_his_voice",self.play_his_voice)
+        EventMesh.subscribe("play_wait_voice",self.play_wait_voice)
         EventMesh.subscribe("play_single_voice",self.play_single_voice)#不带tts的播放(闹钟)
         EventMesh.subscribe("play_music",self.play_music)#播放音乐
         EventMesh.subscribe("play_trans_tts",self.play_trans_tts)#接收翻译tts
         EventMesh.subscribe("set_vad_silence",self.set_vad_silence)
+        EventMesh.subscribe("set_wait_first_flag",self.set_wait_first_flag)
         EventMesh.subscribe("kws_even",self.kws_even)
         EventMesh.subscribe("change_volume",self.change_volume)    
         EventMesh.subscribe("find_cmd",self.find_cmd) #查询命令
         EventMesh.subscribe("change_voice",self.change_voice) #改变音色
         EventMesh.subscribe("Close_VC",self.Close_VC) #外部结束对话
+        EventMesh.subscribe("get_recv_voice",self.get_recv_voice) #获取留言播放状态
         self.voice_timer = osTimer()#语音留言10S按下按键确定是否播放的判断定时器
         self.voice_cnt = 0 #留言定时器计数
         self.voicerupt_flag = 0#留言选择按键接听标志位
@@ -2534,6 +2547,12 @@ class AI_VC(Abstract):
         self.music_timer = osTimer()#音乐播放定时器,等待tts播完才放音乐
         self.music_cnt = 0 #留言定时器计数
 
+        self.his_timer = osTimer()#历史留言播放定时器,等待tts播完再播留言
+        self.his_cnt = 0#历史留言定时器技术
+
+        self.wait_timer = osTimer()#未读留言播放定时器,等待tts播完再播留言
+        self.wait_cnt = 0#未读留言定时器技术
+
         self.error_data = []
         self.asr_taskid  = ""
         self.VC_taskid  = ""
@@ -2545,6 +2564,10 @@ class AI_VC(Abstract):
         #AI翻译标志
         self.trans_flag = 0
 
+        #历史留言查看判断标志
+        self.history_voice_flag = 0#公共变量判断 
+        #60S等待留言判断标志
+        self.wait_voice_flag = 0#公共变量判断 
         EventMesh.publish("AI_alarm_open")#
         self.server_ip = EventMesh.publish("get_storage_config","server_ip")#
         if self.server_ip == None:
@@ -2870,6 +2893,7 @@ class AI_VC(Abstract):
         self.AI_ASR_error_timeout = 0
         self.VC_Thinking_timerout = 0
 
+
         self.record_pcm = None
         self.play_pcm = None
         self.VC_record_thread_id = 0
@@ -2931,7 +2955,10 @@ class AI_VC(Abstract):
         EventMesh.subscribe("set_voicerupt_flag",self.set_voicerupt_flag)#按键中断触发留言播放
         EventMesh.subscribe("get_recv_voice",self.get_recv_voice)#获取是否收到留言
         EventMesh.subscribe("rate_change",self.rate_change)#直接修改语速
-        EventMesh.subscribe("rate_move",self.rate_move)#模糊修改语速
+        EventMesh.subscribe("get_history_voice_flag",self.get_history_voice_flag)#获取查找历史留言状态
+        EventMesh.subscribe("set_history_voice_flag",self.set_history_voice_flag)#修改查找历史留言状态
+        EventMesh.subscribe("get_wait_voice_flag",self.get_wait_voice_flag)#获取60S等待留言播放定时器状态
+        EventMesh.subscribe("set_wait_voice_flag",self.set_wait_voice_flag)#修改60S等待留言播放定时器状态
         # EventMesh.subscribe("get_voicerupt_flag",self.get_voicerupt_flag)#获取留言播放状态
         # EventMesh.subscribe("chenggong_tone",self.chenggong_tone)
         
@@ -3011,6 +3038,21 @@ class AI_VC(Abstract):
             self.speech_rate -= 10
         EventMesh.publish("set_storage_config",["speech_rate",self.speech_rate])
         print("set_speech_rate:{}".format(self.speech_rate))
+
+    #获取60S等待留言播放定时器状态
+    def get_wait_voice_flag(self,event,msg):
+        return self.wait_voice_flag
+    def set_wait_voice_flag(self,event,msg):
+        print("未读留言标记修改为:{}".format(msg))
+        self.wait_voice_flag = msg
+
+    #查看历史留言状态修改
+    def get_history_voice_flag(self,event,msg):
+        return self.history_voice_flag
+    def set_history_voice_flag(self,event,msg):
+        print("历史留言标记修改为:{}".format(msg))
+        self.history_voice_flag = msg
+    
     def audio_test(self,event = None, msg = None):
         self.VC_Speech_Start()   
         self.VC_Play_Start()      
@@ -3414,6 +3456,9 @@ class AI_VC(Abstract):
         # return
         EventMesh.publish("exit_meet_mode")#退出会议纪要
         EventMesh.publish("exit_trans_mode")#退出AI翻译
+        self.recv_voice = 0#退出留言以及留言查看
+        EventMesh.publish("set_history_voice_flag",0)#修改标志位
+        self.AI_new_voice_url = ""
         EventMesh.publish("publish_AI_btnInfo",{"func":self.Close}) 
         EventMesh.publish("stop_sos_call")
         #EventMesh.publish("sleep_BT")#休眠蓝牙
@@ -4071,18 +4116,34 @@ class AI_VC(Abstract):
                                 self.alarm_play_flag = 0
                                 self.voice_choose_flag = 1
                             elif self.AI_TTS_str == "" and  self.AI_new_voice_url != "" and self.music_play_flag == 0:
-                                self.voice_cnt = 0
-                                print("定时器开启222222222")
-                                self.voice_timer.start(1000,1,self.voice_judge)
+                                if EventMesh.publish("get_history_voice_flag") == 1:
+                                    EventMesh.publish("publish_AI_btnInfo",{"func":self.AI_client_new_voice})#播放留言
+                                    self.recv_voice = 0#当留言列表为空,留言播放标志清空
+                                else:
+                                    self.voice_cnt = 0
+                                    print("定时器开启222222222")
+                                    self.voice_timer.start(1000,1,self.voice_judge)
                             elif  self.AI_TTS_str != "" and  self.AI_new_voice_url == "":
                                 EventMesh.publish("publish_AI_btnInfo",{"func":self.AI_client_VC_synthesis})
                             
                             elif self.AI_TTS_str != "" and  self.AI_new_voice_url != "" and self.music_play_flag == 0:#遇到tts和语音留言冲突时(并且没有音乐播放)
-                                EventMesh.publish("publish_AI_btnInfo",{"func":self.AI_client_VC_synthesis})
-                                self.voice_cnt = 0
-                                print("定时器开启111111111")
-                                self.voice_timer.start(1000,1,self.voice_judge) 
-                                self.voice_choose_flag = 1
+                                if EventMesh.publish("get_history_voice_flag") == 1:#播放历史留言
+                                    if EventMesh.publish("get_wait_voice_flag") == 0:
+                                        EventMesh.publish("publish_AI_btnInfo",{"func":self.AI_client_VC_synthesis})
+                                        self.his_cnt = 0
+                                        self.his_timer.start(1000,1,self.history_play) 
+                                        self.voice_choose_flag = 1
+                                    else:#等待留言
+                                        self.wait_cnt = 0
+                                        EventMesh.publish("publish_AI_btnInfo",{"func":self.AI_client_VC_synthesis})
+                                        self.wait_timer.start(1000,1,self.wait_play) 
+                                        self.voice_choose_flag = 1
+                                else:#播放正常留言
+                                    EventMesh.publish("publish_AI_btnInfo",{"func":self.AI_client_VC_synthesis})
+                                    self.voice_cnt = 0
+                                    print("定时器开启111111111")
+                                    self.voice_timer.start(1000,1,self.voice_judge) 
+                                    self.voice_choose_flag = 1
                                 # self.AI_TTS_str = ""    
                             elif self.AI_TTS_str != "" and  self.AI_new_voice_url != "" and self.music_play_flag == 1 :#遇到tts和语音留言冲突时(并且有音乐播放)
                                 self.music_play_flag = 0
@@ -4243,9 +4304,18 @@ class AI_VC(Abstract):
                                 print("语音留言回复停止")
                                 self.revoice_timer.start(1000,1,self.revoice_judge)
                             if EventMesh.publish("get_play_new_voice_state")== 1:
-                                EventMesh.publish("set_play_new_voice_state",1)
-                                EventMesh.publish("update_play_new_voice_info")
+                                EventMesh.publish("set_play_new_voice_state",0)
+                                # EventMesh.publish("update_play_new_voice_info")
                                 EventMesh.publish("play_new_voice_list")
+                            print("是否未读:{},是否播完:{}".format(EventMesh.publish("get_wait_voice_flag"),len(EventMesh.publish("get_play_new_voice_list"))))
+                            if len(EventMesh.publish("get_play_new_voice_list")) ==0:#还在未读并且列表为空
+                                self.wait_first_flag = 0
+                                print("未读留言播完,清空标志")
+                                EventMesh.publish("set_history_voice_flag",0)
+                            EventMesh.publish("update_play_new_voice_info")#更新已读状态
+                            self.recv_voice = 0
+                            self.LocalRespondingEnded_timerout = 8
+                            self.VC_state = VC_State_End
                                 
                             pass
                         elif jsload_data["event"] == "audio.convert.failed": #音频转换失败了
@@ -4328,6 +4398,7 @@ class AI_VC(Abstract):
            self.voice_cnt = 0
            self.recv_voice = 0#进入留言定时器,留言清空
            print("进入留言定时器1,留言清空!!!!!")
+           EventMesh.publish("update_play_new_voice_info")#更新已读状态
            self.voice_timer.stop()
         if self.voice_cnt > 15:#10S后退出播放,5S是为了给语音提示留时间
            self.voice_cnt = 0
@@ -4357,6 +4428,39 @@ class AI_VC(Abstract):
            EventMesh.publish("publish_AI_btnInfo",{"func":self.AI_client_new_voice})#播放留言
            self.music_cnt = 0
            self.music_timer.stop() 
+    #历史留言播放定时器
+    def history_play(self, *args, **kwargs):
+        EventMesh.publish("publish_AI_btnInfo",{"func":self.history_play_cb})  
+    def history_play_cb(self):
+        self.his_cnt += 1
+        if self.his_cnt > 4:#4S后播放,4S是为了给语音提示留时间
+           self.AI_VC_start()
+           EventMesh.publish("publish_AI_btnInfo",{"func":self.AI_client_new_voice})#播放留言
+           self.his_cnt = 0
+           self.his_timer.stop() 
+    #未读留言播放定时器
+    def wait_play(self, *args, **kwargs):
+        EventMesh.publish("publish_AI_btnInfo",{"func":self.wait_play_cb})  
+    def wait_play_cb(self):
+        self.wait_cnt += 1
+        if self.voicerupt_flag == 1:#按键被按下
+           self.AI_VC_start()
+           EventMesh.publish("publish_AI_btnInfo",{"func":self.AI_client_new_voice})#播放留言
+           self.wait_cnt = 0
+           print("进入留言定时器1,留言清空!!!!!")
+           EventMesh.publish("update_play_new_voice_info")#更新已读状态
+           self.wait_timer.stop()
+           self.voicerupt_flag = 0
+        if self.wait_cnt > 10:#10S后退出播放,5S是为了给语音提示留时间
+           self.wait_cnt = 0
+           self.recv_voice = 0#进入留言定时器,留言清空
+           EventMesh.publish("set_history_voice_flag",0)
+           EventMesh.publish("set_wait_voice_flag",0)
+           self.wait_first_flag = 0
+           if self.voice_choose_flag == 1:#播放完语音后,有冲突的时候关闭
+              self.voice_choose_flag = 0
+           print("进入留言定时器2,留言清空!!!!!")
+           self.wait_timer.stop()
     def set_voicerupt_flag(self,event,msg):#按键控制留言播放
         self.voicerupt_flag = msg
     def get_voicerupt_flag(self,event,msg):#获取按键控制留言播放状态
@@ -4665,7 +4769,7 @@ class AI_VC(Abstract):
             return -1
         try:
             if isinstance(text, str): 
-                if dev_type != 'jswm' and dev_type != 'jswm_BOX':#金三完美,不使用设备切换角色
+                # if dev_type != 'jswm' and dev_type != 'jswm_BOX':#金三完美,不使用设备切换角色
                     # if len(text)<25 and (text.find("你好") != -1 or text.find("您好") != -1) :
                     #     try:
                     #         for key in self.VC_TTS_voice_type:
@@ -4677,74 +4781,74 @@ class AI_VC(Abstract):
                     #     except Exception as e:
                     #         usys.print_exception(e) 
                     #     return -1
-                    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 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 dev_type == "7PIN_BK_EU":
                         if self.VC_mode == 0:
@@ -5499,6 +5603,8 @@ class AI_VC(Abstract):
         EventMesh.publish("set_storage_config",["vad_silence",self.vad_silence])  
         # EventMesh.publish("publish_AI_btnInfo",{"func":self.play_new_voice_cb,"data":msg}) 
         #设置tts参数
+    def set_wait_first_flag(self,event = None,msg= None):#设置未读语音播报初次记录flag
+        self.wait_first_flag = msg
     def set_VC_TTS_voice_type(self,event = None,msg= None):
         self.VC_TTS_voice_type["APP_voice"] = msg
         #self.VC_TTS_voice_type[self.VC_TTS_voice_key]
@@ -5648,7 +5754,76 @@ class AI_VC(Abstract):
                 self.recv_voice = 1#收到留言
                 print("已收到最新留言!!!!!")
                 # EventMesh.publish("set_motor_time",[1,1,5,8,4])#设置马达参数
-                EventMesh.publish("play_tts",["您有一条语音留言,10秒内按下中间键可以收听",1])
+                self.AI_new_voice_url = new_voice_url
+                EventMesh.publish("play_tts",["您有一条语音留言,10秒内按下中间键可以收听",1]) 
+            if is_close_VC != None:
+                self.Close_flag = is_close_VC
+            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()
+            EventMesh.publish("open_led_all")
+            self.AI_ASR_send_buf_len = 0
+            self.VC_Speech_End()
+            self.websocket_deconnect_VC()
+            self.AI_VC_start()
+            self.play_new_voice_flag = 1
+            # EventMesh.publish("publish_AI_btnInfo",{"func":self.VC_Speech_End})
+            # EventMesh.publish("publish_AI_btnInfo",{"func":self.websocket_deconnect_VC}) 
+            # EventMesh.publish("publish_AI_btnInfo",{"func":self.AI_VC_start}) 
+        except Exception as e:
+                usys.print_exception(e)   
+        pass
+    #历史留言查看
+    def play_his_voice(self,event = None,msg= None):
+        EventMesh.publish("publish_AI_btnInfo",{"func":self.play_his_voice_cb,"data":msg}) 
+    def play_his_voice_cb(self,data):
+        try:
+            new_voice_url = data[0] #音频地址
+            is_close_VC = data[1]
+            time = data[2]
+            tts_play_str = time + "收到" 
+            EventMesh.publish("play_tts",[tts_play_str,1])
+            if new_voice_url != "":
+                self.recv_voice = 1#收到留言
+                print("历史留言查看")
+                # tts_play_str = "收到" 
+                # EventMesh.publish("play_tts",[tts_play_str,1])
+                # EventMesh.publish("set_motor_time",[1,1,5,8,4])#设置马达参数
+                self.AI_new_voice_url = new_voice_url
+            if is_close_VC != None:
+                self.Close_flag = is_close_VC
+            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()
+            EventMesh.publish("open_led_all")
+            self.AI_ASR_send_buf_len = 0
+            self.VC_Speech_End()
+            self.websocket_deconnect_VC()
+            self.AI_VC_start()
+            self.play_new_voice_flag = 1
+            # EventMesh.publish("publish_AI_btnInfo",{"func":self.VC_Speech_End})
+            # EventMesh.publish("publish_AI_btnInfo",{"func":self.websocket_deconnect_VC}) 
+            # EventMesh.publish("publish_AI_btnInfo",{"func":self.AI_VC_start}) 
+        except Exception as e:
+                usys.print_exception(e)   
+        pass
+    #等待未读留言查看
+    def play_wait_voice(self,event = None,msg= None):
+        EventMesh.publish("publish_AI_btnInfo",{"func":self.play_wait_voice_cb,"data":msg}) 
+    def play_wait_voice_cb(self,data):
+        try:
+            new_voice_url = data[0] #音频地址
+            is_close_VC = data[1]
+            print("是否为第一次:{}".format(self.wait_first_flag))
+            if self.wait_first_flag == 0:
+                tts_play_str = "您有" + str(len(EventMesh.publish("get_play_new_voice_list"))) + "条未读留言,10秒内按下中间键可以收听"
+                EventMesh.publish("play_tts",[tts_play_str,1])  
+                self.wait_first_flag = 1
+            if new_voice_url != "":
+                self.recv_voice = 1#收到留言
+                print("未读留言查看")
                 self.AI_new_voice_url = new_voice_url
             if is_close_VC != None:
                 self.Close_flag = is_close_VC
index 89454cc..40e3f61 100644 (file)
@@ -239,6 +239,7 @@ def main_init():
             pcr.add_support(pro.IOTWeb_put_voice_msg_stateProtoCol())
             pcr.add_support(pro.IOTWeb_new_voice_msg_listProtoCol())
             pcr.add_support(pro.IOTWeb_get_new_voice_msgProtoCol())
+            pcr.add_support(pro.IOTWeb_find_new_voice_msgProtoCol())
             pcr.add_support(pro.IOTWeb_new_voice_msgProtoCol())
             pcr.add_support(pro.IOTWeb_get_bt_connect_record_listProtoCol())
             pcr.add_support(pro.IOTWeb_bt_connect_record_listProtoCol())
index a0c282c..66fd335 100644 (file)
@@ -1339,6 +1339,7 @@ class SockMangager(Abstract):
         self.start_voice_flag = 0
         self.init_send_default=0
         self.play_new_voice_state = 0
+        self.stop_play = 0
         self.get_voice_new_msginit = 0
         self.voice_id = "0"
         self.bt_connect_list = []
@@ -1386,6 +1387,7 @@ class SockMangager(Abstract):
         EventMesh.subscribe("close_websocket_timer",self.close_websocket_timer)
         EventMesh.subscribe("connect_iot_websocket_cb",self.connect_iot_websocket_cb)
         EventMesh.subscribe("set_play_new_voice_list",self.set_play_new_voice_list)
+        EventMesh.subscribe("get_play_new_voice_list",self.get_play_new_voice_list)
 
         EventMesh.subscribe("send_meet_open_flag_to_iot",self.send_meet_open_flag_to_iot)#会议创建
         EventMesh.subscribe("send_meet_end_flag_to_iot",self.send_meet_end_flag_to_iot)#会议结束
@@ -1402,6 +1404,8 @@ class SockMangager(Abstract):
         EventMesh.subscribe("send_bt_connect_list",self.send_bt_connect_list) #发送耳机连接状态列表
         EventMesh.subscribe("set_play_new_voice_state",self.set_play_new_voice_state) #设置播放语音未读状态1正在播放语音未读消息
         EventMesh.subscribe("get_play_new_voice_state",self.get_play_new_voice_state) #获取播放语音未读状态1正在播放语音未读消息
+        EventMesh.subscribe("set_stop_play",self.set_stop_play) #外部控制url音频播放列表暂停
+        EventMesh.subscribe("get_stop_play",self.get_stop_play) #获取外部控制url音频播放列表暂停情况
         EventMesh.subscribe("send_bt_connect_state_to_iot",self.send_bt_connect_state_to_iot) #发耳机;链接状态->IOT
         EventMesh.subscribe("send_unbind_dev_to_iot",self.send_unbind_dev_to_iot) #发送解绑指令到IOT平台
         EventMesh.subscribe("set_location_info",self.set_location_info)  #设置定位信息
@@ -1553,12 +1557,23 @@ class SockMangager(Abstract):
         self.new_voice_list = msg
         pass
 
+    def get_play_new_voice_list(self,event,msg):
+        return self.new_voice_list
+
     def set_play_new_voice_state(self,event,msg):
         self.play_new_voice_state = msg
         pass
 
     def get_play_new_voice_state(self,event,msg):
         return self.play_new_voice_state
+
+    def get_stop_play(self,event,msg):
+        return self.stop_play
+
+    def set_stop_play(self,event,msg):
+        self.stop_play = msg
+        pass
+
     def _1S_timer_cb(self,*argc):
         EventMesh.publish("publish_AI_btnInfo",{"func":self._1S_timer_cb_}) 
 
@@ -1586,9 +1601,23 @@ class SockMangager(Abstract):
                 url = str(data["url"])
                 # url = "http://qipaiai-oss1.tos-cn-beijing.volces.com/qi_pai_ringtone/2025_08_11/742659759219544064test.mp3"
                 self.play_new_voice_state = 1
-                EventMesh.publish("play_new_voice",[url,1])
-                
+                if self.stop_play == 1:
+                    print("结束播放")
+                    self.stop_play = 0
+                    break
+                if EventMesh.publish("get_history_voice_flag") == 1:#播放历史留言 or 播放当前留言
+                    if EventMesh.publish("get_wait_voice_flag") == 1:#等待留言
+                        EventMesh.publish("play_wait_voice",[url,1])
+                    else:
+                        time = str(data["createTimeStr"])
+                        EventMesh.publish("play_his_voice",[url,1,time])
+                    if len(EventMesh.publish("get_play_new_voice_list")) == 0:#列表为空才清零
+                        EventMesh.publish("set_history_voice_flag",0)#修改标志位
+
+                else:
+                    EventMesh.publish("play_new_voice",[url,1])
                 break
+
             pass
     def update_play_new_voice_info(self,event,msg): #更新播放语音留言信息
         date_tmp = utime.localtime()
@@ -2674,6 +2703,8 @@ def ai_cmd_handle(cmd):
             tts_play_str = "音量已经改为" + find
         EventMesh.publish("play_tts",[tts_play_str,0])
     elif "查看历史留言" in cmd :#当指令中有查看历史留言时,调用历史留言接口
+        EventMesh.publish(WEB_CMD_ENUM.GET_NEW_VOICE_MSG_S)
+        EventMesh.publish("set_history_voice_flag",1)#修改标志位
         pass
 
 #NLP指令
@@ -3486,6 +3517,72 @@ class IOTWeb_new_voice_msgProtoCol(ProtoCol):
         EventMesh.publish(WEB_CMD_ENUM.NEW_VOICE_MSG_S)
 
         print("recv new_voice_msg{}".format(msg))
+
+#设备主动查询未读的语音消息列表
+class IOTWeb_find_new_voice_msgProtoCol(ProtoCol):
+    """find_voice_msg_list"""
+    TYPE = "find_voice_msg_list"
+    def __init__(self):
+        super().__init__()
+        self.history_board_flag = 0#第一次进去要广播
+        self.has_processed_history_voice = 0 #播完列表不许再拨“历史未读留言为空”
+        EventMesh.subscribe("set_history_board_flag",self.set_history_board_flag)
+    def send(self, event, msg):
+
+        print("send find_voice_msg_list")
+
+    def recv(self, event, msg):
+        """
+
+        @param event:find_voice_msg_list
+        @param msg: 接收到的下行数据
+        """
+        print("recv find_voice_msg_list{}".format(msg))
+
+        new_voice_list = []#字典列表
+        voice_list = msg["data"]
+        print("msg[\"data\"] = {}".format(voice_list))
+        if EventMesh.publish("get_history_voice_flag") == 1:
+            if len(voice_list) == 0:#为空
+                if EventMesh.publish("get_wait_voice_flag") == 0:#未听历史留言
+                    if self.has_processed_history_voice == 0:
+                        tts_play_str = "历史未读留言列表为空"
+                        EventMesh.publish("play_tts",[tts_play_str,1])
+                    else:
+                        self.has_processed_history_voice = 0#读完了置为0
+                        self.history_board_flag = 0#广播置为0
+                    EventMesh.publish("set_history_voice_flag",0)#修改标志位
+                    self.history_board_flag = 0
+                    self.has_processed_wait_voice = 0
+                    EventMesh.publish("set_wait_voice_flag",0)#修改60S标志位
+                    self.wait_first_flag = 0
+                else:#等待历史留言
+                    self.has_processed_wait_voice = 0
+                    self.wait_first_flag = 0
+                    EventMesh.publish("set_history_voice_flag",0)
+                    EventMesh.publish("set_wait_voice_flag",0)#修改60S标志位
+            else:#有历史留言
+                if EventMesh.publish("get_wait_voice_flag") == 0:#历史留言
+                    print("历史广播状态!!!!! = {}".format(self.history_board_flag))
+                    if self.history_board_flag == 0:
+                        tts_play_str = "您共有" + str(len(voice_list)) + "条历史留言,正在为您播放"
+                        EventMesh.publish("play_tts",[tts_play_str,1])
+                        self.history_board_flag = 1
+                        self.has_processed_history_voice = 1
+                    for da in voice_list:
+                        new_voice_list.append(da)
+                    if len(new_voice_list) > 0:
+                        pass
+                else:#未读留言
+                    for da in voice_list:
+                            new_voice_list.append(da)
+                    if len(new_voice_list) > 0:
+                        pass
+                EventMesh.publish("set_play_new_voice_list",new_voice_list)
+                EventMesh.publish("play_new_voice_list")
+    def set_history_board_flag(self,event,msg):
+        self.history_board_flag = msg           
+
 #请求未读的语音消息列表
 class IOTWeb_get_new_voice_msgProtoCol(ProtoCol):
     """get_new_voice_msg"""
@@ -3607,7 +3704,9 @@ class IOTWeb_player_controlProtoCol(ProtoCol):
 class IOTWeb_new_voice_msg_listProtoCol(ProtoCol):
     """new_voice_msg_list"""
     TYPE = "new_voice_msg_list"
-
+    def __init__(self):
+        super().__init__()
+        self._1M_flag = 0#判断一分钟定时器是否开启中
     def send(self, event, msg):
         print("send new_voice_msg_list{}".format(msg))
         # 通过websocket发送到服务器端
@@ -3634,6 +3733,7 @@ class IOTWeb_new_voice_msg_listProtoCol(ProtoCol):
         @param event:new_voice_msg_list
         @param msg: 接收到的下行数据
         """
+        self._1M_timer = osTimer()#多发留言间隙时间60S
         new_voice_list = []
         if "data" in msg:
             data = msg["data"]
@@ -3642,9 +3742,34 @@ class IOTWeb_new_voice_msg_listProtoCol(ProtoCol):
         if len(new_voice_list) > 0:
             pass
         EventMesh.publish("set_play_new_voice_list",new_voice_list)
-        EventMesh.publish("play_new_voice_list")
+        if EventMesh.publish("get_recv_voice") == 0 and self._1M_flag == 0:#当没有音频在播放时,再播放新的,否则保存下来不播放,等60S后一起播放
+            EventMesh.publish("play_new_voice_list")
+        else:#当有音频在播放时,存下来开始倒计时
+            pass
+            if self._1M_flag == 0:
+                print("等待留言60S倒计时开启")
+                self._1M_timer.start(60000, 1, self._1M_timer_cb)
+                self._1M_flag = 1
         EventMesh.publish(WEB_CMD_ENUM.NEW_VOICE_MSG_LIST_S)
         print("recv new_voice_msg_list{}".format(msg))
+    def _1M_timer_cb(self,*argc):
+        EventMesh.publish("publish_AI_btnInfo",{"func":self._1M_timer_cb_}) 
+
+    def _1M_timer_cb_(self): 
+        #self.iot_web_send_queue.put("ping") 
+        if len(EventMesh.publish("get_play_new_voice_list")) == 0:
+            self._1M_timer.stop()
+            self._1M_flag = 0
+        get_VC_satrt_flag = EventMesh.publish("get_VC_satrt_flag")
+        if get_VC_satrt_flag == None:
+            get_VC_satrt_flag = 0
+        if get_VC_satrt_flag == 0:
+            print("收到多条信息,统一播放")
+            EventMesh.publish(WEB_CMD_ENUM.GET_NEW_VOICE_MSG_S)
+            EventMesh.publish("set_history_voice_flag",1)#修改历史留言标志位
+            EventMesh.publish("set_wait_voice_flag",1)#修改60S标志位
+            self._1M_flag = 0
+            self._1M_timer.stop()
 class IOTWeb_put_voice_msg_stateProtoCol(ProtoCol):
     """put_voice_msg_state"""
     TYPE = "put_voice_msg_state"