金三完美提交1
authorazao <821478748@qq.com>
Mon, 15 Sep 2025 09:18:13 +0000 (17:18 +0800)
committerazao <821478748@qq.com>
Mon, 15 Sep 2025 09:18:13 +0000 (17:18 +0800)
44 files changed:
2.sdk/project/K8/ext/static/01.jpg [new file with mode: 0644]
2.sdk/project/K8/ext/static/02.jpg [new file with mode: 0644]
2.sdk/project/K8/ext/static/51.jpg [new file with mode: 0644]
2.sdk/project/K8/ext/static/52.jpg [new file with mode: 0644]
2.sdk/project/K8/ext/static/61.jpg [new file with mode: 0644]
2.sdk/project/K8/ext/static/62.jpg [new file with mode: 0644]
2.sdk/project/K8/ext/static/dj1.jpg [new file with mode: 0644]
2.sdk/project/K8/ext/static/dj2.jpg [new file with mode: 0644]
2.sdk/project/K8/ext/static/j1.jpg [new file with mode: 0644]
2.sdk/project/K8/ext/static/j2.jpg [new file with mode: 0644]
2.sdk/project/K8/ext/static/mj1.jpg [new file with mode: 0644]
2.sdk/project/K8/ext/static/mj2.jpg [new file with mode: 0644]
2.sdk/project/K8/ext/static/zj1.jpg [new file with mode: 0644]
2.sdk/project/K8/ext/static/zj2.jpg [new file with mode: 0644]
2.sdk/project/K8/images/customer_fs.bin
2.sdk/project/K8/images/ext_fs.bin
2.sdk/project/K8/sdk/services/microPython/ports/quectel/core/Makefile
2.sdk/project/K8/sdk/services/microPython/ports/quectel/core/ai_VC.py
2.sdk/project/K8/sdk/services/microPython/ports/quectel/core/ai_alarm.py [new file with mode: 0644]
2.sdk/project/K8/sdk/services/microPython/ports/quectel/core/alarm.py
2.sdk/project/K8/sdk/services/microPython/ports/quectel/core/lcd.py
2.sdk/project/K8/sdk/services/microPython/ports/quectel/core/main_init.py
2.sdk/project/K8/sdk/services/microPython/ports/quectel/core/mgr.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
2.sdk/project/K8/sdk/services/microPython/ports/quectel/core/ui_WatchFaceScreen.py
2.sdk/project/K8/sdk/services/microPython/ports/quectel/core/versions.py
2.sdk/project/K8/sdk/system/platform/ASR_1606/boards/EG810MCN_GA_VOLTE/images/firmware_base_release_pack.zip
2.sdk/project/K8/usr/audio_gain.nvm [new file with mode: 0644]
2.sdk/project/K8/usr/audio_ve.nvm
2.sdk/project/K8/usr/static/0.png [new file with mode: 0644]
2.sdk/project/K8/usr/static/1.png [new file with mode: 0644]
2.sdk/project/K8/usr/static/100.png [new file with mode: 0644]
2.sdk/project/K8/usr/static/2.png [new file with mode: 0644]
2.sdk/project/K8/usr/static/20.png [new file with mode: 0644]
2.sdk/project/K8/usr/static/3.png [new file with mode: 0644]
2.sdk/project/K8/usr/static/4.png [new file with mode: 0644]
2.sdk/project/K8/usr/static/40.png [new file with mode: 0644]
2.sdk/project/K8/usr/static/60.png [new file with mode: 0644]
2.sdk/project/K8/usr/static/80.png [new file with mode: 0644]
2.sdk/project/K8/usr/static/isconnect.png [new file with mode: 0644]
2.sdk/project/K8/usr/static/nosim.png [new file with mode: 0644]
2.sdk/project/K8/usr/static/notconnect.png [new file with mode: 0644]
2.sdk/project/K8/usr/static/open.PNG [new file with mode: 0644]

diff --git a/2.sdk/project/K8/ext/static/01.jpg b/2.sdk/project/K8/ext/static/01.jpg
new file mode 100644 (file)
index 0000000..b450991
Binary files /dev/null and b/2.sdk/project/K8/ext/static/01.jpg differ
diff --git a/2.sdk/project/K8/ext/static/02.jpg b/2.sdk/project/K8/ext/static/02.jpg
new file mode 100644 (file)
index 0000000..d4b7104
Binary files /dev/null and b/2.sdk/project/K8/ext/static/02.jpg differ
diff --git a/2.sdk/project/K8/ext/static/51.jpg b/2.sdk/project/K8/ext/static/51.jpg
new file mode 100644 (file)
index 0000000..25b7dde
Binary files /dev/null and b/2.sdk/project/K8/ext/static/51.jpg differ
diff --git a/2.sdk/project/K8/ext/static/52.jpg b/2.sdk/project/K8/ext/static/52.jpg
new file mode 100644 (file)
index 0000000..460fdb4
Binary files /dev/null and b/2.sdk/project/K8/ext/static/52.jpg differ
diff --git a/2.sdk/project/K8/ext/static/61.jpg b/2.sdk/project/K8/ext/static/61.jpg
new file mode 100644 (file)
index 0000000..9d16b45
Binary files /dev/null and b/2.sdk/project/K8/ext/static/61.jpg differ
diff --git a/2.sdk/project/K8/ext/static/62.jpg b/2.sdk/project/K8/ext/static/62.jpg
new file mode 100644 (file)
index 0000000..0eb0ade
Binary files /dev/null and b/2.sdk/project/K8/ext/static/62.jpg differ
diff --git a/2.sdk/project/K8/ext/static/dj1.jpg b/2.sdk/project/K8/ext/static/dj1.jpg
new file mode 100644 (file)
index 0000000..948a324
Binary files /dev/null and b/2.sdk/project/K8/ext/static/dj1.jpg differ
diff --git a/2.sdk/project/K8/ext/static/dj2.jpg b/2.sdk/project/K8/ext/static/dj2.jpg
new file mode 100644 (file)
index 0000000..eaaeed9
Binary files /dev/null and b/2.sdk/project/K8/ext/static/dj2.jpg differ
diff --git a/2.sdk/project/K8/ext/static/j1.jpg b/2.sdk/project/K8/ext/static/j1.jpg
new file mode 100644 (file)
index 0000000..374f705
Binary files /dev/null and b/2.sdk/project/K8/ext/static/j1.jpg differ
diff --git a/2.sdk/project/K8/ext/static/j2.jpg b/2.sdk/project/K8/ext/static/j2.jpg
new file mode 100644 (file)
index 0000000..02642bd
Binary files /dev/null and b/2.sdk/project/K8/ext/static/j2.jpg differ
diff --git a/2.sdk/project/K8/ext/static/mj1.jpg b/2.sdk/project/K8/ext/static/mj1.jpg
new file mode 100644 (file)
index 0000000..b30f617
Binary files /dev/null and b/2.sdk/project/K8/ext/static/mj1.jpg differ
diff --git a/2.sdk/project/K8/ext/static/mj2.jpg b/2.sdk/project/K8/ext/static/mj2.jpg
new file mode 100644 (file)
index 0000000..ca83eaa
Binary files /dev/null and b/2.sdk/project/K8/ext/static/mj2.jpg differ
diff --git a/2.sdk/project/K8/ext/static/zj1.jpg b/2.sdk/project/K8/ext/static/zj1.jpg
new file mode 100644 (file)
index 0000000..2cdc10e
Binary files /dev/null and b/2.sdk/project/K8/ext/static/zj1.jpg differ
diff --git a/2.sdk/project/K8/ext/static/zj2.jpg b/2.sdk/project/K8/ext/static/zj2.jpg
new file mode 100644 (file)
index 0000000..95f93da
Binary files /dev/null and b/2.sdk/project/K8/ext/static/zj2.jpg differ
index 87882e5..85388b1 100644 (file)
Binary files a/2.sdk/project/K8/images/customer_fs.bin and b/2.sdk/project/K8/images/customer_fs.bin differ
index 783b2ac..b5dcd17 100644 (file)
Binary files a/2.sdk/project/K8/images/ext_fs.bin and b/2.sdk/project/K8/images/ext_fs.bin differ
index 3ea119b..2046e7d 100644 (file)
@@ -974,6 +974,7 @@ frozen_mpy_list =   $(BUILD)/_boot.mpy \
                                        $(BUILD)/motor.mpy \
                                        $(BUILD)/ai_VC.mpy \
                                        $(BUILD)/ui_setting.mpy \
+                                       $(BUILD)/ai_alarm.mpy \
 
 endif
 
index 36fbf34..b032beb 100644 (file)
@@ -30,10 +30,17 @@ import machine
 import dataCall
 import constants
 import versions
+import usocket
+import lvgl as lv
 try:
     import VAD
 except Exception as e:
     usys.print_exception(e)
+try:   
+    import usr.ai_alarm as _ai_alarm
+except Exception as e:
+    usys.print_exception(e)
+    import ai_alarm as _ai_alarm
 #dev_type = "G10"
 #dev_type = "7PIN_BK"#小瑞
 #dev_type = "7PIN_BK_coze"#k扣子小瑞
@@ -262,6 +269,7 @@ class AI_dev(Abstract):
         EventMesh.subscribe("paly_iccid_imei",self.paly_iccid_imei)
         EventMesh.subscribe("paly_device_res_error",self.paly_device_res_error)
         EventMesh.subscribe("Power_off",self.pwk_key_Long_Press)
+        EventMesh.subscribe("get_usb_status",self.get_usb_status)
         
         print("AI_dev:2")
         self.pk = PowerKey()
@@ -278,9 +286,8 @@ class AI_dev(Abstract):
         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 = 110
-        self.aud.setVolume(self.VC_TTS_volume // 10)
-        print("音量初始化DEV配置为{}".format(self.VC_TTS_volume // 10))
+            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})
@@ -288,7 +295,7 @@ class AI_dev(Abstract):
 
         #双击逻辑
         self.last_time = 0 #上次时间
-        self.gap_time = 2000 #双击间隔时间(ms)
+        self.gap_time = 1500 #双击间隔时间(ms)
         self.double_flag = 0 #双击标志
         self.double_release_timer = osTimer()#双击释放定时器
         print("AI_dev:end")
@@ -297,7 +304,8 @@ class AI_dev(Abstract):
         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 get_usb_status(self,event= None,msg = None):
+        return self.usb_status
     def usb_event(self, state):    
         status = state
         self.usb_charge_flag = 0
@@ -305,6 +313,7 @@ class AI_dev(Abstract):
             print("charge R_CHARGE_in")
             self.usb_status = 1
             VC_satrt_flag = EventMesh.publish("get_VC_satrt_flag")#获取vc是否在运行
+            EventMesh.publish("send_device_information")#发送设备信息
             if VC_satrt_flag == None:
                 VC_satrt_flag = 0
             if VC_satrt_flag == 0:
@@ -319,6 +328,7 @@ class AI_dev(Abstract):
         elif status == 0:#拨出usbs
             self.usb_status = 0
             VC_satrt_flag = EventMesh.publish("get_VC_satrt_flag")#获取vc是否在运行
+            EventMesh.publish("send_device_information")#发送设备信息
             if VC_satrt_flag == None:
                 VC_satrt_flag = 0
             if VC_satrt_flag == 0:
@@ -444,20 +454,23 @@ class AI_dev(Abstract):
                         self.KeyAI_timer_count = 0
                         EventMesh.publish("publish_AI_btnInfo",{"func":self.AI_key_double_press})
                         # 启动双击释放检测计时器
-                        self.double_release_timer.start(500, 1, self.double_release_timeout)
+                        self.double_release_timer.start(500, 0, self.double_release_timeout)
                         return
-                    
-                    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" or dev_type == "7PIN_coze" :
-                        self.aud.aud_tone_play(10,200)#播放按键音  
-                    EventMesh.publish("publish_AI_btnInfo",{"func":self.AI_key_press})
-                    self.last_time = current_time
+                    elif time_tiff > 0 and current_time - self.last_time > self.gap_time:#判断为单击      
+                        EventMesh.publish(constants.EVENT.SYSTEM_UP)#唤醒休眠
+                        self.extint_AI.disable()
+                        self.KeyAI_press = 1
+                        self.KeyAI_long_press = 0
+                        self.double_flag = 0
+                        self.KeyAI_timer.start(100, 1, self.KeyAI_timer_cb)
+                        self.KeyAI_timer_count = 0
+                        #EventMesh.publish("AI_key_press")
+                        screen_name = EventMesh.publish("get_screen_NAME")
+                        if screen_name != "system_init" and screen_name != "poweron":
+                            if dev_type == "7PIN" or dev_type == "7PIN_coze" :
+                                self.aud.aud_tone_play(10,200)#播放按键音  
+                            EventMesh.publish("publish_AI_btnInfo",{"func":self.AI_key_press})
+                        self.last_time = current_time
             else:  # 释放
                 if self.double_flag:
                     # 双击释放处理
@@ -468,12 +481,15 @@ class AI_dev(Abstract):
                     self.KeyAI_timer_count = 0
                     self.KeyAI_press = 0
                     return            
+                    
         except Exception as e: 
             usys.print_exception(e)
     def double_release_timeout(self, *args, **kwargs):#双击释放超时处理
+        print("定时器未关闭!!!!!!!!")
         if self.double_flag:
             #如果超时仍未释放,重置双击状态
             self.double_flag = 0
+            self.double_release_timer.stop()
 
     def AI_key_double_release(self):
         EventMesh.publish("publish_AI_btnInfo",{"func":self.AI_key_double_press})
@@ -484,7 +500,7 @@ class AI_dev(Abstract):
         try:
             self.KeyAI_status = self.extint_AI.read_level()
             self.KeyAI_timer_count +=1
-            print("self.KeyAI_timer_count = {}".format(self.KeyAI_timer_count))
+            # print("self.KeyAI_timer_count = {}".format(self.KeyAI_timer_count))
             if self.KeyAI_timer_count >= 10*1 : #长按1s 
                 if self.KeyAI_long_press == 0:
                     self.KeyAI_long_press = 1
@@ -511,23 +527,6 @@ class AI_dev(Abstract):
                     self.KeyAI_timer.stop()
                     self.KeyAI_timer_count = 0
                     self.KeyAI_press = 0
-                    # current_time = utime.ticks_ms()
-                    # print("current_time:{},last_time:{},current_time - self.last_time={}".format(current_time,self.last_time,current_time - self.last_time)) 
-                    # if (current_time - self.last_time <= self.gap_time):#鉴定为双击
-                    #     print("AI_key_double_press DOUBLE DOUBLE ")
-                    #     self.double_flag = 1#切换标志位
-                    #     self.KeyAI_long_press = 0
-                    #     self.KeyAI_press = 0
-                    #     self.KeyAI_timer_count = 0
-                    #     EventMesh.publish("publish_AI_btnInfo",{"func":self.AI_key_double_press})
-                    #     return
-                    # else:
-                    #     EventMesh.publish("publish_AI_btnInfo",{"func":self.AI_key_press})
-                    #     self.KeyAI_press = 1
-                    #     self.KeyAI_long_press = 0
-                    #     self.KeyAI_timer_count = 0
-
-                    # self.last_time = current_time
         except Exception as e: 
             usys.print_exception(e) 
        
@@ -554,13 +553,13 @@ class AI_dev(Abstract):
         self.check_rest_timer_count = 0
         print("pwk_key_long_press!!!!!!!")
         print("pwk_key_long_press!!!!!!!")
+        EventMesh.publish_async("audio_montage_play",["zhengzaiguanji.mp3"])
         EventMesh.publish("load_screen", {"screen": "poweroff_comfirm"})#关机画面
         # EventMesh.publish("paly_iccid_imei")
         # return
-        EventMesh.publish_async("audio_montage_play",["zhengzaiguanji.mp3"])
         #self.aud.play(1,0,'U:/static/zhengzaiguanji.mp3')#关机音频
         EventMesh.publish("open_led_red")
-        utime.sleep_ms(3000)
+        utime.sleep_ms(4000)
         self.aud.stopPlayStream()
         self.aud.stopAll()
         Power.powerDown()
@@ -588,23 +587,30 @@ class AI_dev(Abstract):
             VC_satrt_flag = 0
         Vbatt = Power.getVbatt()
         if self.usb_status == 1 and VC_satrt_flag == 0:
-            EventMesh.publish("open_led_red")#充电红灯常亮
+            #EventMesh.publish("open_led_red")#充电红灯常亮
+            pass
         if  self.usb_status == 1 and Vbatt>=self.VBATT_tab["charge_full"]and VC_satrt_flag == 0:#充电充满
-            EventMesh.publish("open_led_green")
+            #EventMesh.publish("open_led_green")
             if self.usb_charge_flag == 0 :
-                EventMesh.publish("audio_montage_play",["R_CHARGE_FULL.mp3"])
-                EventMesh.publish("load_screen", {"screen": "charge_full"})#满电弹窗
-                #self.aud.play(1,0,'U:/static/R_CHARGE_FULL.mp3')#充电已满
-                # EventMesh.publish("load_screen", {"screen": "charge_full"})#充满电弹窗
-                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:#低电报警
+                screen_name = EventMesh.publish("get_screen_NAME")
+                if screen_name != "system_init" and screen_name != "poweron" and screen_name != "UI_ai":
+                    EventMesh.publish("audio_montage_play",["R_CHARGE_FULL.mp3"])
+                    EventMesh.publish("load_screen", {"screen": "charge_full"})#满电弹窗
+                    #self.aud.play(1,0,'U:/static/R_CHARGE_FULL.mp3')#充电已满
+                    # EventMesh.publish("load_screen", {"screen": "charge_full"})#充满电弹窗
+                    self.usb_charge_flag = 1
+        if  self.usb_status == 0 and Vbatt<self.VBATT_tab["40"]and VC_satrt_flag == 0 and self.Low_power_warning_flag ==0:#低电报警
             self.Low_power_warning_flag  = 1
-            EventMesh.publish("flicker_led_red")
+            # EventMesh.publish("flicker_led_red")
+            #utime.sleep_ms(150)
+            if screen_name != "system_init" and screen_name != "poweron" :
+                EventMesh.publish("load_screen", {"screen": "LOW_POWER"})#少电弹窗
+                EventMesh.publish("audio_montage_play",["Low_power_warning.mp3"])
             #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"])
+            
         if  self.usb_status == 0 and Vbatt>=self.VBATT_tab["20"]and VC_satrt_flag == 0:#没有充电,电量又正常,关灯
             EventMesh.publish("close_led")
 
@@ -753,6 +759,7 @@ class device_res_author(Abstract):
         #7pin
         self.key = b"uKLrChwrxA1LklgBc3VwawYjUkbT3BgX" 
         self.pid = "cqxJZi5CNgzjS3mX21Zw"
+
         # if dev_type == 'jswm' or dev_type == 'jswm_BOX':#金三完美
         #     self.key = b"FuXG4ptpGbzvKbdB4vpUypisbENgy2nB" 
         #     self.pid = "DieBeXahZHLrjSnORbgN"
@@ -770,6 +777,8 @@ 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.subscribe("iccid_get", self.iccid_get)
+        EventMesh.subscribe("post_iccid", self.post_iccid)
         #EventMesh.publish_async("dev_NTP",thread_size = 8192)
 
         # count = 0
@@ -782,14 +791,46 @@ class device_res_author(Abstract):
         #         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.post_iccid()#上报iccid
+        self.iccid_get()#自动充值
         print("device_res_author __init__ end !!!!!!!!!!!!!!!!!")
 
     def get_dev_token(self, event, msg): 
         return self.dev_token
+    #上报iccid
+    def post_iccid(self, event=None, msg=None):
+        print("post_iccid")
+        deviceId = self.deviceId
+        url = "https://dmp-dev.raisound.com/dmp-api/dev/iccid"
+        token = self.dev_token
+        if token == None:
+            token = ""
+        iccid = sim.getIccid()
+        headers_T = {"bz-dt":"{}".format(token),"Content-Type":"application/x-www-form-urlencoded"}
+        data = "deviceId={}&iccid={}".format(deviceId,iccid)
+        print(ujson.dumps(data))
+        response = request.post(url,data=data,headers = headers_T,timeout=5)
+        data = response.json()
+        print("iccid_post:{}".format(data))
+        print("end_post_iccid")
+
+    #自动充值
+    def iccid_get(self, event=None, msg=None):
+        print("iccid_get")
+        url = "https://dmp-dev.raisound.com/dmp-api/sv/iccid/charge-task?deviceId={}".format(self.deviceId)
+        token = self.dev_token
+        if token == None:
+            token = ""
+        headers_T = {"bz-dt":"{}".format(token),"Content-Type":"application/x-www-form-urlencoded"}
+        print("bz-dt:{}".format(token))
+        response = request.get(url,headers = headers_T,timeout=5)
+        data = response.json()
+        print("iccid_get:{}".format(data))
+        print("end_iccid_get")
+
     #网络校时
     def dev_NTP(self, event=None, msg=None):
         response = None
@@ -799,6 +840,7 @@ class device_res_author(Abstract):
             if dev_type == "7PIN_BK_EU":#英文小瑞
                 url = "http://dmp-global.raisound.com/bz-api/dev/time"
             else:
+                # url = "http://dmp-dev.raisound.com/dmp-api/dev/time"
                 url = "http://dmp.raisound.com/bz-api/dev/time"
             response = request.get(url,timeout=5)
             data = response.json()
@@ -832,6 +874,8 @@ class device_res_author(Abstract):
                 print("timer:{}!!!!!!!!\r\n".format(utime.localtime()))
                 EventMesh.publish_async("dev_active",thread_size = 8192)
                 EventMesh.publish_async("dev_sign_in",thread_size = 8192)
+                EventMesh.publish_async("post_iccid",thread_size = 8192)
+                EventMesh.publish_async("iccid_get",thread_size = 8192)
                 # self.dev_active() #设备激活
                 # self.dev_sign_in() #设备登入
                 self.dev_res_timerCount+=1
@@ -929,6 +973,7 @@ class device_res_author(Abstract):
                 if dev_type == "7PIN_BK_EU":#英文小瑞
                     url = "http://dmp-global.raisound.com/bz-api/dev/auth/active"
                 else:
+                    # url = "http://dmp-dev.raisound.com/dmp-api/dev/auth/active"
                     url = "http://dmp.raisound.com/bz-api/dev/auth/active"
                 data =ujson.dumps(data)
                 response = None
@@ -1040,6 +1085,7 @@ class device_res_author(Abstract):
                 if dev_type == "7PIN_BK_EU":#英文小瑞
                     sign_url = "http://dmp-global.raisound.com/bz-api/dev/auth/sign_in" #登入地址
                 else:
+                    # sign_url = "http://dmp-dev.raisound.com/dmp-api/dev/auth/sign_in"
                     sign_url = "http://dmp.raisound.com/bz-api/dev/auth/sign_in" #登入地址
                 headers_T ={"Content-Type":"application/json"}
                 response_result = 0
@@ -1106,6 +1152,7 @@ class device_res_author(Abstract):
             if dev_type == "7PIN_BK_EU":#英文小瑞
                 dev_tokenip = "http://dmp-global.raisound.com/bz-api/dev/auth/token" #设备新令牌更新地址
             else:
+                # dev_tokenip = "http://dmp-dev.raisound.com/dmp-api/dev/auth/token"
                 dev_tokenip = "http://dmp.raisound.com/bz-api/dev/auth/token" #设备新令牌更新地址
             token = self.dev_token
             if token == None:
@@ -1136,7 +1183,7 @@ class device_res_author(Abstract):
         except Exception as e:
             usys.print_exception(e)   
         print("update_dev_token end")
-        
+    
 #OTA升级
 class OTA():
     def __init__(self):
@@ -1157,7 +1204,7 @@ class OTA():
         self.downloadFileVoURL2= ""
         try:
             sourceVersion = versions.Build_Time
-            sourceVersion = "7PIN-"+sourceVersion[:10]+"-"+sourceVersion[11:-3]
+            sourceVersion = "JSWM-"+sourceVersion[:10]+"-"+sourceVersion[11:-3]
             print("sourceVersion:{}".format(sourceVersion))
             sourceVersion = sourceVersion.replace(" ", "0")
             print("sourceVersion2:{}".format(sourceVersion))
@@ -1221,7 +1268,7 @@ class OTA():
         response = None
         try:
             currentVersion = versions.Build_Time
-            currentVersion = "7PIN-"+currentVersion[:10]+"-"+currentVersion[11:-3]
+            currentVersion = "JSWM-"+currentVersion[:10]+"-"+currentVersion[11:-3]
             print("currentVersion1:{}".format(currentVersion))
             currentVersion = currentVersion.replace(" ", "0")
             print("currentVersion2:{}".format(currentVersion))
@@ -1262,7 +1309,7 @@ class OTA():
                 url =None
                 if dev_type == "7PIN_BK_EU":#英文小瑞
                     url = "http://dmp-global.raisound.com/bz-api/dev/iccid?deviceId={}&iccid={}".format(modem.getDevImei(),iccid)
-                else:
+                else:  
                     url = "http://dmp.raisound.com/bz-api/dev/iccid?deviceId={}&iccid={}".format(modem.getDevImei(),iccid)
                 print("{} H:{}".format(url,headers_T))
                 response = request.post(url,headers = headers_T,timeout=5)
@@ -1308,7 +1355,6 @@ VC_play_TYPE_MP3 = 1
 AI_client_VC_num = 3
 AI_client_asr_num = 4
 
-
 class AI_VC(Abstract):
     # AI
     
@@ -1323,6 +1369,7 @@ class AI_VC(Abstract):
         self.VC_30S_timer = osTimer()
         self.VC_30S_timer.start(30000, 1, self.VC_30S_timer_cb)
         self.get_config_timer_count = 0
+        self.send_timer_count = 0
         self.record_data_save_flag = 0 #是否保存录音文件
         self.play_data_save_flag = 0#是否保存tts数据到文件
         self.record_fd = None
@@ -1337,12 +1384,21 @@ class AI_VC(Abstract):
             self.VC_mode = 0
         self.is_up_error= 0 #是否上传错误id
         self.Close_flag =0 #=1时,连续对话播放完音频就退出
-        
+        self.AI_alarm = _ai_alarm.AI_alarm()
+
+        #表情变化状态以及检索词
+        self.face_status = 0 # 0为正常,1为哭泣,2为愤怒,3为疑惑
+        self.normal_list = ["别生气"]
+        self.cry_list = ["委屈","难过","伤","哭","泪","颤抖","湿润","泛红","惊慌","担忧","失落","对不起","打扰"]
+        self.angry_list = ["怒","生气","不耐烦"]
+        self.confused_list = ["疑惑","困惑","好奇"]
+
         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:# 
@@ -1360,13 +1416,15 @@ class AI_VC(Abstract):
             elif self.VC_server == 8:# 
                 self.server_ip="115.190.94.208:22080"
             elif self.VC_server == 86:# 
-                self.server_ip="118.145.158.207:22086"    
+                self.server_ip="118.145.158.207:22086"  
+                # self.server_ip="118.145.158.207:22080"  
             else:
                 #self.server_ip="sevenpin.qipai.com.cn"
                 self.server_ip="118.145.158.207:22082"
             if dev_type == 'jswm' or dev_type == 'jswm_BOX':# 
                 #self.server_ip="115.190.94.208:22080"
-                self.server_ip="118.145.158.207:22086"   
+                # self.server_ip="118.145.158.207:22086"
+                self.server_ip="118.145.158.207:22080"   
             elif dev_type == "7PIN" or dev_type == "7PIN_coze":
                 #self.server_ip="sevenpin.qipai.com.cn"
                 # self.server_ip="220.160.104.34"
@@ -1739,7 +1797,7 @@ class AI_VC(Abstract):
         except Exception as e:
             usys.print_exception(e)
         #配置词
-        self.commands_mode = 2 #=1用大模型判断命令,=0用服务器本地插件判断命令 =2用设备本地判断方式
+        self.commands_mode = 1 #=1用大模型判断命令,=0用服务器本地插件判断命令 =2用设备本地判断方式
         if dev_type == "7PIN_BK"or dev_type == "7PIN_BK_EU"or dev_type == "7PIN_BK_coze":
             self.commands_mode = 2
         self.commands =  [
@@ -1920,6 +1978,7 @@ class AI_VC(Abstract):
         self.AI_audio_queue = Queue(100)
         #self.AI_WS_connect_Queue = Queue(100) #释放用
         self.AI_TTS_str = ""
+        self.AI_music_str = ""
         self.AI_ASR_str = ""
         self.AI_ASR_flag = 0
         self.AI_ASR_str_tmp = ""
@@ -1957,6 +2016,7 @@ class AI_VC(Abstract):
         self.AI_ASR_check_timeout = 0
         self.AI_ASR_error_timeout = 0
         self.VC_Thinking_timerout = 0
+     
 
         self.record_pcm = None
         self.play_pcm = None
@@ -1989,6 +2049,8 @@ class AI_VC(Abstract):
         self.tts_out_data_len = 0
         self.VC_satrt_flag = 0
         self.session_id = ""
+
+        self.draw_result = 0#抽签结果
         EventMesh.subscribe("AI_key_press", self.AI_key_press)
         EventMesh.subscribe("AI_key_double_press", self.AI_key_double_press)
         EventMesh.subscribe("AI_key_release", self.AI_key_release)
@@ -1998,6 +2060,14 @@ class AI_VC(Abstract):
         EventMesh.subscribe("get_VC_satrt_flag", self.get_VC_satrt_flag)
         EventMesh.subscribe("VC_error", self.VC_error)
         EventMesh.subscribe("screen_get_ai", self.screen_get_ai)
+        EventMesh.subscribe("screen_get_draw", self.screen_get_draw)
+        EventMesh.subscribe("screen_get_face", self.screen_get_face)
+        EventMesh.subscribe("play_tts", self.play_tts)
+        EventMesh.subscribe("play_tts_open", self.play_tts_open)
+        EventMesh.subscribe("play_tts_single", self.play_tts_single)
+        EventMesh.subscribe("draw_handle", self.draw_handle)
+        EventMesh.subscribe("dmp_update", self.dmp_update)
+        EventMesh.subscribe("update_volume", self.update_volume)
         EventMesh.publish("close_led")
 
         self.bot_name = "柒先生"
@@ -2026,6 +2096,7 @@ class AI_VC(Abstract):
                 
                 
                 #EventMesh.publish("get_storage_config",["powerRestart",1])
+                self.aud.play(1, 1, 'E:/static/R_POWER_1.mp3')  #播放播放开机铃声
                 powerRestart =  EventMesh.publish("get_storage_config","powerRestart")#=1非正常重启
                 if powerRestart == None:
                     powerRestart = 0
@@ -2051,12 +2122,93 @@ class AI_VC(Abstract):
         return self.VC_satrt_flag
     def screen_get_ai(self, event=None, msg=None):
         return self.VC_state
+    def screen_get_draw(self, event=None, msg=None):
+        return self.draw_result
+    def screen_get_face(self, event=None, msg=None):
+        return self.face_status
+    def create_ordered_json(self,device_id, server_ip, signalLevel, battery):
+        # 按预期顺序手动拼接JSON字符串
+        # 外层结构:先path,后Body
+        json_str = "{"
+        # 1. 拼接path部分(固定顺序)
+        json_str += '"path": {{"deviceId": "{}"}},'.format(device_id)
+        # 2. 拼接Body部分(按需求顺序排列)
+        json_str += '"Body": {'
+        json_str += '"wifiName": "",'
+        json_str += '"ipAddr": "{}",'.format(server_ip)
+        json_str += '"dnsAddr": "8.8.8.8",'
+        json_str += '"gateWayAddr": "192.168.0.1",'
+        json_str += '"signalLevel": "{}",'.format(signalLevel)
+        json_str += '"battery": "{}"'.format(battery) 
+        json_str += "}"
+        # 闭合外层
+        json_str += "}"
+        return json_str
+        
+    def dmp_update(self, event=None, msg=None):
+        device_id = modem.getDevImei()
+        signalLevel = str(net.csqQueryPoll()*3) + "%"
+        battery = str((EventMesh.publish("screen_get_battery"))[1]) + "%"
+        datacall = dataCall.getInfo(1, 0)
+        network_info_list = datacall[2]
+        # 验证是否为列表(避免数据类型错误)
+        if not isinstance(network_info_list, list):
+            print("tuple 索引2不是列表,无法提取 priDNS")
+            return None
+        
+        # 2. 第二步:从嵌套列表索引3获取 priDNS
+        pri_dns = network_info_list[3]
+        # 3. 验证 priDNS 有效性(可选,避免空值或无效格式)
+        if isinstance(pri_dns, str) and "." in pri_dns:  # DNS通常含"."(如114.114.114.114)
+            print("dns合法")
+            pass
+        else:
+            print("priDNS 格式无效")
+            return
+        dmp_data = {
+                "wifiName": "",
+                "ipAddr": "{}".format(self.server_ip),
+                "dnsAddr": "{}".format(pri_dns),
+                "gateWayAddr": "192.168.0.1",
+                "signalLevel": "{}".format(signalLevel),
+                "battery": "{}".format(battery)
+        }
+        # # 生成有序JSON
+        # ordered_json = self.create_ordered_json(device_id, self.server_ip, signalLevel, battery)
+        # print(ordered_json)
+        token = EventMesh.publish("get_dev_token")
+        print("bz_dt = {}".format(token))
+        headers_T ={
+                    "Content-Type":"application/json",
+                    "bz-dt":"{}".format(token)
+                    }
+        dmp_url = "http://app-api.raisound.com/dev/device/network/{}".format(device_id)
+        # dmp_url = "http://dmp.raisound.com/dmp-api/dev/device/network/{}".format(device_id)
+        print("url = {}".format(dmp_url))
+        # dmp_data =ujson.dumps(dmp_data)
+        print("data_type:{},data:{}".format(type(ujson.dumps(dmp_data)),ujson.dumps(dmp_data)))
+
+        try:
+            print("put")
+            request.put(dmp_url,data=ujson.dumps(dmp_data),headers = headers_T,timeout=5)
+            print("putover")
+        except Exception as e:
+            usys.print_exception(e)   
+            print("dmp_update put error!!!!!\r\n")
+
+    def update_volume(self,event,msg):
+        self.VC_TTS_volume = msg
+        self.aud.setVolume(self.VC_TTS_volume//10)
+        EventMesh.publish("set_storage_config",["VC_TTS_volume",msg])
+        print("声音改为{}".format(msg))
 
     def VC_30S_timer_cb(self, *args): #
         EventMesh.publish("publish_AI_btnInfo",{"func":self.VC_30S_timer_cb_}) 
 
     def VC_30S_timer_cb_(self):    
+        # print('VC_30S_timer_cb_')
         self.get_config_timer_count += 1
+        self.send_timer_count += 1
         if self.get_config_timer_count >= 2*60*2:#2小时更新配置参数
             self.get_config_timer_count = 0
             try:
@@ -2098,7 +2250,8 @@ class AI_VC(Abstract):
             elif dev_type == "7PIN" or dev_type == "7PIN_coze":#柒牌
                 url = "http://ota.qipai.com/bz-cmp-api/api/config/{}".format(modem.getDevImei())
             else:
-                url = "http://dmp.raisound.com/bz-api/dev/config/{}".format(modem.getDevImei())
+                url = "http://dmp-dev.raisound.com/dmp-api/dev/config/{}".format(modem.getDevImei())
+                # url = "http://dmp.raisound.com/bz-api/dev/config/{}".format(modem.getDevImei())
                 
                 
             print(url)
@@ -2139,6 +2292,45 @@ class AI_VC(Abstract):
             usys.print_exception(e)
             if response != None:
                 response.close()
+    def play_tts(self,event = None,msg= None):
+        EventMesh.publish("publish_AI_btnInfo",{"func":self.play_tts_cb,"data":msg}) 
+        
+        
+    def play_tts_open(self,event = None,msg= None):#播报tts并开启vc
+        print("play_tts_open:{}".format(msg))
+        self.AI_TTS_str = msg
+        # EventMesh.publish("AI_key_press")
+        EventMesh.publish("publish_AI_btnInfo",{"func":self.AI_VC_start})
+
+    def play_tts_single(self,event, msg):#单次传递音频文本
+        print("play_tts_single:{}".format(msg))
+        self.AI_TTS_str = msg
+        EventMesh.publish("publish_AI_btnInfo",{"func":self.AI_VC_start})
+        self.Close_flag = 1
+    def play_tts_cb(self,data):
+        try:
+            tts_str = data[0]
+            is_close_VC = data[1]
+            if tts_str != "":
+                self.AI_TTS_str = tts_str
+            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()
+            
+            # 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 audio_cb(self,event):
         if event == 0:
@@ -2151,12 +2343,18 @@ class AI_VC(Abstract):
             print('audio-play finish.!!!!!!')
     def AI_key_double_press(self, event, msg):#双击按键
         print("AI_key_double_press")
-        self.Close_flag = 1
+        # self.Close_flag = 1
         self.Close()
-        EventMesh.publish("load_screen", {"screen": "main_menu"})
+        EventMesh.publish("UI_ai_close")
+        EventMesh.publish("return_prev_screen")
 
     def AI_key_press(self, event, msg):#按键按下
+        # 测试闹钟功能
+        # EventMesh.publish("AI_alarm_open")
+        # EventMesh.publish("AI_add_alarm",[{"alarm_type":"单次闹钟","alarm_timestamp":1753071946,"repeat_day":"2025-07-21","repeat_min":0,"valid_time":"","alarm_timer":"12:25","alarm_content":"开会"}])
+        # return
         print("AI_key_press")
+        EventMesh.publish("send_device_VC_state")#上传VC状态
         self.get_config_timer_count = 0
         self.key_state = 1
         self.Close()
@@ -2173,9 +2371,12 @@ class AI_VC(Abstract):
         #if self.VC_record_state_flag >1:#如果在录音,就先停止录音
         self.VC_Speech_End()
         # return
-        self.VC_Speech_Start()    
+        # self.VC_Speech_Start()    
         self.AI_VC_start() 
+        lv.img.cache_invalidate_src(None)
+        lv.img.cache_set_size(8)
         EventMesh.publish("load_screen", {"screen": "UI_ai"})#ai画面
+        EventMesh.publish("audio_montage_play",["chenggong.mp3"])  
         # if dev_type != "7PIN":
         #     self.chenggong_tone()
         # self.Close()
@@ -2225,9 +2426,9 @@ class AI_VC(Abstract):
             if self.AI_ASR_flag  != 0:
                 return
             
-            if self.VC_record_state_flag  == 0:
-                
+            if self.VC_record_state_flag  == 0:  
                 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)
@@ -2449,9 +2650,14 @@ class AI_VC(Abstract):
                             except Exception as e:
                                 usys.print_exception(e)
                             self.record_fd = open('/usr/record_data.pcm','w')
+                            self.record_file_len = 0
                         if self.record_fd != None:
                             self.record_fd.write(read_buf)
                             print("write record:{}".format(len(read_buf)))
+                            self.record_file_len+=len(read_buf)
+                            if self.record_file_len>=200*1024:
+                                EventMesh.publish("publish_AI_btnInfo",{"func":self.Close}) 
+                            print("write record:{}".format(len(read_buf)))
                             # count+=Record_len
                             # if count >150*1024:
                             #     self.record_fd.close()
@@ -2481,6 +2687,7 @@ class AI_VC(Abstract):
         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))
@@ -2528,16 +2735,17 @@ class AI_VC(Abstract):
                 req_str = "vc/agent?is_auth={}".format(self.is_auth)
 
             if(token):
-                url = 'ws://{}/{}&dt={}'.format(self.server_ip,req_str,token)
+                # url = 'ws://{}/{}&dt={}'.format(self.server_ip,req_str,token)
+                url = 'ws://{}/vc/agent'.format(self.server_ip)
             else:
                 url = 'ws://{}/{}'.format(self.server_ip,req_str)
             #url = 'ws://115.190.94.208:22080/vc/coze?dt={}'.format(token)
-            
+            #ws://118.145.158.207:22080/vc/agent
+            # url = "ws://ec2-3-81-87-67.compute-1.amazonaws.com:22080/vc/chat"
             print("VC VC:url{}".format(url))
             self.AI_client_VC = uwebsocket.Client.connect(url, 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)
@@ -2618,7 +2826,6 @@ class AI_VC(Abstract):
         
         print("websocket_error4")
         
-
     def websocket_deconnect_VC(self):
         #print("websocket_deconnect_VC {}!!!!!!!".format(self.AI_client_VC_isconnect))
         print("websocket_deconnect_VC!!!!!!!")
@@ -2786,6 +2993,8 @@ class AI_VC(Abstract):
                 self.AI_client_VC_recv_lock = 0
 
                 count+=1
+                # if self.VC_state >= VC_State_TTSStart: 
+                #     print("self.tts_in_data_len - self.tts_out_data_len = {}".format(self.tts_in_data_len - self.tts_out_data_len))
                 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)
@@ -2818,8 +3027,26 @@ class AI_VC(Abstract):
                     if isinstance(recv_data, str):#返回的是字符串
                         print("VC VC:recv_data:{}".format(recv_data))
                         jsload_data =  ujson.loads(recv_data)
-                        #print("AI_client_VC_recv jsload_data = {}".format(jsload_data))
-                        
+                        # self.happy_list = ["开心","高兴","兴奋"]
+                        # self.cry_list = ["委屈","难过","伤心","哭泣","受伤"]
+                        # self.angry_list = ["愤怒","生气","不耐烦"]
+                        # self.confused_list = ["疑惑","困惑"]
+                        if jsload_data["event"] == "llm.completed":#只有类型为llm.completed的字符串可以来判断表情
+                            if(any(item in recv_data for item in self.cry_list)):
+                                print("识别到哭泣")
+                                self.face_status = 1#变为哭泣
+                            # elif(any(item in recv_data for item in self.cry_list)):
+                            #     print("识别到哭泣")
+                            #     self.face_status = 1#变为哭泣
+                            elif(any(item in recv_data for item in self.angry_list)):
+                                self.face_status = 2#变为愤怒
+                                print("识别到愤怒")
+                            elif(any(item in recv_data for item in self.confused_list)):
+                                self.face_status = 3#变为疑惑
+                                print("识别到疑惑")
+                            else:
+                                self.face_status = 0#变为正常
+                            #print("face_status1={}".format(self.face_status))
                         if jsload_data["event"] == "started" :#会话开始
                             #payload = jsload_data["payload"]
                             # self.VC_dialog_id = payload["dialog_id"] 
@@ -2827,18 +3054,24 @@ class AI_VC(Abstract):
                             EventMesh.publish("open_led_blue")
                             
                             print("VC:Started!!!!!!!!\r\n")
-                            if self.AI_TTS_str == "":
+                            if self.AI_TTS_str == "" and self.AI_music_str == "":
                                 #开始上传语音
+                                self.draw_result = 0
                                 if dev_type != "7PIN" and dev_type != "7PIN_coze":
-                                    self.chenggong_tone()
+                                    pass
+                                    # self.chenggong_tone()
                                 if self.VC_mode == 0    :
                                     self.VC_record_state_flag  =2
                                 else:
                                     EventMesh.publish("publish_AI_btnInfo",{"func":self.AI_client_VC_send_speech})
                                     
                                 
-                            else:
+                            elif self.AI_TTS_str != "" and self.AI_music_str == "":
                                 EventMesh.publish("publish_AI_btnInfo",{"func":self.AI_client_VC_synthesis})
+                            
+                            elif self.AI_TTS_str == "" and self.AI_music_str != "":
+                                EventMesh.publish("publish_AI_btnInfo",{"func":self.AI_client_VC_sing})
+                                
                             self.VC_state =  VC_State_None  
                         elif jsload_data["event"] == "config.update" :#配置更新中,需要停止录音
                             self.VC_state = VC_State_End
@@ -2855,7 +3088,7 @@ class AI_VC(Abstract):
                             EventMesh.publish("open_led_blue")
                         elif jsload_data["event"] == "asr.completed" :#asr 终止的标识 
                             print("self.commands_mode:{}".format(self.commands_mode))
-                            if self.commands_mode ==2:
+                            if self.commands_mode ==1:
                                 ret= self.check_text(self.AI_ASR_str)
                                 if ret == 0:#配置指令
                                             
@@ -2895,29 +3128,32 @@ class AI_VC(Abstract):
                             if self.is_VAD == 0:
                                 if self.VC_record_state_flag == 1:#llm返回数据还没停止,就先停止
                                     EventMesh.publish("publish_AI_btnInfo",{"func":self.VC_Speech_End})
+                                                    #print("AI_client_VC_recv jsload_data = {}".format(jsload_data))
                         elif jsload_data["event"] == "tts.started" :#tts开始
                             self.VC_state = VC_State_TTSStart
                             if self.is_VAD == 0:
                                 EventMesh.publish("publish_AI_btnInfo",{"func":self.VC_Speech_End})
                             EventMesh.publish("publish_AI_btnInfo",{"func":self.VC_Play_Start})
-                            
                             #self.VC_Play_Start()
                             EventMesh.publish("open_led_green")#绿色
                         elif jsload_data["event"] == "tts.completed" :#tts结束
                             EventMesh.publish("open_led_green")#绿色
                             EventMesh.publish("publish_AI_btnInfo",{"func":self.VC_Play_Start})
-                            self.LocalRespondingEnded_timerout = 8
+                            self.LocalRespondingEnded_timerout = 0
                             self.VC_state = VC_State_TTSEnd
                             pass
 
                         elif jsload_data["event"] == "canceled" :#打断
+                            self.VC_Play_End()#音频设备关闭
+                            self.draw_result = 0
                             EventMesh.publish("publish_AI_btnInfo",{"func":self.VC_Speech_Start_now})#开始录音
                             self.VC_state = VC_State_None
+                            EventMesh.publish("send_device_VC_state")#上传VC状态
                         elif jsload_data["event"] == "completed" :#会话结束
                             #EventMesh.publish("open_led_green")#绿色
-                            
-                            self.LocalRespondingEnded_timerout = 8
+                            self.LocalRespondingEnded_timerout = 3
                             self.VC_state = VC_State_End
+                            EventMesh.publish("send_device_VC_state")#上传VC状态
                             pass
                         elif jsload_data["event"] == "command" :#命令匹配
                             ret = -1
@@ -2946,7 +3182,7 @@ class AI_VC(Abstract):
                         elif jsload_data["event"] == "failed":#接口返回错误
                             if jsload_data["payload"]["error"] == "concurrency_limit_exceeded":
                                 EventMesh.publish("publish_AI_btnInfo",{"func":self.concurrency_limit_exceeded_tone}) 
-                                
+                                print("错误")
                                 #utime.sleep_ms(4000)
                                 
                             else:
@@ -2987,8 +3223,9 @@ class AI_VC(Abstract):
                                     #print("buf已满,等待释放:buf_len:{},count_tmp:{}".format(buf_len,count_tmp))
                                 except Exception as e:
                                     usys.print_exception(e)
-                        EventMesh.publish("publish_AI_btnInfo",{"func":self.put_record_data,"data":[recv_data,""]}) 
-                        utime.sleep_ms(1)
+                            EventMesh.publish("publish_AI_btnInfo",{"func":self.put_record_data,"data":[recv_data,""]}) 
+                            utime.sleep_ms(1)
+                            # print("self.tts_in_data_len - self.tts_out_data_len = {}".format(self.tts_in_data_len - self.tts_out_data_len))
                 except Exception as e:
                     usys.print_exception(e)
                 
@@ -3174,7 +3411,7 @@ class AI_VC(Abstract):
                         return 0
                     if text.find("版本") != -1 :
                         sourceVersion = versions.Build_Time
-                        self.AI_TTS_str ="Mr-Seven-"+sourceVersion
+                        self.AI_TTS_str ="JSWM-"+sourceVersion
                         return 0
                     if text.find("服务器地址") != -1 :
                         self.AI_TTS_str ="服务器地址"+self.server_ip
@@ -3189,11 +3426,13 @@ class AI_VC(Abstract):
                 if len(text)<20 and (text.find("再见") != -1 or text.find("拜拜") != -1 or text.find("关闭对话") != -1):
                     #EventMesh.publish("publish_AI_btnInfo",{"func":self.Close}) 
                     self.AI_TTS_str = "好嘞,再见,我们下次再聊"
-                    EventMesh.publish("load_screen", {"screen": "main_menu"})
+                    EventMesh.publish("UI_ai_close")
+                    EventMesh.publish("return_prev_screen")
                     self.Close_flag = 1
                     return 0
                 if len(text)<12 and (text.find("关机") != -1 ):
                     EventMesh.publish("publish_AI_btnInfo",{"func":self.Close}) 
+                    utime.sleep_ms(400)
                     EventMesh.publish("Power_off")
                     return 1
         except Exception as e:
@@ -3402,10 +3641,58 @@ class AI_VC(Abstract):
                     EventMesh.publish("publish_AI_btnInfo",{"func":self.Close}) 
                     EventMesh.publish("Power_off")
                     return 1
+                if text.find("闹钟设定") != -1:
+                    print("闹钟设定")
+                    alarm_timer_sta = EventMesh.publish("alarm_get_statu")
+                    if alarm_timer_sta == 0 :
+                        EventMesh.publish("AI_alarm_open")#开启轮询
+                        alarm_timer_sta = 1
+                    text = cmd["command"]["params_json"]
+                    print("params_json:{}".format(text))
+
+                    try:
+                        alarm =  ujson.loads(text)
+                        if alarm["is_right"] == True:#大模型判断闹钟格式以及内容正确
+                            add_alarm_tmp = EventMesh.publish("AI_add_alarm",alarm["alarm"])
+                            if add_alarm_tmp[0]> 0:
+                                self.AI_TTS_str = add_alarm_tmp[1]
+                                return 0
+                        else:
+                            pass
+                    except Exception as e:
+                        usys.print_exception(e)
+                if text.find("取消闹钟") != -1 :
+                    EventMesh.publish("AI_delete_alarm")
+                    EventMesh.publish("AI_alarm_close")
+                    self.AI_TTS_str = "闹钟列表已经清空"
+                    return 0
+                if text.find("关帝灵签结果") != -1 :
+                    #占卜师角色,把说的状态改为抽签结果
+                    text = cmd["command"]["params_json"]
+                    text = ujson.loads(text)
+                    EventMesh.publish("draw_handle",text["lots_result"])
+                    self.AI_TTS_str = text["lot_content"] 
+                    return 0
+                if text.find("播放音乐") != -1 :
+                    #音乐播放器角色,播放音乐
+                    text = cmd["command"]["params_json"]
+                    text = ujson.loads(text)
+                    self.AI_music_str = text["mp3"]
+                    return 0
         except Exception as e:
                 usys.print_exception(e)
         self.AI_TTS_str  = cmd["command"]["fail_prompt"]
         return -1
+    def draw_handle(self,event,msg):
+        if msg == "大吉":
+            self.draw_result = 1
+        elif msg == "中吉":
+            self.draw_result = 1
+        elif msg == "吉":
+            self.draw_result = 1
+        elif msg == "末吉":
+            self.draw_result = 1
+
     def check_text(self,text):
         print("check_text:len:{}".format(len(text)))
         if len(text)>60:
@@ -3515,11 +3802,11 @@ class AI_VC(Abstract):
                 if text.find("音量") != -1 or text.find("声音") != -1:
                     if  text.find("加") != -1 or text.find("增") != -1:
                         self.VC_TTS_volume += 10
-                        if self.VC_TTS_volume > 110:
+                        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 = 110
+                            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])
@@ -3590,7 +3877,9 @@ class AI_VC(Abstract):
                     if text.find("服务器地址") != -1 :
                         self.AI_TTS_str ="服务器地址"+self.server_ip
                         return 0
-                
+                    if text.find("闹钟列表") != -1 :
+                        EventMesh.publish("read_alarm_list")
+                        return 0
                 if text.find("讲话") != -1 or text.find("说话") != -1:
                     if text.find("快") != -1 and text.find("太") == -1 :
                         self.speech_rate += 10
@@ -3707,7 +3996,7 @@ class AI_VC(Abstract):
         if self.VC_Play_flag == 0:
             try:
                 if self.VC_play_TYPE == VC_play_TYPE_PCM:
-                    if self.play_pcm == None:        
+                    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)
                         self.play_pcm.setVolume(self.VC_TTS_volume // 10)
@@ -3767,6 +4056,7 @@ class AI_VC(Abstract):
                 EventMesh.publish("publish_AI_btnInfo",{"func":self.websocket_error,"data":"接口超时了。请重试"}) 
                 self.ud_error(["VC",self.VC_taskid])
             else:
+                EventMesh.publish("UI_ai_close")
                 EventMesh.publish("publish_AI_btnInfo",{"func":self.Close}) 
                 EventMesh.publish("load_screen", {"screen": "main_menu"})
                 pass
@@ -3784,6 +4074,7 @@ class AI_VC(Abstract):
                         self.Close_flag = 0
                         EventMesh.publish("publish_AI_btnInfo",{"func":self.Close}) 
                         EventMesh.publish("load_screen", {"screen": "main_menu"})
+                        EventMesh.publish("send_device_VC_state")#上传VC状态
                     else:
                         #utime.sleep_ms(1000)
                         EventMesh.publish("publish_AI_btnInfo",{"func":self.VC_Play_End})
@@ -3867,15 +4158,84 @@ class AI_VC(Abstract):
         # self.VC_pingping_timerout = 0
         # self.asr_pingping_timerout = 0
         print("AI_VC_start5")
+
     #开始会话
     def AI_client_VC_start_requset(self):
+        print("AI_client_VC_start_requset")
         voice="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)    
         #voice="zh_female_dongmanxiaoyang_moon_bigtts"
- 
+        # #海外服务器
+        # json_data = \
+        # {
+        #     "event": "start",
+        #     "payload": {
+        #         "simple_response": False,
+        #         "device_id": modem.getDevImei(),
+        #         "user_agent": "AudioClientWithAEC/1.0",
+        #         "dialog_attributes": {
+        #             "provider": "openai",
+        #             "cfg": {
+        #                 "disable_empty_prompt": True,
+        #                 "greeting":{
+        #                     "enabled": True,
+        #                     "content": "Hi! What can I do for you.",
+        #                 },
+        #                 "openai_option": {
+        #                     "model": "gpt-4o",
+        #                     "system": {
+        #                         "type": "file",
+        #                         "content": "1567d9e19ac09269d8ce6c887494ff01" # 林悦
+        #                     },
+        #                 }
+        #             }
+        #         },
+        #         "outbound_attributes": {
+        #             "provider": "azure",
+        #             "cfg": {
+        #                 "format": "pcm",
+        #                 "sample_rate": 16000,
+        #                 "bit_rate": 16,
+        #                 "channel": 1,
+        #                 "volume": 100,
+        #                 # "voice": "en-US-AvaMultilingualNeural", #"cosyvoice-v2-amp-2f7d423",# "longjielidou",
+        #                 "voice":"zh-CN-XiaoxiaoNeural",# mandarin
+        #                 "speech_rate": 0,
+        #                 "chunk_interval_ms": 10
+        #             }
+        #         },
+        #         "inbound_attributes": {
+        #             "provider": "azure",
+        #             "disable_vad": False,
+        #             "vad_silence": 200,
+        #             "interrupt_options": {
+        #                 "concatenate_results": True,
+        #                 "thinking_time_only": True,
+        #                 # "keyword_interrupt": True,
+        #                 # "interrupt_keywords": ["停止", "打断","打断一下", "等一下", "别说了", "打住"]
+        #             },
+        #             "cfg": {
+        #                 "format": "pcm",
+        #                 "sample_rate": 16000,
+        #                 "bit_rate": 16,
+        #                 "channel": 1,
+        #                 "enable_punctuation": True,
+        #                 "enable_itn": True,
+        #                 "keywords": [
+        #                     "停止",
+        #                     "打断",
+        #                     "打断一下",
+        #                     "等一下",
+        #                     "别说了",
+        #                     "打住"
+        #                 ]
+        #             }
+        #         }
+        #     }
+        # }
         json_data = \
         {
             "header": {
@@ -3948,6 +4308,7 @@ class AI_VC(Abstract):
                 "commands":self.commands,
             }
         }
+
         # "bot_id":"7481164663863459850",#鸭子
         # "workflow_id":"7480485093845991443",
         # "bot_id":"7462617881076351002",#语言助手
@@ -4058,11 +4419,7 @@ class AI_VC(Abstract):
         
         if self.VC_mode == 1:#单对话模式
             self.AI_client_VC_send(ujson.dumps(json_data))
-        
-
-            
-            
-        
+                
         
         self.VC_state =  VC_State_SpeechStart
     #结束上传语音
@@ -4108,7 +4465,25 @@ class AI_VC(Abstract):
         # 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.AI_client_VC_send(ujson.dumps(json_data))
-    
+
+        #唱歌
+    def AI_client_VC_sing(self):
+        json_data = \
+        {
+           "event": "audio.convert",
+           "payload": {
+                "audio_convert_request": {
+                    "audio_url": self.AI_music_str,
+                    "bit_depth": 16,
+                    "channels": 1,
+                    "sample_rate": 16000,
+                    "target_format": "pcm"
+                    }
+                }
+        }
+
+        self.AI_client_VC_send(ujson.dumps(json_data))
+        print("AI_client_VC_sing!!!!!!!!!!!!!!!!!!!!!!!!!!!!!")
     def chenggong_tone(self):
         EventMesh.publish("audio_montage_play",["chenggong.mp3"])    
     def send_tone(self):
@@ -4196,20 +4571,6 @@ class AI_VC(Abstract):
                                 
                                 if tmp != 0:
                                     print("2playStream:error tmp:{} data len:{}!!!!!!!!!!!!".format(tmp,len(data[0])))
-                                    # # #播放失败的时候填充WAV头
-                                    # data_len = len(data[0])
-                                    # data_len_b = data_len.to_bytes(4,'little')#数据长度转16进制数组
-                                    # h_data = [ 0x52 ,0x49 ,0x46 ,0x46 #,0x24 ,0x00 ,0x00 ,0x00 #文件标识、文件大小
-                                    #         ,0x57 ,0x41 ,0x56 ,0x45 ,0x66 ,0x6D ,0x74 ,0x20  #文件格式、格式块标识符
-                                    #         ,0x10 ,0x00 ,0x00 ,0x00 ,0x01 ,0x00 ,0x01 ,0x00 ,0x80 ,0x3E ,0x00 ,0x00  #格式块大小4、音频格式2、声道数2、采样率4
-                                    #         ,0x80 ,0x3E ,0x00 ,0x00 ,0x02 ,0x00 ,0x10 ,0x00 ,0x64 ,0x61 ,0x74 ,0x61]#每秒字节数4、数据块对齐2、位深度2、data4
-                                    # h_data_b = bytes(h_data)
-                                    # file_len = data_len+len(h_data_b)+4+4
-                                    # file_len_b = file_len.to_bytes(4,'little')#文件长度转16进制数组
-                                    # h_data_b = h_data_b[:4]+file_len_b+h_data_b[4:]+data_len_b
-                                    # #self.aud.playStream(2, h_data_b)#播放音频流
-                                    # tmp= self.aud.playStream(2, h_data_b+data[0])#播放音频流
-                                    # print("3playStream:tmp:{} !!!!!!!!!!!!".format(tmp))
                             
                             
                             mem = gc.mem_free()
@@ -4241,6 +4602,7 @@ class AI_VC(Abstract):
         self.VC_Thinking_timerout = 0
         self.VC_satrt_flag = 0
         self.AI_TTS_str = ""
+        self.AI_music_str = ""
         self.AI_ASR_str = ""
         self.AI_ASR_str_tmp = ""
         self.AI_ASR_flag  = 0
@@ -4252,7 +4614,7 @@ class AI_VC(Abstract):
         self.tts_in_data_len = 0
         self.tts_out_data_len = 0
         #必须先销毁线程,不然线程会容易报错
-        
+        EventMesh.publish("send_device_VC_state")#上传VC状态
         try:
             self.AI_audio_queue_thread_close()#销毁音频线程
         except Exception as e:
@@ -4261,7 +4623,6 @@ class AI_VC(Abstract):
             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!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!")
diff --git a/2.sdk/project/K8/sdk/services/microPython/ports/quectel/core/ai_alarm.py b/2.sdk/project/K8/sdk/services/microPython/ports/quectel/core/ai_alarm.py
new file mode 100644 (file)
index 0000000..38f969d
--- /dev/null
@@ -0,0 +1,412 @@
+#ai闹钟
+import EventMesh
+import usys
+import ujson
+import osTimer
+import utime
+class AI_alarm():
+    """
+    sjon格式{
+    "alarm_type":"重复闹钟", #闹钟类型。示例值:重复闹钟(喝水提醒,重复每天闹钟)、单次闹钟(会议提醒)
+    "alarm_timestamp":1750402089,#单次闹钟触发时间戳,单位:秒。只有单次闹钟有效
+    "repeat_day":["周一","周二","周三","2025-06-20"],#按天循环规则。示例值:周一,周五,每天,2025-06-20(自定义日期)
+    "repeat_min":60,#当天是否按多少分钟循环,为0时每天只响应一次,为120时每隔2小时触发一次。示例值:120
+    "valid_time":"9-18",# 当天循环有效时间,只有当repeat_min不为0时有效。repeat_min=60时,在有效时间内1小时循环响应1次。等于空值时,当天24小时有效
+    "alarm_timer":"06:50",#触发时间。示例值:06:50 ,6点50分时触发闹钟
+    "alarm_content":"周例会",#闹钟提醒内容。为空时,播放本地默认音频,不为空时,tts循环播放内容。示例值:"喝水提醒"
+    }
+    """
+    #最多只能设置五个闹钟
+    def __init__(self):
+        self.alarm_array = EventMesh.publish("get_storage_config","alarm_array")#读取闹钟数组
+        if self.alarm_array is None:
+            self.alarm_array =[]
+            print("self.alarm_array =[]")
+        self.AI_alarm_timer = osTimer()
+        self.alarm_min_repeat_tmp = 0
+        self.alarm_min_one_tmp = 0
+        self.alarm_count = len(self.alarm_array)#闹钟个数
+        print("闹钟个数 ={}".format(self.alarm_count))
+        self.alarm_list_text = EventMesh.publish("get_storage_config","alarm_list_text")#闹钟文本列表
+        if self.alarm_list_text is None:
+            self.alarm_list_text =[]
+        print("闹钟列表:{}".format(self.alarm_list_text))
+        self.alarm_timer_sta = 0#alarm定时器开启状态 0为关闭,1为开启
+        self.used_numbers = set()#已经被使用的闹钟编号集合
+        self.circle_alarm_flag = [] #闹钟重复判断标志列表
+        EventMesh.subscribe("AI_alarm_close",self.AI_alarm_close)
+        EventMesh.subscribe("AI_alarm_open",self.AI_alarm_open)
+        EventMesh.subscribe("AI_alarm_poll_extern",self.AI_alarm_poll_extern)
+        EventMesh.subscribe("AI_add_alarm",self.AI_add_alarm)
+        EventMesh.subscribe("alarm_get_statu",self.alarm_get_statu)
+        EventMesh.subscribe("get_have_alarm",self.get_have_alarm)
+        EventMesh.subscribe("AI_delete_alarm",self.AI_delete_alarm)
+        EventMesh.subscribe("read_alarm_list",self.read_alarm_list)
+    def alarm_get_statu(self,event=None,msg=None):
+        print("alarm_get_statu = {}".format(self.alarm_timer_sta))
+        return self.alarm_timer_sta
+
+    def AI_alarm_open(self,event=None,msg=None):
+        print("AI_alarm_open")
+        self.alarm_timer_sta = 1
+        self.AI_alarm_timer.start(20000, 1, self.AI_alarm_timer_cb)
+
+    def AI_alarm_timer_cb(self, *args):
+        EventMesh.publish("publish_AI_btnInfo",{"func":self.AI_alarm_poll}) 
+        pass
+
+    def get_have_alarm(self,event,msg):
+        self.alarm_array = EventMesh.publish("get_storage_config","alarm_array")#读取闹钟数组
+        if self.alarm_array ==None:
+            return 0
+        else:
+            return 1
+        
+    def AI_alarm_poll(self):#轮询调用
+        is_alarm = 0 #是否触发闹钟
+        alarm_TTS_str =""#闹钟播放tts字符串
+        repeat_day_flag = 0
+        alarm_timer_flag = 0
+        # print("AI_alarm_poll111")
+        if len(self.alarm_array) == 0:
+            return
+        print("self.alarm_array = {}".format(self.alarm_array))
+        if all(element is None for element in self.alarm_array):
+            print("删除所有闹钟")
+            self.AI_delete_alarm()#删除所有闹钟
+            self.AI_alarm_close()#关闭相关定时器
+            return
+        if len(self.alarm_array)>0:
+            # print("AI_alarm_poll222")
+            try:
+                now_time = utime.localtime()
+                old_minute =  [None] * len(self.alarm_array)
+                cnt = -1#记录到了闹钟列表第几位
+                for _alarm in self.alarm_array :
+                    cnt += 1 
+                    if _alarm is None:
+                        continue
+                    if len(self.circle_alarm_flag) >0:
+                        print("self.circle_alarm_flag[cnt] = {}".format(self.circle_alarm_flag[cnt]))
+                        if self.circle_alarm_flag[cnt] == 1:#已触发过一次
+                            if old_minute[cnt] is not None:
+                                if now_time[4] > old_minute[cnt]:
+                                    self.circle_alarm_flag[cnt] = 0#清空标志位
+                            old_minute[cnt] = now_time[4]
+                    if _alarm["alarm_type"] == "单次":
+                        #判断闹钟数字合法
+                        repeat_day = _alarm["repeat_day"][0]
+                        Y_M_D = repeat_day.split('-')
+                        alarm_timer = _alarm["alarm_timer"]
+                        H_M = alarm_timer.split(':')
+                        time_tuple = utime.localtime()#获取当前日期&时间的元组
+                        set_year = int(Y_M_D[0])
+                        set_month = int(Y_M_D[1])
+                        set_day = int(Y_M_D[2])
+                        set_hour = int(H_M[0])
+                        set_minute = int(H_M[1])
+                        year_now = time_tuple[0]
+                        month_now = time_tuple[1]
+                        day_now = time_tuple[2]
+                        hour_now = time_tuple[3]
+                        minute_now = time_tuple[4]
+                        if set_year < year_now or (set_year == year_now and set_month < month_now) or \
+                        (set_year == year_now and set_month == month_now and set_day < day_now):
+                            print("闹钟日期已过期,已清除闹钟{}".format(_alarm["number"]))
+                            self.used_numbers.remove(self.alarm_array[cnt]["number"])#从闹钟名集合中移除
+                            self.alarm_array.pop(cnt)
+                            EventMesh.publish("set_storage_config",["alarm_array",self.alarm_array])   
+                            self.alarm_list_text.pop(cnt)
+                            EventMesh.publish("set_storage_config",["alarm_list_text",self.alarm_list_text])   
+                            continue
+                        if (set_year == year_now and set_month == month_now and set_day == day_now) and set_hour < hour_now or (set_hour == hour_now and set_minute < minute_now):
+                            print("闹钟日期已过期,已清除闹钟{}".format(_alarm["number"]))
+                            self.used_numbers.remove(self.alarm_array[cnt]["number"])#从闹钟名集合中移除
+                            self.alarm_array.pop(cnt)
+                            EventMesh.publish("set_storage_config",["alarm_array",self.alarm_array])   
+                            self.alarm_list_text.pop(cnt)
+                            EventMesh.publish("set_storage_config",["alarm_list_text",self.alarm_list_text])           
+                            continue
+                        
+                    if _alarm["alarm_type"] == "重复":
+                        #print("AI_alarm_poll333")
+                        weekday = now_time[6]
+                        weekday_str = ""
+                        if weekday == 0:
+                            weekday_str = "周一"
+                        elif weekday == 1:
+                            weekday_str = "周二"
+                        elif weekday == 2:
+                            weekday_str = "周三"
+                        elif weekday == 3:
+                            weekday_str = "周四"
+                        elif weekday == 4:
+                            weekday_str = "周五"
+                        elif weekday == 5:
+                            weekday_str = "周六"
+                        elif weekday == 6:
+                            weekday_str = "周日"
+                        week = _alarm["repeat_day"]
+                        for _week in week :
+                            if weekday_str == _week:#符合周判断
+                                repeat_day_flag = 1
+                                break
+                        if repeat_day_flag == 0:#周不符合
+                            continue
+                        if _alarm["repeat_min"] ==0: #每天只提醒一次,已添加闹钟1,周一,周二,周三,6:50分提醒您周例会
+                            alarm_timer = _alarm["alarm_timer"]
+                            H_M = alarm_timer.split(':')
+                            if len(H_M) != 2:
+                                continue
+                            hour = int(H_M[0])
+                            min = int(H_M[1])
+                            if hour == now_time[3] and min == now_time[4]:
+                                alarm_timer_flag =1
+                            else:#时间不符合
+                                continue
+
+                            
+                            if  alarm_timer_flag==1:#时间符合,触发闹钟
+                                alarm_TTS_str += _alarm["alarm_content"]
+                                is_alarm = 1
+                                break
+                        else:#每天循环间提醒。已添加闹钟1,周一,周二,周三,9点到18点每隔60分钟提醒您喝水
+                            valid_time = _alarm["valid_time"]
+                            H_H = valid_time.split('-')
+                            if len(H_H) != 2:
+                                continue
+                            start_time = H_H[0].split(':')
+                            end_time = H_H[1].split(':')
+                            if len(start_time)<2 or len(end_time)<2:
+                                continue
+                            start_time_int  = int(start_time)
+                            end_time_int = int(end_time)
+                            now_h = now_time[3]
+                            if now_h>=start_time_int and now_h <= end_time_int:#在有效时间范围
+                                now_m = now_time[4]
+                                repeat_min_int = _alarm["repeat_min"]
+                                if (now_m + repeat_min_int)%repeat_min_int == 0 and self.alarm_min_repeat_tmp != now_m:#每分钟符合
+                                    self.alarm_min_repeat_tmp = now_m
+                                    alarm_TTS_str += _alarm["alarm_content"]
+                                    is_alarm = 1
+                                    continue
+                                
+                            else:
+                                continue
+#EventMesh.publish("AI_add_alarm",{"alarm_type":"单次闹钟","alarm_timestamp":1752739511,"repeat_day":"2025-07-17","repeat_min":0,"valid_time":"","alarm_timer":"16:05","alarm_content":"开会"})                            
+                    elif _alarm["alarm_type"] == "单次":
+                        # print("AI_alarm_poll444")
+                        alarm_timer = _alarm["alarm_timer"]
+                        H_M = alarm_timer.split(':')
+                        if len(H_M) != 2:
+                            print("len(H_M) != 2")
+                            continue
+                        repeat_day = _alarm["repeat_day"][0]
+                        Y_M_D = repeat_day.split('-')
+                        #print("Y_M_D:{}".format(Y_M_D))
+                        if len(Y_M_D)<3:
+                            print("len(Y_M_D)<3")
+                            continue
+                        year_int = int(Y_M_D[0])
+                        month_int = int(Y_M_D[1])
+                        day_int = int(Y_M_D[2])
+                        hour_int = int(H_M[0])
+                        minute_int = int(H_M[1])
+                        if year_int == now_time[0] and month_int == now_time[1]and day_int == now_time[2]and hour_int == now_time[3]and minute_int == now_time[4]:
+                            if self.alarm_min_one_tmp != now_time[4]:
+                                self.alarm_min_one_tmp = now_time[4]
+                                alarm_TTS_str += _alarm["alarm_content"]
+                                is_alarm = 1
+                                print("self.alarm_min_one_tmp != now_time[4]")
+                                break #发现闹钟存在直接跳出循环
+                        #ret_str += "{},{}点{}分提醒您:{}。".format(_alarm["repeat_day"],H_M[0],H_M[1],_alarm["alarm_content"])
+                    # print("AI_alarm_poll555")
+                if  is_alarm == 1 :
+                    if _alarm["alarm_type"] == "重复":
+                        if len(self.circle_alarm_flag) > 0:
+                            if self.circle_alarm_flag[cnt] == 1:#已触发过一次
+                                print("闹钟已触发过一次")
+                                return
+                    EventMesh.publish("audio_montage_play",["chenggong.mp3"])   
+                    EventMesh.publish("play_tts",["小瑞提醒您该{}了,小瑞提醒您该{}了,小瑞提醒您该{}了".format(alarm_TTS_str,alarm_TTS_str,alarm_TTS_str),1]) 
+                    print("闹钟提醒:小瑞提醒您该{}了,小瑞提醒您该{}了,小瑞提醒您该{}了".format(alarm_TTS_str,alarm_TTS_str,alarm_TTS_str))
+                    if _alarm["alarm_type"] == "单次":
+                        self.used_numbers.remove(self.alarm_array[cnt]["number"])#从闹钟名集合中移除
+                        self.alarm_array.pop(cnt)#删除闹钟元素
+                        self.alarm_list_text.pop(cnt)#删除读闹钟列表元素    
+                        EventMesh.publish("set_storage_config",["alarm_array",self.alarm_array])
+                        EventMesh.publish("set_storage_config",["alarm_list_text",self.alarm_list_text])
+                    elif _alarm["alarm_type"] == "重复":
+                        required_length = cnt + 1
+                        current_length = len(self.circle_alarm_flag)
+                        if current_length < required_length:
+                            # 补充缺失的位置,用默认值(如0)填充
+                            self.circle_alarm_flag.extend([0] * (required_length - current_length))
+                        self.circle_alarm_flag[cnt] = 1
+            except Exception as e:
+                usys.print_exception(e)
+                pass
+
+    def AI_alarm_poll_extern(self,event=None,msg=None):#外部调用轮询间隔,关闭定时器调用
+        self.AI_alarm_timer.stop()
+        EventMesh.publish("publish_AI_btnInfo",{"func":self.AI_alarm_poll}) 
+
+    def AI_add_alarm(self,event=None,alarm_array_u=None):#添加闹钟数组
+        ret = 0
+        alarm_array_tmp = self.alarm_array
+        if alarm_array_tmp is None:
+            alarm_array_tmp =[]
+        if self.alarm_count >= 10:
+           tts =  "闹钟列表已满,请清除闹钟后再设置"
+           return [1,tts]
+        #已添加闹钟1,周一,周二,周三,6:50分提醒您周例会
+        ret_str = "已添加"
+        print("AI_add_alarm:{}".format(alarm_array_u))
+        try:
+            for _alarm in alarm_array_u :
+                if ("alarm_content" in _alarm )and (_alarm["alarm_type" ] == "重复" or _alarm["alarm_type" ] == "单次" ):#简单的判断这个配置是合法的
+                    # #判断闹钟数字合法
+                    repeat_day = _alarm["repeat_day"][0]
+                    Y_M_D = repeat_day.split('-')
+                    alarm_timer = _alarm["alarm_timer"]
+                    H_M = alarm_timer.split(':')
+                    # time_tuple = utime.localtime()#获取当前日期&时间的元组
+                    # set_year = int(Y_M_D[0])
+                    # set_month = int(Y_M_D[1])
+                    # set_day = int(Y_M_D[2])
+                    # set_hour = int(H_M[0])
+                    # set_minute = int(H_M[1])
+                    # year_now = time_tuple[0]
+                    # month_now = time_tuple[1]
+                    # day_now = time_tuple[2]
+                    # hour_now = time_tuple[3]
+                    # minute_now = time_tuple[4]
+                    # if set_year < year_now or (set_year == year_now and set_month < month_now) or \
+                    #  (set_year == year_now and set_month == month_now and set_day < day_now):
+                    #      tts =  "您设置的闹钟日期已过期,请重新设置"
+                    #      return [1,tts]
+                    # if set_month > 12 or set_month < 1 or set_day > 31 or set_day <1:
+                    #      tts =  "您设置的闹钟日期非法,请重新设置"
+                    #      return [1,tts]
+                    # if set_hour < hour_now or (set_hour == hour_now and set_minute < minute_now):
+                    #      tts =  "您设置的闹钟时间已过期,请重新设置"
+                    #      return [1,tts]
+                    print(" AI_add_alarm 1111!!!")
+                    ret +=1  
+
+                    number = 0#闹钟编号
+                    #计算闹钟编号
+                    for i in range(1, 11):
+                        if i not in self.used_numbers:#当i不在集合中时,说明闹钟名未被添加,可以加入闹钟集合
+                            self.used_numbers.add(i)
+                            number = i #为当前闹钟赋值
+                            break
+                    #将键加入闹钟字典
+                    _alarm["number"] =  number
+
+                    #加入设定列表
+                    alarm_array_tmp.append(_alarm)
+                    ret_str += "闹钟{},".format(number)
+                    self.alarm_count = len(alarm_array_tmp)#闹钟总数
+                    
+                    if _alarm["alarm_type"] == "重复":
+                        print(" AI_add_alarm 2222!!!")
+                        if _alarm["repeat_min"] ==0: #每天只提醒一次,已添加闹钟1,周一,周二,周三,6:50分提醒您周例会
+                            # if len(H_M) != 2:
+                            #     tts =  "闹钟信息不完整,请重新设置"
+                            #     #移出设定列表
+                            #     alarm_array_tmp.remove(_alarm)
+                            #     ret_str = ""
+                            #     self.alarm_count = len(alarm_array_tmp)#闹钟总数
+                            #     return [1,tts]
+                            ret_str += "{},{}点{}分提醒您{}。".format(_alarm["repeat_day"],H_M[0],H_M[1],_alarm["alarm_content"])
+                            #添加闹钟描述文本
+                            self.alarm_list_text.append("闹钟{}:重复闹钟,{},{}点{}分提醒您{}".format(number,_alarm["repeat_day"],H_M[0],H_M[1],_alarm["alarm_content"]))
+                            EventMesh.publish("set_storage_config",["alarm_list_text",self.alarm_list_text])   
+                        else:#每天循环间提醒。已添加闹钟1,周一,周二,周三,9点到18点每隔60分钟提醒您喝水
+                            valid_time = _alarm["valid_time"]
+                            H_H = valid_time.split('-')
+                            # if len(H_H) != 2:
+                            #     tts =  "闹钟信息不完整,请重新设置"
+                            #     #移出设定列表
+                            #     alarm_array_tmp.remove(_alarm)
+                            #     ret_str = ""
+                            #     self.alarm_count = len(alarm_array_tmp)#闹钟总数
+                            #     return [1,tts]
+                            start_time = H_H[0].split(':')
+                            end_time = H_H[1].split(':')
+                            # if len(start_time)<2 or len(end_time)<2:
+                            #     tts =  "闹钟信息不完整,请重新设置"
+                            #     #移出设定列表
+                            #     alarm_array_tmp.remove(_alarm)
+                            #     ret_str = ""
+                            #     self.alarm_count = len(alarm_array_tmp)#闹钟总数
+                            #     return [1,tts]
+                            #添加闹钟描述文本
+                            self.alarm_list_text.append("闹钟{}:重复闹钟,{},{}点{}分到{}点{}分,每隔{}分钟提醒您{}。".format(number,_alarm["repeat_day"][0],
+                                                                              start_time[0],start_time[1],end_time[0],end_time[1],
+                                                                              _alarm["repeat_min"],_alarm["alarm_content"]))
+                            EventMesh.publish("set_storage_config",["alarm_list_text",self.alarm_list_text])
+                            ret_str += "{},{}点{}分到{}点{}分,每隔{}分钟提醒您{}。".format(_alarm["repeat_day"][0],
+                                                                              start_time[0],start_time[1],end_time[0],end_time[1],
+                                                                              _alarm["repeat_min"],_alarm["alarm_content"])
+                    elif _alarm["alarm_type"] == "单次":
+                        print(" AI_add_alarm 3333!!!")
+                        # if len(H_M) != 2:
+                        #     tts =  "闹钟信息不完整,请重新设置"
+                        #     #移出设定列表
+                        #     alarm_array_tmp.remove(_alarm)
+                        #     ret_str = ""
+                        #     self.alarm_count = len(alarm_array_tmp)#闹钟总数
+                        #     return [1,tts]
+                        # if len(Y_M_D)<3:
+                        #     tts =  "闹钟信息不完整,请重新设置"
+                        #     #移出设定列表
+                        #     alarm_array_tmp.remove(_alarm)
+                        #     ret_str = ""
+                        #     self.alarm_count = len(alarm_array_tmp)#闹钟总数
+                        #     return [1,tts]
+                        #添加闹钟描述文本
+                        self.alarm_list_text.append("闹钟{}:单次闹钟,{}年{}月{}日,{}点{}分提醒您:{}。".format(number,Y_M_D[0],Y_M_D[1],Y_M_D[2],H_M[0],H_M[1],_alarm["alarm_content"]))
+                        EventMesh.publish("set_storage_config",["alarm_list_text",self.alarm_list_text])
+                        ret_str += "{}年{}月{}日,{}点{}分提醒您:{}。".format(Y_M_D[0],Y_M_D[1],Y_M_D[2],H_M[0],H_M[1],_alarm["alarm_content"])
+                    # EventMesh.publish("play_tts_single",ret_str)
+                    print("配置成功")
+                else:
+                    return [-1]
+           
+        except Exception as e:
+                usys.print_exception(e)
+                return [-1] 
+        
+        if ret != 0:#当有有效闹钟数据时
+            print("保存闹钟新建数据")
+            self.alarm_array = alarm_array_tmp
+            print("self.alarm_array = {}".format(self.alarm_array))
+            EventMesh.publish("set_storage_config",["alarm_array",self.alarm_array])
+        return [ret,ret_str]
+    
+    def read_alarm_list(self,event=None,Num=None):#读闹钟全列表
+        alarmlist_TTS_str =""#闹钟全列表播放tts字符串
+        if len(self.alarm_list_text) == 0:
+            alarmlist_TTS_str = "当前闹钟列表没有闹钟信息"
+            EventMesh.publish("play_tts_single",alarmlist_TTS_str)
+            return
+        alarmlist_TTS_str += "当前闹钟信息如下:"
+        for count in self.alarm_list_text:
+            alarmlist_TTS_str += count
+
+        EventMesh.publish("play_tts_single",alarmlist_TTS_str)
+    def AI_delete_alarm(self,event=None,Num=None):#删除闹钟
+        self.alarm_array =[]#闹钟队列清空
+        EventMesh.publish("set_storage_config",["alarm_array",self.alarm_array])
+        self.alarm_list_text =[]#闹钟队列清空
+        EventMesh.publish("set_storage_config",["alarm_list_text",self.alarm_list_text])
+        self.alarm_count = 0
+        self.used_numbers.clear()#清空闹钟名集合 
+
+    def AI_alarm_close(self,event=None,Num=None):
+        print("AI_alarm_close")
+        self.alarm_timer_sta = 0
+        self.AI_alarm_timer.stop()
+
index 92f1679..14edebf 100644 (file)
@@ -107,7 +107,7 @@ clk_list_screen1_1.add_style(style_alarm_screen_default, lv.PART.MAIN | lv.STATE
 no_add_alarm_img = lv.img(clk_list_screen1_1)
 no_add_alarm_img.set_pos(65, 0)
 no_add_alarm_img.set_size(110, 140)
-no_add_alarm_img.set_src("E:/static/IMAGE_IDLE_SCREEN_ALARM_ICON_NEW.png")
+no_add_alarm_img.set_src("E:/static/alarm.png")
 no_add_alarm_img.add_style(style_img, lv.PART.MAIN | lv.STATE.DEFAULT)
 
 #暂未添加闹钟
@@ -785,9 +785,9 @@ popup_alarm_screen.add_style(style_screen, lv.PART.MAIN | lv.STATE.DEFAULT)
 
 
 popup_alarm_img = lv.img(popup_alarm_screen)
-popup_alarm_img.set_pos(63, 60)
-popup_alarm_img.set_size(110, 140)
-popup_alarm_img.set_src("E:/static/IMAGE_IDLE_SCREEN_ALARM_ICON_NEW.png")
+popup_alarm_img.set_pos(0, 0)
+popup_alarm_img.set_size(240, 320)
+popup_alarm_img.set_src("E:/static/alarm.png")
 popup_alarm_img.add_style(style_img, lv.PART.MAIN | lv.STATE.DEFAULT)
 
 popup_alarm_time = lv.label(popup_alarm_screen)
@@ -823,7 +823,7 @@ class PopupAlarmScreen(Screen):
     def exit_alarm_page(self,*arges):
         EventMesh.publish("system_sleep_rest")#防止黑屏
         self.alarm_count+=1
-        if self.alarm_count > 60:
+        if self.alarm_count > 10:
             self.alarm_count = 0
             self.aud.stop()
             self.timer.stop()
index 76065ad..b9490ac 100644 (file)
@@ -161,13 +161,12 @@ LCD_SIZE_H = 320
 # pwm.close()
 # 初始化lvgl
 lv.init()
-
 # Register SDL display driver.
 disp_buf1 = lv.disp_draw_buf_t()
 buf1_1 = bytearray(LCD_SIZE_W * LCD_SIZE_H * 2)
-#buf1_2= bytearray(LCD_SIZE_W * LCD_SIZE_H * 2)
+buf1_2= bytearray(LCD_SIZE_W * LCD_SIZE_H * 2)
 
-disp_buf1.init(buf1_1, None, len(buf1_1))
+disp_buf1.init(buf1_1, buf1_2, len(buf1_1))
 disp_drv = lv.disp_drv_t()
 disp_drv.init()
 disp_drv.draw_buf = disp_buf1
@@ -177,7 +176,22 @@ disp_drv.ver_res = LCD_SIZE_H
 disp_drv.sw_rotate = True
 disp_drv.rotated = 0#旋转角度0-3
 disp_drv.register()
-
+# lv.init()
+# # Register SDL display driver.
+# disp_buf1 = lv.disp_draw_buf_t()
+# buf1_1 = bytearray(LCD_SIZE_W * LCD_SIZE_H * 2)
+# #buf1_2= bytearray(LCD_SIZE_W * LCD_SIZE_H * 2)
+
+# disp_buf1.init(buf1_1, None, len(buf1_1))
+# disp_drv = lv.disp_drv_t()
+# disp_drv.init()
+# disp_drv.draw_buf = disp_buf1
+# disp_drv.flush_cb = lcd.lcd_write
+# disp_drv.hor_res = LCD_SIZE_W
+# disp_drv.ver_res = LCD_SIZE_H
+# disp_drv.sw_rotate = True
+# disp_drv.rotated = 0#旋转角度0-3
+# disp_drv.register()
 
     
 # LVGL触摸注册
@@ -262,5 +276,5 @@ power_on_label.add_style(style_font_youyuan_20_op, lv.PART.MAIN | lv.STATE.DEFAU
 lv.scr_load(power_on_screen)
 utime.sleep_ms(200)
 print("power_on_screen end...")
-PWM_backlight = PWM(PWM.PWM1, PWM.ABOVE_MS, 6, 10)
+PWM_backlight = PWM(PWM.PWM1, PWM.ABOVE_MS, 10, 10)
 PWM_backlight.open()
index 6f8eb18..6ab8028 100644 (file)
@@ -105,9 +105,12 @@ def main_init():
     device = mgr.DeviceInfoManager()
     device.post_processor_after_instantiation()#订阅事件
 
+    light = mgr.getBrightnessManager()
+    light.post_processor_after_instantiation()
+    
     from ui_health import HealthScreen
     import ui as _ui
-
+    import ai_alarm as _al 
     import ui_setting as _us
     # import ui as _ui
     EventMesh.debug_log("init4:{}".format(utime.localtime()))
@@ -115,6 +118,8 @@ def main_init():
     ui.post_processor_after_instantiation()
     app = watchApp()
     app.set_ui(ui)
+    #创建闹钟类
+    al = _al.AI_alarm()
     # if EventMesh.model == "D15":
     #     from motor import motorEventManager
     #     app.append_manager(motorEventManager())
@@ -136,7 +141,10 @@ def main_init():
         ui.add_screen(_ui.PowerOnScreen())
         ui.add_screen(_us.PoweroffConfirmScreen()) 
         ui.add_screen(_ui.chargeInScreen()) #充电已连接
-        ui.add_screen(_ui.chargefullScreen()) #充电已移出
+        ui.add_screen(_ui.chargefullScreen()) #充电已满
+        ui.add_screen(_ui.LowPowerScreen()) #电量低
+        
+        
     except Exception as e:
         usys.print_exception(e)
 
@@ -183,13 +191,47 @@ def main_init():
             app.append_manager(_ai.device_res_author())
         except Exception as e:
             usys.print_exception(e)     
-        
+        #IOT
+        try:
+            import usr.protocol as pro
+        except Exception as e:
+            usys.print_exception(e) 
+            import protocol as pro
+        try:
+            app.append_manager(pro.IOT_socket_SendCmdManager())
+            pcr = pro.ProtoColResolver()
+            pcr.add_support(pro.IOT_post_device_stateProtoCol())
+            pcr.add_support(pro.IOT_FindDeviceProtoCol())
+            # pcr.add_support(pro.IOTWeb_alarm_configProtoCol())
+            # pcr.add_support(pro.IOTWeb_alarm_listProtoCol())
+            sm = pro.SockMangager()
+
+            sm.add_support_resolver(pcr)
+            app.append_manager(sm)
+            print("init_IOT.0:{}".format(utime.localtime()))   
+            
+        except Exception as e:
+            usys.print_exception(e) 
+        #endIOT
         try:
-        
             app.append_manager(_ai.AI_VC())
         except Exception as e:
             usys.print_exception(e) 
-              
+        try:
+            EventMesh.publish("dmp_update")#dmp推送
+        except Exception as e:
+            usys.print_exception(e) 
+        try:
+            EventMesh.publish("connect_iot_socket")#连接IOT
+            print("IOT连接成功")
+        except Exception as e:
+            usys.print_exception(e)       
+        try:
+            EventMesh.publish("login_IOT")#登录IOT
+            EventMesh.publish("send_unbind_dev_to_iot")#开启IOT心跳包
+        except Exception as e:
+            usys.print_exception(e)     
+        
     except Exception as e:
         usys.print_exception(e)   
     EventMesh.publish("load_screen", {"screen": "poweron"})#开机画面
index 9e73ed0..7801697 100644 (file)
@@ -1081,7 +1081,8 @@ class DeviceInfoManager(Abstract):
             if battery[0] == "1":
                 if battery[1] >= 100:
                     if self.charge_full_count > 60 and self.charge_full_count % (60*10) == 0:#每十分钟提醒一次
-                        EventMesh.publish("load_screen", {"screen": "charge_full"})  
+                        # EventMesh.publish("load_screen", {"screen": "charge_full"})  
+                        pass
                     self.charge_full_count+=10
             else:
                 self.charge_full_count = 0
@@ -2985,7 +2986,7 @@ class getTempTimeManager(Abstract):
            
 class getBrightnessManager(Abstract):#获取亮度级别
     def __init__(self):
-        self.level = 6#默认值6
+        self.level = 10#默认值10最亮
         # self.read_data = {}
         self.time = 5
         self.PWM_backlight  = None
index 2ab81a5..d5fa484 100644 (file)
@@ -23,8 +23,12 @@ import usys
 import request
 import umqtt 
 import modem
+import versions
 SHA256 = uhashlib.sha256
 import SecureData
+import log
+import ustruct
+
 def server_init(server_type = None):
     #服务器选择1,防走丢,2大锤,3三基同创,4童信,5云米,6荣为 8:ds未知 dey.hinwatch. com:9968  9:183.62.239.121:31869 10:183.62.239.121:33461
     if server_type == None:
@@ -270,645 +274,668 @@ def mqtt_client_dev_init():#一机一密
     client.error_register_cb(mqtterr_cb)
     return client
 
+                    
 
+import uwebsocket
+import sim
 
-class SockManager(Abstract):
-    def __init__(self):
-        self.sock = None
-        self.resolver = None
-        self.run_flag = False
-        self.lost_conn_check_time = 5 * 60 * 30
-        self.monitor_timer = osTimer()
-        self.publish_timer = osTimer()
-        self.reconnect_timer = osTimer()
-        self.mqtt_recv_timer = osTimer()
-        self.reconnect_time = 1000
-        self.reconnect_flag = 0
-        self.connect_tmp = 0
-        server_data = server_init()
-        # EventMesh.debug_log("SockManager:server_data:{}".format(server_data))
-        # self.server_addr = server_data[0]
-        # self.server_port = server_data[1]
-        self.server_addr = ""
-        self.server_port = ""
-        self.device_id = ""
-        self.device_key = ""
-        self.product_key = gewu_init()
-        self.deviceSecret = ""
-        self.client = 0
-        self.client_dev = 0
-        self.client_state = 0
-        self.mqtt_client_count = 0
-        ip_infor = {}
-        ip_infor = EventMesh.publish("get_new_ip_com")
-        EventMesh.debug_log("ip_infor1:{} \n\n\n".format(ip_infor))
-        
-        if ip_infor != None: #已经改过服务器
-            self.server_addr = ip_infor[0]
-            self.server_port = ip_infor[1]
-        else:
-            self.server_addr = server_data[0]
-            self.server_port = server_data[1]
+class WEB_CMD_ENUM:
+    POST_DEVICE_STATE_R_CMD = "post_device_state_R"
+    POST_DEVICE_STATE_S_CMD = "post_device_state_S"
 
-        EventMesh.debug_log("server_addr:{} server_port:{}".format(self.server_addr,self.server_port))
-        _thread.stack_size((9+3)*1024)
-        _thread.start_new_thread(self.connect, ())
-        _thread.stack_size(8*1024)
-        
-        
-        self.socket_send_queue = Queue()
-        _thread.stack_size((9+2)*1024)
-        _thread.start_new_thread(self.socket_send_queue_thread, ())
-        _thread.stack_size(8*1024)
-        EventMesh.subscribe("set_device_id",self.set_device_id)
-        EventMesh.subscribe("set_device_key",self.set_device_key)
-        EventMesh.subscribe("set_product_key",self.set_product_key)
+    POST_DEVICE_INFOR_R_CMD = "POST_DEVICE_INFOR_R_CMD"
+    POST_DEVICE_INFOR_S_CMD = "POST_DEVICE_INFOR_S_CMD"
 
-        EventMesh.subscribe("get_device_id",self.get_device_id)
-        EventMesh.subscribe("get_device_key",self.get_device_key)
-        EventMesh.subscribe("get_product_key",self.get_product_key)
+    POST_ALARM_R_CMD = "post_alarm_R"
+    POST_ALARM_S_CMD = "post_alarm_S"
 
-        EventMesh.subscribe("set_deviceSecret",self.set_deviceSecret)
+    FIND_DEVCE_R_CMD = "find_device_R"
+    FIND_DEVCE_S_CMD = "find_device_S"
 
-        EventMesh.subscribe("get_deviceSecret",self.get_deviceSecret)
-        if EventMesh.platform == "gewu":
-            str = "deviceSecret:"
-            buf = bytearray(32+len(str))
-            length = SecureData.Read(2, buf, 32+len(str))
-            deviceSecret = buf.decode()
-            print(type(deviceSecret))
-            if deviceSecret != "":
-                if "deviceSecret" in deviceSecret:
-                    self.deviceSecret = deviceSecret.split(":")[1]
-            else:
-                self.deviceSecret = " "
-        if EventMesh.platform == "gewu":
-            self.client = mqtt_client_pro_init()
+    ALARM_CONFIG_R_CMD = "alarm_config_R"
+    ALARM_CONFIG_S_CMD = "alarm_config_S"
 
-    def post_processor_after_instantiation(self):
-        EventMesh.subscribe("get_mqtt_pro_connect_state",self.get_mqtt_pro_connect_state)
-        EventMesh.subscribe("get_mqtt_dev_connect_state",self.get_mqtt_dev_connect_state)
-        EventMesh.subscribe(constants.EVENT.CHANNEL_SOCKET_SEND, self.send)
-        self.monitor_timer.start(7 * 60 * 1000, 1, self.check)
+    ALARM_LIST_R_CMD = "alarm_list_R"
+    ALARM_LIST_S_CMD = "alarm_list_S"
 
-    def add_support_resolver(self, resolver):
-        self.resolver = resolver
+    UNBIND_DEV_R="unbind_dev_R"
+    UNBIND_DEV_S="unbind_dev_S"
 
-    def initialization(self, *args, **kwargs):
-        _thread.stack_size(16*1024)
-        _thread.start_new_thread(self.recv, ())
-        _thread.stack_size(8*1024)
-    
-    def set_device_id(self,event,msg):
-        self.device_id = str(msg)
+    DEVICE_SHAKE_STATE_R_CMD = "device_shake_state_R"
+    DEVICE_SHAKE_STATE_S_CMD = "device_shake_state_S"
+
+class IOT_socket_SendCmdManager(Abstract):
+    #
+    def __init__(self):
+        self.send_data = ""
+        self.time_tmp = 0
+    def post_processor_after_instantiation(self):
+        EventMesh.subscribe("GET_IOT_SEND_CMD", self.get_iot_send_cmd)
+        print("IOTSendCmdManager")
+    #调用:device_state=EventMesh.publish("GET_IOT_SEND_CMD",WEB_CMD_ENUM.POST_DEVICE_INFOR_S_CMD)
+                # print("device_state{}".format(device_state))
+    def get_iot_send_cmd(self, event, msg):#获取准备发送的值
+        date_tmp = utime.localtime()
+        self.time_tmp = utime.mktime(date_tmp)
+        if msg == WEB_CMD_ENUM.POST_DEVICE_STATE_S_CMD:#设备VC状态
+           self.send_data = self.device_report_state_send_data()
+           return self.send_data
+        elif msg == WEB_CMD_ENUM.POST_DEVICE_INFOR_S_CMD:#设备信息
+            self.send_data = self.device_information_send_data()
+            return self.send_data
+        elif msg == WEB_CMD_ENUM.POST_DEVICE_INFOR_S_CMD:#聊天内容
+            self.send_data = self.device_information_send_data()
+            return self.send_data
         
-    def get_device_id(self,event,msg):
+    # 设备对话内容上报数据格式
+    def device_talk_send_data(self):
+        print("device_talk_send_data")
+        infor_send_data = {
+            "cmd":"chat_text",
+            "data":
+                {
+                    "device_id":modem.getDevImei(),#设备号
+                    "type":"req:请求说的话;res:响应的内容",
+                    "text":"用户说话内容",
+                    "createTime":"时间戳"
+                }
+        }
+        return infor_send_data
+    
+    # 设备信息上报数据格式
+    def device_information_send_data(self):
+        print("device_information_send_data")
+        battery_state = (EventMesh.publish("screen_get_battery"))[0]
+        battery = (EventMesh.publish("screen_get_battery"))[1]
+        if battery >= 100 or battery == None:
+            battery = 100
+        VC_TTS_volume =  EventMesh.publish("get_storage_config","VC_TTS_volume")#音量配置
+        if VC_TTS_volume == None:
+            VC_TTS_volume =100
+        sourceVersion =versions.Build_Time
+        Timeversion ="JSWM-"+sourceVersion
+        infor_send_data = {
+            "data":{
+                    "version":Timeversion,#版本号
+                    "charge":battery_state,#0表示未充电,1表示充电中
+                    "current_role_name":"",#当前音色的name
+                    "volume":str(VC_TTS_volume),#百分比数值
+                    "wifi_rssi":str(net.csqQueryPoll()//6),#wifi强弱:0,1,2,3,4,5。转成这几个梯度
+                    "battery":str(battery),#电量
+                    "device_id":modem.getDevImei(),#设备号
+                },
+            "cmd":"device_info"
+        }
+        return infor_send_data
+    
+    #设备上报VC状态
+    def device_report_state_send_data(self):
+        ai_status = EventMesh.publish("screen_get_ai")
+        if EventMesh.publish("get_VC_satrt_flag") == 1:#获取vc是否在运行
+            if ai_status < 6 :
+                target_status = "listening"
+            elif ai_status == 6:
+                target_status = "thinking"
+            elif ai_status >= 8:
+                target_status = "speaking"
+        else:
+            target_status = "idle"
+
+        device_report_data ={
+            "data":{
+                "device_id":modem.getDevImei(),
+                "state":target_status
+            },
+            "cmd":"chat_state"
+        }
+        return device_report_data
+def extract_target_number(json_str):
+    # 查找"target":"的起始位置
+    start_key = '"target":"'
+    start_idx = json_str.find(start_key)
+    if start_idx == -1:
+        print("未找到 target 字段")
+        return None  # 未找到目标字段
+    
+    # 计算数字的起始位置(跳过"target":")
+    num_start = start_idx + len(start_key)
+    
+    # 从数字起始位置开始,查找结束的双引号(")
+    num_end = json_str.find('"', num_start)
+    if num_end == -1:
+        print("未找到数字的结束位置")
+        return None  # 格式异常
+    
+    # 截取数字字符串(从num_start到num_end)
+    number_str = json_str[num_start:num_end]
+    
+    # 转换为整数(如果需要浮点数,可改为float(number_str))
+    try:
+        return int(number_str)
+    except ValueError:
+        print("截取的内容不是有效数字")
+        return None
+    
+def playload_data(data):
+    print("data = {}".format(data))
+    if isinstance(data, bytes) == 0 :
+        print("data类型错误")
+        return
 
-        return self.device_id
-    def set_device_key(self,event,msg):
-        self.device_key = str(msg)
+    if data[0] != 0xff or data[1] !=0xfe:
+        print("data格式错误,重新登录")
+        EventMesh.publish("login_IOT")#登录IOT
         return
-    def get_device_key(self,event,msg):
+    payload_len_bytes = data [3:5]
+    payload_len = ustruct.unpack ('H', payload_len_bytes)[0]
+    # print ("解析到 Payload 长度:{} 字节".format(payload_len))
+
+    payload = data [5 : 5+ payload_len]
+    try:
+        json_str = payload.decode ('utf-8')
+    except UnicodeDecodeError:
+        try:
+            json_str = payload.decode ('gbk')
+            print ("提示:Payload 使用 GBK 编码")
+        except UnicodeDecodeError:
+            print ("Payload 解码失败")
+        return
+    # json_str = "\"" + json_str + "\""
+    if type(json_str) is str and len(json_str)>5:
+        print ("解析出的 JSON 字符串:{}".format(json_str) + "-"*50)
+    if "get_device_state" in json_str:
+        EventMesh.publish("send_device_information")#发送设备信息
+        EventMesh.publish("send_device_VC_state")#上传VC状态
+        print("get_device_state")
+    elif "find_device" in json_str:
+        EventMesh.publish("play_tts_single","我在这呀,我在这呀")
+        print("find_device")
+    elif "renew_device" in json_str:#更新对话模式 重启
+        EventMesh.publish("play_tts_single","更新配置中,设备将自动重启")
+        print("renew_device")
+        utime.sleep_ms(3000)
+        EventMesh.publish("Power_off")
+    elif "switch_volume" in json_str:
+        volume = int(extract_target_number(json_str))
+        print("switch_volume = {}".format(volume))
+        EventMesh.publish("update_volume",volume)
+    elif "switch_brightness" in json_str:
+        light = int(extract_target_number(json_str))//10
+        print("switch_brightness")
+        EventMesh.publish("set_brightness_level",light)
+    elif "setup_role" in json_str:
+        EventMesh.publish("play_tts_open","角色正在切换")
+        print("setup_role")
+        EventMesh.publish("load_screen", {"screen": "UI_ai"})#ai画面
 
-        return self.device_key
-    
-    def set_product_key(self,event,msg):
-        self.product_key = str(msg)
         
-    def get_product_key(self,event,msg):
+    # data_dict = ujson.loads(json_str)
+    # if isinstance(data_dict, dict):
+    #     #下面做小程序下发指令类型判断
+    #     data = data_dict["cmd"]
+    #     if data is "get_device_state":
+    #         EventMesh.publish("send_device_information")#发送设备信息
+    #         print("get_device_state")
+    #     elif data is "find_device":
+    #         EventMesh.publish("play_tts_single","我在这呀,我在这呀")
+    #         print("find_device")
+    # else:
+    #     print("JSON数据不是字典类型")
 
-        return self.product_key
     
-    def set_deviceSecret(self,event,msg):
-        if EventMesh.platform == "gewu":
-            self.deviceSecret = str(msg)
-            deviceSecret_tmp = "deviceSecret:{}".format(msg)
-            SecureData.Store(2, deviceSecret_tmp, len(deviceSecret_tmp))
-        
-    def get_deviceSecret(self,event,msg):
-        return self.deviceSecret
+
+date_tmp = utime.localtime()
+time_tmp = utime.mktime(date_tmp)
+MAGIC =  (0xfffe).to_bytes(2,"big")
+VERSION = (0x01).to_bytes(1,"big")#"03".encode('utf-8')
+TYPE = (0x03).to_bytes(1,"big")
+DATA_LEN = (0x00000000).to_bytes(4,"big")
+#magic+version+type+playload_len+playload
+def protocol_send_total_data(data):
+    MAGIC =  (0xfffe).to_bytes(2,"big")
+    VERSION = (0x01).to_bytes(1,"big")#"03".encode('utf-8')
+    TYPE = (0x03).to_bytes(1,"big")
+    HR_JSON = ujson.dumps(data)
+    GPS_JSON_b = HR_JSON.encode('utf-8')
+    DATA_LEN = (len(HR_JSON)).to_bytes(4,"big")
+    heards_infor = b''
+    heards_infor = MAGIC+VERSION+TYPE+DATA_LEN+GPS_JSON_b
+    return heards_infor
+
+DEFIEN_HR_REPORT_TIME = 5*60
+DEFINE_TIME_COUNT = 5
+DEFIEN_LOCATION_REPORT_TIME = 5
+WEB_CONNECT_MAX_COUNT = 10 #默认重连次数
+
+PROJECT_NAME = "JSWM"
+PROJECT_VERSION = "1.0.0"
+checknet = checkNet.CheckNetwork(PROJECT_NAME, PROJECT_VERSION)
+# 设置日志输出级别
+log.basicConfig(level=log.INFO)
+socket_log = log.getLogger("SOCKET")
+class SockMangager(Abstract):
+    def __init__(self):
+        self.thread_buf_size = 8*1024
+        self.iot_soc_send_queue = Queue(100)
+        self.iot_protoclo_recv_id=None
+        self.connect_timer = osTimer() 
+        self.connect_timer_count = 0
+        self.hr_report_timer = osTimer()
+        self.resolver = None
+        self.send_device_time = 0
+        self.vbat_buf = []
+        self.network_state = 0
+        self.socket_send_queue_id = None
+        self.bat_count = 0
+        self.reconnect_count = 0 #连续重连次数 默认十次 不过就不重连了 等下一个心跳重连
+        self._1S_timer = osTimer()
+        self._5S_timer = osTimer()
+        self.timer_id = 0
+        self.start_voice_flag = 0
+        self.IOT_sock = None
+        self.sock_lock = _thread.allocate_lock()  # 初始化锁
+        #对话状态,一秒检查一次
+        self.last_data = None  # 保存上一次的数据状态
+        self.current_data = None  # 当前数据
+
+        self.send_recv_flag = 0#线程开启状态
+        EventMesh.subscribe("REPORT_ALARM_TO_IOT",self.report_alarm_to_iot)
+
+    def report_alarm_to_iot(self,event,msg):
+        EventMesh.publish(WEB_CMD_ENUM.POST_ALARM_S_CMD,msg)
+        pass
+    def usb_event_cb(self, state):
+        status = state
+    def post_processor_after_instantiation(self):
+        EventMesh.subscribe("CHANNEL_IOT_SEND",self.user_send)#发送数据的函数!!重要
+        EventMesh.subscribe("GET_IOT_PROTOCOL_CILENT",self.get_IOT_sock)
+        EventMesh.subscribe("close_socket_timer",self.close_socket_timer)
+        EventMesh.subscribe("connect_iot_socket",self.connect_iot_socket_cb)#使用socket连接iot平台
+        EventMesh.subscribe("login_IOT",self.login_IOT)#登录iot平台
+        EventMesh.subscribe("heart_IOT",self.heart_IOt)#心跳包
+        EventMesh.subscribe("send_device_information",self.send_device_information)#上报设备信息
+        EventMesh.subscribe("send_device_VC_state",self.send_device_VC_state)#上报VC状态
+        EventMesh.subscribe("send_unbind_dev_to_iot",self.send_unbind_dev_to_iot)#心跳包定时器开启
+        self.reconnect_count = 0
+        self.deviceReadState = ""
+        # self.connect_timer.start(2000,0,self.iot_connect_timerCb)
+
+    def send_device_information(self,event,msg):
+        EventMesh.publish("publish_AI_btnInfo",{"func":self.send_packet_iot,"data":WEB_CMD_ENUM.POST_DEVICE_INFOR_S_CMD})#上报设备信息
+    def send_device_VC_state(self,event,msg):
+        EventMesh.publish("publish_AI_btnInfo",{"func":self.send_packet_iot,"data":WEB_CMD_ENUM.POST_DEVICE_STATE_S_CMD})#上报VC状态
+
+    def send_unbind_dev_to_iot(self,event,msg):
+        self._5S_timer.start(30000,1,self._1M_timer_cb)
+        self._1S_timer.start(1000,1,self._1S_timer_cb)
+    def _1M_timer_cb(self,*argc):
+        EventMesh.publish("heart_IOT")#开启IOT心跳包
+        EventMesh.publish("send_device_information")#发送设备信息
+        pass
     
-    def connect(self):
-        EventMesh.debug_log("connect1{}:{}".format(self.server_addr, self.server_port))
-        if EventMesh.publish("get_sim_Status") != 1: #没sim
-            return
-        try:
-            if(self.sock != None) :
-                self.sock.close()
-            self.sock = usocket.socket(usocket.AF_INET, usocket.SOCK_STREAM)
-            #self.sock.setblocking(False) &self.sock.settimeout(0)不阻塞
-            self.sock.connect((self.server_addr, self.server_port))
-            
-            self.publish_timer.start(2000, 1, self.publish_timer_cb)
-            if EventMesh.platform == "gewu":
-                self.mqtt_client_count = 0
-                self.mqtt_recv_timer.start(5000, 1, self.mqtt_recv_timer_cb)
-            
-            utime.sleep_ms(500)
-            EventMesh.publish(constants.PROTOCOL.LK_SEND)
-            #  发送数据
-            
-            
-        except Exception as e:
-            usys.print_exception(e)
-            self.run_flag = False
+    def initialization(self, *args):
+        pass
+    def connect_iot_socket_cb(self,event,msg):
+        self.connect_iot_socket()
+    def add_support_resolver(self, resolver):
+        self.resolver = resolver
+    def hr_report_event(self, *args, **kwargs):
+        EventMesh.publish("publish_AI_btnInfo",{"func":self.hr_report_event_cb}) #self.connect_iot_websocket()
+    def hr_report_event_cb(self):
+        """电池平均值"""
+        temp = Power.getVbatt()
+        if self.bat_count < 10:
+            self.vbat_buf.append(temp)
+            self.bat_count += 1
         else:
-            self.run_flag = True
-        EventMesh.debug_log("connect2{}:{}".format(self.server_addr, self.server_port))
-        self.reconnect_flag = 0
-    def publish_timer_cb(self, *args):
-        self.authen_set()
-
-    def authen_set(self):
-        sever_state = EventMesh.publish("get_server_state")#获取修改服务器状态
-        # print("sever_state{}".format(sever_state))
-        if sever_state != None:
-            if sever_state == 0:
-                imei = EventMesh.publish(constants.EVENT.GET_IMEI)
-                server_data = EventMesh.publish("get_new_key_pid")#获取pid和key
-                key_data = ""
-                pid_data = ""
-                if server_data != None:
-                    key_data = server_data[0]
-                    pid_data = server_data[1]
-                else:
-                    server_data = server_init()
-                    key_data = server_data[2]
-                    pid_data = server_data[3]
-
-                # server_data = server_init()
-                # key_data = server_data[2]
-                # pid_data = server_data[3]
-               
-                sonce_data = str(urandom.getrandbits(32))#随机生成32位的随机数
-                md5_data = "{}*{}*{}*{}".format(imei,pid_data,sonce_data,key_data)#md5签名
-                sign_data = ""
-                hash_obj = uhashlib.md5(md5_data)
-                res = hash_obj.digest()
-
-                # 转成十六进制表示
-                sign_data = ubinascii.hexlify(res)
-                sign_data = sign_data.decode('ascii')
-                # print("sign_data:{} sonce_data:{}".format(md5_data,sign_data))
-                # sign_data = MD5_head
-                # http://8.134.110.49:31379/dev/device/check?imei=&bid=sonce=sign=
-                # ip_addr = "test.iot.api.thisiot.com"
-                # ip_addr = "app.api.thisiot.com"
-                # http://app.api.thisiot.com/
-                url = "http://app.api.thisiot.com/dev/device/check?imei={}&bid={}&sonce={}&sign={}".format(imei,pid_data,sonce_data,sign_data)
-                
-                # print("url:{}".format(url))
-                response = request.get(url)
-                data_tmp ={}
-                # d_server_addr = "device.miwitracker.com"
-                # d_server_port = 8505
-                # d_md5_key = ""
-                # d_PID = "3G"
-                # response.content = {'protocolType': '', 'host': 'device.miwitracker.com', 'secretKey': '', 'port': 8505, 'bid': '3G', 'extJsonStr': ''}
-                # response.status_code=200
-                print("test-{}".format(response.status_code))
-                if response.status_code == 200:
-                    content = response.content
-                    c = next(content)
-                    # "api.xcloudtech.com"
-                    # d_server_port = 9000
-                    jsload_data =  ujson.loads(c)
-                    print("jsload_data-{}".format(jsload_data))
-                    # jsload_data = {'data':'111','protocolType':'', 'host':'device.miwitracker.com', 'secretKey': 'bZld0ALsZTt15tKEZhOlLPgbsO75BLTP', 'port':8505, 'bid': '3G', 'extJsonStr': ''}
-                    # ujson.loads(c)
-                    
-                    if "success" in jsload_data:
-                        success = jsload_data["success"]
-                        if success == True:#合法设备
-                            if "data" in jsload_data:
-                                data_tmp = jsload_data["data"]#返回的数据 
-                                print("data_tmp:{}".format(data_tmp))
-                                code = jsload_data["code"]
-                                if code == 20000:#合法的设备
-                                    protocloType = data_tmp["protocolType"]#协议类型
-                                    host = data_tmp["host"]#服务骑地址
-                                    secretKey = data_tmp["secretKey"]#
-                                    pid = data_tmp["bid"]#产品型号
-                                    port = data_tmp["port"]#端口号
-
-                                   
-
-                                    if host != '' and (port != '' and port != -1):
-                                        if host != '':
-                                            self.server_addr = host
-                                            EventMesh.publish("set_ip",str(self.server_addr))
-                                        
-                                        if port != '' and port != -1:
-                                            self.server_port = port
-                                            EventMesh.publish("set_com",self.server_port)
-                                        EventMesh.publish("set_new_key", str(secretKey))#获取pid和key
-                                        EventMesh.publish("set_new_pid",str(pid))#获取pid和key
-                                        # self.reconnect_timer_cb()#重连设备
-                                        print("self.reconnect_flag",self.reconnect_flag)
-                                        self.reconnect_flag = 0
-                                        self.reconnect()#重连设备
-                    self.publish_timer.stop()
-                    EventMesh.publish("set_server_state",1)#获取修改服务器状态
-            else:
-                self.publish_timer.stop()
-            
-    
-
-    def mqtt_recv_timer_cb(self, *args):
-        self.mqtt_clien_cb()
+            for i in range(9):
+                self.vbat_buf[i] = self.vbat_buf[i+1]
+            self.vbat_buf[9] = temp
+        curr_count = len(self.vbat_buf)
+        bat_total_value = 0
+        for i in range(curr_count):
+            bat_total_value += self.vbat_buf[i]
+        bat_total_value = bat_total_value//curr_count#一分钟更新一次电量 10个平均值
+        EventMesh.publish("AI_alarm_start") #检查是否有闹钟需要提醒
+        # self.alarm_test()
+        EventMesh.publish("set_curr_battery_level",bat_total_value)
+        # EventMesh.publish("publish_AI_btnInfo",{"func":self.hr_report_publish_event,"data":0})        
+        if self.send_device_time < DEFIEN_LOCATION_REPORT_TIME :
+            self.send_device_time+=DEFINE_TIME_COUNT
+        else:
+            device_state=EventMesh.publish("GET_IOT_SEND_CMD",WEB_CMD_ENUM.POST_DEVICE_INFOR_S_CMD)
+            print("device_information{}".format(device_state))
+            # EventMesh.publish(WEB_CMD_ENUM.POST_DEVICE_INFOR_S_CMD,device_state) #上报设备信息
+            EventMesh.publish("publish_AI_btnInfo",{"func":self.send_packet_iot,"data":WEB_CMD_ENUM.POST_DEVICE_INFOR_S_CMD})#上报设备信息
+
+    def iot_connect_timerCb(self,*argc):
+        self.connect_iot_socket()
+
+    def connect_iot_socket(self):
+        if EventMesh.publish("get_voice_record_flag") == 1:
+            EventMesh.publish("stop_voice_record")
+        print("connect_iot_socket !!!!")
+        # self.iot_close_therad()
         
+        stagecode, subcode = checknet.wait_network_connected(30)
+        if stagecode == 3 and subcode == 1:
+            socket_log.info('Network connection successful!')
 
-
-    def mqtt_clien_cb(self):
-        if EventMesh.platform != "gewu":
+        if self.reconnect_count >= WEB_CONNECT_MAX_COUNT: #重连次数大于10次不在进重连只有下发心跳才重新连接
             return
-       # 需要加密的数据
-        get_deviceSecret = EventMesh.publish("get_deviceSecret")
-        if get_deviceSecret != None:
-            if self.mqtt_client_count == 0:
-                self.mqtt_client_count = 1
-                self.mqtt_recv_timer.stop()
-                get_deviceSecret = EventMesh.publish("get_deviceSecret")#获取设备的秘钥 只获取一次
-                print("get_deviceSecret{}".format(get_deviceSecret))
-                if get_deviceSecret == '':#如果为空就获取一次
-                    # print("self.client:{}".format(self.client))
-                    mqtt_connect = -1
-                    try:
-                        mqtt_connect = self.client.connect()
-                    except Exception as e:
-                        print(e)
-                        mqtt_connect = -1
-                    print("mqtt_connect:{}".format(mqtt_connect))
-                    if mqtt_connect == 0 :
-                        # 订阅主题
-                        get_device_id = EventMesh.publish(constants.EVENT.GET_IMEI)
-                        get_deviceKey = EventMesh.publish(constants.EVENT.GET_IMEI)
-                        get_productKey = gewu_init()
-                        #$sys/{productKey}/{deviceKey}/ext/regist
-                        client_msg = "$sys/{}/{}/ext/regist".format(get_productKey,get_deviceKey)
-                        # client_msg = "$sys/cu1shld45y4hjr1L/866610001011658/ext/regist"
-                        subscribe_msg = client_msg.encode('ascii')
-                        print(subscribe_msg)
-
-                        self.client.subscribe(subscribe_msg,0)#订阅消息主题
-
-                        
-                        self.client.wait_msg()  # 阻塞函数,监听消息
-                        utime.sleep(5)
-                        get_deviceSecret = EventMesh.publish("get_deviceSecret")
-                        if get_deviceSecret != '':
-                            self.client.disconnect()
-                            self.client_dev = mqtt_client_dev_init()
-                            print(self.client_dev)
-                            # mqtt_connect = self.client_dev.connect()
-                            try:
-                                mqtt_connect = self.client_dev.connect()
-                            except Exception as e:
-                                print(e)
-                                mqtt_connect = -1
-                            if mqtt_connect == 0:
-                                # $sys/cu1shld45y4hjr1L/bOOSGN5FlXEjt15/property/batch_reply
-                                msg_reply = "$sys/{}/{}/property/batch_reply".format(get_productKey,get_deviceKey)
-                                sub_msg = msg_reply.encode('ascii')
-                                self.client_dev.subscribe(sub_msg,0)#订阅消息主题
-                                print("Connected to dmp-mqtt.cuiot.cn, subscribed to /public/TEST/quecpython topic")
-                                # 发布消息
-                                # UnicodeHexStr_To_Utf8Str(str_data)
-                                date_tmp = utime.localtime()
-                                time_tmp = utime.mktime(date_tmp)#需要转换成毫秒级别
-                                updataTime = "{}".format(time_tmp*1000)
-                                # imei_tmp= modem.getDevImei()
-                                imei_tmp = EventMesh.publish(constants.EVENT.GET_IMEI)
-                                bat_tmp = EventMesh.publish("screen_get_battery")
-                                imei = "{}".format(imei_tmp)
-                                power = 0
-                                power = int(bat_tmp[1])
-                                hr = 0
-                                hr = EventMesh.publish("get_old_hr_data")
-                                if hr == None:
-                                    hr = 0
-                                deviceTime = "{}".format(time_tmp)
-                                manufactury = "fengda"
-                                DeviceState = "online"
-
-                                data_info = {
-                                    "messageId":"0",
-                                    "params": {
-                                        "data": [
-                                            {
-                                                "key":"deviceOffOn",
-                                                "value": {
-                                                    "deviceStatus":"Poweron",
-                                                    "updateTime":updataTime,
-                                                    "Imei":imei
-                                                }
-                                                
-                                            },
-                                            {
-                                                "key":"HeartRate",
-                                                "value":{
-                                                    "heartRate":hr,
-                                                    "updateTme":updataTime,
-                                                    "Imei":imei
-                                                }
-                                            },
-                                            {
-                                                "key":"powerSavingMode",
-                                                "value":0
-                                            },
-                                            {
-                                                "key":"IMEI",
-                                                "value":imei
-                                            },
-                                            {
-                                                "key":"DEVICE_TIME",
-                                                "value":deviceTime
-                                            },
-                                            {
-                                                "key":"MANUFACTURER",
-                                                "value":manufactury
-                                            },
-                                            {
-                                                "key":"REMAINING_POWER",
-                                                "value":power
-                                            },
-                                            {
-                                                "key":"DeviceState",
-                                                "value":DeviceState
-                                            }
-                                        ]
-                                    }
-                                }
-                                
-                                data_json = ujson.dumps(data_info) 
-                                # print("data_json:{}",data_json)
-                                # $sys/cu1shld45y4hjr1L/{deviceKey}/property/batch
-                                msg_pub = "$sys/{}/{}/property/batch".format(get_productKey,get_deviceKey)
-                                pub_msg = msg_pub.encode('ascii')
-                                self.client_dev.publish(pub_msg,data_json,0)#publis主题内容
-
-                                print("Publish topic: /public/TEST/quecpython758, msg: my name is Quecpython")
-                            pass
+        token = EventMesh.publish("get_dev_token")
+        # token = "9548860f973bffe39e1679db3110e223cb"
+        print("token:{}".format(token))
+        if self.IOT_sock is not None:
+            print("socket已连接")
+            return
+        try:
+            if token != None:
+                self.connect_timer_count = 0
+                #创建一个socket实例
+                self.IOT_sock = usocket.socket(usocket.AF_INET, usocket.SOCK_STREAM)
+                try:
+                    #建立连接
+                    self.IOT_sock.connect(('iot.socket.thisiot.com', 7777))
+                    #设置为阻塞
+                    self.IOT_sock.setblocking(True)
+                    socket_log.info("IOT 连接建立")
+                except Exception as e:
+                    print("再次连接")
+                    self.IOT_sock.connect(('iot.socket.thisiot.com', 7777))
+                    #设置为非阻塞
+                    self.IOT_sock.setblocking(False)
+
+                if self.send_recv_flag == 0:#线程未开启过
+                    self.send_recv_flag = 1
+                    self.reconnect_count = 0
+                    _thread.stack_size(self.thread_buf_size+8*1024) #_thread.stack_size(16*1024)
+                    self.socket_send_queue_id = _thread.start_new_thread(self.socket_send_queue_thread, ())
+                    _thread.stack_size(8*1024)
+                
+                    _thread.stack_size(self.thread_buf_size+8*1024)
+                    self.iot_protoclo_recv_id = _thread.start_new_thread(self.iot_protocol_recv, ())
+                    _thread.stack_size(8*1024)
+                    socket_log.info("self.IOT_sock thread init!!!!!!!!!")
+
 
+                if self.IOT_sock != None:
+                    self.start_voice_flag = 1
                 else:
-                    mqtt_dev_connect = -1
-                    mqtt_ret_connect = -1
-                    mqtt_pro_connect = -1
-                    if self.client_dev == 0:
-                        self.client_dev = mqtt_client_dev_init()
-                    try:
-                        mqtt_dev_connect = self.client_dev.connect()
-                    except Exception as e:
-                        print("erro!{}".format(e))
-                        mqtt_dev_connect = -2
-                        # Server Actively FIN Disconnected.Need Check Connection parameters
-                        err_dis = "FIN Disconnected" in str(e)
-                        err_parm1 = "107" in str(e)
-                        err_parm2 = "4" in str(e)
-                        # print("err_parm1!{} {} {} {}".format(err_parm1,err_parm2,err_info,err_dis))
-                        # Connect Error='4' MQTT Connect error=
-                        if err_dis == True or err_parm1 == True or err_parm2 == True:
-                            mqtt_dev_connect = -1
-                        
-
-                    if mqtt_dev_connect != 0:#连接参数错误可能是deviceScrete出错重新获取
+                    self.start_voice_flag = 0
                     
-                        try:
-                            mqtt_ret_connect = self.client.connect()#重新获取deviceScrete
-                        except Exception as e:
-                            print(e)
-                            mqtt_ret_connect = -1
-                        # mqtt_connect = self.client.connect()
-                        print("mqtt_ret_connect:{}".format(mqtt_ret_connect))
-                        if mqtt_ret_connect == 0:
-                            # 订阅主题
-                            get_device_id = EventMesh.publish(constants.EVENT.GET_IMEI)
-                            get_deviceKey = EventMesh.publish(constants.EVENT.GET_IMEI)
-                            get_productKey = gewu_init()
-                            #$sys/{productKey}/{deviceKey}/ext/regist
-                            client_msg = "$sys/{}/{}/ext/regist".format(get_productKey,get_deviceKey)
-                            # client_msg = "$sys/cu1shld45y4hjr1L/866610001011658/ext/regist"
-                            subscribe_msg = client_msg.encode('ascii')
-                            print(subscribe_msg)
-
-                            self.client.subscribe(subscribe_msg,0)#订阅消息主题
-
-                            self.client.wait_msg()  # 阻塞函数,监听消息
-                            utime.sleep(5)
-
-                            self.client.disconnect()
-                            self.client_dev = mqtt_client_dev_init()
-                            # print(self.client_dev)
-                            try:
-                                mqtt_pro_connect = self.client_dev.connect()
-                            except Exception as e:
-                                print(e)
-                                mqtt_pro_connect = -1
-                    # print("no deviceScret!!!!!!!{}".format(self.client_dev))
-                    # 设备秘钥不为空 重连获取设备失败不连接 第一次连接失败不连接不发送数据
-                    if EventMesh.publish("get_deviceSecret") != "" and (mqtt_pro_connect == 0 or mqtt_dev_connect == 0):
-                        get_device_id = EventMesh.publish(constants.EVENT.GET_IMEI)
-                        get_deviceKey = EventMesh.publish(constants.EVENT.GET_IMEI)
-                        get_productKey = gewu_init()
-                        # $sys/cu1shld45y4hjr1L/bOOSGN5FlXEjt15/property/batch_reply
-                        msg_reply = "$sys/{}/{}/property/batch_reply".format(get_productKey,get_deviceKey)
-                        sub_msg = msg_reply.encode('ascii')
-                        # print(" deviceScret!!!!!!!{} msg_reply:{} sub_msg:{}".format(self.client_dev,msg_reply,sub_msg))
-                        self.client_dev.subscribe(sub_msg,0)#订阅消息主题
-                        print("Connected to dmp-mqtt.cuiot.cn, subscribed to /public/TEST/quecpython topic")
-                        # 发布消息
-                        # UnicodeHexStr_To_Utf8Str(str_data)
-                        date_tmp = utime.localtime()
-                        time_tmp = utime.mktime(date_tmp)#需要转换成毫秒级别
-                        updataTime = "{}".format(time_tmp*1000)
-                        imei_tmp = EventMesh.publish(constants.EVENT.GET_IMEI)
-                        imei = "{}".format(imei_tmp)
-                        bat_tmp = EventMesh.publish("screen_get_battery")
-                        power = 0
-                        power = int(bat_tmp[1])
-                        hr = 0
-                        hr = EventMesh.publish("get_old_hr_data")
-                        if hr == None:
-                            hr = 0
-                        deviceTime = "{}".format(time_tmp)
-                        manufactury = "fengda"
-                        DeviceState = "online"
-
-                        data_info = {
-                            "messageId":"0",
-                            "params": {
-                                "data": [
-                                    {
-                                        "key":"deviceOffOn",
-                                        "value": {
-                                            "deviceStatus":"Poweron",
-                                            "updateTime":updataTime,
-                                            "Imei":imei
-                                        }
-                                        
-                                    },
-                                    {
-                                        "key":"HeartRate",
-                                        "value":{
-                                            "heartRate":hr,
-                                            "updateTme":updataTime,
-                                            "Imei":imei
-                                        }
-                                    },
-                                    {
-                                        "key":"powerSavingMode",
-                                        "value":0
-                                    },
-                                    {
-                                        "key":"IMEI",
-                                        "value":imei
-                                    },
-                                    {
-                                        "key":"DEVICE_TIME",
-                                        "value":deviceTime
-                                    },
-                                    {
-                                        "key":"MANUFACTURER",
-                                        "value":manufactury
-                                    },
-                                    {
-                                        "key":"REMAINING_POWER",
-                                        "value":power
-                                    },
-                                    {
-                                        "key":"DeviceState",
-                                        "value":DeviceState
-                                    }
-                                ]
-                            }
-                        }
-                        
-                        data_json = ujson.dumps(data_info) 
-                        # print("data_json:{}",data_json)
-                        # $sys/cu1shld45y4hjr1L/{deviceKey}/property/batch
-                        msg_pub = "$sys/{}/{}/property/batch".format(get_productKey,get_deviceKey)
-                        pub_msg = msg_pub.encode('ascii')
-                        self.client_dev.publish(pub_msg,data_json,0)#publis主题内容
-
-                        print("Publish topic: /public/TEST/quecpython758, msg: my name is Quecpython")
-
-    def get_mqtt_pro_connect_state(self,event,msg):
-        return self.client
-    def get_mqtt_dev_connect_state(self,event,msg):
-        return self.client_dev
-    
-    def check(self, *args):
-        if (not self.run_flag) or (self.connect_tmp == 0) : #7分钟无数据读取,则认为是掉线了
-            EventMesh.debug_log("tcp reconnect!!!!!!!!!!!!!!!!!!")
-            EventMesh.publish(constants.EVENT.SET_CONNECT,0) #标记断网
-            self.reconnect()
-        self.connect_tmp = 0
-    def reconnect(self):
-        if(self.reconnect_flag == 1):
-            return
-        self.reconnect_flag = 1
-        self.reconnect_timer.start(self.reconnect_time, 0, self.reconnect_timer_cb)
-        if self.reconnect_time < 600*1000:
-            self.reconnect_time += 30*1000
-
-    def reconnect_timer_cb(self, *args): 
-        _thread.stack_size((9+1)*1024)
-        _thread.start_new_thread(self.connect, ())   
-        _thread.stack_size(8*1024)
+                print("self.IOT_sock {} self.start_voice_flag:{}".format(self.IOT_sock,self.start_voice_flag))
+                if self.IOT_sock != None:
+                    if self.timer_id == 0:
+                        # self.hr_report_timer.start(DEFINE_TIME_COUNT*1000, 1, self.hr_report_event)
+                        self.timer_id=1
+            else:
+                print("没有token!!!!!!!!!!")
+                self.connect_timer_count+=1
+                if self.connect_timer_count <= 10:
+                    print("IOT重连定时器开启")
+                    self.connect_timer.start(5000,0,self.iot_connect_timerCb)
+                pass
+        except Exception as e:   
+            self.IOT_sock = None
+            print("connect_iot_socket error")
+    def heart_IOt(self,event,msg):
+        print("heart_IOT.....")
+        #Header
+        header = ustruct.pack('>H', 0xFFFE)  # 使用大端模式
+        #Type
+        packet_type = ustruct.pack('B', 0x02)
+        #拼接
+        heart_packet = header + packet_type
+        EventMesh.publish("CHANNEL_IOT_SEND", heart_packet)
+        # print("心跳发送数据包:{}".format(heart_packet))
+
+    def send_packet_iot(self,data):#发送数据给iot,data为接口json数据
+        #Header
+        header = ustruct.pack('>H', 0xFFFE)  # 使用大端模式
+        #Type
+        packet_type = ustruct.pack('B', 0x03)
+        #字典转为json字符串
+        json_str = EventMesh.publish("GET_IOT_SEND_CMD", data)
+        json_str = ujson.dumps(json_str)
+        #字符串转为二进制数据Payload
+        payload = json_str.encode('utf-8')
+        #PayloadLen
+        payloadLen = ustruct.pack('H', len(payload))
+         #CRC16(2字节,基于pay字段计算)
+        crc = self.crc16(payload)
+        print("crc的长度为{}".format(len(crc)))
+        #拼接
+        full_packet = header + packet_type + payloadLen + payload+ crc
+        EventMesh.publish("CHANNEL_IOT_SEND", full_packet)
+        print("发送更新数据包:{}".format(full_packet))
+
+    def login_IOT(self,event,msg):
+        print("登录中")
+        #Header
+        header = ustruct.pack('>H', 0xFFFE)  # 使用大端模式
+        #Type
+        packet_type = ustruct.pack('B', 0x00)
+        #设备ID
+        device_id_bytes = modem.getDevImei().encode('utf-8')[:20]  # 转为字节并截断到20字节
+        device_id = bytes_ljust(device_id_bytes, 20, b'\x00')
+        #令牌
+        token_bytes = EventMesh.publish("get_dev_token").encode('utf-8')[:36]  # 转为字节并截断
+        token_padded = bytes_ljust(token_bytes, 36, b'\x00')
+        #拼接
+        body = header + packet_type + device_id + token_padded
+        #CRC16(2字节,基于上述所有字段计算)
+        crc = self.crc16(body)
+        # 完整数据包
+        full_packet = body + crc
+        EventMesh.publish("CHANNEL_IOT_SEND", full_packet)
+        print("登录发送数据包:{}".format(full_packet))
+
+
+    def crc16(self, data):
+        """计算CRC16校验值(MODBUS RTU模式)"""
+        crc = 0xFFFF
+        for byte in data:
+            crc ^= byte
+            for _ in range(8):
+                if crc & 0x0001:
+                    crc >>= 1
+                    crc ^= 0xA001
+                else:
+                    crc >>= 1
+        # 返回2字节小端模式
+        return ustruct.pack('<H', crc & 0xFFFF)
         
+    def close_socket_timer(self,event,msg):
+        self._1S_timer.stop()
+        self._5S_timer.stop()
+    
+    def _1S_timer_cb(self,*argc):
+        self.current_data = EventMesh.publish("screen_get_ai")  # 当前数据
+        if self.current_data is not self.last_data :
+            print("VC状态改变")
+            EventMesh.publish("send_device_VC_state")#上传VC状态
+        self.last_data = self.current_data  # 保存上一次的数据状态
+
     def socket_send_queue_thread(self):
         while True:
-            data = self.socket_send_queue.get()
-            EventMesh.debug_log("TCP:send data1 len:{}".format(len(data)))
-
-            #EventMesh.debug_log("ui_queue_thread:data = {}".format(data))
-            socketsta = self.sock.getsocketsta() 
-            if(socketsta == -1): #给释放了或者出错了
-                continue
-            if(socketsta == 4):#正常连击
+            # with self.sock_lock:  # 操作Socket前加锁
+                data = self.iot_soc_send_queue.get()   
                 if data != None:
-                    try:
-                        self.sock.send(data)
-                        EventMesh.debug_log("TCP:send data2 len:{}".format(len(data)))    
+                    try:  
+                        if self.IOT_sock is not None:
+                            self.IOT_sock.send(data)
+                            # EventMesh.debug_log("发送线程") 
+                            self.reconnect_count = 0
+                        else:
+                            EventMesh.publish("publish_AI_btnInfo",{"func":self.connect_iot_socket})
+                            # print("socket关闭退出send线程")
+                            # return
+                        EventMesh.debug_log("socket:send data2 len:{}".format(len(data),self.IOT_sock))    
                     except Exception as e:
-                        self.reconnect()
-                        self.socket_send_queue.put(data)#重新把数据加回队列
-                        #EventMesh.debug_log("socket_send_queue_thread1:ERROR:")
-                        #usys.print_exception(e)
-            elif socketsta < 4:#正在连接,等待连接成功重新发送
-                count = 0
-                while True:
-                    if count > 15 :
-                        break
-                    utime.sleep(1)
-                    if(self.sock.getsocketsta() == 4):#
-                        try:
-                            self.sock.send(data)
-                            EventMesh.debug_log("TCP:send data3 len:{}".format(len(data)))    
-                        except Exception as e:
-                            self.reconnect()
-                            self.socket_send_queue.put(data)#重新把数据加回队列
-                            #EventMesh.debug_log("socket_send_queue_thread2:ERROR:")
-                            #usys.print_exception(e)
+                        EventMesh.debug_log("socket:send error") 
+                        EventMesh.publish("publish_AI_btnInfo",{"func":self.connect_iot_socket})
                         break
-            else :#连接错误
-                EventMesh.debug_log("socket_send_queue_thread:ERROR:reconnect")
-                self.reconnect()
-            utime.sleep(1)
+             
+
+    def iot_protocol_recv(self):
+        while True:
+            # 死循环接收数据
+            # with self.sock_lock:  # 警告:不能加锁,不然会导致线程超长延时
+                socket_flag = self.IOT_sock.getsocketsta()
+                print("socket_flag = {}".format(socket_flag))
+                try:
+                    data = self.IOT_sock.recv(256)
+                    if isinstance(data, bytes) and len(data)>10:
+                        playload_data(data)
+                    socket_log.info("IOT_recv = {} ,len = {}".format(self.bytes_to_hex(data),len(data)))
+                    if self.IOT_sock == None:
+                        print("socket关闭退出send线程")
+                        return
+                except Exception as e:
+                    print("cli break")
+                    print("异常是:{}".format(e))
+                    # EventMesh.publish("connect_iot_websocket_cb")
+                    EventMesh.publish("publish_AI_btnInfo",{"func":self.connect_iot_socket}) 
+                    break
+        self.iot_protoclo_recv_id =None
+    def decode_with_multiple_encodings(self, data):
+        #尝试多种常见编码格式解码,返回第一个成功的结果
+        # 常见编码格式列表(按优先级排序,根据实际场景调整)
+        encodings = ['utf-8', 'gbk', 'latin-1', 'utf-16', 'gb2312']
+        
+        for encoding in encodings:
+            try:
+                # 尝试用当前编码解码,errors='strict'严格模式(确保无乱码)
+                return data.decode(encoding, errors='strict')
+            except UnicodeDecodeError:
+                continue  # 解码失败,尝试下一种编码
+        return None  # 所有编码都失败
+    
+    # bytes转十六进制字符串
+    def bytes_to_hex(self, data):
+        #将bytes类型转换为十六进制字符串(如b'\x03\x01' -> '0301')
+        hex_chars = '0123456789abcdef'
+        hex_str = ''
+        for b in data:
+            # 处理每个字节的高4位和低4位
+            hex_str += hex_chars[(b >> 4) & 0x0F]  # 高4位
+            hex_str += hex_chars[b & 0x0F]          # 低4位
+        return hex_str
+    
+    def iot_send_queue_close(self):
+        if self.socket_send_queue_id != None:
+            if self.iot_soc_send_queue.empty()!=True:
+                self.iot_soc_send_queue.clear()
+            try:
+                _thread.stop_thread(self.socket_send_queue_id)
+            except Exception as e:
+                print("iot_protoclo_recv_id !!!!!!!!")
+        print("iot_protoclo_recv_id 1111!!!!!!!!")
+        self.socket_send_queue_id = None
+    
+    def iot_protoclo_recv_close_therad(self):
+        if self.iot_protoclo_recv_id != None:
+            try:
+                _thread.stop_thread(self.iot_protoclo_recv_id)
+            except Exception as e:
+                print("self.iot_protoclo_recv_id !!!!!!!!")
+        self.iot_protoclo_recv_id = None
+        if self.IOT_sock != None:
+            try:
+                print("关闭socket")
+                self.IOT_sock.close()
+            except Exception as e:   
+                print("关闭socket失败")
+        self.IOT_sock = None
+        
+
+        
+    def iot_close_therad(self):
+        try:
+            self.iot_send_queue_close()
+        except Exception as e:
+            print("iot_send_queue_close error!!!!!!!!")
 
-    def send(self, topic, msg):
+        try:
+            self.iot_protoclo_recv_close_therad()
+        except Exception as e:
+            print("iot_protoclo_recv_close_therad error!!!!!!!!")
+        self.start_voice_flag = 0
+        print("iot_close_therad")
+    
+    def get_IOT_sock(self,event,msg):
+        return self.IOT_sock
+    def user_send(self,event,data):
+        # EventMesh.debug_log("TCP:send data:{}".format(msg))
         # EventMesh.debug_log("TCP:send data:{}".format(msg))
-        if EventMesh.publish("get_sim_Status") != 1: #没sim,则不发送
-            EventMesh.publish(constants.EVENT.SET_CONNECT, 0)#标记断网
-            EventMesh.debug_log("dataCall not connect")
+        sim_state = sim.getStatus() 
+        if sim.getStatus() != 1:#网络不正常
+            print("无 sim卡")
             return
         else :
             try:
-                self.socket_send_queue.put(msg)
+                if self.start_voice_flag == 0: #如果关闭了就需要重新再
+                    EventMesh.publish("publish_AI_btnInfo",{"func":self.connect_iot_socket}) 
+                    return
+                if data != None:
+                    if len(data) != 0:
+                        self.iot_soc_send_queue.put(data)
+                    # EventMesh.debug_log("self.socket_send_queue.put:success:{}".format(len(data)))
             except Exception as e:   
                 EventMesh.debug_log("self.socket_send_queue.put:ERROR:")
                 usys.print_exception(e) 
-                # self.run_flag = False
-
-    def recv(self):
-        data = b''
-        while True:
+                
+        return
+        sim_state = sim.getStatus() 
+        if sim_state != 1 or self.network_state == 0: #没sim,则不发送 ,没联网
+            return
+        else :
             try:
-                r =  b''
-                r = self.sock.recv(1024*5)
+                if self.IOT_sock != None:
+                    EventMesh.publish("publish_AI_btnInfo",{"func":self.iot_protocol_send_cb,"data":data})
+                else:
+                    print("reconnect1 {}".format(data))
+                    EventMesh.publish("publish_AI_btnInfo",{"func":self.connect_iot_socket})
 
-                if not r:
-                    self.run_flag = False
-                    self.reconnect()
-   
-                data = data + r
-                EventMesh.debug_log("TCP recv: data:len:{}".format(len(data)))
-                # EventMesh.debug_log("TCP recv: data:{}".format(data))
-                if data[-1] != 0x5d and len(data)<20*1024: #']':
-                    continue
-                self.connect_tmp = 1 #有数据,就认为是连接状态
-                self.reconnect_time = 1000
-                EventMesh.publish(constants.EVENT.SET_CONNECT, 1)
-                data_str = data.decode('ascii')
-                data_str = data_str.split(']')
-                if len(data_str) < 3 :
-                    self.resolver.handler(data)
-                else :
-                    for i in range(len(data_str)-1):
-                        self.resolver.handler(data_str[i])
-                
-                data = b''
-            except Exception as e:
-                #EventMesh.debug_log("TCP:ERROR:recv:")
-                #usys.print_exception(e)
-                self.run_flag = False
-                self.reconnect()
+            except Exception as e:   
+                print("senc data err reconnect{}".format(data))
+                EventMesh.publish("publish_AI_btnInfo",{"func":self.connect_iot_socket})
                 
-                data = b''
-                utime.sleep(2)
-
-
-
+    def iot_protocol_send_cb(self,data):
+        try:
+            if data != None:
+                print("socket connect success:{} self.IOT_sock:{}".format(data,self.IOT_sock))
+                if self.IOT_sock != None:
+                    self.IOT_sock.send(data)
+                    self.reconnect_count = 0
+                    print("socket send success")
+                else:
+                    print("reconnect2 {}".format(data))
+                    # EventMesh.publish("connect_iot_socket_cb")
+                    EventMesh.publish("publish_AI_btnInfo",{"func":self.connect_iot_socket})
+        except Exception as e:
+            print("发送失败 重新连接")
+            self.reconnect_count+=1
+            # EventMesh.publish("connect_iot_socket_cb")
+            EventMesh.publish("publish_AI_btnInfo",{"func":self.connect_iot_socket})
+   
+def bytes_ljust(data, length, fill_byte=b'\x00'):
+    """
+    手动实现bytes的ljust功能:将字节流填充到指定长度,不足部分用fill_byte在右侧填充
+    :param data: 原始字节流(bytes)
+    :param length: 目标长度(int)
+    :param fill_byte: 填充字节(默认空字节b'\x00')
+    :return: 填充后的字节流(bytes)
+    """
+    if len(data) >= length:
+        # 若原始长度已超过目标长度,直接截断到指定长度
+        return data[:length]
+    else:
+        # 计算需要填充的长度,用fill_byte补齐
+        padding = fill_byte * (length - len(data))
+        return data + padding
+    
 class NetManager(Abstract):
     THRESHOLD = 10
 
@@ -948,7 +975,6 @@ class NetManager(Abstract):
     def get_network_state(self, topic, msg):
         return self.network_state 
 
-
 class ProtoCol(Abstract):
     TYPE = ""
     HEADER = "#@{}@#;"
@@ -1050,7 +1076,72 @@ class ProtoCol(Abstract):
         #EventMesh.debug_log(res)
         #EventMesh.debug_log(MD5_head)
         return MD5_head
+#查找设备
+class IOT_FindDeviceProtoCol(ProtoCol):
+    """find_device"""
+    TYPE = "find_device"
 
+    def send(self, event, msg):
+        # print("send locafind_devicetion{}".format(msg))
+        # 通过websocket发送到服务器端
+        date_tmp = utime.localtime()
+        time_tmp = utime.mktime(date_tmp)
+        find_device = {
+            "cmd":"dispatch_rest",
+            "ts":time_tmp,
+            "msg":"消息收到响应",
+            "data":{
+                "cmd":"find_device",
+                "rest":"success",
+                "msg":"收到查找设备指令"
+            }
+        }
+        send_data = b''
+        send_data = protocol_send_total_data(find_device)
+        print("send_data find_device{}".format(send_data))
+        EventMesh.publish("CHANNEL_IOT_SEND", send_data)
+
+    def recv(self, event, msg):
+        """
+
+        @param event:定位信息下发
+        @param msg: 接收到的下行数据
+        """
+        alarm_TTS_str="在这呢"
+        base_sentence = "{}".format(alarm_TTS_str)
+        repeat_sentence = (base_sentence + ",") * 3  # 重复5次并加逗号分隔
+        final_sentence = repeat_sentence.rstrip(",")
+        
+        EventMesh.publish("play_tts",[final_sentence,1])  #播放tts闹钟文本内容
+        print("recv find_device{}".format(msg))
+        EventMesh.publish(WEB_CMD_ENUM.FIND_DEVCE_S_CMD)
+
+#上报设备VC状态    
+class IOT_post_device_stateProtoCol(ProtoCol):
+    """post_device_state"""
+    TYPE = "post_device_state"
+
+    def send(self, event, msg):
+        print("send post_device_state{}".format(msg))
+        # 通过websocket发送到服务器端
+       
+        send_data = b''
+        send_data = protocol_send_total_data(msg)
+        EventMesh.publish("CHANNEL_IOT_SEND",send_data)
+
+    def recv(self, event, msg):
+        """
+
+        @param event:mpost_device_state
+        @param msg: 接收到的下行数据
+        """
+        # locate_now = {
+        #     "cmd":"locate_duration",
+        #     "ts":1738283829,
+        #     "msg":"下发定位周期",
+        #     "data":300,0表示关
+        # }
+        print("send post_device_state{}".format(msg))
 class LK_ProtoCol(ProtoCol):
     """链路保持"""
     TYPE = "LK"
@@ -1605,12 +1696,6 @@ class REMIND_ProtoCol(ProtoCol):#普通闹钟
         EventMesh.publish(constants.PROTOCOL.REMIND_SEND)   
         EventMesh.publish("clear_normal_alarm")
 
-
-
-
-
-
-
 class HRSTART_ProtoCol(ProtoCol):
     """心率频率数据"""
     TYPE = "hrtstart"
@@ -3747,13 +3832,7 @@ class ProtoColResolver(object):
         try:
             if len(data) > 0: 
                 #EventMesh.debug_log("handler:{}".format(len(data)))
-                data_tmp = data.decode('ascii')
-                data_tmp = data_tmp.split(']')[0] #去掉]
-                ProtoCol_type = data_tmp.split('*')[3] #拿到协议标识
-                ProtoCol_type = ProtoCol_type.split(',')[0]
-                ProtoCol_type = "%s_RECV"%(ProtoCol_type)
-                # EventMesh.debug_log("ProtoColResolver:ProtoCol_type:%s\r\ndata:%s"%(ProtoCol_type,data))
-                EventMesh.publish(ProtoCol_type, data) #返回协议read
+                playload_data(data)
         except Exception as e:
             EventMesh.debug_log("handler:ERROR:")
             usys.print_exception(e)
index 87f71df..a88f6af 100644 (file)
@@ -23,6 +23,7 @@ from queue import Queue
 from machine import RTC
 import usys
 from Gsensor import SC7A20
+
 def audio_cb(event):
     if event == 0:
         EventMesh.publish("set_audio_state", 1)
@@ -1721,6 +1722,9 @@ class chargefullScreen(Screen):#充电已满弹窗提示
         energe_img.add_style(style_img, lv.PART.MAIN | lv.STATE.DEFAULT)
 
         self.meta = self.charge_full_screen
+        
+
+    def post_processor_after_initialization(self):
         self.count = 0
         self.timer.start(1*1000,1,self.fun)
 
@@ -1732,10 +1736,10 @@ class chargefullScreen(Screen):#充电已满弹窗提示
     def fun(self,*argc):
         EventMesh.publish("system_sleep_rest")#防止黑屏
         self.count+=1
-        if self.count > 2*60:
+        if self.count > 5:
             self.count = 0
             self.timer.stop()
-            #EventMesh.publish("return_prev_screen")
+            EventMesh.publish("load_screen", {"screen": "main_menu"})
     
     def done_click(self):
         EventMesh.publish("return_prev_screen")
@@ -1755,7 +1759,8 @@ ui_screen.add_style(style_screen, lv.PART.MAIN | lv.STATE.DEFAULT)
 ai_img = lv.img(ui_screen)
 ai_img.set_pos(0, 0)
 ai_img.set_size(240, 320)
-ai_img.set_src("E:/static/listen.png")
+# ai_img.set_src("E:/static/listen.jpg")
+ai_img.set_src("E:/static/01.jpg")
 ai_img.add_style(style_img, lv.PART.MAIN | lv.STATE.DEFAULT) 
 class UI_ai(Screen):
     NAME = "UI_ai"
@@ -1765,14 +1770,44 @@ class UI_ai(Screen):
         print("UI_ai:__init__")
         self.meta = ui_screen
         self.timer = osTimer()
-
+        self.image_sequences = {
+            # 为不同face_status定义图片序列,格式: [(图片路径, 显示时长), ...]
+            0: [("E:/static/61.jpg", 0.5), #平常说
+                    ("E:/static/62.jpg", 0.5)],
+            # 1: [("E:/static/dj1.jpg", 0.5), #大吉
+            #         ("E:/static/dj2.jpg", 0.5)],
+            # 2: [("E:/static/zj1.jpg", 0.5),#中吉
+            #         ("E:/static/zj2.jpg", 0.5)],
+            # 3: [("E:/static/j1.jpg", 0.5), #吉
+            #         ("E:/static/j2.jpg", 0.5)],
+            # 4: [("E:/static/mj1.jpg", 0.5), #末吉
+            #         ("E:/static/mj2.jpg", 0.5)],
+            1: [("E:/static/61.jpg", 0.5), #大吉
+                    ("E:/static/62.jpg", 0.5)],
+            2: [("E:/static/61.jpg", 0.5),#中吉
+                    ("E:/static/62.jpg", 0.5)],
+            3: [("E:/static/61.jpg", 0.5), #吉
+                    ("E:/static/62.jpg", 0.5)],
+            4: [("E:/static/61.jpg", 0.5), #末吉
+                    ("E:/static/62.jpg", 0.5)],
+            5: [("E:/static/01.jpg", 0.5), 
+                    ("E:/static/02.jpg", 0.5)],#听
+            6: [("E:/static/51.jpg", 0.5), 
+                    ("E:/static/52.jpg", 0.5)],#思考
+        }
+        self.current_sequence = None
+        self.sequence_thread = None
+        self.running = False
+        #硬件资源缓存标识,记录当前加载的图片路径
+        self.current_image_path = None
     def initialization(self):   
         print("UI_ai:initialization") 
         #获取ai状态
         ai_status = EventMesh.publish("screen_get_ai")
         if ai_status:
-            self.__ai_vc(None, ai_status)
-        self.timer.start(500,1, self.timerout_update)
+            self.__ai_vc(None, ai_status,0)
+        self.timer.start(2000,1, self.timerout_update)
+        EventMesh.subscribe("UI_ai_close",self.UI_ai_close)
 
     def timerout_update(self, *args):
         EventMesh.publish("publish_message_event_ui",{"func":self.timerout_update_cb,"data":0})
@@ -1781,19 +1816,117 @@ class UI_ai(Screen):
         EventMesh.publish("system_sleep_rest")#防止黑屏
         #获取ai状态
         ai_status = EventMesh.publish("screen_get_ai")
+        draw_status = EventMesh.publish("screen_get_draw")
+        # print ("draw_status = {}".format(draw_status))
         # print("ai_status = {}".format(ai_status))
-        self.__ai_vc(None, ai_status)
-    def __ai_vc(self, event, msg):
+        self.__ai_vc(None, ai_status,draw_status)
+
+    def __ai_vc(self, event, msg,draw_status):
     #msg = 1:listen,2:think,3:speak
+        # 记录上一次的face_status,避免重复启动
+        if not hasattr(self, "last_face_status"):
+            self.last_face_status = -1  # 初始化
+        target_status = None
         if msg < 6:
-           ai_img.set_src("E:/static/listen.png")#正在听    
+            target_status = 5
         elif msg == 6:
-           ai_img.set_src("E:/static/think.png")#正在想
+            target_status = 6
         elif msg == 8:
-           ai_img.set_src("E:/static/speak.png")#正在说
-        # elif msg == 14:
-        #    ai_img.set_src("E:/static/listen.png")#正在听    
-        pass
+            target_status = draw_status
+        
+        # 仅当状态变化时,才启动新线程
+        if target_status is not None and target_status != self.last_face_status:
+            lv.img.cache_invalidate_src(None)
+            lv.img.cache_set_size(8)
+            EventMesh.publish("publish_message_event_ui", {"func": self.start_sequence, "data": target_status})
+            self.last_face_status = target_status  # 更新状态
+    def UI_ai_close(self,event,msg):
+        if self.running:
+            self.stop_sequence()
+        self.timer.stop()
+        lv.img.cache_invalidate_src(None)
+        lv.img.cache_set_size(8)
+
+    def start_sequence(self, face_status):
+        #停止当前序列(确保旧线程退出)
+        if self.running:
+            self.stop_sequence()
+        #强制等待旧线程彻底退出(延长等待时间+主动清理)
+        start_wait = utime.time()
+        while self.sequence_thread is not None:
+            utime.sleep(0.05)  # 更短间隔检测
+            if utime.time() - start_wait > 2:  # 延长等待至2秒
+                print("警告:旧线程超时未退出,强制清理")
+                self.sequence_thread = None  # 强制重置标识
+                break
+        
+        # 启动新线程前清理硬件资源
+        if self.current_image_path:
+            self.current_image_path = None  # 重置路径记录
+        
+        #启动新线程
+        if face_status in self.image_sequences:
+            self.current_sequence = self.image_sequences[face_status]
+            self.running = True
+            self.sequence_thread = _thread.start_new_thread(self._play_sequence, ())
+            print("启动新线程")
+    
+    def stop_sequence(self):
+        #停止当前图片序列轮播
+        self.running = False  # 仅设置标志位,让线程自然退出
+        # 等待线程退出(最多等待1秒,避免无限阻塞)
+        start_wait = utime.time()
+        while self.sequence_thread is not None and utime.time() - start_wait < 2:
+            utime.sleep(0.1)  # 短休眠等待
+    def _play_sequence(self):
+        try:
+            while self.running:
+                current = list(self.current_sequence)
+                if not current:
+                    utime.sleep(0.1)
+                    continue
+                for image_path, duration in current:
+                    if not self.running:
+                        break
+                    # 硬件操作添加超时和详细日志
+                    try:
+                        # 记录开始时间,防止set_src无限阻塞
+                        set_start = utime.time()
+                        ai_img.set_src(image_path)
+                        # 检查set_src是否耗时过长
+                        # 记录当前图片路径,用于后续清理
+                        self.current_image_path = image_path
+                        if utime.time() - set_start > 1:
+                            print("警告:set_src()耗时过长")
+                    except OSError as e:  # 捕获硬件相关错误
+                        print("硬件错误:设置图片失败")
+                        # 发生硬件错误后,暂停轮播避免持续冲突
+                        self.running = False
+                        break
+                    except Exception as e:
+                        print("未知错误:设置图片失败")
+                        continue
+
+                    # 分段休眠逻辑保持,但增加超时保护
+                    start_time = utime.time()
+                    sleep_ok = True
+                    while utime.time() - start_time < duration:
+                        if not self.running:
+                            sleep_ok = False
+                            break
+                        utime.sleep(0.05)
+                    if not sleep_ok:
+                        break
+                utime.sleep(0.1)
+        except Exception as e:
+            print("轮播线程异常(致命)")
+        finally:
+            # 加锁确保线程安全
+            self.running = False
+            self.sequence_thread = None
+            self.current_image_path = None
+            print("轮播线程已退出并释放资源")
+   
     def post_processor_before_initialization(self):
         pass
     def post_processor_after_initialization(self):
@@ -1804,6 +1937,7 @@ class UI_ai(Screen):
         return self.meta
     def Close(self):
         self.timer.stop()
+        EventMesh.publish("return_prev_screen")
 message_popup_screen = None
 message_popup_title = None
 #信息弹窗
@@ -5910,8 +6044,8 @@ class LowPowerScreen(Screen):
             Lowpower_screen.add_style(style_screen, lv.PART.MAIN|lv.STATE.DEFAULT)
             #进入图片
             Lowpower_screen_img = lv.img(Lowpower_screen)
-            Lowpower_screen_img.set_pos(int(40),int(45))
-            Lowpower_screen_img.set_size(160,230)
+            Lowpower_screen_img.set_pos(int(0),int(0))
+            Lowpower_screen_img.set_size(240,320)
             Lowpower_screen_img.set_scrollbar_mode(lv.SCROLLBAR_MODE.OFF)
             Lowpower_screen_img.add_flag(lv.obj.FLAG.CLICKABLE)
             Lowpower_screen_img.set_src("E:/static/low_power.png")
@@ -6460,14 +6594,15 @@ class chargeInScreen(Screen):
             # charge_in_screen_label.set_long_mode(lv.label.LONG.WRAP)
             # charge_in_screen_label.set_style_text_align(lv.TEXT_ALIGN.CENTER, 0)
 
-        charge_out_img = lv.img(self.charge_in_screen)
-        charge_out_img.set_size(240, 320)
-        charge_out_img.set_src("E:/static/charge_in.png")
-        charge_out_img.add_flag(lv.obj.FLAG.CLICKABLE)
-        charge_out_img.add_style(style_img, lv.PART.MAIN | lv.STATE.DEFAULT)
-        charge_out_img.set_pos(0, 0)
+        charge_in_img = lv.img(self.charge_in_screen)
+        charge_in_img.set_size(240, 320)
+        charge_in_img.set_src("E:/static/charge_in.png")
+        charge_in_img.add_flag(lv.obj.FLAG.CLICKABLE)
+        charge_in_img.add_style(style_img, lv.PART.MAIN | lv.STATE.DEFAULT)
+        charge_in_img.set_pos(0, 0)
 
         self.meta = self.charge_in_screen
+       
 
 
     def post_processor_after_initialization(self):
@@ -6482,7 +6617,8 @@ class chargeInScreen(Screen):
         self.count+=1
         if self.count >= 5:
             self.count = 0
-            EventMesh.publish("return_prev_screen")
+            self.timer.stop()
+            EventMesh.publish("load_screen", {"screen": "main_menu"})
 
 
     def done_left_to_right(self):
@@ -6817,7 +6953,7 @@ class UI(object):
         self.rotate_flag = 0 #0为原来的,1为垂直翻转后的
 
         if self.level == None:
-            self.level = 6
+            self.level = 10
         self.PWM_backlight = PWM(PWM.PWM1, PWM.ABOVE_MS, self.level, 10)
         self.PWM_backlight.open()
         self.gsensor = SC7A20()
@@ -6832,12 +6968,16 @@ class UI(object):
     def set_rotation(self,angle):#软件设置屏幕方向
         global disp_drv
         PWM_backlight.close()
+        if disp_drv.rotated == angle:
+            return
         disp_drv.rotated = angle
         # 重新注册驱动
         disp_drv.register()
+        lv.img.cache_invalidate_src(None)
+        lv.img.cache_set_size(8)
         # 刷新屏幕
         lv.scr_load(lv.scr_act())
-        utime.sleep_ms(200)
+        utime.sleep_ms(750)
         PWM_backlight.open()
 
     def gsensor_cb(self, para):
@@ -7113,13 +7253,16 @@ class UI(object):
             utime.sleep_ms(60)
             self.level = EventMesh.publish("get_brightness_level")
             if self.level == None:
-                self.level = 6 
+                self.level = 10
             elif self.level > 10:
                 self.level = 10
             elif self.level <= 0:
                 self.level = 1
+            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()
+            
             self.sleep_lock = 0
             
 
@@ -7139,6 +7282,14 @@ class UI(object):
             self.PWM_backlight.open()
             #lcd_ctrl.write(0)
             #
+            #检测闹钟是否还存在,若存在不关闭定时器,若没有闹钟则关闭定时器
+
+            get_have_alarm = EventMesh.publish("get_have_alarm")
+            if get_have_alarm == 0:#不存在闹钟
+                alarm_timer_sta = EventMesh.publish("alarm_get_statu")#看定时器是否开启
+                if alarm_timer_sta == 1 :#当定时器开启时
+                    EventMesh.publish("AI_alarm_close")#关闭轮询
+                    alarm_timer_sta = 0
             lv.autoSleep(1)
             pm.autosleep(1)
             pm.sclkEx_set(1, 1, 5)
@@ -7149,6 +7300,7 @@ class UI(object):
             EventMesh.publish("set_lcd_state",self.sleep_flag)
             self.sleep_lock = 0
             self.screen.lcd_off()
+            self.screen.Close()
             self.system_sleep_timer.stop()
             EventMesh.publish("Hsensor_set_sleep") #让系统更快休眠
 
@@ -7237,7 +7389,7 @@ class UI(object):
                 if self.screen_old != None :
                     self.screen_old.Close() #先关闭上一次界面
                     self.lv.img.cache_invalidate_src(None) #清img cache
-                    self.lv.img.cache_set_size(16) #开img cache
+                    self.lv.img.cache_set_size(8) #开img cache
                     if self.screen.meta_type != "popup": #只要当前界面不是弹窗界面都要保存当前界面
                         if self.screen_old.meta_type != "popup":#上个界面也不为弹窗界面
                             self.screen_prev = self.screen_old #第二种方式
@@ -7251,21 +7403,25 @@ class UI(object):
                 print("load_screen:post_processor_before_initialization")
                 self.screen.post_processor_before_initialization()
                 self.screen_old = self.screen
+                utime.sleep_ms(100)
                 print("load_screen:initialization")
                 self.screen.initialization()
                 
                 print("load_screen.load()1")
+                
                 self.screen.load()
                 #print("load_screen.load()2")
                 self.lv.scr_load(self.screen.get_meta())
-                #print("load_screen.load()3")
-                
-                self.screen.post_processor_after_initialization()
-                #print("load_screen.load()4")
                 if self.screen_prev == None:
                     if self.screen.meta_type != "popup":
                         self.screen_prev = self.screen
+                #print("load_screen.load()3")
                 self.__lcd_on()
+                utime.sleep_ms(100)
+                self.screen.post_processor_after_initialization()
+                #print("load_screen.load()4")
+                
+                # self.__lcd_on()
                 #print("load_screen.load()5")
                 mem = gc.mem_free()
                 #print('2剩余内存RAM:{} KB'.format(mem / 1024))
index 74a9de8..6eeab82 100644 (file)
@@ -139,7 +139,7 @@ def get_week(msg):
 
 
 watchface1_time1_text = lv.label(Watchface1)
-watchface1_time1_text.set_pos(30, 139)
+watchface1_time1_text.set_pos(30, 110)
 watchface1_time1_text.set_size(240, 71)
 watchface1_time1_text.set_align(lv.TEXT_ALIGN.LEFT)
 watchface1_time1_text.set_text("{}:{}".format("%02d"%(hour),"%02d"%(min)))
@@ -179,14 +179,14 @@ status_img3.add_style(style_watchface_img_default, lv.PART.MAIN|lv.STATE.DEFAULT
 
 #日期
 watchface1_date_span = lv.label(Watchface1)
-watchface1_date_span.set_pos(8, 122)
-watchface1_date_span.set_size(140, 30)
+watchface1_date_span.set_pos(85, 191)
+watchface1_date_span.set_size(140, 50)
 watchface1_date_span.set_align(lv.TEXT_ALIGN.LEFT)
 watchface1_date_span.set_text("")
 watchface1_date_span.add_style(style_font_youyuan_28, lv.PART.MAIN|lv.STATE.DEFAULT)
 #星期
 watchface1_week_span = lv.label(Watchface1)
-watchface1_week_span.set_pos(8, 160)
+watchface1_week_span.set_pos(85, 230)
 watchface1_week_span.set_size(100, 30)
 watchface1_week_span.set_align(lv.TEXT_ALIGN.LEFT)
 watchface1_week_span.set_text("")
@@ -260,6 +260,7 @@ class WatchFace1():
         self.__stepValue(None, step)
 
     def timerout_update(self):
+        # print("主界面定时器在更新")
         signal = EventMesh.publish("screen_get_sig")
         if signal:
             self.__signal(None, signal)
@@ -288,9 +289,8 @@ class WatchFace1():
     def __time(self, event, msg):
         #时间
         watchface1_time1_text.set_text("{}:{}".format("%02d"%(msg[0][0]),"%02d"%(msg[0][1])))
-
-        # watchface1_date_span.set_text(msg[2])#日期
-        # watchface1_week_span.set_text(msg[3])   #星期
+        watchface1_date_span.set_text(msg[2])#日期
+        watchface1_week_span.set_text(msg[3])   #星期
 
     def __signal(self, event, msg):
         #print("__signal_cb:",str(msg))
index 14def22..166374e 100644 (file)
Binary files a/2.sdk/project/K8/sdk/system/platform/ASR_1606/boards/EG810MCN_GA_VOLTE/images/firmware_base_release_pack.zip and b/2.sdk/project/K8/sdk/system/platform/ASR_1606/boards/EG810MCN_GA_VOLTE/images/firmware_base_release_pack.zip differ
diff --git a/2.sdk/project/K8/usr/audio_gain.nvm b/2.sdk/project/K8/usr/audio_gain.nvm
new file mode 100644 (file)
index 0000000..f34e83b
Binary files /dev/null and b/2.sdk/project/K8/usr/audio_gain.nvm differ
index a33dd45..43ef7f6 100644 (file)
Binary files a/2.sdk/project/K8/usr/audio_ve.nvm and b/2.sdk/project/K8/usr/audio_ve.nvm differ
diff --git a/2.sdk/project/K8/usr/static/0.png b/2.sdk/project/K8/usr/static/0.png
new file mode 100644 (file)
index 0000000..28b2f12
Binary files /dev/null and b/2.sdk/project/K8/usr/static/0.png differ
diff --git a/2.sdk/project/K8/usr/static/1.png b/2.sdk/project/K8/usr/static/1.png
new file mode 100644 (file)
index 0000000..92910b1
Binary files /dev/null and b/2.sdk/project/K8/usr/static/1.png differ
diff --git a/2.sdk/project/K8/usr/static/100.png b/2.sdk/project/K8/usr/static/100.png
new file mode 100644 (file)
index 0000000..6c15fbd
Binary files /dev/null and b/2.sdk/project/K8/usr/static/100.png differ
diff --git a/2.sdk/project/K8/usr/static/2.png b/2.sdk/project/K8/usr/static/2.png
new file mode 100644 (file)
index 0000000..9d84e33
Binary files /dev/null and b/2.sdk/project/K8/usr/static/2.png differ
diff --git a/2.sdk/project/K8/usr/static/20.png b/2.sdk/project/K8/usr/static/20.png
new file mode 100644 (file)
index 0000000..5637e71
Binary files /dev/null and b/2.sdk/project/K8/usr/static/20.png differ
diff --git a/2.sdk/project/K8/usr/static/3.png b/2.sdk/project/K8/usr/static/3.png
new file mode 100644 (file)
index 0000000..9cc577d
Binary files /dev/null and b/2.sdk/project/K8/usr/static/3.png differ
diff --git a/2.sdk/project/K8/usr/static/4.png b/2.sdk/project/K8/usr/static/4.png
new file mode 100644 (file)
index 0000000..bf44f21
Binary files /dev/null and b/2.sdk/project/K8/usr/static/4.png differ
diff --git a/2.sdk/project/K8/usr/static/40.png b/2.sdk/project/K8/usr/static/40.png
new file mode 100644 (file)
index 0000000..96bb25e
Binary files /dev/null and b/2.sdk/project/K8/usr/static/40.png differ
diff --git a/2.sdk/project/K8/usr/static/60.png b/2.sdk/project/K8/usr/static/60.png
new file mode 100644 (file)
index 0000000..bed9019
Binary files /dev/null and b/2.sdk/project/K8/usr/static/60.png differ
diff --git a/2.sdk/project/K8/usr/static/80.png b/2.sdk/project/K8/usr/static/80.png
new file mode 100644 (file)
index 0000000..80378a4
Binary files /dev/null and b/2.sdk/project/K8/usr/static/80.png differ
diff --git a/2.sdk/project/K8/usr/static/isconnect.png b/2.sdk/project/K8/usr/static/isconnect.png
new file mode 100644 (file)
index 0000000..551708f
Binary files /dev/null and b/2.sdk/project/K8/usr/static/isconnect.png differ
diff --git a/2.sdk/project/K8/usr/static/nosim.png b/2.sdk/project/K8/usr/static/nosim.png
new file mode 100644 (file)
index 0000000..6288a73
Binary files /dev/null and b/2.sdk/project/K8/usr/static/nosim.png differ
diff --git a/2.sdk/project/K8/usr/static/notconnect.png b/2.sdk/project/K8/usr/static/notconnect.png
new file mode 100644 (file)
index 0000000..515ac2d
Binary files /dev/null and b/2.sdk/project/K8/usr/static/notconnect.png differ
diff --git a/2.sdk/project/K8/usr/static/open.PNG b/2.sdk/project/K8/usr/static/open.PNG
new file mode 100644 (file)
index 0000000..9dab238
Binary files /dev/null and b/2.sdk/project/K8/usr/static/open.PNG differ