AMP改为正式地址
authorazao <821478748@qq.com>
Wed, 17 Sep 2025 09:44:16 +0000 (17:44 +0800)
committerazao <821478748@qq.com>
Wed, 17 Sep 2025 09:45:31 +0000 (17:45 +0800)
加入设备号二维码界面接口
做IOT重连判断

2.sdk/project/K8/sdk/services/microPython/ports/quectel/core/ai_VC.py
2.sdk/project/K8/sdk/services/microPython/ports/quectel/core/main_init.py
2.sdk/project/K8/sdk/services/microPython/ports/quectel/core/protocol.py
2.sdk/project/K8/sdk/services/microPython/ports/quectel/core/ui.py

index aa467bd..3260fad 100644 (file)
@@ -32,6 +32,7 @@ import constants
 import versions
 import usocket
 import lvgl as lv
+from machine import UART
 try:
     import VAD
 except Exception as e:
@@ -322,7 +323,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"])
-                EventMesh.publish("load_screen", {"screen": "charge_in"})#充电弹窗
+                EventMesh.publish("load_screen", {"screen": "charge_in"})#充电弹窗   
             self.Low_power_warning_flag  = 0
             pass
         elif status == 0:#拨出usbs
@@ -671,7 +672,8 @@ class AI_dev(Abstract):
                 audio_buf.index("R_READ_TIME_{}".format(iccid[8])),audio_buf.index("R_READ_TIME_{}".format(iccid[9])),audio_buf.index("R_READ_TIME_{}".format(iccid[10])),audio_buf.index("R_READ_TIME_{}".format(iccid[11])),\
                 audio_buf.index("R_READ_TIME_{}".format(iccid[12])),audio_buf.index("R_READ_TIME_{}".format(iccid[13])),audio_buf.index("R_READ_TIME_{}".format(iccid[14])),audio_buf.index("R_READ_TIME_{}".format(iccid[15])),\
                 audio_buf.index("R_READ_TIME_{}".format(iccid[16])),audio_buf.index("R_READ_TIME_{}".format(iccid[17])),audio_buf.index("R_READ_TIME_{}".format(iccid[18])),audio_buf.index("R_READ_TIME_{}".format(iccid[19])))
-        str_data += '{}.mp3+'.format(audio_buf.index("shouhou"))#可联系售后解决,联系方式见售后客服电话是400-886-8777或到微信公众号柒牌SEVENBRAND自行充值:
+        # str_data += '{}.mp3+'.format(audio_buf.index("shouhou"))#可联系售后解决,联系方式见售后客服电话是400-886-8777或到微信公众号柒牌SEVENBRAND自行充值:
+        # EventMesh.publish("load_screen", {"screen": "imei"})#IMEI弹窗
         self.aud.montage_play('E:/static/audio.bin',1,1,str_data)
     #鉴权出错,播放imei号
     def paly_device_res_error(self,event,msg):
@@ -684,6 +686,7 @@ class AI_dev(Abstract):
                 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))
+        # EventMesh.publish("load_screen", {"screen": "imei"})#IMEI弹窗
         self.aud.montage_play('E:/static/audio.bin',1,1,str_data)
 
 #存储信息
@@ -1385,7 +1388,7 @@ class AI_VC(Abstract):
         self.is_up_error= 0 #是否上传错误id
         self.Close_flag =0 #=1时,连续对话播放完音频就退出
         self.AI_alarm = _ai_alarm.AI_alarm()
-
+        self.buffer = bytearray(16384) #音频缓存区
         #表情变化状态以及检索词
         self.face_status = 0 # 0为正常,1为哭泣,2为愤怒,3为疑惑
         self.normal_list = ["别生气"]
@@ -2347,7 +2350,8 @@ class AI_VC(Abstract):
         # self.Close_flag = 1
         self.Close()
         EventMesh.publish("UI_ai_close")
-        EventMesh.publish("return_prev_screen")
+        EventMesh.publish("load_screen", {"screen": "main_menu"})
+        # EventMesh.publish("return_prev_screen")
 
     def AI_key_press(self, event, msg):#按键按下
         # 测试闹钟功能
@@ -2480,18 +2484,18 @@ class AI_VC(Abstract):
             if self.VC_record_TYPE == VC_record_TYPE_AMR:
                 self.record.stream_stop()
                 self.record.stop()#关闭录音
-                Record_read_buf = bytearray(self.Audio_buf_size)
+                # Record_read_buf = bytearray(self.Audio_buf_size)
                 for i in range(10):
-                    Record_len = self.record.stream_read(Record_read_buf, self.Audio_buf_size)
+                    Record_len = self.record.stream_read(self.buffer, self.Audio_buf_size)
                     print("Record_len:!!!!!!{}".format(Record_len))
                     if Record_len <= 0:
                         break
             elif self.VC_record_TYPE == VC_record_TYPE_PCM:
                 self.record.stream_stop()
                 self.record.stop()#关闭录音
-                Record_read_buf = bytearray(self.Audio_buf_size)
+                # Record_read_buf = bytearray(self.Audio_buf_size)
                 for i in range(10):
-                    Record_len = self.record.stream_read(Record_read_buf, self.Audio_buf_size)
+                    Record_len = self.record.stream_read(self.buffer, self.Audio_buf_size)
                     print("Record_len:!!!!!!{}".format(Record_len))
                     if Record_len <= 0:
                         break
@@ -2558,22 +2562,22 @@ class AI_VC(Abstract):
                 self.VC_record_thread_lock = 1
                 # 死循环接收数据
                 #if self.VC_state ==  VC_State_SpeechStart:
-                Record_read_buf = bytearray(self.Audio_buf_size)
+                # 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)
+                    Record_len = self.record.stream_read(self.buffer, self.Audio_buf_size)
                     #utime.sleep_ms(60)
                     
                 else :
                     
-                    Record_len = self.record.stream_read(Record_read_buf, self.Audio_buf_size)
+                    Record_len = self.record.stream_read(self.buffer, self.Audio_buf_size)
                     utime.sleep_ms(600)
 
                 #Record_len = 1024*2
                 #print("VC_record_thread:{}".format(Record_len))
                 if Record_len > 0:
-                    read_buf = bytes(Record_read_buf[:Record_len])
+                    read_buf = bytes(self.buffer[:Record_len])
                     print("Record_len:{}".format(Record_len))
                     #VAD检测
                     if self.is_VAD == 1:
@@ -2585,16 +2589,16 @@ class AI_VC(Abstract):
                                 break
                             #vad_buf_len = len(vad_buf)
                             if VAD_data_count == 0:#没数据的时候
-                                vad_buf = Record_read_buf[:self.VAD_data_len]
+                                vad_buf = self.buffer[:self.VAD_data_len]
                                 VAD_data_count = self.VAD_data_len
                                 self.vad.custom_vad_reset()#重置vad
                             else:#有数据的时候
                                 if Record_len - VAD_data_count < self.VAD_data_len :#剩余长度不够一次填充,先保留,但不填算法
-                                    vad_buf = Record_read_buf[VAD_data_count:Record_len]
+                                    vad_buf = self.buffer[VAD_data_count:Record_len]
                                     VAD_data_count = 0
                                     break
                                 else:#剩余长度够填一次数据
-                                    vad_buf = Record_read_buf[VAD_data_count:VAD_data_count+self.VAD_data_len]
+                                    vad_buf = self.buffer[VAD_data_count:VAD_data_count+self.VAD_data_len]
                                     VAD_data_count += len(vad_buf)
                             #print("vad_buf_len:{},{}".format(len(vad_buf),VAD_data_count))
                             
@@ -3680,6 +3684,7 @@ class AI_VC(Abstract):
                     text = cmd["command"]["params_json"]
                     text = ujson.loads(text)
                     self.AI_music_str = text["mp3"]
+                    self.VC_Speech_End()
                     return 0
         except Exception as e:
                 usys.print_exception(e)
@@ -3868,7 +3873,10 @@ class AI_VC(Abstract):
                         imei = modem.getDevImei()
                         if imei != -1 and len(imei) > 5:
                             print("IMEI:{}".format(imei))
+                            # EventMesh.publish("UI_ai_close")
+                            # EventMesh.publish("load_screen", {"screen": "imei"})#IMEI弹窗
                             self.AI_TTS_str = "当前设备号为:{}".format(imei)
+                            # self.Close_flag = 1
                         else:
                             self.AI_TTS_str = "设备号查询失败"
                         return 0
@@ -4060,7 +4068,9 @@ class AI_VC(Abstract):
             else:
                 EventMesh.publish("UI_ai_close")
                 EventMesh.publish("publish_AI_btnInfo",{"func":self.Close}) 
-                EventMesh.publish("load_screen", {"screen": "main_menu"})
+                screen_name = EventMesh.publish("get_screen_NAME")
+                if screen_name != "main_menu" and screen_name != "imei":
+                    EventMesh.publish("load_screen", {"screen": "main_menu"})
                 pass
         # print("get_audio_state !!!!!{} {} {}\r\n".format(self.play_end,EventMesh.publish("get_audio_state"),self.play_flag))
         if self.LocalRespondingEnded_timerout>0  :#
@@ -4075,7 +4085,8 @@ class AI_VC(Abstract):
                     if self.Close_flag == 1:
                         self.Close_flag = 0
                         EventMesh.publish("publish_AI_btnInfo",{"func":self.Close}) 
-                        EventMesh.publish("load_screen", {"screen": "main_menu"})
+                        if screen_name != "main_menu" and screen_name != "imei":
+                            EventMesh.publish("load_screen", {"screen": "main_menu"})
                         EventMesh.publish("send_device_VC_state")#上传VC状态
                     else:
                         #utime.sleep_ms(1000)
index 6ab8028..dc4e50e 100644 (file)
@@ -143,7 +143,7 @@ def main_init():
         ui.add_screen(_ui.chargeInScreen()) #充电已连接
         ui.add_screen(_ui.chargefullScreen()) #充电已满
         ui.add_screen(_ui.LowPowerScreen()) #电量低
-        
+        ui.add_screen(_ui.IMEIScreen()) #IMEI二维码显示
         
     except Exception as e:
         usys.print_exception(e)
index d5fa484..aa04f5d 100644 (file)
@@ -779,6 +779,9 @@ class SockMangager(Abstract):
              
 
     def iot_protocol_recv(self):
+        # 配置超时参数,单位:秒
+        RECV_TIMEOUT = 30*1000  # 30秒未收到数据则重连
+        last_recv_time = utime.time()  # 初始化最后一次收到数据的时间
         while True:
             # 死循环接收数据
             # with self.sock_lock:  # 警告:不能加锁,不然会导致线程超长延时
@@ -788,14 +791,30 @@ class SockMangager(Abstract):
                     data = self.IOT_sock.recv(256)
                     if isinstance(data, bytes) and len(data)>10:
                         playload_data(data)
+                        last_recv_time = utime.time()  # 更新最后接收时间
                     socket_log.info("IOT_recv = {} ,len = {}".format(self.bytes_to_hex(data),len(data)))
+                    #检查socket是否已关闭
                     if self.IOT_sock == None:
-                        print("socket关闭退出send线程")
+                        print("socket关闭开启重连")
+                        EventMesh.publish("publish_AI_btnInfo",{"func":self.connect_iot_socket}) 
                         return
+                    #超时检查:如果超过设定时间未收到数据,触发重连
+                    if utime.time() - last_recv_time > RECV_TIMEOUT:
+                        print("超过{}秒未收到数据,触发重连".format(RECV_TIMEOUT))
+                        # 先关闭现有连接
+                        if self.IOT_sock:
+                            self.IOT_sock.close()
+                        # 触发重连
+                        EventMesh.publish("publish_AI_btnInfo", {"func": self.connect_iot_socket})
+                        # 重置超时计时器
+                        last_recv_time = utime.time()
+                        # 重连后短暂延迟再继续循环
+                        utime.sleep(1)
                 except Exception as e:
                     print("cli break")
                     print("异常是:{}".format(e))
                     # EventMesh.publish("connect_iot_websocket_cb")
+                    last_recv_time = utime.time()
                     EventMesh.publish("publish_AI_btnInfo",{"func":self.connect_iot_socket}) 
                     break
         self.iot_protoclo_recv_id =None
index a88f6af..42f910a 100644 (file)
@@ -6563,7 +6563,56 @@ class PowerOnScreen(Screen):
     def btn8_press(self):
         pass
 
+#IMEI号弹窗
+imei_screen = lv.obj()
+print("imei_screen")
+imei_screen.add_style(style_screen, lv.PART.MAIN | lv.STATE.DEFAULT)
+
+bg_color = lv.palette_lighten(lv.PALETTE.LIGHT_BLUE, 5)
+fg_color = lv.palette_darken(lv.PALETTE.BLUE, 4)
+
+imei_qr = lv.qrcode(imei_screen, 150, fg_color, bg_color)
+imei_qr.center()
+# Add a border with bg_color
+imei_qr.set_style_border_color(bg_color, 0)
+imei_qr.set_style_border_width(5, 0)
+
+imei_label = lv.label(imei_screen)
+imei_label.set_pos(0, 280)
+imei_label.set_size(240, 20)
+imei_label.set_text(" ")
+imei_label.set_long_mode(lv.label.LONG.WRAP)
+imei_label.set_style_text_align(lv.TEXT_ALIGN.CENTER, 0)
+imei_label.add_style(style_font_youyuan_20, lv.PART.MAIN | lv.STATE.DEFAULT)
+class IMEIScreen(Screen):
+    NAME = "imei"
 
+    def __init__(self):
+        super().__init__()
+        self.meta = imei_screen
+        self.meta_type = "popup"
+        self.timer = osTimer()
+
+    def initialization(self):
+        imei = EventMesh.publish(constants.EVENT.GET_IMEI)
+        imei_qr_data = str(imei)
+        imei_qr.update(imei_qr_data,len(imei_qr_data))
+        imei_label.set_text(imei)
+
+    def post_processor_after_initialization(self):
+        self.count = 0
+        self.timer.start(1000,1,self.timer_cb_onescond)
+
+    def Close(self):
+        self.timer.stop()
+
+    def timer_cb_onescond(self,e):
+        EventMesh.publish("system_sleep_rest")#防止黑屏
+        self.count+=1
+        if self.count >= 10:
+            self.count = 0
+            self.timer.stop()
+            EventMesh.publish("load_screen", {"screen": "main_menu"})
 
 
 #正在充电
@@ -6603,8 +6652,6 @@ class chargeInScreen(Screen):
 
         self.meta = self.charge_in_screen
        
-
-
     def post_processor_after_initialization(self):
         self.count = 0
         self.timer.start(1000,1,self.timer_cb_onescond)
@@ -7258,7 +7305,7 @@ class UI(object):
                 self.level = 10
             elif self.level <= 0:
                 self.level = 1
-            EventMesh.publish("load_screen", {"screen": "main_menu"})
+            # EventMesh.publish("load_screen", {"screen": "main_menu"})
             utime.sleep_ms(150)
             self.PWM_backlight = PWM(PWM.PWM1, PWM.ABOVE_MS, self.level, 10)
             self.PWM_backlight.open()